Merge "Fix ActivityEmbedding crash when process died" into tm-qpr-dev am: 491a02bee1

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19466294

Change-Id: I1c4df79fee0a576caab96a9b222480b0a4af14ef
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Chris Li
2022-08-02 02:19:03 +00:00
committed by Automerger Merge Worker
4 changed files with 44 additions and 0 deletions

View File

@@ -401,6 +401,10 @@ class TaskFragment extends WindowContainer<WindowContainer> {
mTaskFragmentOrganizerProcessName = processName; mTaskFragmentOrganizerProcessName = processName;
} }
void onTaskFragmentOrganizerRemoved() {
mTaskFragmentOrganizer = null;
}
/** Whether this TaskFragment is organized by the given {@code organizer}. */ /** Whether this TaskFragment is organized by the given {@code organizer}. */
boolean hasTaskFragmentOrganizer(ITaskFragmentOrganizer organizer) { boolean hasTaskFragmentOrganizer(ITaskFragmentOrganizer organizer) {
return organizer != null && mTaskFragmentOrganizer != null return organizer != null && mTaskFragmentOrganizer != null

View File

@@ -136,6 +136,9 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
void dispose() { void dispose() {
while (!mOrganizedTaskFragments.isEmpty()) { while (!mOrganizedTaskFragments.isEmpty()) {
final TaskFragment taskFragment = mOrganizedTaskFragments.get(0); 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(); taskFragment.removeImmediately();
mOrganizedTaskFragments.remove(taskFragment); mOrganizedTaskFragments.remove(taskFragment);
} }
@@ -512,10 +515,21 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
mPendingTaskFragmentEvents.add(pendingEvent); mPendingTaskFragmentEvents.add(pendingEvent);
} }
boolean isOrganizerRegistered(ITaskFragmentOrganizer organizer) {
return mTaskFragmentOrganizerState.containsKey(organizer.asBinder());
}
private void removeOrganizer(ITaskFragmentOrganizer organizer) { private void removeOrganizer(ITaskFragmentOrganizer organizer) {
final TaskFragmentOrganizerState state = validateAndGetState(organizer); final TaskFragmentOrganizerState state = validateAndGetState(organizer);
// remove all of the children of the organized TaskFragment // remove all of the children of the organized TaskFragment
state.dispose(); 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()); mTaskFragmentOrganizerState.remove(organizer.asBinder());
} }

View File

@@ -385,6 +385,12 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
private void applyTransaction(@NonNull WindowContainerTransaction t, int syncId, private void applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
@Nullable Transition transition, @NonNull CallerInfo caller, @Nullable Transition transition, @NonNull CallerInfo caller,
@Nullable Transition finishTransition) { @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; int effects = 0;
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Apply window transaction, syncId=%d", syncId); ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Apply window transaction, syncId=%d", syncId);
mService.deferWindowLayout(); mService.deferWindowLayout();

View File

@@ -420,6 +420,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
@Test @Test
public void testApplyTransaction_enforceHierarchyChange_setAdjacentRoots() public void testApplyTransaction_enforceHierarchyChange_setAdjacentRoots()
throws RemoteException { throws RemoteException {
mAtm.mTaskFragmentOrganizerController.registerOrganizer(mIOrganizer);
final TaskFragment taskFragment2 = final TaskFragment taskFragment2 =
new TaskFragment(mAtm, new Binder(), true /* createdByOrganizer */); new TaskFragment(mAtm, new Binder(), true /* createdByOrganizer */);
final WindowContainerToken token2 = taskFragment2.mRemoteToken.toWindowContainerToken(); final WindowContainerToken token2 = taskFragment2.mRemoteToken.toWindowContainerToken();
@@ -594,6 +595,25 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
assertEquals(activity0, mDisplayContent.mFocusedApp); assertEquals(activity0, mDisplayContent.mFocusedApp);
} }
@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 @Test
public void testTaskFragmentInPip_startActivityInTaskFragment() { public void testTaskFragmentInPip_startActivityInTaskFragment() {
setupTaskFragmentInPip(); setupTaskFragmentInPip();