Skip to content

Commit

Permalink
Back-port fixes for b/62196835
Browse files Browse the repository at this point in the history
Bug: 62196835
Test: Created an accessibility service that displays a system
and a toast overlay, confirmed that it disappeared when we
reached the accessibility permission screen that uses this
flag.

Change-Id: Ic51ead670fc480e549512ba1d02f49d9c13bc3f0
(cherry picked from commit 41ff538)
  • Loading branch information
pweaver-google authored and Klozz committed Sep 17, 2017
1 parent f612e18 commit 818f511
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 0 deletions.
1 change: 1 addition & 0 deletions api/system-current.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
28 changes: 28 additions & 0 deletions core/java/android/view/WindowManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,25 @@ public static class LayoutParams extends ViewGroup.LayoutParams implements Parce
*/
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;
Expand Down Expand Up @@ -1288,6 +1307,15 @@ public static class LayoutParams extends ViewGroup.LayoutParams implements Parce
*/
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;

/**
* Window flag: Overrides default power key behavior
* @hide
Expand Down
9 changes: 9 additions & 0 deletions core/res/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2205,6 +2205,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.
Expand Down
9 changes: 9 additions & 0 deletions services/core/java/com/android/server/wm/Session.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -80,6 +85,10 @@ public Session(WindowManagerService service, IWindowSessionCallback callback,
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{");
Expand Down
37 changes: 37 additions & 0 deletions services/core/java/com/android/server/wm/WindowManagerService.java
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,9 @@ public void onReceive(Context context, Intent intent) {
*/
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.
*/
Expand Down Expand Up @@ -2138,6 +2141,9 @@ public int addWindow(Session session, IWindow client, int seq,
}
}

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
Expand Down Expand Up @@ -2585,6 +2591,7 @@ void removeWindowInnerLocked(WindowState win) {

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);

Expand Down Expand Up @@ -11846,6 +11853,36 @@ public boolean isDockedDividerResizing() {
}
}

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);
}
}
}

public int mSingleHandMode = 0;
private SingleHandAdapter mSingleHandAdapter;
private final Handler mUiHandler;
Expand Down
38 changes: 38 additions & 0 deletions services/core/java/com/android/server/wm/WindowState.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
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;
Expand All @@ -91,7 +92,9 @@
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;
Expand Down Expand Up @@ -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;
Expand All @@ -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?
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -1882,6 +1889,10 @@ boolean showLw(boolean doAnimation, boolean requestAnim) {
// 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;
Expand Down Expand Up @@ -1955,6 +1966,22 @@ boolean hideLw(boolean doAnimation, boolean requestAnim) {
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;
Expand Down Expand Up @@ -2760,6 +2787,17 @@ void dump(PrintWriter pw, String prefix, boolean dumpAll) {
}
}

/**
* 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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,7 @@ void hide(String reason) {
//dump();
mLastHidden = true;
if (mSurfaceController != null) {
mService.updateNonSystemOverlayWindowsVisibilityIfNeeded(mWin, false);
mSurfaceController.hideInTransaction(reason);
}
}
Expand Down Expand Up @@ -1864,6 +1865,7 @@ private boolean showSurfaceRobustlyLocked() {
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;
Expand Down

0 comments on commit 818f511

Please sign in to comment.