diff --git a/core/api/test-current.txt b/core/api/test-current.txt index e876a36fc0b0c..13fef0ea5407c 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -333,8 +333,10 @@ package android.app { method public void clickNotification(@Nullable String, int, int, boolean); method @RequiresPermission(android.Manifest.permission.STATUS_BAR) public void collapsePanels(); method public void expandNotificationsPanel(); + method @RequiresPermission(android.Manifest.permission.STATUS_BAR) public void handleSystemKey(int); method public void sendNotificationFeedback(@Nullable String, @Nullable android.os.Bundle); method @RequiresPermission(android.Manifest.permission.STATUS_BAR) public void setExpansionDisabledForSimNetworkLock(boolean); + method @RequiresPermission(android.Manifest.permission.STATUS_BAR) public void togglePanel(); } public final class SyncNotedAppOp implements android.os.Parcelable { diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java index 232b077538ef8..77bcef3ae009f 100644 --- a/core/java/android/app/StatusBarManager.java +++ b/core/java/android/app/StatusBarManager.java @@ -351,6 +351,42 @@ public class StatusBarManager { } } + /** + * Toggles the notification panel. + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.STATUS_BAR) + @TestApi + public void togglePanel() { + try { + final IStatusBarService svc = getService(); + if (svc != null) { + svc.togglePanel(); + } + } catch (RemoteException ex) { + throw ex.rethrowFromSystemServer(); + } + } + + /** + * Sends system keys to the status bar. + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.STATUS_BAR) + @TestApi + public void handleSystemKey(int key) { + try { + final IStatusBarService svc = getService(); + if (svc != null) { + svc.handleSystemKey(key); + } + } catch (RemoteException ex) { + throw ex.rethrowFromSystemServer(); + } + } + /** * Expand the settings panel. * diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 6255d77dc7cd6..3a7e13b8d8720 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -671,20 +671,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D @Override public void collapsePanels() { - int uid = Binder.getCallingUid(); - int pid = Binder.getCallingPid(); - if (CompatChanges.isChangeEnabled(LOCK_DOWN_COLLAPSE_STATUS_BAR, uid)) { - enforceStatusBar(); - } else { - if (mContext.checkPermission(Manifest.permission.STATUS_BAR, pid, uid) - != PackageManager.PERMISSION_GRANTED) { - enforceExpandStatusBar(); - if (!mActivityTaskManager.canCloseSystemDialogs(pid, uid)) { - Slog.e(TAG, "Permission Denial: Method collapsePanels() requires permission " - + Manifest.permission.STATUS_BAR + ", ignoring call."); - return; - } - } + if (!checkCanCollapseStatusBar("collapsePanels")) { + return; } if (mBar != null) { @@ -697,7 +685,9 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D @Override public void togglePanel() { - enforceExpandStatusBar(); + if (!checkCanCollapseStatusBar("togglePanel")) { + return; + } if (isDisable2FlagSet(DISABLE2_NOTIFICATION_SHADE)) { return; @@ -758,7 +748,9 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D @Override public void handleSystemKey(int key) throws RemoteException { - enforceExpandStatusBar(); + if (!checkCanCollapseStatusBar("handleSystemKey")) { + return; + } if (mBar != null) { try { @@ -1201,6 +1193,29 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D "StatusBarManagerService"); } + /** + * For targetSdk S+ we require STATUS_BAR. For targetSdk < S, we only require EXPAND_STATUS_BAR + * but also require that it falls into one of the allowed use-cases to lock down abuse vector. + */ + private boolean checkCanCollapseStatusBar(String method) { + int uid = Binder.getCallingUid(); + int pid = Binder.getCallingUid(); + if (CompatChanges.isChangeEnabled(LOCK_DOWN_COLLAPSE_STATUS_BAR, uid)) { + enforceStatusBar(); + } else { + if (mContext.checkPermission(Manifest.permission.STATUS_BAR, pid, uid) + != PackageManager.PERMISSION_GRANTED) { + enforceExpandStatusBar(); + if (!mActivityTaskManager.canCloseSystemDialogs(pid, uid)) { + Slog.e(TAG, "Permission Denial: Method " + method + "() requires permission " + + Manifest.permission.STATUS_BAR + ", ignoring call."); + return false; + } + } + } + return true; + } + // ================================================================================ // Callbacks from the status bar service. // ================================================================================