summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/window/TaskFragmentInfo.java22
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java4
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java1
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java2
-rw-r--r--services/core/java/com/android/server/wm/Task.java35
-rw-r--r--services/core/java/com/android/server/wm/TaskFragment.java18
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskTests.java22
9 files changed, 84 insertions, 24 deletions
diff --git a/core/java/android/window/TaskFragmentInfo.java b/core/java/android/window/TaskFragmentInfo.java
index e2c8a31cc987..dc60eddaf7db 100644
--- a/core/java/android/window/TaskFragmentInfo.java
+++ b/core/java/android/window/TaskFragmentInfo.java
@@ -83,6 +83,12 @@ public final class TaskFragmentInfo implements Parcelable {
private final boolean mIsTaskFragmentClearedForPip;
/**
+ * Whether the last running activity of the TaskFragment was removed because it was reordered to
+ * front of the Task.
+ */
+ private final boolean mIsClearedForReorderActivityToFront;
+
+ /**
* The maximum {@link ActivityInfo.WindowLayout#minWidth} and
* {@link ActivityInfo.WindowLayout#minHeight} aggregated from the TaskFragment's child
* activities.
@@ -96,7 +102,7 @@ public final class TaskFragmentInfo implements Parcelable {
@NonNull Configuration configuration, int runningActivityCount,
boolean isVisible, @NonNull List<IBinder> activities, @NonNull Point positionInParent,
boolean isTaskClearedForReuse, boolean isTaskFragmentClearedForPip,
- @NonNull Point minimumDimensions) {
+ boolean isClearedForReorderActivityToFront, @NonNull Point minimumDimensions) {
mFragmentToken = requireNonNull(fragmentToken);
mToken = requireNonNull(token);
mConfiguration.setTo(configuration);
@@ -106,6 +112,7 @@ public final class TaskFragmentInfo implements Parcelable {
mPositionInParent.set(positionInParent);
mIsTaskClearedForReuse = isTaskClearedForReuse;
mIsTaskFragmentClearedForPip = isTaskFragmentClearedForPip;
+ mIsClearedForReorderActivityToFront = isClearedForReorderActivityToFront;
mMinimumDimensions.set(minimumDimensions);
}
@@ -160,6 +167,11 @@ public final class TaskFragmentInfo implements Parcelable {
return mIsTaskFragmentClearedForPip;
}
+ /** @hide */
+ public boolean isClearedForReorderActivityToFront() {
+ return mIsClearedForReorderActivityToFront;
+ }
+
@WindowingMode
public int getWindowingMode() {
return mConfiguration.windowConfiguration.getWindowingMode();
@@ -207,6 +219,7 @@ public final class TaskFragmentInfo implements Parcelable {
&& mPositionInParent.equals(that.mPositionInParent)
&& mIsTaskClearedForReuse == that.mIsTaskClearedForReuse
&& mIsTaskFragmentClearedForPip == that.mIsTaskFragmentClearedForPip
+ && mIsClearedForReorderActivityToFront == that.mIsClearedForReorderActivityToFront
&& mMinimumDimensions.equals(that.mMinimumDimensions);
}
@@ -220,6 +233,7 @@ public final class TaskFragmentInfo implements Parcelable {
mPositionInParent.readFromParcel(in);
mIsTaskClearedForReuse = in.readBoolean();
mIsTaskFragmentClearedForPip = in.readBoolean();
+ mIsClearedForReorderActivityToFront = in.readBoolean();
mMinimumDimensions.readFromParcel(in);
}
@@ -235,6 +249,7 @@ public final class TaskFragmentInfo implements Parcelable {
mPositionInParent.writeToParcel(dest, flags);
dest.writeBoolean(mIsTaskClearedForReuse);
dest.writeBoolean(mIsTaskFragmentClearedForPip);
+ dest.writeBoolean(mIsClearedForReorderActivityToFront);
mMinimumDimensions.writeToParcel(dest, flags);
}
@@ -262,8 +277,9 @@ public final class TaskFragmentInfo implements Parcelable {
+ " activities=" + mActivities
+ " positionInParent=" + mPositionInParent
+ " isTaskClearedForReuse=" + mIsTaskClearedForReuse
- + " isTaskFragmentClearedForPip" + mIsTaskFragmentClearedForPip
- + " minimumDimensions" + mMinimumDimensions
+ + " isTaskFragmentClearedForPip=" + mIsTaskFragmentClearedForPip
+ + " mIsClearedForReorderActivityToFront=" + mIsClearedForReorderActivityToFront
+ + " minimumDimensions=" + mMinimumDimensions
+ "}";
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 16760e26b3f1..d52caaf4c3e8 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -389,6 +389,10 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
// launching activity in the Task.
mTransactionManager.getCurrentTransactionRecord().setOriginType(TRANSIT_CLOSE);
mPresenter.cleanupContainer(wct, container, false /* shouldFinishDependent */);
+ } else if (taskFragmentInfo.isClearedForReorderActivityToFront()) {
+ // Do not finish the dependents if this TaskFragment was cleared to reorder
+ // the launching Activity to front of the Task.
+ mPresenter.cleanupContainer(wct, container, false /* shouldFinishDependent */);
} else if (!container.isWaitingActivityAppear()) {
// Do not finish the container before the expected activity appear until
// timeout.
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java
index 40f7a273980a..92011af27619 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java
@@ -169,6 +169,7 @@ public class EmbeddingTestUtils {
new Point(),
false /* isTaskClearedForReuse */,
false /* isTaskFragmentClearedForPip */,
+ false /* isClearedForReorderActivityToFront */,
new Point());
}
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java
index 957a24873998..79813c7d064e 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java
@@ -144,6 +144,6 @@ public class JetpackTaskFragmentOrganizerTest {
mock(WindowContainerToken.class), new Configuration(), 0 /* runningActivityCount */,
false /* isVisible */, new ArrayList<>(), new Point(),
false /* isTaskClearedForReuse */, false /* isTaskFragmentClearedForPip */,
- new Point());
+ false /* isClearedForReorderActivityToFront */, new Point());
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index a857d900d771..3ec24d5d4d7d 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2136,7 +2136,7 @@ class ActivityStarter {
mStartActivity.mUserId);
if (act != null) {
final Task task = act.getTask();
- boolean actuallyMoved = task.moveActivityToFrontLocked(act);
+ boolean actuallyMoved = task.moveActivityToFront(act);
if (actuallyMoved) {
// Only record if the activity actually moved.
mMovedToTopActivity = act;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index dfb61a8cf989..51d4bd220bc1 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -1401,13 +1401,26 @@ class Task extends TaskFragment {
* Reorder the history task so that the passed activity is brought to the front.
* @return whether it was actually moved (vs already being top).
*/
- final boolean moveActivityToFrontLocked(ActivityRecord newTop) {
+ final boolean moveActivityToFront(ActivityRecord newTop) {
ProtoLog.i(WM_DEBUG_ADD_REMOVE, "Removing and adding activity %s to root task at top "
+ "callers=%s", newTop, Debug.getCallers(4));
- int origDist = getDistanceFromTop(newTop);
- positionChildAtTop(newTop);
+ final TaskFragment taskFragment = newTop.getTaskFragment();
+ boolean moved;
+ if (taskFragment != this) {
+ if (taskFragment.isEmbedded() && taskFragment.getNonFinishingActivityCount() == 1) {
+ taskFragment.mClearedForReorderActivityToFront = true;
+ }
+ newTop.reparent(this, POSITION_TOP);
+ moved = true;
+ if (taskFragment.isEmbedded()) {
+ mAtmService.mWindowOrganizerController.mTaskFragmentOrganizerController
+ .onActivityReparentedToTask(newTop);
+ }
+ } else {
+ moved = moveChildToFront(newTop);
+ }
updateEffectiveIntent();
- return getDistanceFromTop(newTop) != origDist;
+ return moved;
}
@Override
@@ -3075,20 +3088,6 @@ class Task extends TaskFragment {
});
}
- void positionChildAtTop(ActivityRecord child) {
- positionChildAt(child, POSITION_TOP);
- }
-
- void positionChildAt(ActivityRecord child, int position) {
- if (child == null) {
- Slog.w(TAG_WM,
- "Attempted to position of non-existing app");
- return;
- }
-
- positionChildAt(position, child, false /* includeParents */);
- }
-
void setTaskDescription(TaskDescription taskDescription) {
mTaskDescription = taskDescription;
}
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 6588f26c513a..911a8da1db99 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -249,6 +249,12 @@ class TaskFragment extends WindowContainer<WindowContainer> {
boolean mClearedTaskFragmentForPip;
/**
+ * The last running activity of the TaskFragment was removed and added to the top-most of the
+ * Task because it was launched with FLAG_ACTIVITY_REORDER_TO_FRONT.
+ */
+ boolean mClearedForReorderActivityToFront;
+
+ /**
* When we are in the process of pausing an activity, before starting the
* next one, this variable holds the activity that is currently being paused.
*
@@ -1868,6 +1874,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
ActivityRecord r = topRunningActivity();
mClearedTaskForReuse = false;
mClearedTaskFragmentForPip = false;
+ mClearedForReorderActivityToFront = false;
final ActivityRecord addingActivity = child.asActivityRecord();
final boolean isAddingActivity = addingActivity != null;
@@ -2456,6 +2463,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
positionInParent,
mClearedTaskForReuse,
mClearedTaskFragmentForPip,
+ mClearedForReorderActivityToFront,
calculateMinDimension());
}
@@ -2742,6 +2750,16 @@ class TaskFragment extends WindowContainer<WindowContainer> {
return callback.test(this) ? this : null;
}
+ /**
+ * Moves the passed child to front
+ * @return whether it was actually moved (vs already being top).
+ */
+ boolean moveChildToFront(WindowContainer newTop) {
+ int origDist = getDistanceFromTop(newTop);
+ positionChildAt(POSITION_TOP, newTop, false /* includeParents */);
+ return getDistanceFromTop(newTop) != origDist;
+ }
+
String toFullString() {
final StringBuilder sb = new StringBuilder(128);
sb.append(this);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index bd8da4e713b7..079897bc099f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -2806,7 +2806,7 @@ public class ActivityRecordTests extends WindowTestsBase {
final Task task = activity.getTask();
final ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(task).build();
topActivity.setVisible(false);
- task.positionChildAt(topActivity, POSITION_TOP);
+ task.positionChildAt(POSITION_TOP, topActivity, false /* includeParents */);
activity.addStartingWindow(mPackageName, android.R.style.Theme, null, true, true, false,
true, false, false, false);
waitUntilHandlersIdle();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index 0b6cea28e86b..d52c34bdc9e1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -36,6 +36,7 @@ import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_90;
import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
@@ -80,6 +81,7 @@ import android.util.DisplayMetrics;
import android.util.Xml;
import android.view.Display;
import android.view.DisplayInfo;
+import android.window.TaskFragmentOrganizer;
import androidx.test.filters.MediumTest;
@@ -1489,6 +1491,26 @@ public class TaskTests extends WindowTestsBase {
tf0, parentTask.getTaskFragment(TaskFragment::isOrganizedTaskFragment));
}
+ @Test
+ public void testReorderActivityToFront() {
+ final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
+ final Task task = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
+ doNothing().when(task).onActivityVisibleRequestedChanged();
+ final ActivityRecord activity = task.getTopMostActivity();
+
+ final TaskFragment fragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
+ final ActivityRecord embeddedActivity = fragment.getTopMostActivity();
+ task.moveActivityToFront(activity);
+ assertEquals("Activity must be moved to front", activity, task.getTopMostActivity());
+
+ doNothing().when(fragment).sendTaskFragmentInfoChanged();
+ task.moveActivityToFront(embeddedActivity);
+ assertEquals("Activity must be moved to front", embeddedActivity,
+ task.getTopMostActivity());
+ assertEquals("Activity must not be embedded", embeddedActivity,
+ task.getTopChild());
+ }
+
private Task getTestTask() {
final Task task = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
return task.getBottomMostTask();