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