Loading data/etc/services.core.protolog.json +6 −6 Original line number Diff line number Diff line Loading @@ -613,12 +613,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", Loading Loading @@ -4165,6 +4159,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", Loading services/core/java/com/android/server/wm/AppTransitionController.java +6 −9 Original line number Diff line number Diff line Loading @@ -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; } Loading services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java +41 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading
data/etc/services.core.protolog.json +6 −6 Original line number Diff line number Diff line Loading @@ -613,12 +613,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", Loading Loading @@ -4165,6 +4159,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", Loading
services/core/java/com/android/server/wm/AppTransitionController.java +6 −9 Original line number Diff line number Diff line Loading @@ -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; } Loading
services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java +41 −0 Original line number Diff line number Diff line Loading @@ -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); Loading