summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/TaskFragment.java4
-rw-r--r--services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java14
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java20
4 files changed, 44 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 68884247df97..863e506b9d35 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -393,6 +393,10 @@ class TaskFragment extends WindowContainer<WindowContainer> {
mTaskFragmentOrganizerProcessName = processName;
}
+ void onTaskFragmentOrganizerRemoved() {
+ mTaskFragmentOrganizer = null;
+ }
+
/** Whether this TaskFragment is organized by the given {@code organizer}. */
boolean hasTaskFragmentOrganizer(ITaskFragmentOrganizer organizer) {
return organizer != null && mTaskFragmentOrganizer != null
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index d4551becbaaf..602579fb4f9f 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -136,6 +136,9 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
void dispose() {
while (!mOrganizedTaskFragments.isEmpty()) {
final TaskFragment taskFragment = mOrganizedTaskFragments.get(0);
+ // Cleanup before remove to prevent it from sending any additional event, such as
+ // #onTaskFragmentVanished, to the removed organizer.
+ taskFragment.onTaskFragmentOrganizerRemoved();
taskFragment.removeImmediately();
mOrganizedTaskFragments.remove(taskFragment);
}
@@ -512,10 +515,21 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
mPendingTaskFragmentEvents.add(pendingEvent);
}
+ boolean isOrganizerRegistered(ITaskFragmentOrganizer organizer) {
+ return mTaskFragmentOrganizerState.containsKey(organizer.asBinder());
+ }
+
private void removeOrganizer(ITaskFragmentOrganizer organizer) {
final TaskFragmentOrganizerState state = validateAndGetState(organizer);
// remove all of the children of the organized TaskFragment
state.dispose();
+ // Remove any pending event of this organizer.
+ for (int i = mPendingTaskFragmentEvents.size() - 1; i >= 0; i--) {
+ final PendingTaskFragmentEvent event = mPendingTaskFragmentEvents.get(i);
+ if (event.mTaskFragmentOrg.asBinder().equals(organizer.asBinder())) {
+ mPendingTaskFragmentEvents.remove(i);
+ }
+ }
mTaskFragmentOrganizerState.remove(organizer.asBinder());
}
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 0f5655c74f31..ca6d9c793c96 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -386,6 +386,12 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
private void applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
@Nullable Transition transition, @NonNull CallerInfo caller,
@Nullable Transition finishTransition) {
+ if (t.getTaskFragmentOrganizer() != null && !mTaskFragmentOrganizerController
+ .isOrganizerRegistered(t.getTaskFragmentOrganizer())) {
+ Slog.e(TAG, "Caller organizer=" + t.getTaskFragmentOrganizer()
+ + " is no longer registered");
+ return;
+ }
int effects = 0;
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Apply window transaction, syncId=%d", syncId);
mService.deferWindowLayout();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
index 97f0918e8136..eba27553937e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -420,6 +420,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
@Test
public void testApplyTransaction_enforceHierarchyChange_setAdjacentRoots()
throws RemoteException {
+ mAtm.mTaskFragmentOrganizerController.registerOrganizer(mIOrganizer);
final TaskFragment taskFragment2 =
new TaskFragment(mAtm, new Binder(), true /* createdByOrganizer */);
final WindowContainerToken token2 = taskFragment2.mRemoteToken.toWindowContainerToken();
@@ -595,6 +596,25 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
}
@Test
+ public void testApplyTransaction_skipTransactionForUnregisterOrganizer() {
+ final ActivityRecord ownerActivity = createActivityRecord(mDisplayContent);
+ final IBinder fragmentToken = new Binder();
+
+ // Allow organizer to create TaskFragment and start/reparent activity to TaskFragment.
+ createTaskFragmentFromOrganizer(mTransaction, ownerActivity, fragmentToken);
+ mAtm.mWindowOrganizerController.applyTransaction(mTransaction);
+
+ // Nothing should happen as the organizer is not registered.
+ assertNull(mAtm.mWindowOrganizerController.getTaskFragment(fragmentToken));
+
+ mController.registerOrganizer(mIOrganizer);
+ mAtm.mWindowOrganizerController.applyTransaction(mTransaction);
+
+ // Successfully created when the organizer is registered.
+ assertNotNull(mAtm.mWindowOrganizerController.getTaskFragment(fragmentToken));
+ }
+
+ @Test
public void testTaskFragmentInPip_startActivityInTaskFragment() {
setupTaskFragmentInPip();
final ActivityRecord activity = mTaskFragment.getTopMostActivity();