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

Commit 23355f1f authored by Jiaming Liu's avatar Jiaming Liu
Browse files

Allow RemoteTransition for system TF organizer.

Bug: 284050041
Test: atest TaskFragmentOrganizerControllerTest TaskFragmentOrganizerPolicyTest WindowOrganizerTests
Change-Id: Ic072e42c3a88b713e175e81f3366b89ffea8404c
parent 0bab1185
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.window;
import android.os.IBinder;
import android.view.RemoteAnimationDefinition;
import android.window.ITaskFragmentOrganizer;
import android.window.RemoteTransition;
import android.window.WindowContainerTransaction;

/** @hide */
@@ -65,7 +66,10 @@ interface ITaskFragmentOrganizerController {

    /**
     * Requests the server to apply the given {@link WindowContainerTransaction}.
     *
     * {@link RemoteTransition} can only be used by a system organizer and
     * {@code shouldApplyIndependently} must be {@code true}. See {@link registerOrganizer}.
     */
    void applyTransaction(in WindowContainerTransaction wct, int transitionType,
        boolean shouldApplyIndependently);
        boolean shouldApplyIndependently, in RemoteTransition remoteTransition);
}
+25 −1
Original line number Diff line number Diff line
@@ -275,7 +275,31 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
        }
        wct.setTaskFragmentOrganizer(mInterface);
        try {
            getController().applyTransaction(wct, transitionType, shouldApplyIndependently);
            getController().applyTransaction(
                    wct, transitionType, shouldApplyIndependently, null /* remoteTransition */);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Applies a transaction with a {@link RemoteTransition}. Only a system organizer is allowed to
     * use {@link RemoteTransition}. See {@link TaskFragmentOrganizer#registerOrganizer(boolean)}.
     *
     * @hide
     */
    @FlaggedApi(Flags.FLAG_TASK_FRAGMENT_SYSTEM_ORGANIZER_FLAG)
    public void applySystemTransaction(@NonNull WindowContainerTransaction wct,
            @TaskFragmentTransitionType int transitionType,
            @Nullable RemoteTransition remoteTransition) {
        if (wct.isEmpty()) {
            return;
        }
        wct.setTaskFragmentOrganizer(mInterface);
        try {
            getController().applyTransaction(
                    wct, transitionType, remoteTransition != null /* shouldApplyIndependently */,
                    remoteTransition);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+7 −3
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import android.view.RemoteAnimationDefinition;
import android.view.WindowManager;
import android.window.ITaskFragmentOrganizer;
import android.window.ITaskFragmentOrganizerController;
import android.window.RemoteTransition;
import android.window.TaskFragmentInfo;
import android.window.TaskFragmentOperation;
import android.window.TaskFragmentParentInfo;
@@ -566,7 +567,8 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
        // Keep the calling identity to avoid unsecure change.
        synchronized (mGlobalLock) {
            if (isValidTransaction(wct)) {
                applyTransaction(wct, transitionType, shouldApplyIndependently);
                applyTransaction(
                        wct, transitionType, shouldApplyIndependently, null /* remoteTransition */);
            }
            // Even if the transaction is empty, we still need to invoke #onTransactionFinished
            // unless the organizer has been unregistered.
@@ -587,14 +589,15 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr

    @Override
    public void applyTransaction(@NonNull WindowContainerTransaction wct,
            @WindowManager.TransitionType int transitionType, boolean shouldApplyIndependently) {
            @WindowManager.TransitionType int transitionType, boolean shouldApplyIndependently,
            @Nullable RemoteTransition remoteTransition) {
        // Keep the calling identity to avoid unsecure change.
        synchronized (mGlobalLock) {
            if (!isValidTransaction(wct)) {
                return;
            }
            mWindowOrganizerController.applyTaskFragmentTransactionLocked(wct, transitionType,
                    shouldApplyIndependently);
                    shouldApplyIndependently, remoteTransition);
        }
    }

@@ -839,6 +842,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
            Slog.e(TAG, "Caller organizer=" + organizer + " is no longer registered");
            return false;
        }

        return true;
    }

+11 −2
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ import android.window.ITransitionMetricsReporter;
import android.window.ITransitionPlayer;
import android.window.IWindowContainerTransactionCallback;
import android.window.IWindowOrganizerController;
import android.window.RemoteTransition;
import android.window.TaskFragmentAnimationParams;
import android.window.TaskFragmentCreationParams;
import android.window.TaskFragmentOperation;
@@ -464,12 +465,20 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
     *                                  transition, which will be queued until the sync engine is
     *                                  free if there is any other active sync. If {@code false},
     *                                  the {@code wct} will be directly applied to the active sync.
     * @param remoteTransition {@link RemoteTransition} to apply for the transaction. Only available
     *                                                 for system organizers.
     */
    void applyTaskFragmentTransactionLocked(@NonNull WindowContainerTransaction wct,
            @WindowManager.TransitionType int type, boolean shouldApplyIndependently) {
            @WindowManager.TransitionType int type, boolean shouldApplyIndependently,
            @Nullable RemoteTransition remoteTransition) {
        enforceTaskFragmentOrganizerPermission("applyTaskFragmentTransaction()",
                Objects.requireNonNull(wct.getTaskFragmentOrganizer()),
                Objects.requireNonNull(wct));
        if (remoteTransition != null && !mTaskFragmentOrganizerController.isSystemOrganizer(
                wct.getTaskFragmentOrganizer().asBinder())) {
            throw new SecurityException(
                    "Only a system organizer is allowed to use remote transition!");
        }
        final CallerInfo caller = new CallerInfo();
        final long ident = Binder.clearCallingIdentity();
        try {
@@ -512,7 +521,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                    return;
                }
                mTransitionController.requestStartTransition(transition, null /* startTask */,
                        null /* remoteTransition */, null /* displayChange */);
                        remoteTransition, null /* displayChange */);
                transition.setAllReady();
            };
            mTransitionController.startCollectOrQueue(transition, doApply);
+33 −2
Original line number Diff line number Diff line
@@ -86,7 +86,9 @@ import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.view.RemoteAnimationDefinition;
import android.view.SurfaceControl;
import android.window.IRemoteTransition;
import android.window.ITaskFragmentOrganizer;
import android.window.RemoteTransition;
import android.window.TaskFragmentAnimationParams;
import android.window.TaskFragmentCreationParams;
import android.window.TaskFragmentInfo;
@@ -545,6 +547,35 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
        assertNull(mController.getRemoteAnimationDefinition(mIOrganizer));
    }

    @Test
    public void testApplyTransaction_disallowRemoteTransitionForNonSystemOrganizer() {
        mTransaction.setRelativeBounds(mFragmentWindowToken, new Rect(0, 0, 100, 100));
        mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */,
                "Test:TaskFragmentOrganizer" /* processName */);

        // Throw exception if the transaction has remote transition and is not requested by system
        // organizer
        assertThrows(SecurityException.class, () ->
                mController.applyTransaction(mTransaction, TASK_FRAGMENT_TRANSIT_CHANGE,
                        true /* shouldApplyIndependently */,
                        new RemoteTransition(mock(IRemoteTransition.class))));
    }

    @Test
    public void testApplyTransaction_allowRemoteTransitionForSystemOrganizer() {
        mController.unregisterOrganizer(mIOrganizer);
        mController.registerOrganizerInternal(mIOrganizer, true /* isSystemOrganizer */);

        mTransaction.setRelativeBounds(mFragmentWindowToken, new Rect(0, 0, 100, 100));
        mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */,
                "Test:TaskFragmentOrganizer" /* processName */);

        // Remote transition is allowed for system organizer
        mController.applyTransaction(mTransaction, TASK_FRAGMENT_TRANSIT_CHANGE,
                true /* shouldApplyIndependently */,
                new RemoteTransition(mock(IRemoteTransition.class)));
    }

    @Test
    public void testApplyTransaction_enforceConfigurationChangeOnOrganizedTaskFragment() {
        // Throw exception if the transaction is trying to change a window that is not organized by
@@ -1801,13 +1832,13 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
    private void assertApplyTransactionDisallowed(WindowContainerTransaction t) {
        assertThrows(SecurityException.class, () ->
                mController.applyTransaction(t, TASK_FRAGMENT_TRANSIT_CHANGE,
                        false /* shouldApplyIndependently */));
                        false /* shouldApplyIndependently */, null /* remoteTransition */));
    }

    /** Asserts that applying the given transaction will not throw any exception. */
    private void assertApplyTransactionAllowed(WindowContainerTransaction t) {
        mController.applyTransaction(t, TASK_FRAGMENT_TRANSIT_CHANGE,
                false /* shouldApplyIndependently */);
                false /* shouldApplyIndependently */, null /* remoteTransition */);
    }

    /** Asserts that there will be a transaction for TaskFragment appeared. */
Loading