From 2c458b7cf6f4462506b978c8615a4c91bfc01ca1 Mon Sep 17 00:00:00 2001 From: Bernardo Rufino Date: Mon, 11 Jan 2021 12:34:18 +0000 Subject: [PATCH] Add DISMISS_NOTIFICATION_SHADE action for a11y As discussed in b/159334261, although the current a11y use-cases for closing the notification shade are already handled, it makes sense to add an explicit global action for accessibility services to close the notification shade (especially given there is one for opening the shade already). Added dependency to SystemActions, which required me to change add SystemActions to SystemUIGoogleBinder (topic). I also added to CarSystemUIBinder since SystemActions was also in their xml. I don't know if I need to add to others (eg. Arc), please advise. Bug: 159334261 Bug: 159105552 Test: With the shade opened, as a11y service send GLOBAL_ACTION_DISMISS_NOTIFICATION_SHADE and verify shade is closed. Change-Id: If52a1763170d5a5efd6b4756794206fd8bfb18a0 --- core/api/current.txt | 1 + .../AccessibilityService.java | 5 ++ core/res/res/values/strings.xml | 2 + core/res/res/values/symbols.xml | 1 + .../systemui/accessibility/SystemActions.java | 75 +++++++++++++++++-- .../systemui/dagger/DependencyProvider.java | 7 -- 6 files changed, 79 insertions(+), 12 deletions(-) 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