1 /* 2 * Copyright (C) 2023 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.accessibilitymenu.tests; 18 19 import static android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_LOCK_SCREEN; 20 import static android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS; 21 import static android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_POWER_DIALOG; 22 import static android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS; 23 import static android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_RECENTS; 24 import static android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT; 25 26 import static com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService.INTENT_GLOBAL_ACTION; 27 import static com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService.INTENT_GLOBAL_ACTION_EXTRA; 28 import static com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService.INTENT_HIDE_MENU; 29 import static com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService.INTENT_OPEN_BLOCKED; 30 import static com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService.INTENT_TOGGLE_MENU; 31 import static com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService.PACKAGE_NAME; 32 33 import static com.google.common.truth.Truth.assertThat; 34 35 import android.accessibilityservice.AccessibilityServiceInfo; 36 import android.app.Instrumentation; 37 import android.app.KeyguardManager; 38 import android.app.UiAutomation; 39 import android.content.BroadcastReceiver; 40 import android.content.ComponentName; 41 import android.content.Context; 42 import android.content.Intent; 43 import android.content.IntentFilter; 44 import android.hardware.display.BrightnessInfo; 45 import android.hardware.display.DisplayManager; 46 import android.media.AudioManager; 47 import android.os.PowerManager; 48 import android.os.UserManager; 49 import android.platform.uiautomatorhelpers.WaitUtils; 50 import android.provider.Settings; 51 import android.util.Log; 52 import android.view.Display; 53 import android.view.KeyEvent; 54 import android.view.accessibility.AccessibilityManager; 55 import android.view.accessibility.AccessibilityNodeInfo; 56 57 import androidx.test.ext.junit.runners.AndroidJUnit4; 58 import androidx.test.platform.app.InstrumentationRegistry; 59 import androidx.test.uiautomator.Configurator; 60 import androidx.test.uiautomator.UiDevice; 61 62 import com.android.compatibility.common.util.TestUtils; 63 import com.android.systemui.accessibility.accessibilitymenu.model.A11yMenuShortcut.ShortcutId; 64 65 import org.junit.After; 66 import org.junit.AfterClass; 67 import org.junit.Assume; 68 import org.junit.Before; 69 import org.junit.BeforeClass; 70 import org.junit.Test; 71 import org.junit.runner.RunWith; 72 73 import java.io.IOException; 74 import java.util.List; 75 import java.util.concurrent.atomic.AtomicBoolean; 76 import java.util.concurrent.atomic.AtomicInteger; 77 78 @RunWith(AndroidJUnit4.class) 79 public class AccessibilityMenuServiceTest { 80 private static final String TAG = "A11yMenuServiceTest"; 81 private static final int CLICK_ID = AccessibilityNodeInfo.ACTION_CLICK; 82 83 private static final int TIMEOUT_SERVICE_STATUS_CHANGE_S = 5; 84 private static final int TIMEOUT_UI_CHANGE_S = 5; 85 private static final int NO_GLOBAL_ACTION = -1; 86 private static final Intent INTENT_OPEN_MENU = 87 new Intent(INTENT_TOGGLE_MENU).setPackage(PACKAGE_NAME); 88 private static final String SERVICE_NAME = PACKAGE_NAME + "/.AccessibilityMenuService"; 89 90 private static Instrumentation sInstrumentation; 91 private static UiAutomation sUiAutomation; 92 private static UiDevice sUiDevice; 93 private static String sLockSettings; 94 private static final AtomicInteger sLastGlobalAction = new AtomicInteger(NO_GLOBAL_ACTION); 95 private static final AtomicBoolean sOpenBlocked = new AtomicBoolean(false); 96 97 private static AccessibilityManager sAccessibilityManager; 98 private static PowerManager sPowerManager; 99 private static KeyguardManager sKeyguardManager; 100 private static DisplayManager sDisplayManager; 101 102 @BeforeClass classSetup()103 public static void classSetup() throws Throwable { 104 Configurator.getInstance() 105 .setUiAutomationFlags(UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES); 106 sInstrumentation = InstrumentationRegistry.getInstrumentation(); 107 sUiAutomation = sInstrumentation.getUiAutomation( 108 UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES); 109 sUiAutomation.adoptShellPermissionIdentity( 110 UiAutomation.ALL_PERMISSIONS.toArray(new String[0])); 111 sUiDevice = UiDevice.getInstance(sInstrumentation); 112 sLockSettings = sUiDevice.executeShellCommand("locksettings get-disabled"); 113 Log.i(TAG, "locksettings get-disabled returns " + sLockSettings); 114 // Some test in the test class requires the device to be in lock screen 115 // ensure we have locksettings enabled before running the tests 116 sUiDevice.executeShellCommand("locksettings set-disabled false"); 117 118 final Context context = sInstrumentation.getTargetContext(); 119 sAccessibilityManager = context.getSystemService(AccessibilityManager.class); 120 sPowerManager = context.getSystemService(PowerManager.class); 121 sKeyguardManager = context.getSystemService(KeyguardManager.class); 122 sDisplayManager = context.getSystemService(DisplayManager.class); 123 unlockSignal(); 124 125 enableA11yMenuService(context); 126 127 context.registerReceiver(new BroadcastReceiver() { 128 @Override 129 public void onReceive(Context context, Intent intent) { 130 Log.i(TAG, "Received global action intent."); 131 sLastGlobalAction.set( 132 intent.getIntExtra(INTENT_GLOBAL_ACTION_EXTRA, NO_GLOBAL_ACTION)); 133 }}, 134 new IntentFilter(INTENT_GLOBAL_ACTION), 135 null, null, Context.RECEIVER_EXPORTED); 136 137 context.registerReceiver(new BroadcastReceiver() { 138 @Override 139 public void onReceive(Context context, Intent intent) { 140 Log.i(TAG, "Received notification that menu cannot be opened."); 141 sOpenBlocked.set(true); 142 }}, 143 new IntentFilter(INTENT_OPEN_BLOCKED), 144 null, null, Context.RECEIVER_EXPORTED); 145 } 146 147 @AfterClass classTeardown()148 public static void classTeardown() throws IOException { 149 Settings.Secure.putString(sInstrumentation.getTargetContext().getContentResolver(), 150 Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, ""); 151 sUiDevice.executeShellCommand("locksettings set-disabled " + sLockSettings); 152 } 153 154 @Before setup()155 public void setup() throws Throwable { 156 sOpenBlocked.set(false); 157 } 158 159 @After tearDown()160 public void tearDown() throws Throwable { 161 closeMenu(); 162 sLastGlobalAction.set(NO_GLOBAL_ACTION); 163 // Leave the device in clean state when the test finished 164 unlockSignal(); 165 // dismisses screenshot popup if present. 166 sUiDevice.pressBack(); 167 sUiDevice.pressHome(); 168 } 169 enableA11yMenuService(Context context)170 private static void enableA11yMenuService(Context context) throws Throwable { 171 // Disable all a11yServices if any are active. 172 if (!sAccessibilityManager.getEnabledAccessibilityServiceList( 173 AccessibilityServiceInfo.FEEDBACK_ALL_MASK).isEmpty()) { 174 Settings.Secure.putString(context.getContentResolver(), 175 Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, ""); 176 TestUtils.waitUntil("Failed to disable all services", 177 TIMEOUT_SERVICE_STATUS_CHANGE_S, 178 () -> sAccessibilityManager.getEnabledAccessibilityServiceList( 179 AccessibilityServiceInfo.FEEDBACK_ALL_MASK).isEmpty()); 180 } 181 182 // Enable a11yMenu service. 183 Settings.Secure.putString(context.getContentResolver(), 184 Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, SERVICE_NAME); 185 186 TestUtils.waitUntil("Failed to enable service", 187 TIMEOUT_SERVICE_STATUS_CHANGE_S, 188 () -> sAccessibilityManager.getEnabledAccessibilityServiceList( 189 AccessibilityServiceInfo.FEEDBACK_ALL_MASK).stream().filter( 190 info -> info.getId().contains(SERVICE_NAME)).count() == 1); 191 } 192 isMenuVisible()193 private static boolean isMenuVisible() { 194 sUiDevice.waitForIdle(); 195 AccessibilityNodeInfo root = sUiAutomation.getRootInActiveWindow(); 196 return root != null && root.getPackageName().toString().equals(PACKAGE_NAME); 197 } 198 wakeUpScreen()199 private static void wakeUpScreen() { 200 sUiDevice.pressKeyCode(KeyEvent.KEYCODE_WAKEUP); 201 WaitUtils.waitForValueToSettle("Screen On", AccessibilityMenuServiceTest::isScreenOn); 202 WaitUtils.ensureThat("Screen is on", AccessibilityMenuServiceTest::isScreenOn); 203 } 204 closeScreen()205 private static void closeScreen() { 206 // go/adb-cheats#lock-screen 207 sUiDevice.pressKeyCode(KeyEvent.KEYCODE_SLEEP); 208 WaitUtils.waitForValueToSettle("Screen Off", AccessibilityMenuServiceTest::isScreenOff); 209 WaitUtils.ensureThat("Screen is off", AccessibilityMenuServiceTest::isScreenOff); 210 WaitUtils.ensureThat( 211 "Screen is locked", () -> sKeyguardManager.isKeyguardLocked()); 212 } 213 openMenu()214 private static void openMenu() throws Throwable { 215 unlockSignal(); 216 if (!isMenuVisible()) { 217 sInstrumentation.getTargetContext().sendBroadcast(INTENT_OPEN_MENU); 218 WaitUtils.ensureThat("Accessibility Menu is visible", 219 AccessibilityMenuServiceTest::isMenuVisible); 220 } 221 } 222 closeMenu()223 private static void closeMenu() throws Throwable { 224 if (!isMenuVisible()) { 225 return; 226 } 227 Intent intent = new Intent(INTENT_HIDE_MENU); 228 intent.setPackage(PACKAGE_NAME); 229 sInstrumentation.getContext().sendBroadcast(intent); 230 TestUtils.waitUntil("Timed out before menu could close.", 231 TIMEOUT_UI_CHANGE_S, () -> !isMenuVisible()); 232 } 233 234 /** 235 * Provides list of all present shortcut buttons. 236 * @return List of shortcut buttons. 237 */ getGridButtonList()238 private List<AccessibilityNodeInfo> getGridButtonList() { 239 return sUiAutomation.getRootInActiveWindow() 240 .findAccessibilityNodeInfosByViewId(PACKAGE_NAME + ":id/shortcutIconBtn"); 241 } 242 243 /** 244 * Returns the first button whose uniqueID matches the provided text. 245 * @param buttons List of buttons. 246 * @param text Text to match button's uniqueID to. 247 * @return Button whose uniqueID matches text, {@code null} otherwise. 248 */ findGridButtonInfo( List<AccessibilityNodeInfo> buttons, String text)249 private AccessibilityNodeInfo findGridButtonInfo( 250 List<AccessibilityNodeInfo> buttons, String text) { 251 for (AccessibilityNodeInfo button: buttons) { 252 if (button.getUniqueId().equals(text)) { 253 return button; 254 } 255 } 256 return null; 257 } 258 259 @Test testAdjustBrightness()260 public void testAdjustBrightness() throws Throwable { 261 openMenu(); 262 Context context = sInstrumentation.getTargetContext(); 263 DisplayManager displayManager = context.getSystemService( 264 DisplayManager.class); 265 float resetBrightness = displayManager.getBrightness(context.getDisplayId()); 266 267 List<AccessibilityNodeInfo> buttons = getGridButtonList(); 268 AccessibilityNodeInfo brightnessUpButton = findGridButtonInfo(buttons, 269 String.valueOf(ShortcutId.ID_BRIGHTNESS_UP_VALUE.ordinal())); 270 AccessibilityNodeInfo brightnessDownButton = findGridButtonInfo(buttons, 271 String.valueOf(ShortcutId.ID_BRIGHTNESS_DOWN_VALUE.ordinal())); 272 273 BrightnessInfo brightnessInfo = displayManager.getDisplay( 274 context.getDisplayId()).getBrightnessInfo(); 275 276 try { 277 TestUtils.waitUntil("Could not change to minimum brightness", 278 TIMEOUT_UI_CHANGE_S, 279 () -> { 280 displayManager.setBrightness( 281 context.getDisplayId(), brightnessInfo.brightnessMinimum); 282 return displayManager.getBrightness(context.getDisplayId()) 283 == brightnessInfo.brightnessMinimum; 284 }); 285 brightnessUpButton.performAction(CLICK_ID); 286 TestUtils.waitUntil("Did not detect an increase in brightness.", 287 TIMEOUT_UI_CHANGE_S, 288 () -> displayManager.getBrightness(context.getDisplayId()) 289 > brightnessInfo.brightnessMinimum); 290 291 TestUtils.waitUntil("Could not change to maximum brightness", 292 TIMEOUT_UI_CHANGE_S, 293 () -> { 294 displayManager.setBrightness( 295 context.getDisplayId(), brightnessInfo.brightnessMaximum); 296 return displayManager.getBrightness(context.getDisplayId()) 297 == brightnessInfo.brightnessMaximum; 298 }); 299 brightnessDownButton.performAction(CLICK_ID); 300 TestUtils.waitUntil("Did not detect a decrease in brightness.", 301 TIMEOUT_UI_CHANGE_S, 302 () -> displayManager.getBrightness(context.getDisplayId()) 303 < brightnessInfo.brightnessMaximum); 304 } finally { 305 displayManager.setBrightness(context.getDisplayId(), resetBrightness); 306 } 307 } 308 309 @Test testAdjustVolume()310 public void testAdjustVolume() throws Throwable { 311 openMenu(); 312 Context context = sInstrumentation.getTargetContext(); 313 AudioManager audioManager = context.getSystemService(AudioManager.class); 314 int resetVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); 315 316 List<AccessibilityNodeInfo> buttons = getGridButtonList(); 317 AccessibilityNodeInfo volumeUpButton = findGridButtonInfo(buttons, 318 String.valueOf(ShortcutId.ID_VOLUME_UP_VALUE.ordinal())); 319 AccessibilityNodeInfo volumeDownButton = findGridButtonInfo(buttons, 320 String.valueOf(ShortcutId.ID_VOLUME_DOWN_VALUE.ordinal())); 321 322 try { 323 int min = audioManager.getStreamMinVolume(AudioManager.STREAM_MUSIC); 324 audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, min, 325 AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE); 326 TestUtils.waitUntil("Could not change audio stream to minimum volume.", 327 TIMEOUT_UI_CHANGE_S, 328 () -> audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) == min); 329 volumeUpButton.performAction(CLICK_ID); 330 TestUtils.waitUntil("Did not detect an increase in volume.", 331 TIMEOUT_UI_CHANGE_S, 332 () -> audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) > min); 333 334 int max = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); 335 audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, max, 336 AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE); 337 TestUtils.waitUntil("Could not change audio stream to maximum volume.", 338 TIMEOUT_UI_CHANGE_S, 339 () -> audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) == max); 340 volumeDownButton.performAction(CLICK_ID); 341 TestUtils.waitUntil("Did not detect a decrease in volume.", 342 TIMEOUT_UI_CHANGE_S, 343 () -> audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) < max); 344 } finally { 345 audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 346 resetVolume, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE); 347 } 348 } 349 350 @Test testAssistantButton_opensVoiceAssistant()351 public void testAssistantButton_opensVoiceAssistant() throws Throwable { 352 openMenu(); 353 AccessibilityNodeInfo assistantButton = findGridButtonInfo(getGridButtonList(), 354 String.valueOf(ShortcutId.ID_ASSISTANT_VALUE.ordinal())); 355 Intent expectedIntent = new Intent(Intent.ACTION_VOICE_COMMAND); 356 ComponentName componentName = expectedIntent.resolveActivity( 357 sInstrumentation.getContext().getPackageManager()); 358 Assume.assumeNotNull(componentName); 359 String expectedPackage = componentName.getPackageName(); 360 361 sUiAutomation.executeAndWaitForEvent( 362 () -> assistantButton.performAction(CLICK_ID), 363 (event) -> 364 event.getPackageName() != null 365 && expectedPackage.contains(event.getPackageName()), 366 TIMEOUT_UI_CHANGE_S * 1000 367 ); 368 } 369 370 @Test testAccessibilitySettingsButton_opensAccessibilitySettings()371 public void testAccessibilitySettingsButton_opensAccessibilitySettings() throws Throwable { 372 openMenu(); 373 AccessibilityNodeInfo settingsButton = findGridButtonInfo(getGridButtonList(), 374 String.valueOf(ShortcutId.ID_A11YSETTING_VALUE.ordinal())); 375 Intent expectedIntent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS); 376 String expectedPackage = expectedIntent.resolveActivity( 377 sInstrumentation.getContext().getPackageManager()).getPackageName(); 378 379 sUiAutomation.executeAndWaitForEvent( 380 () -> settingsButton.performAction(CLICK_ID), 381 (event) -> 382 event.getPackageName() != null 383 && expectedPackage.contains(event.getPackageName()), 384 TIMEOUT_UI_CHANGE_S * 1000 385 ); 386 } 387 388 @Test testPowerButton_performsGlobalAction()389 public void testPowerButton_performsGlobalAction() throws Throwable { 390 openMenu(); 391 AccessibilityNodeInfo button = findGridButtonInfo(getGridButtonList(), 392 String.valueOf(ShortcutId.ID_POWER_VALUE.ordinal())); 393 394 button.performAction(CLICK_ID); 395 TestUtils.waitUntil("Did not detect Power action being performed.", 396 TIMEOUT_UI_CHANGE_S, 397 () -> sLastGlobalAction.compareAndSet( 398 GLOBAL_ACTION_POWER_DIALOG, NO_GLOBAL_ACTION)); 399 } 400 401 @Test testRecentButton_performsGlobalAction()402 public void testRecentButton_performsGlobalAction() throws Throwable { 403 openMenu(); 404 AccessibilityNodeInfo button = findGridButtonInfo(getGridButtonList(), 405 String.valueOf(ShortcutId.ID_RECENT_VALUE.ordinal())); 406 407 button.performAction(CLICK_ID); 408 TestUtils.waitUntil("Did not detect Recents action being performed.", 409 TIMEOUT_UI_CHANGE_S, 410 () -> sLastGlobalAction.compareAndSet( 411 GLOBAL_ACTION_RECENTS, NO_GLOBAL_ACTION)); 412 } 413 414 @Test testLockButton_performsGlobalAction()415 public void testLockButton_performsGlobalAction() throws Throwable { 416 openMenu(); 417 AccessibilityNodeInfo button = findGridButtonInfo(getGridButtonList(), 418 String.valueOf(ShortcutId.ID_LOCKSCREEN_VALUE.ordinal())); 419 420 button.performAction(CLICK_ID); 421 TestUtils.waitUntil("Did not detect Lock action being performed.", 422 TIMEOUT_UI_CHANGE_S, 423 () -> sLastGlobalAction.compareAndSet( 424 GLOBAL_ACTION_LOCK_SCREEN, NO_GLOBAL_ACTION)); 425 } 426 427 @Test testQuickSettingsButton_performsGlobalAction()428 public void testQuickSettingsButton_performsGlobalAction() throws Throwable { 429 openMenu(); 430 AccessibilityNodeInfo button = findGridButtonInfo(getGridButtonList(), 431 String.valueOf(ShortcutId.ID_QUICKSETTING_VALUE.ordinal())); 432 433 button.performAction(CLICK_ID); 434 TestUtils.waitUntil("Did not detect Quick Settings action being performed.", 435 TIMEOUT_UI_CHANGE_S, 436 () -> sLastGlobalAction.compareAndSet( 437 GLOBAL_ACTION_QUICK_SETTINGS, NO_GLOBAL_ACTION)); 438 } 439 440 @Test testNotificationsButton_performsGlobalAction()441 public void testNotificationsButton_performsGlobalAction() throws Throwable { 442 openMenu(); 443 AccessibilityNodeInfo button = findGridButtonInfo(getGridButtonList(), 444 String.valueOf(ShortcutId.ID_NOTIFICATION_VALUE.ordinal())); 445 446 button.performAction(CLICK_ID); 447 TestUtils.waitUntil("Did not detect Notifications action being performed.", 448 TIMEOUT_UI_CHANGE_S, 449 () -> sLastGlobalAction.compareAndSet( 450 GLOBAL_ACTION_NOTIFICATIONS, NO_GLOBAL_ACTION)); 451 } 452 453 @Test testScreenshotButton_performsGlobalAction()454 public void testScreenshotButton_performsGlobalAction() throws Throwable { 455 openMenu(); 456 AccessibilityNodeInfo button = findGridButtonInfo(getGridButtonList(), 457 String.valueOf(ShortcutId.ID_SCREENSHOT_VALUE.ordinal())); 458 459 button.performAction(CLICK_ID); 460 TestUtils.waitUntil("Did not detect Screenshot action being performed.", 461 TIMEOUT_UI_CHANGE_S, 462 () -> sLastGlobalAction.compareAndSet( 463 GLOBAL_ACTION_TAKE_SCREENSHOT, NO_GLOBAL_ACTION)); 464 } 465 466 @Test testOnScreenLock_closesMenu()467 public void testOnScreenLock_closesMenu() throws Throwable { 468 openMenu(); 469 closeScreen(); 470 wakeUpScreen(); 471 assertThat(sKeyguardManager.isKeyguardLocked()).isTrue(); 472 473 TestUtils.waitUntil("Menu did not close.", 474 TIMEOUT_UI_CHANGE_S, 475 () -> !isMenuVisible() 476 ); 477 } 478 479 @Test testOnScreenLock_cannotOpenMenu()480 public void testOnScreenLock_cannotOpenMenu() throws Throwable { 481 closeScreen(); 482 wakeUpScreen(); 483 assertThat(sKeyguardManager.isKeyguardLocked()).isTrue(); 484 485 sInstrumentation.getContext().sendBroadcast(INTENT_OPEN_MENU); 486 sUiDevice.waitForIdle(); 487 488 TestUtils.waitUntil("Did not receive signal that menu cannot open", 489 TIMEOUT_UI_CHANGE_S, 490 sOpenBlocked::get); 491 } 492 493 @Test testRestrictedActions_BrightnessNotAvailable()494 public void testRestrictedActions_BrightnessNotAvailable() throws Throwable { 495 try { 496 setUserRestriction(UserManager.DISALLOW_CONFIG_BRIGHTNESS, true); 497 openMenu(); 498 499 List<AccessibilityNodeInfo> buttons = getGridButtonList(); 500 AccessibilityNodeInfo brightnessUpButton = findGridButtonInfo(buttons, 501 String.valueOf(ShortcutId.ID_BRIGHTNESS_UP_VALUE.ordinal())); 502 AccessibilityNodeInfo brightnessDownButton = findGridButtonInfo(buttons, 503 String.valueOf(ShortcutId.ID_BRIGHTNESS_DOWN_VALUE.ordinal())); 504 505 assertThat(brightnessUpButton).isNull(); 506 assertThat(brightnessDownButton).isNull(); 507 } finally { 508 setUserRestriction(UserManager.DISALLOW_CONFIG_BRIGHTNESS, false); 509 } 510 } 511 512 @Test testRestrictedActions_VolumeNotAvailable()513 public void testRestrictedActions_VolumeNotAvailable() throws Throwable { 514 try { 515 setUserRestriction(UserManager.DISALLOW_ADJUST_VOLUME, true); 516 openMenu(); 517 518 List<AccessibilityNodeInfo> buttons = getGridButtonList(); 519 AccessibilityNodeInfo volumeUpButton = findGridButtonInfo(buttons, 520 String.valueOf(ShortcutId.ID_VOLUME_UP_VALUE.ordinal())); 521 AccessibilityNodeInfo volumeDownButton = findGridButtonInfo(buttons, 522 String.valueOf(ShortcutId.ID_VOLUME_DOWN_VALUE.ordinal())); 523 524 assertThat(volumeUpButton).isNull(); 525 assertThat(volumeDownButton).isNull(); 526 } finally { 527 setUserRestriction(UserManager.DISALLOW_ADJUST_VOLUME, false); 528 } 529 } 530 setUserRestriction(String restriction, boolean isRestricted)531 private void setUserRestriction(String restriction, boolean isRestricted) throws Throwable { 532 final Context context = sInstrumentation.getTargetContext(); 533 final UserManager userManager = context.getSystemService(UserManager.class); 534 userManager.setUserRestriction(restriction, isRestricted); 535 } 536 unlockSignal()537 private static void unlockSignal() throws IOException { 538 // go/adb-cheats#unlock-screen 539 wakeUpScreen(); 540 if (sKeyguardManager.isKeyguardLocked()) { 541 sUiDevice.pressMenu(); 542 } 543 WaitUtils.ensureThat( 544 "Device unlocked & isInteractive", 545 () -> isScreenOn() && !sKeyguardManager.isKeyguardLocked()); 546 } 547 isScreenOn()548 private static boolean isScreenOn() { 549 int display = Display.DEFAULT_DISPLAY; 550 return sPowerManager.isInteractive(display) 551 && sDisplayManager.getDisplay(display).getState() == Display.STATE_ON; 552 } 553 isScreenOff()554 private static boolean isScreenOff() { 555 int display = Display.DEFAULT_DISPLAY; 556 return !sPowerManager.isInteractive(display) 557 && sDisplayManager.getDisplay(display).getState() == Display.STATE_OFF; 558 } 559 } 560