From 88400d3a31139c40c4014faf86c243647087ef6c Mon Sep 17 00:00:00 2001 From: Craig Mautner Date: Sun, 30 Sep 2012 12:35:45 -0700 Subject: [PATCH] Add flag for displaying non-user's Windows to user. Created a new flag that indicates that a window should be shown to all users. For the flag to be valid the owner of the window must have system permissions. Also separated system window types into those that show to all users (e.g. StatusBar, Keyguard, ....) and those that appear only to the owning users (e.g. Drag, ANR, TOAST, ...). Those that appear only to their owner can override their default behavior using the new flag (e.g. LowBattery). Fixes bug 7211965. Change-Id: I1fdca25d57b7b523f0c7f8bceb819af656c388d4 --- core/java/android/view/WindowManager.java | 45 +++++++++++++ .../android/view/WindowManagerPolicy.java | 10 +++ .../com/android/systemui/power/PowerUI.java | 4 ++ .../policy/impl/PhoneWindowManager.java | 64 +++++++++++++++++-- .../policy/impl/RecentApplicationsDialog.java | 2 +- .../impl/keyguard/KeyguardViewManager.java | 3 + .../server/accessibility/ScreenMagnifier.java | 3 +- .../server/wm/WindowManagerService.java | 51 ++++++++++----- .../com/android/server/wm/WindowState.java | 28 ++++---- .../server/wm/WindowStateAnimator.java | 2 +- 10 files changed, 173 insertions(+), 39 deletions(-) diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 6e51270433370..eb3f72eb0e64c 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -298,12 +298,14 @@ public interface WindowManager extends ViewManager { * Window type: the status bar. There can be only one status bar * window; it is placed at the top of the screen, and all other * windows are shifted down so they are below it. + * In multiuser systems shows on all users' windows. */ public static final int TYPE_STATUS_BAR = FIRST_SYSTEM_WINDOW; /** * Window type: the search bar. There can be only one search bar * window; it is placed at the top of the screen. + * In multiuser systems shows on all users' windows. */ public static final int TYPE_SEARCH_BAR = FIRST_SYSTEM_WINDOW+1; @@ -312,22 +314,26 @@ public interface WindowManager extends ViewManager { * user interaction with the phone (in particular incoming calls). * These windows are normally placed above all applications, but behind * the status bar. + * In multiuser systems shows on all users' windows. */ public static final int TYPE_PHONE = FIRST_SYSTEM_WINDOW+2; /** * Window type: system window, such as low power alert. These windows * are always on top of application windows. + * In multiuser systems shows only on the owning user's window. */ public static final int TYPE_SYSTEM_ALERT = FIRST_SYSTEM_WINDOW+3; /** * Window type: keyguard window. + * In multiuser systems shows on all users' windows. */ public static final int TYPE_KEYGUARD = FIRST_SYSTEM_WINDOW+4; /** * Window type: transient notifications. + * In multiuser systems shows only on the owning user's window. */ public static final int TYPE_TOAST = FIRST_SYSTEM_WINDOW+5; @@ -335,6 +341,7 @@ public interface WindowManager extends ViewManager { * Window type: system overlay windows, which need to be displayed * on top of everything else. These windows must not take input * focus, or they will interfere with the keyguard. + * In multiuser systems shows only on the owning user's window. */ public static final int TYPE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+6; @@ -342,22 +349,26 @@ public interface WindowManager extends ViewManager { * Window type: priority phone UI, which needs to be displayed even if * the keyguard is active. These windows must not take input * focus, or they will interfere with the keyguard. + * In multiuser systems shows on all users' windows. */ public static final int TYPE_PRIORITY_PHONE = FIRST_SYSTEM_WINDOW+7; /** * Window type: panel that slides out from the status bar + * In multiuser systems shows on all users' windows. */ public static final int TYPE_SYSTEM_DIALOG = FIRST_SYSTEM_WINDOW+8; /** * Window type: dialogs that the keyguard shows + * In multiuser systems shows on all users' windows. */ public static final int TYPE_KEYGUARD_DIALOG = FIRST_SYSTEM_WINDOW+9; /** * Window type: internal system error windows, appear on top of * everything they can. + * In multiuser systems shows only on the owning user's window. */ public static final int TYPE_SYSTEM_ERROR = FIRST_SYSTEM_WINDOW+10; @@ -365,23 +376,27 @@ public interface WindowManager extends ViewManager { * Window type: internal input methods windows, which appear above * the normal UI. Application windows may be resized or panned to keep * the input focus visible while this window is displayed. + * In multiuser systems shows only on the owning user's window. */ public static final int TYPE_INPUT_METHOD = FIRST_SYSTEM_WINDOW+11; /** * Window type: internal input methods dialog windows, which appear above * the current input method window. + * In multiuser systems shows only on the owning user's window. */ public static final int TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW+12; /** * Window type: wallpaper window, placed behind any window that wants * to sit on top of the wallpaper. + * In multiuser systems shows only on the owning user's window. */ public static final int TYPE_WALLPAPER = FIRST_SYSTEM_WINDOW+13; /** * Window type: panel that slides out from over the status bar + * In multiuser systems shows on all users' windows. */ public static final int TYPE_STATUS_BAR_PANEL = FIRST_SYSTEM_WINDOW+14; @@ -393,6 +408,8 @@ public interface WindowManager extends ViewManager { * This is exactly like {@link #TYPE_SYSTEM_OVERLAY} except that only the * system itself is allowed to create these overlays. Applications cannot * obtain permission to create secure system overlays. + * + * In multiuser systems shows only on the owning user's window. * @hide */ public static final int TYPE_SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+15; @@ -400,24 +417,28 @@ public interface WindowManager extends ViewManager { /** * Window type: the drag-and-drop pseudowindow. There is only one * drag layer (at most), and it is placed on top of all other windows. + * In multiuser systems shows only on the owning user's window. * @hide */ public static final int TYPE_DRAG = FIRST_SYSTEM_WINDOW+16; /** * Window type: panel that slides out from under the status bar + * In multiuser systems shows on all users' windows. * @hide */ public static final int TYPE_STATUS_BAR_SUB_PANEL = FIRST_SYSTEM_WINDOW+17; /** * Window type: (mouse) pointer + * In multiuser systems shows on all users' windows. * @hide */ public static final int TYPE_POINTER = FIRST_SYSTEM_WINDOW+18; /** * Window type: Navigation bar (when distinct from status bar) + * In multiuser systems shows on all users' windows. * @hide */ public static final int TYPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW+19; @@ -425,6 +446,7 @@ public interface WindowManager extends ViewManager { /** * Window type: The volume level overlay/dialog shown when the user * changes the system volume. + * In multiuser systems shows on all users' windows. * @hide */ public static final int TYPE_VOLUME_OVERLAY = FIRST_SYSTEM_WINDOW+20; @@ -432,6 +454,7 @@ public interface WindowManager extends ViewManager { /** * Window type: The boot progress dialog, goes on top of everything * in the world. + * In multiuser systems shows on all users' windows. * @hide */ public static final int TYPE_BOOT_PROGRESS = FIRST_SYSTEM_WINDOW+21; @@ -439,30 +462,35 @@ public interface WindowManager extends ViewManager { /** * Window type: Fake window to consume touch events when the navigation * bar is hidden. + * In multiuser systems shows on all users' windows. * @hide */ public static final int TYPE_HIDDEN_NAV_CONSUMER = FIRST_SYSTEM_WINDOW+22; /** * Window type: Dreams (screen saver) window, just above keyguard. + * In multiuser systems shows only on the owning user's window. * @hide */ public static final int TYPE_DREAM = FIRST_SYSTEM_WINDOW+23; /** * Window type: Navigation bar panel (when navigation bar is distinct from status bar) + * In multiuser systems shows on all users' windows. * @hide */ public static final int TYPE_NAVIGATION_BAR_PANEL = FIRST_SYSTEM_WINDOW+24; /** * Window type: Behind the universe of the real windows. + * In multiuser systems shows on all users' windows. * @hide */ public static final int TYPE_UNIVERSE_BACKGROUND = FIRST_SYSTEM_WINDOW+25; /** * Window type: Display overlay window. Used to simulate secondary display devices. + * In multiuser systems shows on all users' windows. * @hide */ public static final int TYPE_DISPLAY_OVERLAY = FIRST_SYSTEM_WINDOW+26; @@ -470,10 +498,19 @@ public interface WindowManager extends ViewManager { /** * Window type: Magnification overlay window. Used to highlight the magnified * portion of a display when accessibility magnification is enabled. + * In multiuser systems shows on all users' windows. * @hide */ public static final int TYPE_MAGNIFICATION_OVERLAY = FIRST_SYSTEM_WINDOW+27; + /** + * Window type: Recents. Same layer as {@link #TYPE_SYSTEM_DIALOG} but only appears on + * one user's screen. + * In multiuser systems shows on all users' windows. + * @hide + */ + public static final int TYPE_RECENTS_OVERLAY = FIRST_SYSTEM_WINDOW+28; + /** * End of types of system windows. */ @@ -879,6 +916,14 @@ public interface WindowManager extends ViewManager { */ public static final int PRIVATE_FLAG_SET_NEEDS_MENU_KEY = 0x00000008; + /** In a multiuser system if this flag is set and the owner is a system process then this + * window will appear on all user screens. This overrides the default behavior of window + * types that normally only appear on the owning user's screen. Refer to each window type + * to determine its default behavior. + * + * {@hide} */ + public static final int PRIVATE_FLAG_SHOW_FOR_ALL_USERS = 0x00000010; + /** * Control flags that are private to the platform. * @hide diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 82f07c7bbbb56..2d399a26beb89 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -499,6 +499,16 @@ public interface WindowManagerPolicy { */ public int checkAddPermission(WindowManager.LayoutParams attrs); + /** + * Check permissions when adding a window. + * + * @param attrs The window's LayoutParams. + * + * @return True if the window may only be shown to the current user, false if the window can + * be shown on all users' windows. + */ + public boolean checkShowToOwnerOnly(WindowManager.LayoutParams attrs); + /** * Sanitize the layout parameters coming from a client. Allows the policy * to do things like ensure that windows of a specific type can't take diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java index 3c30f5dd77b3d..07fd0abb259a9 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java @@ -207,6 +207,7 @@ public class PowerUI extends SystemUI { if (intent.resolveActivity(mContext.getPackageManager()) != null) { b.setNegativeButton(R.string.battery_low_why, new DialogInterface.OnClickListener() { + @Override public void onClick(DialogInterface dialog, int which) { mContext.startActivity(intent); dismissLowBatteryWarning(); @@ -216,12 +217,15 @@ public class PowerUI extends SystemUI { AlertDialog d = b.create(); d.setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override public void onDismiss(DialogInterface dialog) { mLowBatteryDialog = null; mBatteryLevelTextView = null; } }); d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); + d.getWindow().getAttributes().privateFlags |= + WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; d.show(); mLowBatteryDialog = d; } diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index ba76bcd797318..5ed0a5ced82fc 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -17,7 +17,6 @@ package com.android.internal.policy.impl; import android.app.ActivityManager; import android.app.ActivityManagerNative; -import android.app.IUiModeManager; import android.app.ProgressDialog; import android.app.SearchManager; import android.app.UiModeManager; @@ -101,6 +100,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; @@ -108,6 +108,7 @@ import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY; @@ -119,6 +120,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_PHONE; import static android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE; +import static android.view.WindowManager.LayoutParams.TYPE_RECENTS_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR; import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; @@ -202,7 +204,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { static final int KEYGUARD_LAYER = 11; static final int KEYGUARD_DIALOG_LAYER = 12; // used for Dreams (screensavers with TYPE_DREAM windows) - static final int SCREENSAVER_LAYER = 13; + static final int SCREENSAVER_LAYER = 13; static final int STATUS_BAR_SUB_PANEL_LAYER = 14; static final int STATUS_BAR_LAYER = 15; static final int STATUS_BAR_PANEL_LAYER = 16; @@ -234,7 +236,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1; static final int APPLICATION_PANEL_SUBLAYER = 1; static final int APPLICATION_SUB_PANEL_SUBLAYER = 2; - + static public final String SYSTEM_DIALOG_REASON_KEY = "reason"; static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions"; static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps"; @@ -289,7 +291,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { // Vibrator pattern for haptic feedback of a long press. long[] mLongPressVibePattern; - + // Vibrator pattern for haptic feedback of virtual key press. long[] mVirtualKeyVibePattern; @@ -1199,6 +1201,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } /** {@inheritDoc} */ + @Override public int checkAddPermission(WindowManager.LayoutParams attrs) { int type = attrs.type; @@ -1236,7 +1239,55 @@ public class PhoneWindowManager implements WindowManagerPolicy { } return WindowManagerGlobal.ADD_OKAY; } - + + @Override + public boolean checkShowToOwnerOnly(WindowManager.LayoutParams attrs) { + + // If this switch statement is modified, modify the comment in the declarations of + // the type in {@link WindowManager.LayoutParams} as well. + switch (attrs.type) { + default: + // These are the windows that by default are shown only to the user that created + // them. If this needs to be overridden, set + // {@link WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS} in + // {@link WindowManager.LayoutParams}. Note that permission + // {@link android.Manifest.permission.INTERNAL_SYSTEM_WINDOW} is required as well. + if ((attrs.privateFlags & PRIVATE_FLAG_SHOW_FOR_ALL_USERS) == 0) { + return true; + } + break; + + // These are the windows that by default are shown to all users. However, to + // protect against spoofing, check permissions below. + case TYPE_APPLICATION_STARTING: + case TYPE_BOOT_PROGRESS: + case TYPE_DISPLAY_OVERLAY: + case TYPE_HIDDEN_NAV_CONSUMER: + case TYPE_KEYGUARD: + case TYPE_KEYGUARD_DIALOG: + case TYPE_MAGNIFICATION_OVERLAY: + case TYPE_NAVIGATION_BAR: + case TYPE_NAVIGATION_BAR_PANEL: + case TYPE_PHONE: + case TYPE_POINTER: + case TYPE_PRIORITY_PHONE: + case TYPE_RECENTS_OVERLAY: + case TYPE_SEARCH_BAR: + case TYPE_STATUS_BAR: + case TYPE_STATUS_BAR_PANEL: + case TYPE_STATUS_BAR_SUB_PANEL: + case TYPE_SYSTEM_DIALOG: + case TYPE_UNIVERSE_BACKGROUND: + case TYPE_VOLUME_OVERLAY: + break; + } + + // Check if third party app has set window to system window type. + return mContext.checkCallingOrSelfPermission( + android.Manifest.permission.INTERNAL_SYSTEM_WINDOW) + != PackageManager.PERMISSION_GRANTED; + } + public void adjustWindowParamsLw(WindowManager.LayoutParams attrs) { switch (attrs.type) { case TYPE_SYSTEM_OVERLAY: @@ -1355,6 +1406,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { return DISPLAY_OVERLAY_LAYER; case TYPE_MAGNIFICATION_OVERLAY: return MAGNIFICATION_OVERLAY_LAYER; + case TYPE_RECENTS_OVERLAY: + return SYSTEM_DIALOG_LAYER; } Log.e(TAG, "Unknown window type: " + type); return APPLICATION_LAYER; @@ -1510,6 +1563,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { com.android.internal.R.styleable.Window_windowAnimationStyle, 0); params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED; + params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; params.setTitle("Starting " + packageName); WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE); diff --git a/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java b/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java index b9903dd906ea6..2f0d7d6a81d83 100644 --- a/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java +++ b/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java @@ -94,7 +94,7 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener Window window = getWindow(); window.requestFeature(Window.FEATURE_NO_TITLE); - window.setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG); + window.setType(WindowManager.LayoutParams.TYPE_RECENTS_OVERLAY); window.setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); window.setTitle("Recents"); diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java index 23a96fb2e9e60..7a1e235a97e0f 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java @@ -164,6 +164,9 @@ public class KeyguardViewManager { WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED; } lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY; + if (isActivity) { + lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; + } lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY; lp.userActivityTimeout = KeyguardViewMediator.AWAKE_INTERVAL_DEFAULT_MS; lp.setTitle(isActivity ? "KeyguardMock" : "Keyguard"); diff --git a/services/java/com/android/server/accessibility/ScreenMagnifier.java b/services/java/com/android/server/accessibility/ScreenMagnifier.java index 14762a14800e6..ec3c88c4c598c 100644 --- a/services/java/com/android/server/accessibility/ScreenMagnifier.java +++ b/services/java/com/android/server/accessibility/ScreenMagnifier.java @@ -1009,7 +1009,8 @@ public final class ScreenMagnifier implements EventStreamTransformation { case WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG: case WindowManager.LayoutParams.TYPE_SYSTEM_ERROR: case WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY: - case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL: { + case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL: + case WindowManager.LayoutParams.TYPE_RECENTS_OVERLAY: { Rect magnifiedRegionBounds = mMagnificationController .getMagnifiedRegionBounds(); Rect touchableRegion = info.touchableRegion; diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 180579dc025ce..1b1d85b7adc7a 100755 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -34,6 +34,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_DREAM; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD; +import static android.view.WindowManager.LayoutParams.TYPE_RECENTS_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR; import static android.view.WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND; @@ -2083,6 +2084,7 @@ public class WindowManagerService extends IWindowManager.Stub WindowState attachedWindow = null; WindowState win = null; long origId; + final int type = attrs.type; synchronized(mWindowMap) { if (!mDisplayReady) { @@ -2094,7 +2096,7 @@ public class WindowManagerService extends IWindowManager.Stub return WindowManagerGlobal.ADD_DUPLICATE_ADD; } - if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) { + if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) { attachedWindow = windowForClientLocked(null, attrs.token, false); if (attachedWindow == null) { Slog.w(TAG, "Attempted to add window with token that is not a window: " @@ -2112,31 +2114,29 @@ public class WindowManagerService extends IWindowManager.Stub boolean addToken = false; WindowToken token = mTokenMap.get(attrs.token); if (token == null) { - if (attrs.type >= FIRST_APPLICATION_WINDOW - && attrs.type <= LAST_APPLICATION_WINDOW) { + if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) { Slog.w(TAG, "Attempted to add application window with unknown token " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } - if (attrs.type == TYPE_INPUT_METHOD) { + if (type == TYPE_INPUT_METHOD) { Slog.w(TAG, "Attempted to add input method window with unknown token " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } - if (attrs.type == TYPE_WALLPAPER) { + if (type == TYPE_WALLPAPER) { Slog.w(TAG, "Attempted to add wallpaper window with unknown token " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } - if (attrs.type == TYPE_DREAM) { + if (type == TYPE_DREAM) { Slog.w(TAG, "Attempted to add Dream window with unknown token " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } token = new WindowToken(this, attrs.token, -1, false); addToken = true; - } else if (attrs.type >= FIRST_APPLICATION_WINDOW - && attrs.type <= LAST_APPLICATION_WINDOW) { + } else if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) { AppWindowToken atoken = token.appWindowToken; if (atoken == null) { Slog.w(TAG, "Attempted to add window with non-application token " @@ -2147,25 +2147,25 @@ public class WindowManagerService extends IWindowManager.Stub + token + ". Aborting."); return WindowManagerGlobal.ADD_APP_EXITING; } - if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) { + if (type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) { // No need for this guy! if (localLOGV) Slog.v( TAG, "**** NO NEED TO START: " + attrs.getTitle()); return WindowManagerGlobal.ADD_STARTING_NOT_NEEDED; } - } else if (attrs.type == TYPE_INPUT_METHOD) { + } else if (type == TYPE_INPUT_METHOD) { if (token.windowType != TYPE_INPUT_METHOD) { Slog.w(TAG, "Attempted to add input method window with bad token " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } - } else if (attrs.type == TYPE_WALLPAPER) { + } else if (type == TYPE_WALLPAPER) { if (token.windowType != TYPE_WALLPAPER) { Slog.w(TAG, "Attempted to add wallpaper window with bad token " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } - } else if (attrs.type == TYPE_DREAM) { + } else if (type == TYPE_DREAM) { if (token.windowType != TYPE_DREAM) { Slog.w(TAG, "Attempted to add Dream window with bad token " + attrs.token + ". Aborting."); @@ -2185,6 +2185,7 @@ public class WindowManagerService extends IWindowManager.Stub } mPolicy.adjustWindowParamsLw(win.mAttrs); + win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs)); res = mPolicy.prepareAddWindowLw(win, attrs); if (res != WindowManagerGlobal.ADD_OKAY) { @@ -2213,8 +2214,7 @@ public class WindowManagerService extends IWindowManager.Stub win.attach(); mWindowMap.put(client.asBinder(), win); - if (attrs.type == TYPE_APPLICATION_STARTING && - token.appWindowToken != null) { + if (type == TYPE_APPLICATION_STARTING && token.appWindowToken != null) { token.appWindowToken.startingWindow = win; if (DEBUG_STARTING_WINDOW) Slog.v (TAG, "addWindow: " + token.appWindowToken + " startingWindow=" + win); @@ -2222,19 +2222,19 @@ public class WindowManagerService extends IWindowManager.Stub boolean imMayMove = true; - if (attrs.type == TYPE_INPUT_METHOD) { + if (type == TYPE_INPUT_METHOD) { win.mGivenInsetsPending = true; mInputMethodWindow = win; addInputMethodWindowToListLocked(win); imMayMove = false; - } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) { + } else if (type == TYPE_INPUT_METHOD_DIALOG) { mInputMethodDialogs.add(win); addWindowToListInOrderLocked(win, true); adjustInputMethodDialogsLocked(); imMayMove = false; } else { addWindowToListInOrderLocked(win, true); - if (attrs.type == TYPE_WALLPAPER) { + if (type == TYPE_WALLPAPER) { mLastWallpaperTimeoutTime = 0; adjustWallpaperWindowsLocked(); } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) { @@ -5404,6 +5404,22 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mWindowMap) { mCurrentUserId = newUserId; mPolicy.setCurrentUserLw(newUserId); + + // Hide windows that should not be seen by the new user. + DisplayContentsIterator iterator = new DisplayContentsIterator(); + while (iterator.hasNext()) { + final WindowList windows = iterator.next().getWindowList(); + for (int i = 0; i < windows.size(); i++) { + final WindowState win = windows.get(i); + if (win.isOtherUsersAppWindow()) { + Slog.w(TAG, "current user violation " + newUserId + " hiding " + + win + ", attrs=" + win.mAttrs.type + ", belonging to " + + win.mOwnerUid); + win.hideLw(false); + } + } + } + performLayoutAndPlaceSurfacesLocked(); } } @@ -8784,6 +8800,7 @@ public class WindowManagerService extends IWindowManager.Stub final int type = attrs.type; if (canBeSeen && (type == TYPE_SYSTEM_DIALOG + || type == TYPE_RECENTS_OVERLAY || type == TYPE_KEYGUARD || type == TYPE_SYSTEM_ERROR)) { mInnerFields.mSyswin = true; diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java index d23448b783cf2..6e388f24836fa 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/java/com/android/server/wm/WindowState.java @@ -22,9 +22,6 @@ import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; -import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; -import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; -import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import com.android.server.input.InputWindowHandle; @@ -36,7 +33,6 @@ import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; import android.os.IBinder; -import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.util.Slog; @@ -263,7 +259,10 @@ final class WindowState implements WindowManagerPolicy.WindowState { DisplayContent mDisplayContent; // UserId and appId of the owner. Don't display windows of non-current user. - final int mOwnerUid; + int mOwnerUid; + + /** When true this window can be displayed on screens owther than mOwnerUid's */ + private boolean mShowToOwnerOnly; WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, WindowState attachedWindow, int seq, WindowManager.LayoutParams a, @@ -654,6 +653,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { * surface, or we are in the process of running an exit animation * that will remove the surface, or its app token has been hidden. */ + @Override public boolean isVisibleLw() { final AppWindowToken atoken = mAppToken; return mHasSurface && mPolicyVisibility && !mAttachedHidden @@ -669,6 +669,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { * for this "hidden behind keyguard" state rather than overloading * mPolicyVisibility. Ungh. */ + @Override public boolean isVisibleOrBehindKeyguardLw() { if (mRootToken.waitingToShow && mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) { @@ -940,7 +941,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { boolean showLw(boolean doAnimation, boolean requestAnim) { if (isOtherUsersAppWindow()) { - Slog.w(TAG, "Current user " + mService.mCurrentUserId + " trying to display " + Slog.w(TAG, "current user violation " + mService.mCurrentUserId + " trying to display " + this + ", type " + mAttrs.type + ", belonging to " + mOwnerUid); return false; } @@ -1025,15 +1026,12 @@ final class WindowState implements WindowManagerPolicy.WindowState { return mDisplayContent.isDefaultDisplay; } + public void setShowToOwnerOnlyLocked(boolean showToOwnerOnly) { + mShowToOwnerOnly = showToOwnerOnly; + } + boolean isOtherUsersAppWindow() { - final int type = mAttrs.type; - if ((UserHandle.getUserId(mOwnerUid) != mService.mCurrentUserId) - && (mOwnerUid != Process.SYSTEM_UID) - && (type >= TYPE_BASE_APPLICATION) && (type <= LAST_APPLICATION_WINDOW) - && (type != TYPE_APPLICATION_STARTING)) { - return true; - } - return false; + return mShowToOwnerOnly && UserHandle.getUserId(mOwnerUid) != mService.mCurrentUserId; } private static void applyInsets(Region outRegion, Rect frame, Rect inset) { @@ -1072,6 +1070,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { pw.print(prefix); pw.print("mDisplayId="); pw.print(mDisplayContent.getDisplayId()); pw.print(" mSession="); pw.print(mSession); pw.print(" mClient="); pw.println(mClient.asBinder()); + pw.print(prefix); pw.print("mOwnerUid="); pw.print(mOwnerUid); + pw.print(" mShowToOwnerOnly="); pw.println(mShowToOwnerOnly); pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs); pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth); pw.print(" h="); pw.print(mRequestedHeight); diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java index acf452ffc7131..817a2344a5452 100644 --- a/services/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/java/com/android/server/wm/WindowStateAnimator.java @@ -1335,7 +1335,7 @@ class WindowStateAnimator { // This must be called while inside a transaction. boolean performShowLocked() { if (mWin.isOtherUsersAppWindow()) { - Slog.w(TAG, "Current user " + mService.mCurrentUserId + " trying to display " + Slog.w(TAG, "current user violation " + mService.mCurrentUserId + " trying to display " + this + ", type " + mWin.mAttrs.type + ", belonging to " + mWin.mOwnerUid); return false; }