Loading services/core/java/com/android/server/wm/ActivityRecord.java +11 −0 Original line number Diff line number Diff line Loading @@ -248,6 +248,7 @@ 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.WindowManagerService.sEnableShellTransitions; 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 @@ -6223,6 +6224,16 @@ 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) { return false; } // Check if the activity is on a sleeping display and keyguard is not going away (to // align with TaskFragment#shouldSleepActivities), canTurnScreenOn will also check keyguard // visibility Loading services/core/java/com/android/server/wm/DisplayContent.java +3 −0 Original line number Diff line number Diff line Loading @@ -547,6 +547,9 @@ 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/WindowManagerService.java +7 −0 Original line number Diff line number Diff line Loading @@ -157,6 +157,7 @@ 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 @@ -1925,6 +1926,12 @@ public class WindowManagerService extends IWindowManager.Stub 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); } Loading services/core/java/com/android/server/wm/WindowState.java +7 −0 Original line number Diff line number Diff line Loading @@ -182,6 +182,7 @@ 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 @@ -2317,6 +2318,12 @@ 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); } Loading services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +35 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import static android.permission.flags.Flags.FLAG_SENSITIVE_CONTENT_RECENTS_SCRE import static android.permission.flags.Flags.FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.FLAG_OWN_FOCUS; import static android.view.Display.FLAG_PRESENTATION; import static android.view.Display.INVALID_DISPLAY; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; Loading Loading @@ -53,6 +54,7 @@ import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_BACKGROUND_ import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING; import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_BACKGROUND_SOLID_COLOR; import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_BACKGROUND_WALLPAPER; import static com.android.window.flags.Flags.FLAG_ENABLE_PRESENTATION_FOR_CONNECTED_DISPLAYS; import static com.google.common.truth.Truth.assertThat; Loading Loading @@ -99,6 +101,7 @@ import android.provider.Settings; import android.util.ArraySet; import android.util.MergedConfiguration; import android.view.ContentRecordingSession; import android.view.DisplayInfo; import android.view.IWindow; import android.view.InputChannel; import android.view.InputDevice; Loading Loading @@ -1405,6 +1408,38 @@ public class WindowManagerServiceTests extends WindowTestsBase { assertEquals(activityWindowInfo2, activityWindowInfo3); } @EnableFlags(FLAG_ENABLE_PRESENTATION_FOR_CONNECTED_DISPLAYS) @Test public void testPresentationHidesActivitiesBehind() { DisplayInfo displayInfo = new DisplayInfo(); displayInfo.copyFrom(mDisplayInfo); displayInfo.flags = FLAG_PRESENTATION; DisplayContent dc = createNewDisplay(displayInfo); int displayId = dc.getDisplayId(); doReturn(dc).when(mWm.mRoot).getDisplayContentOrCreate(displayId); ActivityRecord activity = createActivityRecord(createTask(dc)); assertTrue(activity.isVisible()); doReturn(true).when(() -> UserManager.isVisibleBackgroundUsersEnabled()); int uid = 100000; // uid for non-system user Session session = createTestSession(mAtm, 1234 /* pid */, uid); int userId = UserHandle.getUserId(uid); doReturn(false).when(mWm.mUmInternal).isUserVisible(eq(userId), eq(displayId)); WindowManager.LayoutParams params = new WindowManager.LayoutParams( LayoutParams.TYPE_PRESENTATION); final IWindow clientWindow = new TestIWindow(); int result = mWm.addWindow(session, clientWindow, params, View.VISIBLE, displayId, userId, WindowInsets.Type.defaultVisible(), null, new InsetsState(), new InsetsSourceControl.Array(), new Rect(), new float[1]); assertTrue(result >= WindowManagerGlobal.ADD_OKAY); assertFalse(activity.isVisible()); final WindowState window = mWm.windowForClientLocked(session, clientWindow, false); window.removeImmediately(); assertTrue(activity.isVisible()); } @Test public void testAddOverlayWindowToUnassignedDisplay_notAllowed_ForVisibleBackgroundUsers() { doReturn(true).when(() -> UserManager.isVisibleBackgroundUsersEnabled()); Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +11 −0 Original line number Diff line number Diff line Loading @@ -248,6 +248,7 @@ 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.WindowManagerService.sEnableShellTransitions; 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 @@ -6223,6 +6224,16 @@ 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) { return false; } // Check if the activity is on a sleeping display and keyguard is not going away (to // align with TaskFragment#shouldSleepActivities), canTurnScreenOn will also check keyguard // visibility Loading
services/core/java/com/android/server/wm/DisplayContent.java +3 −0 Original line number Diff line number Diff line Loading @@ -547,6 +547,9 @@ 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/WindowManagerService.java +7 −0 Original line number Diff line number Diff line Loading @@ -157,6 +157,7 @@ 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 @@ -1925,6 +1926,12 @@ public class WindowManagerService extends IWindowManager.Stub 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); } Loading
services/core/java/com/android/server/wm/WindowState.java +7 −0 Original line number Diff line number Diff line Loading @@ -182,6 +182,7 @@ 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 @@ -2317,6 +2318,12 @@ 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); } Loading
services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +35 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import static android.permission.flags.Flags.FLAG_SENSITIVE_CONTENT_RECENTS_SCRE import static android.permission.flags.Flags.FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.FLAG_OWN_FOCUS; import static android.view.Display.FLAG_PRESENTATION; import static android.view.Display.INVALID_DISPLAY; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; Loading Loading @@ -53,6 +54,7 @@ import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_BACKGROUND_ import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING; import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_BACKGROUND_SOLID_COLOR; import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_BACKGROUND_WALLPAPER; import static com.android.window.flags.Flags.FLAG_ENABLE_PRESENTATION_FOR_CONNECTED_DISPLAYS; import static com.google.common.truth.Truth.assertThat; Loading Loading @@ -99,6 +101,7 @@ import android.provider.Settings; import android.util.ArraySet; import android.util.MergedConfiguration; import android.view.ContentRecordingSession; import android.view.DisplayInfo; import android.view.IWindow; import android.view.InputChannel; import android.view.InputDevice; Loading Loading @@ -1405,6 +1408,38 @@ public class WindowManagerServiceTests extends WindowTestsBase { assertEquals(activityWindowInfo2, activityWindowInfo3); } @EnableFlags(FLAG_ENABLE_PRESENTATION_FOR_CONNECTED_DISPLAYS) @Test public void testPresentationHidesActivitiesBehind() { DisplayInfo displayInfo = new DisplayInfo(); displayInfo.copyFrom(mDisplayInfo); displayInfo.flags = FLAG_PRESENTATION; DisplayContent dc = createNewDisplay(displayInfo); int displayId = dc.getDisplayId(); doReturn(dc).when(mWm.mRoot).getDisplayContentOrCreate(displayId); ActivityRecord activity = createActivityRecord(createTask(dc)); assertTrue(activity.isVisible()); doReturn(true).when(() -> UserManager.isVisibleBackgroundUsersEnabled()); int uid = 100000; // uid for non-system user Session session = createTestSession(mAtm, 1234 /* pid */, uid); int userId = UserHandle.getUserId(uid); doReturn(false).when(mWm.mUmInternal).isUserVisible(eq(userId), eq(displayId)); WindowManager.LayoutParams params = new WindowManager.LayoutParams( LayoutParams.TYPE_PRESENTATION); final IWindow clientWindow = new TestIWindow(); int result = mWm.addWindow(session, clientWindow, params, View.VISIBLE, displayId, userId, WindowInsets.Type.defaultVisible(), null, new InsetsState(), new InsetsSourceControl.Array(), new Rect(), new float[1]); assertTrue(result >= WindowManagerGlobal.ADD_OKAY); assertFalse(activity.isVisible()); final WindowState window = mWm.windowForClientLocked(session, clientWindow, false); window.removeImmediately(); assertTrue(activity.isVisible()); } @Test public void testAddOverlayWindowToUnassignedDisplay_notAllowed_ForVisibleBackgroundUsers() { doReturn(true).when(() -> UserManager.isVisibleBackgroundUsersEnabled()); Loading