Loading core/proto/android/server/windowmanagerservice.proto +1 −0 Original line number Diff line number Diff line Loading @@ -384,6 +384,7 @@ message ActivityRecordProto { optional float min_aspect_ratio = 33; optional bool provides_max_bounds = 34; optional bool enable_recents_screenshot = 35; optional int32 last_drop_input_mode = 36; } /* represents WindowToken */ Loading data/etc/services.core.protolog.json +6 −0 Original line number Diff line number Diff line Loading @@ -613,6 +613,12 @@ "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 services/core/java/com/android/server/wm/ActivityRecord.java +19 −4 Original line number Diff line number Diff line Loading @@ -156,6 +156,7 @@ import static com.android.server.wm.ActivityRecordProto.IN_SIZE_COMPAT_MODE; import static com.android.server.wm.ActivityRecordProto.IS_ANIMATING; import static com.android.server.wm.ActivityRecordProto.IS_WAITING_FOR_TRANSITION_START; import static com.android.server.wm.ActivityRecordProto.LAST_ALL_DRAWN; import static com.android.server.wm.ActivityRecordProto.LAST_DROP_INPUT_MODE; import static com.android.server.wm.ActivityRecordProto.LAST_SURFACE_SHOWING; import static com.android.server.wm.ActivityRecordProto.MIN_ASPECT_RATIO; import static com.android.server.wm.ActivityRecordProto.NAME; Loading Loading @@ -786,6 +787,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A /** The last set {@link DropInputMode} for this activity surface. */ @DropInputMode private int mLastDropInputMode = DropInputMode.NONE; /** Whether the input to this activity will be dropped during the current playing animation. */ private boolean mIsInputDroppedForAnimation; /** * If it is non-null, it requires all activities who have the same starting data to be drawn Loading Loading @@ -1567,6 +1570,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } /** Sets if all input will be dropped as a protection during the client-driven animation. */ void setDropInputForAnimation(boolean isInputDroppedForAnimation) { if (mIsInputDroppedForAnimation == isInputDroppedForAnimation) { return; } mIsInputDroppedForAnimation = isInputDroppedForAnimation; updateUntrustedEmbeddingInputProtection(); } /** * Sets to drop input when obscured to activity if it is embedded in untrusted mode. * Loading @@ -1576,11 +1588,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A * all untrusted activities. */ private void updateUntrustedEmbeddingInputProtection() { final SurfaceControl sc = getSurfaceControl(); if (sc == null) { if (getSurfaceControl() == null) { return; } if (isEmbeddedInUntrustedMode()) { if (mIsInputDroppedForAnimation) { // Disable all input during the animation. setDropInputMode(DropInputMode.ALL); } else if (isEmbeddedInUntrustedMode()) { // Set drop input to OBSCURED when untrusted embedded. setDropInputMode(DropInputMode.OBSCURED); } else { Loading @@ -1591,7 +1605,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A @VisibleForTesting void setDropInputMode(@DropInputMode int mode) { if (mLastDropInputMode != mode && getSurfaceControl() != null) { if (mLastDropInputMode != mode) { mLastDropInputMode = mode; mWmService.mTransactionFactory.get() .setDropInputMode(getSurfaceControl(), mode) Loading Loading @@ -9299,6 +9313,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // permission to access the device configs. proto.write(PROVIDES_MAX_BOUNDS, providesMaxBounds()); proto.write(ENABLE_RECENTS_SCREENSHOT, mEnableRecentsScreenshot); proto.write(LAST_DROP_INPUT_MODE, mLastDropInputMode); } @Override Loading services/core/java/com/android/server/wm/AppTransitionController.java +38 −8 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.LinkedList; import java.util.function.Consumer; import java.util.function.Predicate; /** Loading Loading @@ -541,12 +542,13 @@ public class AppTransitionController { } /** * Finds the common {@link android.window.TaskFragmentOrganizer} that organizes all app windows * in the current transition. * @return {@code null} if there is no such organizer, or if there are more than one. * Finds the common parent {@link Task} that is parent of all embedded app windows in the * current transition. * @return {@code null} if app windows in the transition are not children of the same Task, or * if none of the app windows is embedded. */ @Nullable private ITaskFragmentOrganizer findTaskFragmentOrganizerForAllWindows() { private Task findParentTaskForAllEmbeddedWindows() { mTempTransitionWindows.clear(); mTempTransitionWindows.addAll(mDisplayContent.mClosingApps); mTempTransitionWindows.addAll(mDisplayContent.mOpeningApps); Loading Loading @@ -600,13 +602,22 @@ public class AppTransitionController { leafTask = task; } mTempTransitionWindows.clear(); if (leafTask == null) { return null; return leafTask; } /** * Finds the common {@link android.window.TaskFragmentOrganizer} that organizes all embedded * {@link TaskFragment} belong to the given {@link Task}. * @return {@code null} if there is no such organizer, or if there are more than one. */ @Nullable private ITaskFragmentOrganizer findTaskFragmentOrganizer(@Nullable Task task) { if (task == null) { return null; } // We don't support remote animation for Task with multiple TaskFragmentOrganizers. final ITaskFragmentOrganizer[] organizer = new ITaskFragmentOrganizer[1]; final boolean hasMultipleOrganizers = leafTask.forAllLeafTaskFragments(taskFragment -> { final boolean hasMultipleOrganizers = task.forAllLeafTaskFragments(taskFragment -> { final ITaskFragmentOrganizer tfOrganizer = taskFragment.getTaskFragmentOrganizer(); if (tfOrganizer == null) { return false; Loading Loading @@ -638,7 +649,8 @@ public class AppTransitionController { return false; } final ITaskFragmentOrganizer organizer = findTaskFragmentOrganizerForAllWindows(); final Task task = findParentTaskForAllEmbeddedWindows(); final ITaskFragmentOrganizer organizer = findTaskFragmentOrganizer(task); final RemoteAnimationDefinition definition = organizer != null ? mDisplayContent.mAtmService.mTaskFragmentOrganizerController .getRemoteAnimationDefinition(organizer) Loading @@ -653,6 +665,24 @@ public class AppTransitionController { ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "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. 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); } return true; } Loading services/core/java/com/android/server/wm/RemoteAnimationController.java +19 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Point; import android.graphics.Rect; import android.os.Binder; Loading @@ -49,6 +50,7 @@ import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.function.Consumer; /** * Helper class to run app animations in a remote process. Loading @@ -72,6 +74,8 @@ class RemoteAnimationController implements DeathRecipient { private FinishedCallback mFinishedCallback; private boolean mCanceled; private boolean mLinkedToDeathOfRunner; @Nullable private Runnable mOnRemoteAnimationReady; RemoteAnimationController(WindowManagerService service, DisplayContent displayContent, RemoteAnimationAdapter remoteAnimationAdapter, Handler handler) { Loading Loading @@ -101,6 +105,11 @@ class RemoteAnimationController implements DeathRecipient { return adapters; } /** Sets callback to run before starting remote animation. */ void setOnRemoteAnimationReady(@Nullable Runnable onRemoteAnimationReady) { mOnRemoteAnimationReady = onRemoteAnimationReady; } /** * Called when the transition is ready to be started, and all leashes have been set up. */ Loading Loading @@ -133,6 +142,11 @@ class RemoteAnimationController implements DeathRecipient { return; } if (mOnRemoteAnimationReady != null) { mOnRemoteAnimationReady.run(); mOnRemoteAnimationReady = null; } // Create the remote wallpaper animation targets (if any) final RemoteAnimationTarget[] wallpaperTargets = createWallpaperAnimations(); Loading Loading @@ -292,6 +306,10 @@ class RemoteAnimationController implements DeathRecipient { mService.closeSurfaceTransaction("RemoteAnimationController#finished"); } } // Reset input for all activities when the remote animation is finished. final Consumer<ActivityRecord> updateActivities = activity -> activity.setDropInputForAnimation(false); mDisplayContent.forAllActivities(updateActivities); setRunningRemoteAnimation(false); ProtoLog.i(WM_DEBUG_REMOTE_ANIMATIONS, "Finishing remote animation"); } Loading @@ -303,6 +321,7 @@ class RemoteAnimationController implements DeathRecipient { } catch (RemoteException e) { Slog.e(TAG, "Failed to notify cancel", e); } mOnRemoteAnimationReady = null; } private void releaseFinishedCallback() { Loading Loading
core/proto/android/server/windowmanagerservice.proto +1 −0 Original line number Diff line number Diff line Loading @@ -384,6 +384,7 @@ message ActivityRecordProto { optional float min_aspect_ratio = 33; optional bool provides_max_bounds = 34; optional bool enable_recents_screenshot = 35; optional int32 last_drop_input_mode = 36; } /* represents WindowToken */ Loading
data/etc/services.core.protolog.json +6 −0 Original line number Diff line number Diff line Loading @@ -613,6 +613,12 @@ "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
services/core/java/com/android/server/wm/ActivityRecord.java +19 −4 Original line number Diff line number Diff line Loading @@ -156,6 +156,7 @@ import static com.android.server.wm.ActivityRecordProto.IN_SIZE_COMPAT_MODE; import static com.android.server.wm.ActivityRecordProto.IS_ANIMATING; import static com.android.server.wm.ActivityRecordProto.IS_WAITING_FOR_TRANSITION_START; import static com.android.server.wm.ActivityRecordProto.LAST_ALL_DRAWN; import static com.android.server.wm.ActivityRecordProto.LAST_DROP_INPUT_MODE; import static com.android.server.wm.ActivityRecordProto.LAST_SURFACE_SHOWING; import static com.android.server.wm.ActivityRecordProto.MIN_ASPECT_RATIO; import static com.android.server.wm.ActivityRecordProto.NAME; Loading Loading @@ -786,6 +787,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A /** The last set {@link DropInputMode} for this activity surface. */ @DropInputMode private int mLastDropInputMode = DropInputMode.NONE; /** Whether the input to this activity will be dropped during the current playing animation. */ private boolean mIsInputDroppedForAnimation; /** * If it is non-null, it requires all activities who have the same starting data to be drawn Loading Loading @@ -1567,6 +1570,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } /** Sets if all input will be dropped as a protection during the client-driven animation. */ void setDropInputForAnimation(boolean isInputDroppedForAnimation) { if (mIsInputDroppedForAnimation == isInputDroppedForAnimation) { return; } mIsInputDroppedForAnimation = isInputDroppedForAnimation; updateUntrustedEmbeddingInputProtection(); } /** * Sets to drop input when obscured to activity if it is embedded in untrusted mode. * Loading @@ -1576,11 +1588,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A * all untrusted activities. */ private void updateUntrustedEmbeddingInputProtection() { final SurfaceControl sc = getSurfaceControl(); if (sc == null) { if (getSurfaceControl() == null) { return; } if (isEmbeddedInUntrustedMode()) { if (mIsInputDroppedForAnimation) { // Disable all input during the animation. setDropInputMode(DropInputMode.ALL); } else if (isEmbeddedInUntrustedMode()) { // Set drop input to OBSCURED when untrusted embedded. setDropInputMode(DropInputMode.OBSCURED); } else { Loading @@ -1591,7 +1605,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A @VisibleForTesting void setDropInputMode(@DropInputMode int mode) { if (mLastDropInputMode != mode && getSurfaceControl() != null) { if (mLastDropInputMode != mode) { mLastDropInputMode = mode; mWmService.mTransactionFactory.get() .setDropInputMode(getSurfaceControl(), mode) Loading Loading @@ -9299,6 +9313,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // permission to access the device configs. proto.write(PROVIDES_MAX_BOUNDS, providesMaxBounds()); proto.write(ENABLE_RECENTS_SCREENSHOT, mEnableRecentsScreenshot); proto.write(LAST_DROP_INPUT_MODE, mLastDropInputMode); } @Override Loading
services/core/java/com/android/server/wm/AppTransitionController.java +38 −8 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.LinkedList; import java.util.function.Consumer; import java.util.function.Predicate; /** Loading Loading @@ -541,12 +542,13 @@ public class AppTransitionController { } /** * Finds the common {@link android.window.TaskFragmentOrganizer} that organizes all app windows * in the current transition. * @return {@code null} if there is no such organizer, or if there are more than one. * Finds the common parent {@link Task} that is parent of all embedded app windows in the * current transition. * @return {@code null} if app windows in the transition are not children of the same Task, or * if none of the app windows is embedded. */ @Nullable private ITaskFragmentOrganizer findTaskFragmentOrganizerForAllWindows() { private Task findParentTaskForAllEmbeddedWindows() { mTempTransitionWindows.clear(); mTempTransitionWindows.addAll(mDisplayContent.mClosingApps); mTempTransitionWindows.addAll(mDisplayContent.mOpeningApps); Loading Loading @@ -600,13 +602,22 @@ public class AppTransitionController { leafTask = task; } mTempTransitionWindows.clear(); if (leafTask == null) { return null; return leafTask; } /** * Finds the common {@link android.window.TaskFragmentOrganizer} that organizes all embedded * {@link TaskFragment} belong to the given {@link Task}. * @return {@code null} if there is no such organizer, or if there are more than one. */ @Nullable private ITaskFragmentOrganizer findTaskFragmentOrganizer(@Nullable Task task) { if (task == null) { return null; } // We don't support remote animation for Task with multiple TaskFragmentOrganizers. final ITaskFragmentOrganizer[] organizer = new ITaskFragmentOrganizer[1]; final boolean hasMultipleOrganizers = leafTask.forAllLeafTaskFragments(taskFragment -> { final boolean hasMultipleOrganizers = task.forAllLeafTaskFragments(taskFragment -> { final ITaskFragmentOrganizer tfOrganizer = taskFragment.getTaskFragmentOrganizer(); if (tfOrganizer == null) { return false; Loading Loading @@ -638,7 +649,8 @@ public class AppTransitionController { return false; } final ITaskFragmentOrganizer organizer = findTaskFragmentOrganizerForAllWindows(); final Task task = findParentTaskForAllEmbeddedWindows(); final ITaskFragmentOrganizer organizer = findTaskFragmentOrganizer(task); final RemoteAnimationDefinition definition = organizer != null ? mDisplayContent.mAtmService.mTaskFragmentOrganizerController .getRemoteAnimationDefinition(organizer) Loading @@ -653,6 +665,24 @@ public class AppTransitionController { ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "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. 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); } return true; } Loading
services/core/java/com/android/server/wm/RemoteAnimationController.java +19 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Point; import android.graphics.Rect; import android.os.Binder; Loading @@ -49,6 +50,7 @@ import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.function.Consumer; /** * Helper class to run app animations in a remote process. Loading @@ -72,6 +74,8 @@ class RemoteAnimationController implements DeathRecipient { private FinishedCallback mFinishedCallback; private boolean mCanceled; private boolean mLinkedToDeathOfRunner; @Nullable private Runnable mOnRemoteAnimationReady; RemoteAnimationController(WindowManagerService service, DisplayContent displayContent, RemoteAnimationAdapter remoteAnimationAdapter, Handler handler) { Loading Loading @@ -101,6 +105,11 @@ class RemoteAnimationController implements DeathRecipient { return adapters; } /** Sets callback to run before starting remote animation. */ void setOnRemoteAnimationReady(@Nullable Runnable onRemoteAnimationReady) { mOnRemoteAnimationReady = onRemoteAnimationReady; } /** * Called when the transition is ready to be started, and all leashes have been set up. */ Loading Loading @@ -133,6 +142,11 @@ class RemoteAnimationController implements DeathRecipient { return; } if (mOnRemoteAnimationReady != null) { mOnRemoteAnimationReady.run(); mOnRemoteAnimationReady = null; } // Create the remote wallpaper animation targets (if any) final RemoteAnimationTarget[] wallpaperTargets = createWallpaperAnimations(); Loading Loading @@ -292,6 +306,10 @@ class RemoteAnimationController implements DeathRecipient { mService.closeSurfaceTransaction("RemoteAnimationController#finished"); } } // Reset input for all activities when the remote animation is finished. final Consumer<ActivityRecord> updateActivities = activity -> activity.setDropInputForAnimation(false); mDisplayContent.forAllActivities(updateActivities); setRunningRemoteAnimation(false); ProtoLog.i(WM_DEBUG_REMOTE_ANIMATIONS, "Finishing remote animation"); } Loading @@ -303,6 +321,7 @@ class RemoteAnimationController implements DeathRecipient { } catch (RemoteException e) { Slog.e(TAG, "Failed to notify cancel", e); } mOnRemoteAnimationReady = null; } private void releaseFinishedCallback() { Loading