Merge "Fix ActivityEmbedding crash when process died" into tm-qpr-dev

This commit is contained in:
Chris Li
2022-08-02 02:11:24 +00:00
committed by Android (Google) Code Review
4 changed files with 44 additions and 0 deletions

View File

@@ -401,6 +401,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

View File

@@ -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());
}

View File

@@ -385,6 +385,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();

View File

@@ -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();
@@ -594,6 +595,25 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
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
public void testTaskFragmentInPip_startActivityInTaskFragment() {
setupTaskFragmentInPip();