Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2581a7e4 authored by Chris Li's avatar Chris Li
Browse files

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
parent 8be2f810
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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
+14 −0
Original line number Diff line number Diff line
@@ -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());
    }

+6 −0
Original line number Diff line number Diff line
@@ -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();
+20 −0
Original line number Diff line number Diff line
@@ -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();