Loading services/core/java/com/android/server/wm/ActivityRecord.java +2 −8 Original line number Diff line number Diff line Loading @@ -247,7 +247,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES; import static com.android.server.wm.WindowState.LEGACY_POLICY_VISIBILITY; import static com.android.window.flags.Flags.enablePresentationForConnectedDisplays; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.END_TAG; Loading Loading @@ -6208,13 +6207,8 @@ final class ActivityRecord extends WindowToken { return false; } // Hide all activities on the presenting display so that malicious apps can't do tap // jacking (b/391466268). // For now, this should only be applied to external displays because presentations can only // be shown on them. // TODO(b/390481621): Disallow a presentation from covering its controlling activity so that // the presentation won't stop its controlling activity. if (enablePresentationForConnectedDisplays() && mDisplayContent.mIsPresenting) { // A presentation stopps all activities behind on the same display. if (mWmService.mPresentationController.shouldOccludeActivities(getDisplayId())) { return false; } Loading services/core/java/com/android/server/wm/DisplayContent.java +0 −3 Original line number Diff line number Diff line Loading @@ -547,9 +547,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp // TODO(multi-display): remove some of the usages. boolean isDefaultDisplay; /** Indicates whether any presentation is shown on this display. */ boolean mIsPresenting; /** Save allocating when calculating rects */ private final Rect mTmpRect = new Rect(); private final Region mTmpRegion = new Region(); Loading services/core/java/com/android/server/wm/PresentationController.java 0 → 100644 +79 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.wm; import static com.android.window.flags.Flags.enablePresentationForConnectedDisplays; import android.annotation.NonNull; import android.util.IntArray; /** * Manages presentation windows. */ class PresentationController { // TODO(b/395475549): Add support for display add/remove, and activity move across displays. private final IntArray mPresentingDisplayIds = new IntArray(); PresentationController() {} private boolean isPresenting(int displayId) { return mPresentingDisplayIds.contains(displayId); } boolean shouldOccludeActivities(int displayId) { // All activities on the presenting display must be hidden so that malicious apps can't do // tap jacking (b/391466268). // For now, this should only be applied to external displays because presentations can only // be shown on them. // TODO(b/390481621): Disallow a presentation from covering its controlling activity so that // the presentation won't stop its controlling activity. return enablePresentationForConnectedDisplays() && isPresenting(displayId); } void onPresentationAdded(@NonNull WindowState win) { final int displayId = win.getDisplayId(); if (isPresenting(displayId)) { return; } mPresentingDisplayIds.add(displayId); if (enablePresentationForConnectedDisplays()) { // A presentation hides all activities behind on the same display. win.mDisplayContent.ensureActivitiesVisible(/*starting=*/ null, /*notifyClients=*/ true); } win.mWmService.mDisplayManagerInternal.onPresentation(displayId, /*isShown=*/ true); } void onPresentationRemoved(@NonNull WindowState win) { final int displayId = win.getDisplayId(); if (!isPresenting(displayId)) { return; } // TODO(b/393945496): Make sure that there's one presentation at most per display. final int displayIdIndex = mPresentingDisplayIds.indexOf(displayId); if (displayIdIndex != -1) { mPresentingDisplayIds.remove(displayIdIndex); } if (enablePresentationForConnectedDisplays()) { // A presentation hides all activities behind on the same display. win.mDisplayContent.ensureActivitiesVisible(/*starting=*/ null, /*notifyClients=*/ true); } win.mWmService.mDisplayManagerInternal.onPresentation(displayId, /*isShown=*/ false); } } services/core/java/com/android/server/wm/WindowManagerService.java +5 −11 Original line number Diff line number Diff line Loading @@ -157,7 +157,6 @@ import static com.android.server.wm.WindowManagerServiceDumpProto.POLICY; import static com.android.server.wm.WindowManagerServiceDumpProto.ROOT_WINDOW_CONTAINER; import static com.android.server.wm.WindowManagerServiceDumpProto.WINDOW_FRAMES_VALID; import static com.android.window.flags.Flags.enableDisplayFocusInShellTransitions; import static com.android.window.flags.Flags.enablePresentationForConnectedDisplays; import static com.android.window.flags.Flags.multiCrop; import static com.android.window.flags.Flags.setScPropertiesInClient; Loading Loading @@ -503,6 +502,8 @@ public class WindowManagerService extends IWindowManager.Stub final StartingSurfaceController mStartingSurfaceController; final PresentationController mPresentationController; private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() { @Override public void onVrStateChanged(boolean enabled) { Loading Loading @@ -1433,6 +1434,7 @@ public class WindowManagerService extends IWindowManager.Stub setGlobalShadowSettings(); mAnrController = new AnrController(this); mStartingSurfaceController = new StartingSurfaceController(this); mPresentationController = new PresentationController(); mBlurController = new BlurController(mContext, mPowerManager); mTaskFpsCallbackController = new TaskFpsCallbackController(mContext); Loading Loading @@ -1937,16 +1939,8 @@ public class WindowManagerService extends IWindowManager.Stub } outSizeCompatScale[0] = win.getCompatScaleForClient(); if (res >= ADD_OKAY && (type == TYPE_PRESENTATION || type == TYPE_PRIVATE_PRESENTATION)) { displayContent.mIsPresenting = true; if (enablePresentationForConnectedDisplays()) { // A presentation hides all activities behind on the same display. displayContent.ensureActivitiesVisible(/*starting=*/ null, /*notifyClients=*/ true); } mDisplayManagerInternal.onPresentation(displayContent.getDisplay().getDisplayId(), /*isShown=*/ true); if (res >= ADD_OKAY && win.isPresentation()) { mPresentationController.onPresentationAdded(win); } } Loading services/core/java/com/android/server/wm/WindowState.java +6 −10 Original line number Diff line number Diff line Loading @@ -182,7 +182,6 @@ import static com.android.server.wm.WindowStateProto.UNRESTRICTED_KEEP_CLEAR_ARE import static com.android.server.wm.WindowStateProto.VIEW_VISIBILITY; import static com.android.server.wm.WindowStateProto.WINDOW_CONTAINER; import static com.android.server.wm.WindowStateProto.WINDOW_FRAMES; import static com.android.window.flags.Flags.enablePresentationForConnectedDisplays; import static com.android.window.flags.Flags.surfaceTrustedOverlay; import android.annotation.CallSuper; Loading Loading @@ -2300,15 +2299,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP final int type = mAttrs.type; if (type == TYPE_PRESENTATION || type == TYPE_PRIVATE_PRESENTATION) { // TODO(b/393945496): Make sure that there's one presentation at most per display. dc.mIsPresenting = false; if (enablePresentationForConnectedDisplays()) { // A presentation hides all activities behind on the same display. dc.ensureActivitiesVisible(/*starting=*/ null, /*notifyClients=*/ true); } mWmService.mDisplayManagerInternal.onPresentation(dc.getDisplay().getDisplayId(), /*isShown=*/ false); if (isPresentation()) { mWmService.mPresentationController.onPresentationRemoved(this); } // Check if window provides non decor insets before clearing its provided insets. final boolean windowProvidesDisplayDecorInsets = providesDisplayDecorInsets(); Loading Loading @@ -3337,6 +3329,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } } boolean isPresentation() { return mAttrs.type == TYPE_PRESENTATION || mAttrs.type == TYPE_PRIVATE_PRESENTATION; } private boolean isOnVirtualDisplay() { return getDisplayContent().mDisplay.getType() == Display.TYPE_VIRTUAL; } Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +2 −8 Original line number Diff line number Diff line Loading @@ -247,7 +247,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES; import static com.android.server.wm.WindowState.LEGACY_POLICY_VISIBILITY; import static com.android.window.flags.Flags.enablePresentationForConnectedDisplays; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.END_TAG; Loading Loading @@ -6208,13 +6207,8 @@ final class ActivityRecord extends WindowToken { return false; } // Hide all activities on the presenting display so that malicious apps can't do tap // jacking (b/391466268). // For now, this should only be applied to external displays because presentations can only // be shown on them. // TODO(b/390481621): Disallow a presentation from covering its controlling activity so that // the presentation won't stop its controlling activity. if (enablePresentationForConnectedDisplays() && mDisplayContent.mIsPresenting) { // A presentation stopps all activities behind on the same display. if (mWmService.mPresentationController.shouldOccludeActivities(getDisplayId())) { return false; } Loading
services/core/java/com/android/server/wm/DisplayContent.java +0 −3 Original line number Diff line number Diff line Loading @@ -547,9 +547,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp // TODO(multi-display): remove some of the usages. boolean isDefaultDisplay; /** Indicates whether any presentation is shown on this display. */ boolean mIsPresenting; /** Save allocating when calculating rects */ private final Rect mTmpRect = new Rect(); private final Region mTmpRegion = new Region(); Loading
services/core/java/com/android/server/wm/PresentationController.java 0 → 100644 +79 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.wm; import static com.android.window.flags.Flags.enablePresentationForConnectedDisplays; import android.annotation.NonNull; import android.util.IntArray; /** * Manages presentation windows. */ class PresentationController { // TODO(b/395475549): Add support for display add/remove, and activity move across displays. private final IntArray mPresentingDisplayIds = new IntArray(); PresentationController() {} private boolean isPresenting(int displayId) { return mPresentingDisplayIds.contains(displayId); } boolean shouldOccludeActivities(int displayId) { // All activities on the presenting display must be hidden so that malicious apps can't do // tap jacking (b/391466268). // For now, this should only be applied to external displays because presentations can only // be shown on them. // TODO(b/390481621): Disallow a presentation from covering its controlling activity so that // the presentation won't stop its controlling activity. return enablePresentationForConnectedDisplays() && isPresenting(displayId); } void onPresentationAdded(@NonNull WindowState win) { final int displayId = win.getDisplayId(); if (isPresenting(displayId)) { return; } mPresentingDisplayIds.add(displayId); if (enablePresentationForConnectedDisplays()) { // A presentation hides all activities behind on the same display. win.mDisplayContent.ensureActivitiesVisible(/*starting=*/ null, /*notifyClients=*/ true); } win.mWmService.mDisplayManagerInternal.onPresentation(displayId, /*isShown=*/ true); } void onPresentationRemoved(@NonNull WindowState win) { final int displayId = win.getDisplayId(); if (!isPresenting(displayId)) { return; } // TODO(b/393945496): Make sure that there's one presentation at most per display. final int displayIdIndex = mPresentingDisplayIds.indexOf(displayId); if (displayIdIndex != -1) { mPresentingDisplayIds.remove(displayIdIndex); } if (enablePresentationForConnectedDisplays()) { // A presentation hides all activities behind on the same display. win.mDisplayContent.ensureActivitiesVisible(/*starting=*/ null, /*notifyClients=*/ true); } win.mWmService.mDisplayManagerInternal.onPresentation(displayId, /*isShown=*/ false); } }
services/core/java/com/android/server/wm/WindowManagerService.java +5 −11 Original line number Diff line number Diff line Loading @@ -157,7 +157,6 @@ import static com.android.server.wm.WindowManagerServiceDumpProto.POLICY; import static com.android.server.wm.WindowManagerServiceDumpProto.ROOT_WINDOW_CONTAINER; import static com.android.server.wm.WindowManagerServiceDumpProto.WINDOW_FRAMES_VALID; import static com.android.window.flags.Flags.enableDisplayFocusInShellTransitions; import static com.android.window.flags.Flags.enablePresentationForConnectedDisplays; import static com.android.window.flags.Flags.multiCrop; import static com.android.window.flags.Flags.setScPropertiesInClient; Loading Loading @@ -503,6 +502,8 @@ public class WindowManagerService extends IWindowManager.Stub final StartingSurfaceController mStartingSurfaceController; final PresentationController mPresentationController; private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() { @Override public void onVrStateChanged(boolean enabled) { Loading Loading @@ -1433,6 +1434,7 @@ public class WindowManagerService extends IWindowManager.Stub setGlobalShadowSettings(); mAnrController = new AnrController(this); mStartingSurfaceController = new StartingSurfaceController(this); mPresentationController = new PresentationController(); mBlurController = new BlurController(mContext, mPowerManager); mTaskFpsCallbackController = new TaskFpsCallbackController(mContext); Loading Loading @@ -1937,16 +1939,8 @@ public class WindowManagerService extends IWindowManager.Stub } outSizeCompatScale[0] = win.getCompatScaleForClient(); if (res >= ADD_OKAY && (type == TYPE_PRESENTATION || type == TYPE_PRIVATE_PRESENTATION)) { displayContent.mIsPresenting = true; if (enablePresentationForConnectedDisplays()) { // A presentation hides all activities behind on the same display. displayContent.ensureActivitiesVisible(/*starting=*/ null, /*notifyClients=*/ true); } mDisplayManagerInternal.onPresentation(displayContent.getDisplay().getDisplayId(), /*isShown=*/ true); if (res >= ADD_OKAY && win.isPresentation()) { mPresentationController.onPresentationAdded(win); } } Loading
services/core/java/com/android/server/wm/WindowState.java +6 −10 Original line number Diff line number Diff line Loading @@ -182,7 +182,6 @@ import static com.android.server.wm.WindowStateProto.UNRESTRICTED_KEEP_CLEAR_ARE import static com.android.server.wm.WindowStateProto.VIEW_VISIBILITY; import static com.android.server.wm.WindowStateProto.WINDOW_CONTAINER; import static com.android.server.wm.WindowStateProto.WINDOW_FRAMES; import static com.android.window.flags.Flags.enablePresentationForConnectedDisplays; import static com.android.window.flags.Flags.surfaceTrustedOverlay; import android.annotation.CallSuper; Loading Loading @@ -2300,15 +2299,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP final int type = mAttrs.type; if (type == TYPE_PRESENTATION || type == TYPE_PRIVATE_PRESENTATION) { // TODO(b/393945496): Make sure that there's one presentation at most per display. dc.mIsPresenting = false; if (enablePresentationForConnectedDisplays()) { // A presentation hides all activities behind on the same display. dc.ensureActivitiesVisible(/*starting=*/ null, /*notifyClients=*/ true); } mWmService.mDisplayManagerInternal.onPresentation(dc.getDisplay().getDisplayId(), /*isShown=*/ false); if (isPresentation()) { mWmService.mPresentationController.onPresentationRemoved(this); } // Check if window provides non decor insets before clearing its provided insets. final boolean windowProvidesDisplayDecorInsets = providesDisplayDecorInsets(); Loading Loading @@ -3337,6 +3329,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } } boolean isPresentation() { return mAttrs.type == TYPE_PRESENTATION || mAttrs.type == TYPE_PRIVATE_PRESENTATION; } private boolean isOnVirtualDisplay() { return getDisplayContent().mDisplay.getType() == Display.TYPE_VIRTUAL; } Loading