From b4c0c4e81b91a57a9609ce0b6fb13a6a94fe32fb Mon Sep 17 00:00:00 2001 From: Chris Li Date: Wed, 23 Mar 2022 17:49:56 +0800 Subject: 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 --- data/etc/services.core.protolog.json | 12 +++---- .../android/server/wm/AppTransitionController.java | 15 ++++---- .../server/wm/AppTransitionControllerTest.java | 41 ++++++++++++++++++++++ 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index e1b32b5f22c5..f804911edebb 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -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", diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java index a31d8603e2f2..0b4d8876cf8f 100644 --- a/services/core/java/com/android/server/wm/AppTransitionController.java +++ b/services/core/java/com/android/server/wm/AppTransitionController.java @@ -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 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; } diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java index 94f900efb845..97d477f2bae9 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java @@ -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); -- cgit v1.2.3-59-g8ed1b