summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chris Li <lihongyu@google.com> 2022-07-29 17:45:04 +0800
committer Chris Li <lihongyu@google.com> 2022-07-29 21:57:20 +0800
commit2581a7e42cc7366c5f45455b7b643fb62d5474fe (patch)
treebc29a3d463fd106902759d2eafb9d92105712045
parent8be2f8108625ca6aa35ce58d67cc1222db0709eb (diff)
Fix ActivityEmbedding crash when process died
1. When the organizer is removed, also remove any pending event. 2. Only apply transaction when the organizer is registered. Fix: 240628043 Test: testApplyTransaction_skipTransactionForUnregisterOrganizer Change-Id: I24c25691fd49fd83100b7ae51ff7fbfeb39a03e9
-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();