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

Commit 27626413 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Abort tf transition if window transaction is no-op

Otherwise TaskFragmentOrganizerController#onTransactionHandled
-> onTransactionFinished may trigger transition ready too early
that causes an empty transition and misses to collect the
later visibility changes, which breaks the animation.

For example, the transaction only calls createTaskFragment, but it
is failed by SecurityException for different owner task uid. And
then the client organizer will use the standard startActivity to
handle the rejection. With the abort, the failed wct can be no-op
completely and run the normal transition from startActivity.

Bug: 273422767
Test: TaskFragmentOrganizerControllerTest
Change-Id: If5e915ed3914b38273669f3d8ad715448a45f896
parent 7e9609b4
Loading
Loading
Loading
Loading
+16 −8
Original line number Diff line number Diff line
@@ -439,7 +439,11 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                // multiple sync at the same time because it may cause conflict.
                // Create a new transition when there is no active sync to collect the changes.
                final Transition transition = mTransitionController.createTransition(type);
                applyTransaction(wct, -1 /* syncId */, transition, caller);
                if (applyTransaction(wct, -1 /* syncId */, transition, caller)
                        == TRANSACT_EFFECTS_NONE && transition.mParticipants.isEmpty()) {
                    transition.abort();
                    return;
                }
                mTransitionController.requestStartTransition(transition, null /* startTask */,
                        null /* remoteTransition */, null /* displayChange */);
                transition.setAllReady();
@@ -476,24 +480,26 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                    // calls startSyncSet.
                    () -> mTransitionController.moveToCollecting(nextTransition),
                    () -> {
                        if (mTaskFragmentOrganizerController.isValidTransaction(wct)) {
                            applyTransaction(wct, -1 /*syncId*/, nextTransition, caller);
                        if (mTaskFragmentOrganizerController.isValidTransaction(wct)
                                && (applyTransaction(wct, -1 /* syncId */, nextTransition, caller)
                                        != TRANSACT_EFFECTS_NONE
                                || !nextTransition.mParticipants.isEmpty())) {
                            mTransitionController.requestStartTransition(nextTransition,
                                    null /* startTask */, null /* remoteTransition */,
                                    null /* displayChange */);
                            nextTransition.setAllReady();
                        } else {
                            nextTransition.abort();
                            return;
                        }
                        nextTransition.abort();
                    });
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

    private void applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
    private int applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
            @Nullable Transition transition, @NonNull CallerInfo caller) {
        applyTransaction(t, syncId, transition, caller, null /* finishTransition */);
        return applyTransaction(t, syncId, transition, caller, null /* finishTransition */);
    }

    /**
@@ -501,8 +507,9 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
     * @param transition A transition to collect changes into.
     * @param caller Info about the calling process.
     * @param finishTransition The transition that is currently being finished.
     * @return The effects of the window container transaction.
     */
    private void applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
    private int applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
            @Nullable Transition transition, @NonNull CallerInfo caller,
            @Nullable Transition finishTransition) {
        int effects = TRANSACT_EFFECTS_NONE;
@@ -639,6 +646,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
            mService.mTaskSupervisor.setDeferRootVisibilityUpdate(false /* deferUpdate */);
            mService.continueWindowLayout();
        }
        return effects;
    }

    private int applyChanges(@NonNull WindowContainer<?> container,