summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-07-26 23:18:38 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-07-26 23:18:38 +0000
commitd186092cc1fef8726c245088634dd4af9bbc6607 (patch)
treee08d0f6d41a5d5b75fbeee71e7f1669898056fe4
parent98b67dc463881d7bd8ae4ae2d4a125eca2a835c7 (diff)
parent95047a66c11e0d2185d497c8b16cebb6c02cbd3d (diff)
downloadbase-nougat-mr1-flounder-release.tar.gz
Merge cherrypicks of [2604297, 2604299, 2604519, 2606195, 2605695, 2604520, 2606196, 2604521, 2604522, 2606197, 2604523, 2605696, 2605697, 2605698, 2606198, 2604524, 2604525, 2604526, 2604300, 2604527, 2606199, 2604528, 2604529, 2604301, 2606200, 2604302, 2606410, 2606201, 2606411, 2606202, 2606413, 2606203, 2606414, 2604303, 2604304, 2606204, 2604305, 2606206, 2606207, 2604306, 2606415, 2606208, 2606209, 2606416] into nyc-mr1-volantis-releaseandroid-7.1.1_r53nougat-mr1-flounder-release
Change-Id: Ib841181af81988d84e9623ab18c2d2beaa563fa7
-rw-r--r--api/system-current.txt1
-rw-r--r--core/java/android/view/WindowManager.java28
-rw-r--r--core/res/AndroidManifest.xml9
-rw-r--r--services/core/java/com/android/server/wm/Session.java9
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java37
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java38
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java2
7 files changed, 124 insertions, 0 deletions
diff --git a/api/system-current.txt b/api/system-current.txt
index 0fe164a269cd..6b6f7e99e4b1 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -112,6 +112,7 @@ package android {
field public static final java.lang.String GRANT_RUNTIME_PERMISSIONS = "android.permission.GRANT_RUNTIME_PERMISSIONS";
field public static final java.lang.String HARDWARE_TEST = "android.permission.HARDWARE_TEST";
field public static final java.lang.String HDMI_CEC = "android.permission.HDMI_CEC";
+ field public static final java.lang.String HIDE_NON_SYSTEM_OVERLAY_WINDOWS = "android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS";
field public static final java.lang.String INJECT_EVENTS = "android.permission.INJECT_EVENTS";
field public static final java.lang.String INSTALL_GRANT_RUNTIME_PERMISSIONS = "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS";
field public static final java.lang.String INSTALL_LOCATION_PROVIDER = "android.permission.INSTALL_LOCATION_PROVIDER";
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 395f73844b07..169f7e170dd6 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -655,6 +655,25 @@ public interface WindowManager extends ViewManager {
*/
public static final int LAST_SYSTEM_WINDOW = 2999;
+ /**
+ * Return true if the window type is an alert window.
+ *
+ * @param type The window type.
+ * @return If the window type is an alert window.
+ * @hide
+ */
+ public static boolean isSystemAlertWindowType(int type) {
+ switch (type) {
+ case TYPE_PHONE:
+ case TYPE_PRIORITY_PHONE:
+ case TYPE_SYSTEM_ALERT:
+ case TYPE_SYSTEM_ERROR:
+ case TYPE_SYSTEM_OVERLAY:
+ return true;
+ }
+ return false;
+ }
+
/** @deprecated this is ignored, this value is set automatically when needed. */
@Deprecated
public static final int MEMORY_TYPE_NORMAL = 0;
@@ -1263,6 +1282,15 @@ public interface WindowManager extends ViewManager {
public static final int PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE = 0x00040000;
/**
+ * Flag to indicate that any window added by an application process that is of type
+ * {@link #TYPE_TOAST} or that requires
+ * {@link android.app.AppOpsManager#OP_SYSTEM_ALERT_WINDOW} permission should be hidden when
+ * this window is visible.
+ * @hide
+ */
+ public static final int PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS = 0x00080000;
+
+ /**
* Control flags that are private to the platform.
* @hide
*/
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index c79d50067f93..43deb02d6fa6 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2151,6 +2151,15 @@
<permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"
android:protectionLevel="signature" />
+ <!-- @SystemApi Allows an application to use
+ {@link android.view.WindowManager.LayoutsParams#PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS}
+ to hide non-system-overlay windows.
+ <p>Not for use by third-party applications.
+ @hide
+ -->
+ <permission android:name="android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS"
+ android:protectionLevel="signature|installer" />
+
<!-- @SystemApi Allows an application to manage (create, destroy,
Z-order) application tokens in the window manager.
<p>Not for use by third-party applications.
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 08c0a4b01357..b5c4202dc107 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -16,6 +16,9 @@
package com.android.server.wm;
+import static android.Manifest.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
@@ -67,6 +70,8 @@ final class Session extends IWindowSession.Stub
final int mUid;
final int mPid;
final String mStringName;
+ final boolean mCanAddInternalSystemWindow;
+ final boolean mCanHideNonSystemOverlayWindows;
SurfaceSession mSurfaceSession;
int mNumWindow = 0;
boolean mClientDead = false;
@@ -80,6 +85,10 @@ final class Session extends IWindowSession.Stub
mInputContext = inputContext;
mUid = Binder.getCallingUid();
mPid = Binder.getCallingPid();
+ mCanAddInternalSystemWindow = service.mContext.checkCallingOrSelfPermission(
+ INTERNAL_SYSTEM_WINDOW) == PERMISSION_GRANTED;
+ mCanHideNonSystemOverlayWindows = service.mContext.checkCallingOrSelfPermission(
+ HIDE_NON_SYSTEM_OVERLAY_WINDOWS) == PERMISSION_GRANTED;
mLastReportedAnimatorScale = service.getCurrentAnimatorScale();
StringBuilder sb = new StringBuilder();
sb.append("Session{");
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ca2610af3f66..0d970591cb5c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -490,6 +490,9 @@ public class WindowManagerService extends IWindowManager.Stub
*/
final ArrayList<WindowState> mForceRemoves = new ArrayList<>();
+ /** List of window currently causing non-system overlay windows to be hidden. */
+ private ArrayList<WindowState> mHidingNonSystemOverlayWindows = new ArrayList<WindowState>();
+
/**
* Windows that clients are waiting to have drawn.
*/
@@ -2129,6 +2132,9 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
+ final boolean hideSystemAlertWindows = !mHidingNonSystemOverlayWindows.isEmpty();
+ win.setForceHideNonSystemOverlayWindowIfNeeded(hideSystemAlertWindows);
+
if (type == TYPE_APPLICATION_STARTING && token.appWindowToken != null) {
token.appWindowToken.startingWindow = win;
if (DEBUG_STARTING_WINDOW) Slog.v (TAG_WM, "addWindow: " + token.appWindowToken
@@ -2576,6 +2582,7 @@ public class WindowManagerService extends IWindowManager.Stub
mPendingRemove.remove(win);
mResizingWindows.remove(win);
+ updateNonSystemOverlayWindowsVisibilityIfNeeded(win, false /* surfaceShown */);
mWindowsChanged = true;
if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Final remove of window: " + win);
@@ -11771,4 +11778,34 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
}
+
+ void updateNonSystemOverlayWindowsVisibilityIfNeeded(WindowState win, boolean surfaceShown) {
+ if (!win.hideNonSystemOverlayWindowsWhenVisible()) {
+ return;
+ }
+ final boolean systemAlertWindowsHidden = !mHidingNonSystemOverlayWindows.isEmpty();
+ if (surfaceShown) {
+ if (!mHidingNonSystemOverlayWindows.contains(win)) {
+ mHidingNonSystemOverlayWindows.add(win);
+ }
+ } else {
+ mHidingNonSystemOverlayWindows.remove(win);
+ }
+
+ final boolean hideSystemAlertWindows = !mHidingNonSystemOverlayWindows.isEmpty();
+
+ if (systemAlertWindowsHidden == hideSystemAlertWindows) {
+ return;
+ }
+
+ final int numDisplays = mDisplayContents.size();
+ for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+ final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
+ final int numWindows = windows.size();
+ for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
+ final WindowState w = windows.get(winNdx);
+ w.setForceHideNonSystemOverlayWindowIfNeeded(hideSystemAlertWindows);
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index fbef2c626a9c..228ef1afb2a9 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -79,6 +79,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH;
@@ -91,7 +92,9 @@ import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
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_TOAST;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
@@ -141,6 +144,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
final int mAppOp;
// UserId and appId of the owner. Don't display windows of non-current user.
final int mOwnerUid;
+ final boolean mOwnerCanAddInternalSystemWindow;
final IWindowId mWindowId;
WindowToken mToken;
WindowToken mRootToken;
@@ -167,6 +171,8 @@ final class WindowState implements WindowManagerPolicy.WindowState {
boolean mPolicyVisibilityAfterAnim = true;
boolean mAppOpVisibility = true;
boolean mPermanentlyHidden; // the window should never be shown again
+ // This is a non-system overlay window that is currently force hidden.
+ private boolean mForceHideNonSystemOverlayWindow;
boolean mAppFreezing;
boolean mAttachedHidden; // is our parent window hidden?
boolean mWallpaperVisible; // for wallpaper, what was last vis report?
@@ -522,6 +528,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
mAppOp = appOp;
mToken = token;
mOwnerUid = s.mUid;
+ mOwnerCanAddInternalSystemWindow = s.mCanAddInternalSystemWindow;
mWindowId = new IWindowId.Stub() {
@Override
public void registerFocusObserver(IWindowFocusObserver observer) {
@@ -1882,6 +1889,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
// to handle their windows being removed from under them.
return false;
}
+ if (mForceHideNonSystemOverlayWindow) {
+ // This is an alert window that is currently force hidden.
+ return false;
+ }
if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
// Already showing.
return false;
@@ -1955,6 +1966,22 @@ final class WindowState implements WindowManagerPolicy.WindowState {
return true;
}
+ void setForceHideNonSystemOverlayWindowIfNeeded(boolean forceHide) {
+ if (mOwnerCanAddInternalSystemWindow
+ || (!isSystemAlertWindowType(mAttrs.type) && mAttrs.type != TYPE_TOAST)) {
+ return;
+ }
+ if (mForceHideNonSystemOverlayWindow == forceHide) {
+ return;
+ }
+ mForceHideNonSystemOverlayWindow = forceHide;
+ if (forceHide) {
+ hideLw(true /* doAnimation */, true /* requestAnim */);
+ } else {
+ showLw(true /* doAnimation */, true /* requestAnim */);
+ }
+ }
+
public void setAppOpVisibilityLw(boolean state) {
if (mAppOpVisibility != state) {
mAppOpVisibility = state;
@@ -2755,6 +2782,17 @@ final class WindowState implements WindowManagerPolicy.WindowState {
}
}
+ /**
+ * Returns true if any window added by an application process that if of type
+ * {@link android.view.WindowManager.LayoutParams#TYPE_TOAST} or that requires that requires
+ * {@link android.app.AppOpsManager#OP_SYSTEM_ALERT_WINDOW} permission should be hidden when
+ * this window is visible.
+ */
+ boolean hideNonSystemOverlayWindowsWhenVisible() {
+ return (mAttrs.privateFlags & PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0
+ && mSession.mCanHideNonSystemOverlayWindows;
+ }
+
String makeInputChannelName() {
return Integer.toHexString(System.identityHashCode(this))
+ " " + getWindowTag();
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index aa8e781b1c07..ec3208b3cc6c 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -582,6 +582,7 @@ class WindowStateAnimator {
//dump();
mLastHidden = true;
if (mSurfaceController != null) {
+ mService.updateNonSystemOverlayWindowsVisibilityIfNeeded(mWin, false);
mSurfaceController.hideInTransaction(reason);
}
}
@@ -1814,6 +1815,7 @@ class WindowStateAnimator {
if (!shown)
return false;
+ mService.updateNonSystemOverlayWindowsVisibilityIfNeeded(mWin, true);
if (mWin.mTurnOnScreen) {
if (DEBUG_VISIBILITY) Slog.v(TAG, "Show surface turning screen on: " + mWin);
mWin.mTurnOnScreen = false;