Loading services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java +3 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,9 @@ public interface StatusBarManagerInternal { void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey); /** Collapses the notification shade. */ void collapsePanels(); void dismissKeyboardShortcutsMenu(); void toggleKeyboardShortcutsMenu(int deviceId); Loading services/core/java/com/android/server/statusbar/StatusBarManagerService.java +10 −0 Original line number Diff line number Diff line Loading @@ -383,6 +383,16 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D } } @Override public void collapsePanels() { if (mBar != null) { try { mBar.animateCollapsePanels(); } catch (RemoteException ex) { } } } @Override public void dismissKeyboardShortcutsMenu() { if (mBar != null) { Loading services/core/java/com/android/server/wm/ActivityStarter.java +15 −0 Original line number Diff line number Diff line Loading @@ -118,6 +118,7 @@ import com.android.internal.protolog.common.ProtoLog; import com.android.server.am.PendingIntentRecord; import com.android.server.pm.InstantAppResolver; import com.android.server.power.ShutdownCheckPoints; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.uri.NeededUriGrants; import com.android.server.wm.ActivityMetricsLogger.LaunchingState; import com.android.server.wm.ActivityTaskSupervisor.PendingActivityLaunch; Loading Loading @@ -1589,6 +1590,20 @@ class ActivityStarter { newTransition.abort(); } } else { if (!mAvoidMoveToFront && mDoResume && mRootWindowContainer.hasVisibleWindowAboveNotificationShade( r.launchedFromUid)) { // If the UID launching the activity has a visible window on top of the // notification shade and it's launching an activity that's going to be at the // front, we should move the shade out of the way so the user can see it. // We want to avoid the case where the activity is launched on top of a // background task which is not moved to the front. StatusBarManagerInternal statusBar = mService.getStatusBarManagerInternal(); if (statusBar != null) { // This results in a async call since the interface is one-way statusBar.collapsePanels(); } } if (result == START_SUCCESS || result == START_TASK_TO_FRONT) { // The activity is started new rather than just brought forward, so record // it as an existence change. Loading services/core/java/com/android/server/wm/ActivityTaskManagerService.java +27 −4 Original line number Diff line number Diff line Loading @@ -28,6 +28,8 @@ import static android.Manifest.permission.READ_FRAME_BUFFER; import static android.Manifest.permission.REMOVE_TASKS; import static android.Manifest.permission.START_TASKS_FROM_RECENTS; import static android.Manifest.permission.STOP_APP_SWITCHES; import static android.app.ActivityManager.DROP_CLOSE_SYSTEM_DIALOGS; import static android.app.ActivityManager.LOCK_DOWN_CLOSE_SYSTEM_DIALOGS; import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; import static android.app.ActivityManagerInternal.ALLOW_NON_FULL; import static android.app.ActivityTaskManager.INVALID_TASK_ID; Loading Loading @@ -253,6 +255,7 @@ import com.android.server.firewall.IntentFirewall; import com.android.server.inputmethod.InputMethodSystemProperty; import com.android.server.pm.UserManagerService; import com.android.server.policy.PermissionPolicyInternal; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.uri.NeededUriGrants; import com.android.server.uri.UriGrantsManagerInternal; Loading Loading @@ -342,6 +345,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** The cached sys ui service component name from package manager. */ private ComponentName mSysUiServiceComponent; private PermissionPolicyInternal mPermissionPolicyInternal; private StatusBarManagerInternal mStatusBarManagerInternal; @VisibleForTesting final ActivityTaskManagerInternal mInternal; PowerManagerInternal mPowerManagerInternal; Loading Loading @@ -2927,14 +2931,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } if (!canCloseSystemDialogs(pid, uid, process)) { // The app can't close system dialogs, throw only if it targets S+ if (CompatChanges.isChangeEnabled( ActivityManager.LOCK_DOWN_CLOSE_SYSTEM_DIALOGS, uid)) { if (CompatChanges.isChangeEnabled(LOCK_DOWN_CLOSE_SYSTEM_DIALOGS, uid)) { throw new SecurityException( "Permission Denial: " + Intent.ACTION_CLOSE_SYSTEM_DIALOGS + " broadcast from " + caller + " requires " + Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS + "."); } else if (CompatChanges.isChangeEnabled( ActivityManager.DROP_CLOSE_SYSTEM_DIALOGS, uid)) { } else if (CompatChanges.isChangeEnabled(DROP_CLOSE_SYSTEM_DIALOGS, uid)) { Slog.e(TAG, "Permission Denial: " + Intent.ACTION_CLOSE_SYSTEM_DIALOGS + " broadcast from " + caller + " requires " Loading Loading @@ -2983,6 +2985,20 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return true; } } // This covers the case where the app is displaying some UI on top of the notification shade // and wants to start an activity. The app then sends the intent in order to move the // notification shade out of the way and show the activity to the user. This is fine since // the caller already has privilege to show a visible window on top of the notification // shade, so it can already prevent the user from accessing the shade if it wants to. // We only allow for targetSdk < S, for S+ we automatically collapse the shade on // startActivity() for these apps. if (!CompatChanges.isChangeEnabled(LOCK_DOWN_CLOSE_SYSTEM_DIALOGS, uid)) { synchronized (mGlobalLock) { if (mRootWindowContainer.hasVisibleWindowAboveNotificationShade(uid)) { return true; } } } return false; } Loading Loading @@ -4787,6 +4803,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return mPermissionPolicyInternal; } StatusBarManagerInternal getStatusBarManagerInternal() { if (mStatusBarManagerInternal == null) { mStatusBarManagerInternal = LocalServices.getService(StatusBarManagerInternal.class); } return mStatusBarManagerInternal; } AppWarnings getAppWarningsLocked() { return mAppWarnings; } Loading services/core/java/com/android/server/wm/RootWindowContainer.java +22 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import static android.view.Display.INVALID_DISPLAY; import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE; import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE; import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManager.TRANSIT_FLAG_APP_CRASHED; import static android.view.WindowManager.TRANSIT_NONE; Loading Loading @@ -3137,6 +3138,27 @@ class RootWindowContainer extends WindowContainer<DisplayContent> }); } /** * Returns {@code true} if {@code uid} has a visible window that's above a window of type {@link * WindowManager.LayoutParams#TYPE_NOTIFICATION_SHADE}. If there is no window with type {@link * WindowManager.LayoutParams#TYPE_NOTIFICATION_SHADE}, it returns {@code false}. */ boolean hasVisibleWindowAboveNotificationShade(int uid) { boolean[] visibleWindowFound = {false}; // We only return true if we found the notification shade (ie. window of type // TYPE_NOTIFICATION_SHADE). Usually, it should always be there, but if for some reason // it isn't, we should better be on the safe side and return false for this. return forAllWindows(w -> { if (w.mOwnerUid == uid && w.isVisible()) { visibleWindowFound[0] = true; } if (w.mAttrs.type == TYPE_NOTIFICATION_SHADE) { return visibleWindowFound[0]; } return false; }, true /* traverseTopToBottom */); } private boolean shouldCloseAssistant(ActivityRecord r, String reason) { if (!r.isActivityTypeAssistant()) return false; if (reason == SYSTEM_DIALOG_REASON_ASSIST) return false; Loading Loading
services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java +3 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,9 @@ public interface StatusBarManagerInternal { void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey); /** Collapses the notification shade. */ void collapsePanels(); void dismissKeyboardShortcutsMenu(); void toggleKeyboardShortcutsMenu(int deviceId); Loading
services/core/java/com/android/server/statusbar/StatusBarManagerService.java +10 −0 Original line number Diff line number Diff line Loading @@ -383,6 +383,16 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D } } @Override public void collapsePanels() { if (mBar != null) { try { mBar.animateCollapsePanels(); } catch (RemoteException ex) { } } } @Override public void dismissKeyboardShortcutsMenu() { if (mBar != null) { Loading
services/core/java/com/android/server/wm/ActivityStarter.java +15 −0 Original line number Diff line number Diff line Loading @@ -118,6 +118,7 @@ import com.android.internal.protolog.common.ProtoLog; import com.android.server.am.PendingIntentRecord; import com.android.server.pm.InstantAppResolver; import com.android.server.power.ShutdownCheckPoints; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.uri.NeededUriGrants; import com.android.server.wm.ActivityMetricsLogger.LaunchingState; import com.android.server.wm.ActivityTaskSupervisor.PendingActivityLaunch; Loading Loading @@ -1589,6 +1590,20 @@ class ActivityStarter { newTransition.abort(); } } else { if (!mAvoidMoveToFront && mDoResume && mRootWindowContainer.hasVisibleWindowAboveNotificationShade( r.launchedFromUid)) { // If the UID launching the activity has a visible window on top of the // notification shade and it's launching an activity that's going to be at the // front, we should move the shade out of the way so the user can see it. // We want to avoid the case where the activity is launched on top of a // background task which is not moved to the front. StatusBarManagerInternal statusBar = mService.getStatusBarManagerInternal(); if (statusBar != null) { // This results in a async call since the interface is one-way statusBar.collapsePanels(); } } if (result == START_SUCCESS || result == START_TASK_TO_FRONT) { // The activity is started new rather than just brought forward, so record // it as an existence change. Loading
services/core/java/com/android/server/wm/ActivityTaskManagerService.java +27 −4 Original line number Diff line number Diff line Loading @@ -28,6 +28,8 @@ import static android.Manifest.permission.READ_FRAME_BUFFER; import static android.Manifest.permission.REMOVE_TASKS; import static android.Manifest.permission.START_TASKS_FROM_RECENTS; import static android.Manifest.permission.STOP_APP_SWITCHES; import static android.app.ActivityManager.DROP_CLOSE_SYSTEM_DIALOGS; import static android.app.ActivityManager.LOCK_DOWN_CLOSE_SYSTEM_DIALOGS; import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; import static android.app.ActivityManagerInternal.ALLOW_NON_FULL; import static android.app.ActivityTaskManager.INVALID_TASK_ID; Loading Loading @@ -253,6 +255,7 @@ import com.android.server.firewall.IntentFirewall; import com.android.server.inputmethod.InputMethodSystemProperty; import com.android.server.pm.UserManagerService; import com.android.server.policy.PermissionPolicyInternal; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.uri.NeededUriGrants; import com.android.server.uri.UriGrantsManagerInternal; Loading Loading @@ -342,6 +345,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** The cached sys ui service component name from package manager. */ private ComponentName mSysUiServiceComponent; private PermissionPolicyInternal mPermissionPolicyInternal; private StatusBarManagerInternal mStatusBarManagerInternal; @VisibleForTesting final ActivityTaskManagerInternal mInternal; PowerManagerInternal mPowerManagerInternal; Loading Loading @@ -2927,14 +2931,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } if (!canCloseSystemDialogs(pid, uid, process)) { // The app can't close system dialogs, throw only if it targets S+ if (CompatChanges.isChangeEnabled( ActivityManager.LOCK_DOWN_CLOSE_SYSTEM_DIALOGS, uid)) { if (CompatChanges.isChangeEnabled(LOCK_DOWN_CLOSE_SYSTEM_DIALOGS, uid)) { throw new SecurityException( "Permission Denial: " + Intent.ACTION_CLOSE_SYSTEM_DIALOGS + " broadcast from " + caller + " requires " + Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS + "."); } else if (CompatChanges.isChangeEnabled( ActivityManager.DROP_CLOSE_SYSTEM_DIALOGS, uid)) { } else if (CompatChanges.isChangeEnabled(DROP_CLOSE_SYSTEM_DIALOGS, uid)) { Slog.e(TAG, "Permission Denial: " + Intent.ACTION_CLOSE_SYSTEM_DIALOGS + " broadcast from " + caller + " requires " Loading Loading @@ -2983,6 +2985,20 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return true; } } // This covers the case where the app is displaying some UI on top of the notification shade // and wants to start an activity. The app then sends the intent in order to move the // notification shade out of the way and show the activity to the user. This is fine since // the caller already has privilege to show a visible window on top of the notification // shade, so it can already prevent the user from accessing the shade if it wants to. // We only allow for targetSdk < S, for S+ we automatically collapse the shade on // startActivity() for these apps. if (!CompatChanges.isChangeEnabled(LOCK_DOWN_CLOSE_SYSTEM_DIALOGS, uid)) { synchronized (mGlobalLock) { if (mRootWindowContainer.hasVisibleWindowAboveNotificationShade(uid)) { return true; } } } return false; } Loading Loading @@ -4787,6 +4803,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return mPermissionPolicyInternal; } StatusBarManagerInternal getStatusBarManagerInternal() { if (mStatusBarManagerInternal == null) { mStatusBarManagerInternal = LocalServices.getService(StatusBarManagerInternal.class); } return mStatusBarManagerInternal; } AppWarnings getAppWarningsLocked() { return mAppWarnings; } Loading
services/core/java/com/android/server/wm/RootWindowContainer.java +22 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import static android.view.Display.INVALID_DISPLAY; import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE; import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE; import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManager.TRANSIT_FLAG_APP_CRASHED; import static android.view.WindowManager.TRANSIT_NONE; Loading Loading @@ -3137,6 +3138,27 @@ class RootWindowContainer extends WindowContainer<DisplayContent> }); } /** * Returns {@code true} if {@code uid} has a visible window that's above a window of type {@link * WindowManager.LayoutParams#TYPE_NOTIFICATION_SHADE}. If there is no window with type {@link * WindowManager.LayoutParams#TYPE_NOTIFICATION_SHADE}, it returns {@code false}. */ boolean hasVisibleWindowAboveNotificationShade(int uid) { boolean[] visibleWindowFound = {false}; // We only return true if we found the notification shade (ie. window of type // TYPE_NOTIFICATION_SHADE). Usually, it should always be there, but if for some reason // it isn't, we should better be on the safe side and return false for this. return forAllWindows(w -> { if (w.mOwnerUid == uid && w.isVisible()) { visibleWindowFound[0] = true; } if (w.mAttrs.type == TYPE_NOTIFICATION_SHADE) { return visibleWindowFound[0]; } return false; }, true /* traverseTopToBottom */); } private boolean shouldCloseAssistant(ActivityRecord r, String reason) { if (!r.isActivityTypeAssistant()) return false; if (reason == SYSTEM_DIALOG_REASON_ASSIST) return false; Loading