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

Commit b4c0c4e8 authored by Chris Li's avatar Chris Li
Browse files

Disable all input on ActivityRecord during trusted animation

As a followup to ag/17258046, since we don't have any use case to
rely on handling input during animation, disable input even if it
is trusted embedding so that it could cover some edge-cases when
a previously truste host starts doing something bad.

Bug: 197364677
Test: atest WmTests:AppTransitionControllerTest
Change-Id: I7312b6ed961891c5c58adad73f660d4a18084c52
parent a53b05ca
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -577,12 +577,6 @@
      "group": "WM_DEBUG_CONFIGURATION",
      "at": "com\/android\/server\/wm\/ActivityStarter.java"
    },
    "-1488852351": {
      "message": "Task=%d contains embedded TaskFragment in untrusted mode. Disabled all input during TaskFragment remote animation.",
      "level": "DEBUG",
      "group": "WM_DEBUG_APP_TRANSITIONS",
      "at": "com\/android\/server\/wm\/AppTransitionController.java"
    },
    "-1483435730": {
      "message": "InsetsSource setWin %s for type %s",
      "level": "DEBUG",
@@ -3961,6 +3955,12 @@
      "group": "WM_DEBUG_KEEP_SCREEN_ON",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    "2100457473": {
      "message": "Task=%d contains embedded TaskFragment. Disabled all input during TaskFragment remote animation.",
      "level": "DEBUG",
      "group": "WM_DEBUG_APP_TRANSITIONS",
      "at": "com\/android\/server\/wm\/AppTransitionController.java"
    },
    "2114149926": {
      "message": "Not removing %s because app died while it's visible",
      "level": "VERBOSE",
+6 −9
Original line number Diff line number Diff line
@@ -666,22 +666,19 @@ public class AppTransitionController {
                "Override with TaskFragment remote animation for transit=%s",
                AppTransition.appTransitionOldToString(transit));

        final boolean hasUntrustedEmbedding = task.forAllLeafTasks(
                taskFragment -> !taskFragment.isAllowedToBeEmbeddedInTrustedMode());
        final RemoteAnimationController remoteAnimationController =
                mDisplayContent.mAppTransition.getRemoteAnimationController();
        if (hasUntrustedEmbedding && remoteAnimationController != null) {
            // We are going to use client-driven animation, but the Task is in untrusted embedded
            // mode. We need to disable all input on activity windows during the animation to
            // ensure it is safe. This is needed for all activity windows in the animation Task.
        if (remoteAnimationController != null) {
            // We are going to use client-driven animation, Disable all input on activity windows
            // during the animation to ensure it is safe to allow client to animate the surfaces.
            // This is needed for all activity windows in the animation Task.
            remoteAnimationController.setOnRemoteAnimationReady(() -> {
                final Consumer<ActivityRecord> updateActivities =
                        activity -> activity.setDropInputForAnimation(true);
                task.forAllActivities(updateActivities);
            });
            ProtoLog.d(WM_DEBUG_APP_TRANSITIONS, "Task=%d contains embedded TaskFragment in"
                    + " untrusted mode. Disabled all input during TaskFragment remote animation.",
                    task.mTaskId);
            ProtoLog.d(WM_DEBUG_APP_TRANSITIONS, "Task=%d contains embedded TaskFragment."
                    + " Disabled all input during TaskFragment remote animation.", task.mTaskId);
        }
        return true;
    }
+41 −0
Original line number Diff line number Diff line
@@ -1064,6 +1064,47 @@ public class AppTransitionControllerTest extends WindowTestsBase {
        verify(activity2).setDropInputMode(DropInputMode.NONE);
    }

    /**
     * Since we don't have any use case to rely on handling input during animation, disable it even
     * if it is trusted embedding so that it could cover some edge-cases when a previously trusted
     * host starts doing something bad.
     */
    @Test
    public void testOverrideTaskFragmentAdapter_inputProtectedForTrustedAnimation() {
        final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
        final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
        setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);

        // Create a TaskFragment with only trusted embedded activity
        final Task task = createTask(mDisplayContent);
        final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
                .setParentTask(task)
                .createActivityCount(1)
                .setOrganizer(organizer)
                .build();
        final ActivityRecord activity = taskFragment.getChildAt(0).asActivityRecord();
        prepareActivityForAppTransition(activity);
        doReturn(true).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity);
        spyOn(mDisplayContent.mAppTransition);

        // Prepare and start transition.
        prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment);
        mWm.mAnimator.executeAfterPrepareSurfacesRunnables();

        // The animation will be animated remotely by client and all activities are input disabled
        // for untrusted animation.
        assertTrue(remoteAnimationRunner.isAnimationStarted());
        verify(activity).setDropInputForAnimation(true);
        verify(activity).setDropInputMode(DropInputMode.ALL);

        // Reset input after animation is finished.
        clearInvocations(activity);
        remoteAnimationRunner.finishAnimation();

        verify(activity).setDropInputForAnimation(false);
        verify(activity).setDropInputMode(DropInputMode.NONE);
    }

    @Test
    public void testTransitionGoodToGoForTaskFragments() {
        final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);