diff --git a/core/api/current.txt b/core/api/current.txt index db5d143662e47..d864a56cb228a 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -3015,6 +3015,7 @@ package android.accessibilityservice { field public static final int GLOBAL_ACTION_ACCESSIBILITY_BUTTON_CHOOSER = 12; // 0xc field public static final int GLOBAL_ACTION_ACCESSIBILITY_SHORTCUT = 13; // 0xd field public static final int GLOBAL_ACTION_BACK = 1; // 0x1 + field public static final int GLOBAL_ACTION_DISMISS_NOTIFICATION_SHADE = 15; // 0xf field public static final int GLOBAL_ACTION_HOME = 2; // 0x2 field public static final int GLOBAL_ACTION_KEYCODE_HEADSETHOOK = 10; // 0xa field public static final int GLOBAL_ACTION_LOCK_SCREEN = 8; // 0x8 diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index dab4a5dc316c3..d5368213be087 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -555,6 +555,11 @@ public abstract class AccessibilityService extends Service { */ public static final int GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS = 14; + /** + * Action to dismiss the notification shade + */ + public static final int GLOBAL_ACTION_DISMISS_NOTIFICATION_SHADE = 15; + private static final String LOG_TAG = "AccessibilityService"; /** diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 3505dee134c06..f094be0bd51f9 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -5519,6 +5519,8 @@ On-screen Accessibility Shortcut Chooser Accessibility Shortcut + + Dismiss Notification Shade Caption bar of %1$s. diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index e73d6e3af3cbe..06a366c62d9f3 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3964,6 +3964,7 @@ + diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java index 1bf747408d95a..c051b695e8234 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java @@ -53,12 +53,18 @@ import com.android.systemui.Dependency; import com.android.systemui.SystemUI; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.recents.Recents; +import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.phone.StatusBar; +import com.android.systemui.statusbar.phone.StatusBarWindowCallback; +import com.android.systemui.util.Assert; import java.util.Locale; import javax.inject.Inject; +import dagger.Lazy; + /** * Class to register system actions with accessibility framework. */ @@ -128,23 +134,39 @@ public class SystemActions extends SystemUI { public static final int SYSTEM_ACTION_ID_ACCESSIBILITY_SHORTCUT = AccessibilityService.GLOBAL_ACTION_ACCESSIBILITY_SHORTCUT; // 13 + public static final int SYSTEM_ACTION_ID_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE = + AccessibilityService.GLOBAL_ACTION_DISMISS_NOTIFICATION_SHADE; // 15 + private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF"; - private SystemActionsBroadcastReceiver mReceiver; + private final SystemActionsBroadcastReceiver mReceiver; private Locale mLocale; - private AccessibilityManager mA11yManager; + private final AccessibilityManager mA11yManager; + private final Lazy mStatusBar; + private final NotificationShadeWindowController mNotificationShadeController; + private final StatusBarWindowCallback mNotificationShadeCallback; + private boolean mDismissNotificationShadeActionRegistered; @Inject - public SystemActions(Context context) { + public SystemActions(Context context, + NotificationShadeWindowController notificationShadeController, + Lazy statusBar) { super(context); mReceiver = new SystemActionsBroadcastReceiver(); mLocale = mContext.getResources().getConfiguration().getLocales().get(0); mA11yManager = (AccessibilityManager) mContext.getSystemService( Context.ACCESSIBILITY_SERVICE); + mNotificationShadeController = notificationShadeController; + // Saving in instance variable since to prevent GC since + // NotificationShadeWindowController.registerCallback() only keeps weak references. + mNotificationShadeCallback = (keyguardShowing, keyguardOccluded, bouncerShowing) -> + registerOrUnregisterDismissNotificationShadeAction(); + mStatusBar = statusBar; } @Override public void start() { + mNotificationShadeController.registerCallback(mNotificationShadeCallback); mContext.registerReceiverForAllUsers( mReceiver, mReceiver.createIntentFilter(), @@ -210,6 +232,32 @@ public class SystemActions extends SystemUI { mA11yManager.registerSystemAction(actionTakeScreenshot, SYSTEM_ACTION_ID_TAKE_SCREENSHOT); mA11yManager.registerSystemAction( actionAccessibilityShortcut, SYSTEM_ACTION_ID_ACCESSIBILITY_SHORTCUT); + registerOrUnregisterDismissNotificationShadeAction(); + } + + private void registerOrUnregisterDismissNotificationShadeAction() { + Assert.isMainThread(); + + // Saving state in instance variable since this callback is called quite often to avoid + // binder calls + StatusBar statusBar = mStatusBar.get(); + if (statusBar.isPanelExpanded() && !statusBar.isKeyguardShowing()) { + if (!mDismissNotificationShadeActionRegistered) { + mA11yManager.registerSystemAction( + createRemoteAction( + R.string.accessibility_system_action_dismiss_notification_shade, + SystemActionsBroadcastReceiver + .INTENT_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE), + SYSTEM_ACTION_ID_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE); + mDismissNotificationShadeActionRegistered = true; + } + } else { + if (mDismissNotificationShadeActionRegistered) { + mA11yManager.unregisterSystemAction( + SYSTEM_ACTION_ID_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE); + mDismissNotificationShadeActionRegistered = false; + } + } } /** @@ -261,10 +309,15 @@ public class SystemActions extends SystemUI { R.string.accessibility_system_action_on_screen_a11y_shortcut_chooser_label; intent = SystemActionsBroadcastReceiver.INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER; break; - case SYSTEM_ACTION_ID_ACCESSIBILITY_SHORTCUT: + case SYSTEM_ACTION_ID_ACCESSIBILITY_SHORTCUT: labelId = R.string.accessibility_system_action_hardware_a11y_shortcut_label; intent = SystemActionsBroadcastReceiver.INTENT_ACTION_ACCESSIBILITY_SHORTCUT; break; + case SYSTEM_ACTION_ID_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE: + labelId = R.string.accessibility_system_action_dismiss_notification_shade; + intent = SystemActionsBroadcastReceiver + .INTENT_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE; + break; default: return; } @@ -369,6 +422,10 @@ public class SystemActions extends SystemUI { mA11yManager.performAccessibilityShortcut(); } + private void handleAccessibilityDismissNotificationShade() { + mStatusBar.get().animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, false /* force */); + } + private class SystemActionsBroadcastReceiver extends BroadcastReceiver { private static final String INTENT_ACTION_BACK = "SYSTEM_ACTION_BACK"; private static final String INTENT_ACTION_HOME = "SYSTEM_ACTION_HOME"; @@ -384,6 +441,8 @@ public class SystemActions extends SystemUI { "SYSTEM_ACTION_ACCESSIBILITY_BUTTON_MENU"; private static final String INTENT_ACTION_ACCESSIBILITY_SHORTCUT = "SYSTEM_ACTION_ACCESSIBILITY_SHORTCUT"; + private static final String INTENT_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE = + "SYSTEM_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE"; private PendingIntent createPendingIntent(Context context, String intentAction) { switch (intentAction) { @@ -397,7 +456,8 @@ public class SystemActions extends SystemUI { case INTENT_ACTION_TAKE_SCREENSHOT: case INTENT_ACTION_ACCESSIBILITY_BUTTON: case INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER: - case INTENT_ACTION_ACCESSIBILITY_SHORTCUT: { + case INTENT_ACTION_ACCESSIBILITY_SHORTCUT: + case INTENT_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE: { Intent intent = new Intent(intentAction); intent.setPackage(context.getPackageName()); return PendingIntent.getBroadcast(context, 0, intent, @@ -422,6 +482,7 @@ public class SystemActions extends SystemUI { intentFilter.addAction(INTENT_ACTION_ACCESSIBILITY_BUTTON); intentFilter.addAction(INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER); intentFilter.addAction(INTENT_ACTION_ACCESSIBILITY_SHORTCUT); + intentFilter.addAction(INTENT_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE); return intentFilter; } @@ -473,6 +534,10 @@ public class SystemActions extends SystemUI { handleAccessibilityShortcut(); break; } + case INTENT_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE: { + handleAccessibilityDismissNotificationShade(); + break; + } default: break; } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java index 726e2d06bf909..21b10a1e70300 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java @@ -334,13 +334,6 @@ public class DependencyProvider { return WindowManagerWrapper.getInstance(); } - /** */ - @Provides - @SysUISingleton - public SystemActions providesSystemActions(Context context) { - return new SystemActions(context); - } - /** */ @Provides @SysUISingleton