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

Commit e65c16a0 authored by Jiaming Liu's avatar Jiaming Liu Committed by Android (Google) Code Review
Browse files

Merge "Allow RemoteTransition for system TF organizer." into main

parents 6b4fa94f 23355f1f
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