1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.accessibility; 18 19 import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_ACCESSIBILITY_ACTIONS; 20 21 import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME; 22 23 import android.accessibilityservice.AccessibilityService; 24 import android.app.PendingIntent; 25 import android.app.RemoteAction; 26 import android.content.BroadcastReceiver; 27 import android.content.Context; 28 import android.content.Intent; 29 import android.content.IntentFilter; 30 import android.content.res.Configuration; 31 import android.graphics.drawable.Icon; 32 import android.hardware.input.InputManager; 33 import android.os.Handler; 34 import android.os.Looper; 35 import android.os.PowerManager; 36 import android.os.RemoteException; 37 import android.os.SystemClock; 38 import android.os.UserHandle; 39 import android.util.Log; 40 import android.view.Display; 41 import android.view.IWindowManager; 42 import android.view.InputDevice; 43 import android.view.KeyCharacterMap; 44 import android.view.KeyEvent; 45 import android.view.WindowManager; 46 import android.view.WindowManagerGlobal; 47 import android.view.accessibility.AccessibilityManager; 48 49 import com.android.internal.R; 50 import com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity; 51 import com.android.internal.util.ScreenshotHelper; 52 import com.android.systemui.SystemUI; 53 import com.android.systemui.dagger.SysUISingleton; 54 import com.android.systemui.recents.Recents; 55 import com.android.systemui.statusbar.CommandQueue; 56 import com.android.systemui.statusbar.NotificationShadeWindowController; 57 import com.android.systemui.statusbar.phone.StatusBar; 58 import com.android.systemui.statusbar.phone.StatusBarWindowCallback; 59 import com.android.systemui.util.Assert; 60 61 import java.util.Locale; 62 63 import javax.inject.Inject; 64 65 import dagger.Lazy; 66 67 /** 68 * Class to register system actions with accessibility framework. 69 */ 70 @SysUISingleton 71 public class SystemActions extends SystemUI { 72 private static final String TAG = "SystemActions"; 73 74 /** 75 * Action ID to go back. 76 */ 77 private static final int SYSTEM_ACTION_ID_BACK = AccessibilityService.GLOBAL_ACTION_BACK; // = 1 78 79 /** 80 * Action ID to go home. 81 */ 82 private static final int SYSTEM_ACTION_ID_HOME = AccessibilityService.GLOBAL_ACTION_HOME; // = 2 83 84 /** 85 * Action ID to toggle showing the overview of recent apps. Will fail on platforms that don't 86 * show recent apps. 87 */ 88 private static final int SYSTEM_ACTION_ID_RECENTS = 89 AccessibilityService.GLOBAL_ACTION_RECENTS; // = 3 90 91 /** 92 * Action ID to open the notifications. 93 */ 94 private static final int SYSTEM_ACTION_ID_NOTIFICATIONS = 95 AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS; // = 4 96 97 /** 98 * Action ID to open the quick settings. 99 */ 100 private static final int SYSTEM_ACTION_ID_QUICK_SETTINGS = 101 AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS; // = 5 102 103 /** 104 * Action ID to open the power long-press dialog. 105 */ 106 private static final int SYSTEM_ACTION_ID_POWER_DIALOG = 107 AccessibilityService.GLOBAL_ACTION_POWER_DIALOG; // = 6 108 109 /** 110 * Action ID to lock the screen 111 */ 112 private static final int SYSTEM_ACTION_ID_LOCK_SCREEN = 113 AccessibilityService.GLOBAL_ACTION_LOCK_SCREEN; // = 8 114 115 /** 116 * Action ID to take a screenshot 117 */ 118 private static final int SYSTEM_ACTION_ID_TAKE_SCREENSHOT = 119 AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT; // = 9 120 121 /** 122 * Action ID to trigger the accessibility button 123 */ 124 public static final int SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON = 125 AccessibilityService.GLOBAL_ACTION_ACCESSIBILITY_BUTTON; // 11 126 127 /** 128 * Action ID to show accessibility button's menu of services 129 */ 130 public static final int SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON_CHOOSER = 131 AccessibilityService.GLOBAL_ACTION_ACCESSIBILITY_BUTTON_CHOOSER; // 12 132 133 public static final int SYSTEM_ACTION_ID_ACCESSIBILITY_SHORTCUT = 134 AccessibilityService.GLOBAL_ACTION_ACCESSIBILITY_SHORTCUT; // 13 135 136 public static final int SYSTEM_ACTION_ID_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE = 137 AccessibilityService.GLOBAL_ACTION_DISMISS_NOTIFICATION_SHADE; // 15 138 139 private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF"; 140 141 private final SystemActionsBroadcastReceiver mReceiver; 142 private final Recents mRecents; 143 private Locale mLocale; 144 private final AccessibilityManager mA11yManager; 145 private final Lazy<StatusBar> mStatusBar; 146 private final NotificationShadeWindowController mNotificationShadeController; 147 private final StatusBarWindowCallback mNotificationShadeCallback; 148 private boolean mDismissNotificationShadeActionRegistered; 149 150 @Inject SystemActions(Context context, NotificationShadeWindowController notificationShadeController, Lazy<StatusBar> statusBar, Recents recents)151 public SystemActions(Context context, 152 NotificationShadeWindowController notificationShadeController, 153 Lazy<StatusBar> statusBar, 154 Recents recents) { 155 super(context); 156 mRecents = recents; 157 mReceiver = new SystemActionsBroadcastReceiver(); 158 mLocale = mContext.getResources().getConfiguration().getLocales().get(0); 159 mA11yManager = (AccessibilityManager) mContext.getSystemService( 160 Context.ACCESSIBILITY_SERVICE); 161 mNotificationShadeController = notificationShadeController; 162 // Saving in instance variable since to prevent GC since 163 // NotificationShadeWindowController.registerCallback() only keeps weak references. 164 mNotificationShadeCallback = (keyguardShowing, keyguardOccluded, bouncerShowing) -> 165 registerOrUnregisterDismissNotificationShadeAction(); 166 mStatusBar = statusBar; 167 } 168 169 @Override start()170 public void start() { 171 mNotificationShadeController.registerCallback(mNotificationShadeCallback); 172 mContext.registerReceiverForAllUsers( 173 mReceiver, 174 mReceiver.createIntentFilter(), 175 PERMISSION_SELF, 176 null); 177 registerActions(); 178 } 179 180 @Override onConfigurationChanged(Configuration newConfig)181 public void onConfigurationChanged(Configuration newConfig) { 182 super.onConfigurationChanged(newConfig); 183 final Locale locale = mContext.getResources().getConfiguration().getLocales().get(0); 184 if (!locale.equals(mLocale)) { 185 mLocale = locale; 186 registerActions(); 187 } 188 } 189 registerActions()190 private void registerActions() { 191 RemoteAction actionBack = createRemoteAction( 192 R.string.accessibility_system_action_back_label, 193 SystemActionsBroadcastReceiver.INTENT_ACTION_BACK); 194 195 RemoteAction actionHome = createRemoteAction( 196 R.string.accessibility_system_action_home_label, 197 SystemActionsBroadcastReceiver.INTENT_ACTION_HOME); 198 199 RemoteAction actionRecents = createRemoteAction( 200 R.string.accessibility_system_action_recents_label, 201 SystemActionsBroadcastReceiver.INTENT_ACTION_RECENTS); 202 203 RemoteAction actionNotifications = createRemoteAction( 204 R.string.accessibility_system_action_notifications_label, 205 SystemActionsBroadcastReceiver.INTENT_ACTION_NOTIFICATIONS); 206 207 RemoteAction actionQuickSettings = createRemoteAction( 208 R.string.accessibility_system_action_quick_settings_label, 209 SystemActionsBroadcastReceiver.INTENT_ACTION_QUICK_SETTINGS); 210 211 RemoteAction actionPowerDialog = createRemoteAction( 212 R.string.accessibility_system_action_power_dialog_label, 213 SystemActionsBroadcastReceiver.INTENT_ACTION_POWER_DIALOG); 214 215 RemoteAction actionLockScreen = createRemoteAction( 216 R.string.accessibility_system_action_lock_screen_label, 217 SystemActionsBroadcastReceiver.INTENT_ACTION_LOCK_SCREEN); 218 219 RemoteAction actionTakeScreenshot = createRemoteAction( 220 R.string.accessibility_system_action_screenshot_label, 221 SystemActionsBroadcastReceiver.INTENT_ACTION_TAKE_SCREENSHOT); 222 223 RemoteAction actionAccessibilityShortcut = createRemoteAction( 224 R.string.accessibility_system_action_hardware_a11y_shortcut_label, 225 SystemActionsBroadcastReceiver.INTENT_ACTION_ACCESSIBILITY_SHORTCUT); 226 227 mA11yManager.registerSystemAction(actionBack, SYSTEM_ACTION_ID_BACK); 228 mA11yManager.registerSystemAction(actionHome, SYSTEM_ACTION_ID_HOME); 229 mA11yManager.registerSystemAction(actionRecents, SYSTEM_ACTION_ID_RECENTS); 230 mA11yManager.registerSystemAction(actionNotifications, SYSTEM_ACTION_ID_NOTIFICATIONS); 231 mA11yManager.registerSystemAction(actionQuickSettings, SYSTEM_ACTION_ID_QUICK_SETTINGS); 232 mA11yManager.registerSystemAction(actionPowerDialog, SYSTEM_ACTION_ID_POWER_DIALOG); 233 mA11yManager.registerSystemAction(actionLockScreen, SYSTEM_ACTION_ID_LOCK_SCREEN); 234 mA11yManager.registerSystemAction(actionTakeScreenshot, SYSTEM_ACTION_ID_TAKE_SCREENSHOT); 235 mA11yManager.registerSystemAction( 236 actionAccessibilityShortcut, SYSTEM_ACTION_ID_ACCESSIBILITY_SHORTCUT); 237 registerOrUnregisterDismissNotificationShadeAction(); 238 } 239 registerOrUnregisterDismissNotificationShadeAction()240 private void registerOrUnregisterDismissNotificationShadeAction() { 241 Assert.isMainThread(); 242 243 // Saving state in instance variable since this callback is called quite often to avoid 244 // binder calls 245 StatusBar statusBar = mStatusBar.get(); 246 if (statusBar.isPanelExpanded() && !statusBar.isKeyguardShowing()) { 247 if (!mDismissNotificationShadeActionRegistered) { 248 mA11yManager.registerSystemAction( 249 createRemoteAction( 250 R.string.accessibility_system_action_dismiss_notification_shade, 251 SystemActionsBroadcastReceiver 252 .INTENT_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE), 253 SYSTEM_ACTION_ID_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE); 254 mDismissNotificationShadeActionRegistered = true; 255 } 256 } else { 257 if (mDismissNotificationShadeActionRegistered) { 258 mA11yManager.unregisterSystemAction( 259 SYSTEM_ACTION_ID_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE); 260 mDismissNotificationShadeActionRegistered = false; 261 } 262 } 263 } 264 265 /** 266 * Register a system action. 267 * @param actionId the action ID to register. 268 */ register(int actionId)269 public void register(int actionId) { 270 int labelId; 271 String intent; 272 switch (actionId) { 273 case SYSTEM_ACTION_ID_BACK: 274 labelId = R.string.accessibility_system_action_back_label; 275 intent = SystemActionsBroadcastReceiver.INTENT_ACTION_BACK; 276 break; 277 case SYSTEM_ACTION_ID_HOME: 278 labelId = R.string.accessibility_system_action_home_label; 279 intent = SystemActionsBroadcastReceiver.INTENT_ACTION_HOME; 280 break; 281 case SYSTEM_ACTION_ID_RECENTS: 282 labelId = R.string.accessibility_system_action_recents_label; 283 intent = SystemActionsBroadcastReceiver.INTENT_ACTION_RECENTS; 284 break; 285 case SYSTEM_ACTION_ID_NOTIFICATIONS: 286 labelId = R.string.accessibility_system_action_notifications_label; 287 intent = SystemActionsBroadcastReceiver.INTENT_ACTION_NOTIFICATIONS; 288 break; 289 case SYSTEM_ACTION_ID_QUICK_SETTINGS: 290 labelId = R.string.accessibility_system_action_quick_settings_label; 291 intent = SystemActionsBroadcastReceiver.INTENT_ACTION_QUICK_SETTINGS; 292 break; 293 case SYSTEM_ACTION_ID_POWER_DIALOG: 294 labelId = R.string.accessibility_system_action_power_dialog_label; 295 intent = SystemActionsBroadcastReceiver.INTENT_ACTION_POWER_DIALOG; 296 break; 297 case SYSTEM_ACTION_ID_LOCK_SCREEN: 298 labelId = R.string.accessibility_system_action_lock_screen_label; 299 intent = SystemActionsBroadcastReceiver.INTENT_ACTION_LOCK_SCREEN; 300 break; 301 case SYSTEM_ACTION_ID_TAKE_SCREENSHOT: 302 labelId = R.string.accessibility_system_action_screenshot_label; 303 intent = SystemActionsBroadcastReceiver.INTENT_ACTION_TAKE_SCREENSHOT; 304 break; 305 case SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON: 306 labelId = R.string.accessibility_system_action_on_screen_a11y_shortcut_label; 307 intent = SystemActionsBroadcastReceiver.INTENT_ACTION_ACCESSIBILITY_BUTTON; 308 break; 309 case SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON_CHOOSER: 310 labelId = 311 R.string.accessibility_system_action_on_screen_a11y_shortcut_chooser_label; 312 intent = SystemActionsBroadcastReceiver.INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER; 313 break; 314 case SYSTEM_ACTION_ID_ACCESSIBILITY_SHORTCUT: 315 labelId = R.string.accessibility_system_action_hardware_a11y_shortcut_label; 316 intent = SystemActionsBroadcastReceiver.INTENT_ACTION_ACCESSIBILITY_SHORTCUT; 317 break; 318 case SYSTEM_ACTION_ID_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE: 319 labelId = R.string.accessibility_system_action_dismiss_notification_shade; 320 intent = SystemActionsBroadcastReceiver 321 .INTENT_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE; 322 break; 323 default: 324 return; 325 } 326 mA11yManager.registerSystemAction(createRemoteAction(labelId, intent), actionId); 327 } 328 createRemoteAction(int labelId, String intent)329 private RemoteAction createRemoteAction(int labelId, String intent) { 330 // TODO(b/148087487): update the icon used below to a valid one 331 return new RemoteAction( 332 Icon.createWithResource(mContext, R.drawable.ic_info), 333 mContext.getString(labelId), 334 mContext.getString(labelId), 335 mReceiver.createPendingIntent(mContext, intent)); 336 } 337 338 /** 339 * Unregister a system action. 340 * @param actionId the action ID to unregister. 341 */ unregister(int actionId)342 public void unregister(int actionId) { 343 mA11yManager.unregisterSystemAction(actionId); 344 } 345 handleBack()346 private void handleBack() { 347 sendDownAndUpKeyEvents(KeyEvent.KEYCODE_BACK); 348 } 349 handleHome()350 private void handleHome() { 351 sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HOME); 352 } 353 sendDownAndUpKeyEvents(int keyCode)354 private void sendDownAndUpKeyEvents(int keyCode) { 355 final long downTime = SystemClock.uptimeMillis(); 356 sendKeyEventIdentityCleared(keyCode, KeyEvent.ACTION_DOWN, downTime, downTime); 357 sendKeyEventIdentityCleared( 358 keyCode, KeyEvent.ACTION_UP, downTime, SystemClock.uptimeMillis()); 359 } 360 sendKeyEventIdentityCleared(int keyCode, int action, long downTime, long time)361 private void sendKeyEventIdentityCleared(int keyCode, int action, long downTime, long time) { 362 KeyEvent event = KeyEvent.obtain(downTime, time, action, keyCode, 0, 0, 363 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FROM_SYSTEM, 364 InputDevice.SOURCE_KEYBOARD, null); 365 InputManager.getInstance() 366 .injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 367 event.recycle(); 368 } 369 handleRecents()370 private void handleRecents() { 371 mRecents.toggleRecentApps(); 372 } 373 handleNotifications()374 private void handleNotifications() { 375 mStatusBar.get().animateExpandNotificationsPanel(); 376 } 377 handleQuickSettings()378 private void handleQuickSettings() { 379 mStatusBar.get().animateExpandSettingsPanel(null); 380 } 381 handlePowerDialog()382 private void handlePowerDialog() { 383 IWindowManager windowManager = WindowManagerGlobal.getWindowManagerService(); 384 385 try { 386 windowManager.showGlobalActions(); 387 } catch (RemoteException e) { 388 Log.e(TAG, "failed to display power dialog."); 389 } 390 } 391 handleLockScreen()392 private void handleLockScreen() { 393 IWindowManager windowManager = WindowManagerGlobal.getWindowManagerService(); 394 395 mContext.getSystemService(PowerManager.class).goToSleep(SystemClock.uptimeMillis(), 396 PowerManager.GO_TO_SLEEP_REASON_ACCESSIBILITY, 0); 397 try { 398 windowManager.lockNow(null); 399 } catch (RemoteException e) { 400 Log.e(TAG, "failed to lock screen."); 401 } 402 } 403 handleTakeScreenshot()404 private void handleTakeScreenshot() { 405 ScreenshotHelper screenshotHelper = new ScreenshotHelper(mContext); 406 screenshotHelper.takeScreenshot(WindowManager.TAKE_SCREENSHOT_FULLSCREEN, true, true, 407 SCREENSHOT_ACCESSIBILITY_ACTIONS, new Handler(Looper.getMainLooper()), null); 408 } 409 handleAccessibilityButton()410 private void handleAccessibilityButton() { 411 AccessibilityManager.getInstance(mContext).notifyAccessibilityButtonClicked( 412 Display.DEFAULT_DISPLAY); 413 } 414 handleAccessibilityButtonChooser()415 private void handleAccessibilityButtonChooser() { 416 final Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON); 417 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 418 final String chooserClassName = AccessibilityButtonChooserActivity.class.getName(); 419 intent.setClassName(CHOOSER_PACKAGE_NAME, chooserClassName); 420 mContext.startActivityAsUser(intent, UserHandle.CURRENT); 421 } 422 handleAccessibilityShortcut()423 private void handleAccessibilityShortcut() { 424 mA11yManager.performAccessibilityShortcut(); 425 } 426 handleAccessibilityDismissNotificationShade()427 private void handleAccessibilityDismissNotificationShade() { 428 mStatusBar.get().animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, false /* force */); 429 } 430 431 private class SystemActionsBroadcastReceiver extends BroadcastReceiver { 432 private static final String INTENT_ACTION_BACK = "SYSTEM_ACTION_BACK"; 433 private static final String INTENT_ACTION_HOME = "SYSTEM_ACTION_HOME"; 434 private static final String INTENT_ACTION_RECENTS = "SYSTEM_ACTION_RECENTS"; 435 private static final String INTENT_ACTION_NOTIFICATIONS = "SYSTEM_ACTION_NOTIFICATIONS"; 436 private static final String INTENT_ACTION_QUICK_SETTINGS = "SYSTEM_ACTION_QUICK_SETTINGS"; 437 private static final String INTENT_ACTION_POWER_DIALOG = "SYSTEM_ACTION_POWER_DIALOG"; 438 private static final String INTENT_ACTION_LOCK_SCREEN = "SYSTEM_ACTION_LOCK_SCREEN"; 439 private static final String INTENT_ACTION_TAKE_SCREENSHOT = "SYSTEM_ACTION_TAKE_SCREENSHOT"; 440 private static final String INTENT_ACTION_ACCESSIBILITY_BUTTON = 441 "SYSTEM_ACTION_ACCESSIBILITY_BUTTON"; 442 private static final String INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER = 443 "SYSTEM_ACTION_ACCESSIBILITY_BUTTON_MENU"; 444 private static final String INTENT_ACTION_ACCESSIBILITY_SHORTCUT = 445 "SYSTEM_ACTION_ACCESSIBILITY_SHORTCUT"; 446 private static final String INTENT_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE = 447 "SYSTEM_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE"; 448 createPendingIntent(Context context, String intentAction)449 private PendingIntent createPendingIntent(Context context, String intentAction) { 450 switch (intentAction) { 451 case INTENT_ACTION_BACK: 452 case INTENT_ACTION_HOME: 453 case INTENT_ACTION_RECENTS: 454 case INTENT_ACTION_NOTIFICATIONS: 455 case INTENT_ACTION_QUICK_SETTINGS: 456 case INTENT_ACTION_POWER_DIALOG: 457 case INTENT_ACTION_LOCK_SCREEN: 458 case INTENT_ACTION_TAKE_SCREENSHOT: 459 case INTENT_ACTION_ACCESSIBILITY_BUTTON: 460 case INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER: 461 case INTENT_ACTION_ACCESSIBILITY_SHORTCUT: 462 case INTENT_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE: { 463 Intent intent = new Intent(intentAction); 464 intent.setPackage(context.getPackageName()); 465 return PendingIntent.getBroadcast(context, 0, intent, 466 PendingIntent.FLAG_IMMUTABLE); 467 } 468 default: 469 break; 470 } 471 return null; 472 } 473 createIntentFilter()474 private IntentFilter createIntentFilter() { 475 IntentFilter intentFilter = new IntentFilter(); 476 intentFilter.addAction(INTENT_ACTION_BACK); 477 intentFilter.addAction(INTENT_ACTION_HOME); 478 intentFilter.addAction(INTENT_ACTION_RECENTS); 479 intentFilter.addAction(INTENT_ACTION_NOTIFICATIONS); 480 intentFilter.addAction(INTENT_ACTION_QUICK_SETTINGS); 481 intentFilter.addAction(INTENT_ACTION_POWER_DIALOG); 482 intentFilter.addAction(INTENT_ACTION_LOCK_SCREEN); 483 intentFilter.addAction(INTENT_ACTION_TAKE_SCREENSHOT); 484 intentFilter.addAction(INTENT_ACTION_ACCESSIBILITY_BUTTON); 485 intentFilter.addAction(INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER); 486 intentFilter.addAction(INTENT_ACTION_ACCESSIBILITY_SHORTCUT); 487 intentFilter.addAction(INTENT_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE); 488 return intentFilter; 489 } 490 491 @Override onReceive(Context context, Intent intent)492 public void onReceive(Context context, Intent intent) { 493 String intentAction = intent.getAction(); 494 switch (intentAction) { 495 case INTENT_ACTION_BACK: { 496 handleBack(); 497 break; 498 } 499 case INTENT_ACTION_HOME: { 500 handleHome(); 501 break; 502 } 503 case INTENT_ACTION_RECENTS: { 504 handleRecents(); 505 break; 506 } 507 case INTENT_ACTION_NOTIFICATIONS: { 508 handleNotifications(); 509 break; 510 } 511 case INTENT_ACTION_QUICK_SETTINGS: { 512 handleQuickSettings(); 513 break; 514 } 515 case INTENT_ACTION_POWER_DIALOG: { 516 handlePowerDialog(); 517 break; 518 } 519 case INTENT_ACTION_LOCK_SCREEN: { 520 handleLockScreen(); 521 break; 522 } 523 case INTENT_ACTION_TAKE_SCREENSHOT: { 524 handleTakeScreenshot(); 525 break; 526 } 527 case INTENT_ACTION_ACCESSIBILITY_BUTTON: { 528 handleAccessibilityButton(); 529 break; 530 } 531 case INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER: { 532 handleAccessibilityButtonChooser(); 533 break; 534 } 535 case INTENT_ACTION_ACCESSIBILITY_SHORTCUT: { 536 handleAccessibilityShortcut(); 537 break; 538 } 539 case INTENT_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE: { 540 handleAccessibilityDismissNotificationShade(); 541 break; 542 } 543 default: 544 break; 545 } 546 } 547 } 548 } 549