1 /* 2 * Copyright (C) 2017 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.server; 18 19 import static android.service.quickaccesswallet.Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP; 20 import static android.service.quickaccesswallet.Flags.FLAG_LAUNCH_WALLET_VIA_SYSUI_CALLBACKS; 21 import static android.service.quickaccesswallet.Flags.launchWalletOptionOnPowerDoubleTap; 22 import static android.service.quickaccesswallet.Flags.launchWalletViaSysuiCallbacks; 23 24 import static com.android.server.GestureLauncherService.DOUBLE_TAP_POWER_DISABLED_MODE; 25 import static com.android.server.GestureLauncherService.DOUBLE_TAP_POWER_LAUNCH_CAMERA_MODE; 26 import static com.android.server.GestureLauncherService.DOUBLE_TAP_POWER_MULTI_TARGET_MODE; 27 import static com.android.server.GestureLauncherService.LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER; 28 import static com.android.server.GestureLauncherService.LAUNCH_WALLET_ON_DOUBLE_TAP_POWER; 29 import static com.android.server.GestureLauncherService.POWER_DOUBLE_TAP_MAX_TIME_MS; 30 31 import static org.junit.Assert.assertEquals; 32 import static org.junit.Assert.assertFalse; 33 import static org.junit.Assert.assertTrue; 34 import static org.mockito.ArgumentMatchers.any; 35 import static org.mockito.ArgumentMatchers.anyInt; 36 import static org.mockito.ArgumentMatchers.eq; 37 import static org.mockito.Mockito.doAnswer; 38 import static org.mockito.Mockito.never; 39 import static org.mockito.Mockito.times; 40 import static org.mockito.Mockito.verify; 41 import static org.mockito.Mockito.when; 42 43 import android.app.PendingIntent; 44 import android.app.StatusBarManager; 45 import android.content.BroadcastReceiver; 46 import android.content.Context; 47 import android.content.Intent; 48 import android.content.IntentFilter; 49 import android.content.res.Resources; 50 import android.os.Looper; 51 import android.os.UserHandle; 52 import android.platform.test.annotations.Presubmit; 53 import android.platform.test.annotations.RequiresFlagsDisabled; 54 import android.platform.test.annotations.RequiresFlagsEnabled; 55 import android.platform.test.flag.junit.CheckFlagsRule; 56 import android.platform.test.flag.junit.DeviceFlagsValueProvider; 57 import android.provider.Settings; 58 import android.service.quickaccesswallet.QuickAccessWalletClient; 59 import android.telecom.TelecomManager; 60 import android.test.mock.MockContentResolver; 61 import android.testing.TestableLooper; 62 import android.util.MutableBoolean; 63 import android.view.KeyEvent; 64 65 import androidx.test.InstrumentationRegistry; 66 import androidx.test.filters.SmallTest; 67 import androidx.test.runner.AndroidJUnit4; 68 69 import com.android.internal.logging.MetricsLogger; 70 import com.android.internal.logging.UiEventLogger; 71 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 72 import com.android.internal.util.test.FakeSettingsProvider; 73 import com.android.server.statusbar.StatusBarManagerInternal; 74 75 import org.junit.Before; 76 import org.junit.BeforeClass; 77 import org.junit.Rule; 78 import org.junit.Test; 79 import org.junit.runner.RunWith; 80 import org.mockito.ArgumentCaptor; 81 import org.mockito.Mock; 82 import org.mockito.MockitoAnnotations; 83 84 import java.util.List; 85 import java.util.concurrent.CountDownLatch; 86 import java.util.concurrent.TimeUnit; 87 88 /** 89 * Unit tests for {@link GestureLauncherService}. 90 * runtest frameworks-services -c com.android.server.GestureLauncherServiceTest 91 */ 92 @Presubmit 93 @SmallTest 94 @RunWith(AndroidJUnit4.class) 95 @TestableLooper.RunWithLooper(setAsMainLooper = true) 96 public class GestureLauncherServiceTest { 97 98 private static final int FAKE_USER_ID = 1337; 99 private static final int FAKE_SOURCE = 1982; 100 private static final long INITIAL_EVENT_TIME_MILLIS = 20000L; 101 private static final long IGNORED_DOWN_TIME = 1234L; 102 private static final int IGNORED_ACTION = 13; 103 private static final int IGNORED_CODE = 1999; 104 private static final int IGNORED_REPEAT = 42; 105 private static final int IGNORED_META_STATE = 0; 106 private static final int IGNORED_DEVICE_ID = 0; 107 private static final int IGNORED_SCANCODE = 0; 108 109 private @Mock Context mContext; 110 private @Mock Resources mResources; 111 private @Mock StatusBarManagerInternal mStatusBarManagerInternal; 112 private @Mock TelecomManager mTelecomManager; 113 private @Mock MetricsLogger mMetricsLogger; 114 @Mock private UiEventLogger mUiEventLogger; 115 @Mock private QuickAccessWalletClient mQuickAccessWalletClient; 116 private MockContentResolver mContentResolver; 117 private GestureLauncherService mGestureLauncherService; 118 119 private Context mInstrumentationContext = 120 InstrumentationRegistry.getInstrumentation().getContext(); 121 122 private static final String LAUNCH_TEST_WALLET_ACTION = "LAUNCH_TEST_WALLET_ACTION"; 123 private static final String LAUNCH_FALLBACK_ACTION = "LAUNCH_FALLBACK_ACTION"; 124 private PendingIntent mGesturePendingIntent = 125 PendingIntent.getBroadcast( 126 mInstrumentationContext, 127 0, 128 new Intent(LAUNCH_TEST_WALLET_ACTION), 129 PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT); 130 131 private PendingIntent mFallbackPendingIntent = 132 PendingIntent.getBroadcast( 133 mInstrumentationContext, 134 0, 135 new Intent(LAUNCH_FALLBACK_ACTION), 136 PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT); 137 138 @Rule 139 public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); 140 141 @BeforeClass oneTimeInitialization()142 public static void oneTimeInitialization() { 143 if (Looper.myLooper() == null) { 144 Looper.prepare(); 145 } 146 } 147 148 @Before setup()149 public void setup() { 150 MockitoAnnotations.initMocks(this); 151 152 LocalServices.removeServiceForTest(StatusBarManagerInternal.class); 153 LocalServices.addService(StatusBarManagerInternal.class, mStatusBarManagerInternal); 154 155 final Context originalContext = InstrumentationRegistry.getContext(); 156 when(mContext.getApplicationInfo()).thenReturn(originalContext.getApplicationInfo()); 157 when(mContext.getResources()).thenReturn(mResources); 158 mContentResolver = new MockContentResolver(mContext); 159 mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); 160 when(mContext.getContentResolver()).thenReturn(mContentResolver); 161 when(mContext.getSystemService(Context.TELECOM_SERVICE)).thenReturn(mTelecomManager); 162 when(mTelecomManager.createLaunchEmergencyDialerIntent(null)).thenReturn(new Intent()); 163 when(mQuickAccessWalletClient.isWalletServiceAvailable()).thenReturn(true); 164 165 mGestureLauncherService = 166 new GestureLauncherService( 167 mContext, mMetricsLogger, mQuickAccessWalletClient, mUiEventLogger); 168 169 Settings.Secure.clearProviderForTest(); 170 } 171 registerWalletLaunchedReceiver(String action)172 private WalletLaunchedReceiver registerWalletLaunchedReceiver(String action) { 173 IntentFilter filter = new IntentFilter(action); 174 WalletLaunchedReceiver receiver = new WalletLaunchedReceiver(); 175 mInstrumentationContext.registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED); 176 return receiver; 177 } 178 179 /** 180 * A simple {@link BroadcastReceiver} implementation that counts down a {@link CountDownLatch} 181 * when a matching message is received 182 */ 183 private static final class WalletLaunchedReceiver extends BroadcastReceiver { 184 private static final int TIMEOUT_SECONDS = 3; 185 186 private final CountDownLatch mLatch; 187 WalletLaunchedReceiver()188 WalletLaunchedReceiver() { 189 mLatch = new CountDownLatch(1); 190 } 191 192 @Override onReceive(Context context, Intent intent)193 public void onReceive(Context context, Intent intent) { 194 mLatch.countDown(); 195 context.unregisterReceiver(this); 196 } 197 waitUntilShown()198 Boolean waitUntilShown() { 199 try { 200 return mLatch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS); 201 } catch (InterruptedException e) { 202 return false; 203 } 204 } 205 } 206 207 @Test testIsCameraDoubleTapPowerEnabled_configFalse()208 public void testIsCameraDoubleTapPowerEnabled_configFalse() { 209 withCameraDoubleTapPowerEnableConfigValue(false); 210 assertFalse(mGestureLauncherService.isCameraDoubleTapPowerEnabled(mResources)); 211 } 212 213 @Test testIsCameraDoubleTapPowerEnabled_configTrue()214 public void testIsCameraDoubleTapPowerEnabled_configTrue() { 215 withCameraDoubleTapPowerEnableConfigValue(true); 216 assertTrue(mGestureLauncherService.isCameraDoubleTapPowerEnabled(mResources)); 217 } 218 219 @Test 220 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testIsCameraDoubleTapPowerSettingEnabled_flagEnabled_configFalseSettingDisabled()221 public void testIsCameraDoubleTapPowerSettingEnabled_flagEnabled_configFalseSettingDisabled() { 222 withDoubleTapPowerModeConfigValue( 223 DOUBLE_TAP_POWER_DISABLED_MODE); 224 withMultiTargetDoubleTapPowerGestureEnableSettingValue(false); 225 withDoubleTapPowerGestureActionSettingValue(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); 226 227 assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( 228 mContext, FAKE_USER_ID)); 229 } 230 231 @Test 232 @RequiresFlagsDisabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testIsCameraDoubleTapPowerSettingEnabled_flagDisabled_configFalseSettingDisabled()233 public void testIsCameraDoubleTapPowerSettingEnabled_flagDisabled_configFalseSettingDisabled() { 234 withCameraDoubleTapPowerEnableConfigValue(false); 235 withCameraDoubleTapPowerDisableSettingValue(1); 236 237 assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( 238 mContext, FAKE_USER_ID)); 239 } 240 241 @Test 242 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testIsCameraDoubleTapPowerSettingEnabled_flagEnabled_configFalseSettingEnabled()243 public void testIsCameraDoubleTapPowerSettingEnabled_flagEnabled_configFalseSettingEnabled() { 244 withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_DISABLED_MODE); 245 withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); 246 withDoubleTapPowerGestureActionSettingValue(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); 247 248 assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( 249 mContext, FAKE_USER_ID)); 250 } 251 252 @Test 253 @RequiresFlagsDisabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testIsCameraDoubleTapPowerSettingEnabled_flagDisabled_configFalseSettingEnabled()254 public void testIsCameraDoubleTapPowerSettingEnabled_flagDisabled_configFalseSettingEnabled() { 255 withCameraDoubleTapPowerEnableConfigValue(false); 256 withCameraDoubleTapPowerDisableSettingValue(0); 257 258 assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( 259 mContext, FAKE_USER_ID)); 260 } 261 262 @Test 263 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testIsCameraDoubleTapPowerSettingEnabled_flagEnabled_configTrueSettingDisabled()264 public void testIsCameraDoubleTapPowerSettingEnabled_flagEnabled_configTrueSettingDisabled() { 265 withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); 266 withMultiTargetDoubleTapPowerGestureEnableSettingValue(false); 267 withDoubleTapPowerGestureActionSettingValue(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); 268 269 assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( 270 mContext, FAKE_USER_ID)); 271 } 272 273 @Test 274 @RequiresFlagsDisabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testIsCameraDoubleTapPowerSettingEnabled_flagDisabled_configTrueSettingDisabled()275 public void testIsCameraDoubleTapPowerSettingEnabled_flagDisabled_configTrueSettingDisabled() { 276 withCameraDoubleTapPowerEnableConfigValue(true); 277 withCameraDoubleTapPowerDisableSettingValue(1); 278 279 assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( 280 mContext, FAKE_USER_ID)); 281 } 282 283 @Test 284 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testIsCameraDoubleTapPowerSettingEnabled_flagEnabled_configTrueSettingEnabled()285 public void testIsCameraDoubleTapPowerSettingEnabled_flagEnabled_configTrueSettingEnabled() { 286 withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); 287 withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); 288 withDoubleTapPowerGestureActionSettingValue(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); 289 290 assertTrue(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( 291 mContext, FAKE_USER_ID)); 292 } 293 294 @Test 295 @RequiresFlagsDisabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testIsCameraDoubleTapPowerSettingEnabled_flagDisabled_configTrueSettingEnabled()296 public void testIsCameraDoubleTapPowerSettingEnabled_flagDisabled_configTrueSettingEnabled() { 297 withCameraDoubleTapPowerEnableConfigValue(true); 298 withCameraDoubleTapPowerDisableSettingValue(0); 299 300 assertTrue(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( 301 mContext, FAKE_USER_ID)); 302 } 303 304 @Test 305 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testIsCameraDoubleTapPowerSettingEnabled_launchCameraMode_settingEnabled()306 public void testIsCameraDoubleTapPowerSettingEnabled_launchCameraMode_settingEnabled() { 307 withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_LAUNCH_CAMERA_MODE); 308 withCameraDoubleTapPowerDisableSettingValue(0); 309 310 assertTrue( 311 mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( 312 mContext, FAKE_USER_ID)); 313 } 314 315 @Test 316 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testIsCameraDoubleTapPowerSettingEnabled_launchCameraMode_settingDisabled()317 public void testIsCameraDoubleTapPowerSettingEnabled_launchCameraMode_settingDisabled() { 318 withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_LAUNCH_CAMERA_MODE); 319 withCameraDoubleTapPowerDisableSettingValue(1); 320 321 assertFalse( 322 mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( 323 mContext, FAKE_USER_ID)); 324 } 325 326 @Test 327 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testIsCameraDoubleTapPowerSettingEnabled_actionWallet()328 public void testIsCameraDoubleTapPowerSettingEnabled_actionWallet() { 329 withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); 330 withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); 331 withDoubleTapPowerGestureActionSettingValue(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER); 332 333 assertFalse( 334 mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( 335 mContext, FAKE_USER_ID)); 336 } 337 338 @Test 339 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testIsCameraDoubleTapPowerSettingEnabled_defaultActionCamera()340 public void testIsCameraDoubleTapPowerSettingEnabled_defaultActionCamera() { 341 withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); 342 withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); 343 withDefaultDoubleTapPowerGestureActionConfig(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); 344 345 assertTrue( 346 mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( 347 mContext, FAKE_USER_ID)); 348 } 349 350 @Test 351 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testIsCameraDoubleTapPowerSettingEnabled_defaultActionNotCamera()352 public void testIsCameraDoubleTapPowerSettingEnabled_defaultActionNotCamera() { 353 withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); 354 withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); 355 withDefaultDoubleTapPowerGestureActionConfig(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER); 356 357 assertFalse( 358 mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( 359 mContext, FAKE_USER_ID)); 360 } 361 362 @Test 363 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testIsWalletDoubleTapPowerSettingEnabled()364 public void testIsWalletDoubleTapPowerSettingEnabled() { 365 withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); 366 withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); 367 withDoubleTapPowerGestureActionSettingValue(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER); 368 369 assertTrue( 370 mGestureLauncherService.isWalletDoubleTapPowerSettingEnabled( 371 mContext, FAKE_USER_ID)); 372 } 373 374 @Test 375 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testIsWalletDoubleTapPowerSettingEnabled_configDisabled()376 public void testIsWalletDoubleTapPowerSettingEnabled_configDisabled() { 377 withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_DISABLED_MODE); 378 withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); 379 withDoubleTapPowerGestureActionSettingValue(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER); 380 381 assertFalse( 382 mGestureLauncherService.isWalletDoubleTapPowerSettingEnabled( 383 mContext, FAKE_USER_ID)); 384 } 385 386 @Test 387 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testIsWalletDoubleTapPowerSettingEnabled_settingDisabled()388 public void testIsWalletDoubleTapPowerSettingEnabled_settingDisabled() { 389 withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); 390 withMultiTargetDoubleTapPowerGestureEnableSettingValue(false); 391 withDoubleTapPowerGestureActionSettingValue(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER); 392 393 assertFalse( 394 mGestureLauncherService.isWalletDoubleTapPowerSettingEnabled( 395 mContext, FAKE_USER_ID)); 396 } 397 398 @Test 399 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testIsWalletDoubleTapPowerSettingEnabled_actionCamera()400 public void testIsWalletDoubleTapPowerSettingEnabled_actionCamera() { 401 withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); 402 withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); 403 withDoubleTapPowerGestureActionSettingValue(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); 404 405 assertFalse( 406 mGestureLauncherService.isWalletDoubleTapPowerSettingEnabled( 407 mContext, FAKE_USER_ID)); 408 } 409 410 @Test 411 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testIsWalletDoubleTapPowerSettingEnabled_defaultActionWallet()412 public void testIsWalletDoubleTapPowerSettingEnabled_defaultActionWallet() { 413 withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); 414 withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); 415 withDefaultDoubleTapPowerGestureActionConfig(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER); 416 417 assertTrue( 418 mGestureLauncherService.isWalletDoubleTapPowerSettingEnabled( 419 mContext, FAKE_USER_ID)); 420 } 421 422 @Test 423 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testIsWalletDoubleTapPowerSettingEnabled_defaultActionNotWallet()424 public void testIsWalletDoubleTapPowerSettingEnabled_defaultActionNotWallet() { 425 withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); 426 withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); 427 withDefaultDoubleTapPowerGestureActionConfig(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); 428 429 assertFalse( 430 mGestureLauncherService.isWalletDoubleTapPowerSettingEnabled( 431 mContext, FAKE_USER_ID)); 432 } 433 434 @Test testIsEmergencyGestureSettingEnabled_settingDisabled()435 public void testIsEmergencyGestureSettingEnabled_settingDisabled() { 436 withEmergencyGestureEnabledConfigValue(true); 437 withEmergencyGestureEnabledSettingValue(false); 438 assertFalse(mGestureLauncherService.isEmergencyGestureSettingEnabled( 439 mContext, FAKE_USER_ID)); 440 } 441 442 @Test testIsEmergencyGestureSettingEnabled_settingEnabled()443 public void testIsEmergencyGestureSettingEnabled_settingEnabled() { 444 withEmergencyGestureEnabledConfigValue(true); 445 withEmergencyGestureEnabledSettingValue(true); 446 assertTrue(mGestureLauncherService.isEmergencyGestureSettingEnabled( 447 mContext, FAKE_USER_ID)); 448 } 449 450 @Test testIsEmergencyGestureSettingEnabled_supportDisabled()451 public void testIsEmergencyGestureSettingEnabled_supportDisabled() { 452 withEmergencyGestureEnabledConfigValue(false); 453 withEmergencyGestureEnabledSettingValue(true); 454 assertFalse(mGestureLauncherService.isEmergencyGestureSettingEnabled( 455 mContext, FAKE_USER_ID)); 456 } 457 458 @Test testGetEmergencyGesturePowerButtonCooldownPeriodMs_enabled()459 public void testGetEmergencyGesturePowerButtonCooldownPeriodMs_enabled() { 460 withEmergencyGesturePowerButtonCooldownPeriodMsValue(4000); 461 assertEquals(4000, 462 mGestureLauncherService.getEmergencyGesturePowerButtonCooldownPeriodMs(mContext, 463 FAKE_USER_ID)); 464 } 465 466 @Test testGetEmergencyGesturePowerButtonCooldownPeriodMs_disabled()467 public void testGetEmergencyGesturePowerButtonCooldownPeriodMs_disabled() { 468 withEmergencyGesturePowerButtonCooldownPeriodMsValue(0); 469 assertEquals(0, 470 mGestureLauncherService.getEmergencyGesturePowerButtonCooldownPeriodMs(mContext, 471 FAKE_USER_ID)); 472 } 473 474 @Test testGetEmergencyGesturePowerButtonCooldownPeriodMs_cappedAtMaximum()475 public void testGetEmergencyGesturePowerButtonCooldownPeriodMs_cappedAtMaximum() { 476 withEmergencyGesturePowerButtonCooldownPeriodMsValue(10000); 477 assertEquals(GestureLauncherService.EMERGENCY_GESTURE_POWER_BUTTON_COOLDOWN_PERIOD_MS_MAX, 478 mGestureLauncherService.getEmergencyGesturePowerButtonCooldownPeriodMs(mContext, 479 FAKE_USER_ID)); 480 } 481 482 @Test testHandleCameraLaunchGesture_userSetupComplete()483 public void testHandleCameraLaunchGesture_userSetupComplete() { 484 withUserSetupCompleteValue(true); 485 486 boolean useWakeLock = false; 487 assertTrue(mGestureLauncherService.handleCameraGesture(useWakeLock, FAKE_SOURCE)); 488 verify(mStatusBarManagerInternal).onCameraLaunchGestureDetected(FAKE_SOURCE); 489 } 490 491 @Test testHandleEmergencyGesture_userSetupComplete()492 public void testHandleEmergencyGesture_userSetupComplete() { 493 withUserSetupCompleteValue(true); 494 495 assertTrue(mGestureLauncherService.handleEmergencyGesture()); 496 } 497 498 @Test testHandleCameraLaunchGesture_userSetupNotComplete()499 public void testHandleCameraLaunchGesture_userSetupNotComplete() { 500 withUserSetupCompleteValue(false); 501 502 boolean useWakeLock = false; 503 assertFalse(mGestureLauncherService.handleCameraGesture(useWakeLock, FAKE_SOURCE)); 504 } 505 506 @Test testHandleEmergencyGesture_userSetupNotComplete()507 public void testHandleEmergencyGesture_userSetupNotComplete() { 508 withUserSetupCompleteValue(false); 509 510 assertFalse(mGestureLauncherService.handleEmergencyGesture()); 511 } 512 513 @Test testInterceptPowerKeyDown_firstPowerDownCameraPowerGestureOnInteractive()514 public void testInterceptPowerKeyDown_firstPowerDownCameraPowerGestureOnInteractive() { 515 enableCameraGesture(); 516 517 long eventTime = INITIAL_EVENT_TIME_MILLIS + POWER_DOUBLE_TAP_MAX_TIME_MS - 1; 518 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 519 IGNORED_REPEAT); 520 boolean interactive = true; 521 MutableBoolean outLaunched = new MutableBoolean(true); 522 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 523 outLaunched); 524 assertFalse(intercepted); 525 assertFalse(outLaunched.value); 526 verify(mMetricsLogger).histogram("power_consecutive_short_tap_count", 1); 527 verify(mMetricsLogger).histogram("power_double_tap_interval", (int) eventTime); 528 } 529 530 @Test testInterceptPowerKeyDown_firstPowerDown_emergencyGestureNotLaunched()531 public void testInterceptPowerKeyDown_firstPowerDown_emergencyGestureNotLaunched() { 532 withEmergencyGestureEnabledSettingValue(true); 533 mGestureLauncherService.updateEmergencyGestureEnabled(); 534 535 long eventTime = INITIAL_EVENT_TIME_MILLIS 536 + GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS - 1; 537 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 538 IGNORED_REPEAT); 539 boolean interactive = true; 540 MutableBoolean outLaunched = new MutableBoolean(true); 541 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 542 outLaunched); 543 544 assertFalse(intercepted); 545 assertFalse(outLaunched.value); 546 verify(mMetricsLogger).histogram("power_double_tap_interval", (int) eventTime); 547 } 548 549 @Test testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOffInteractive()550 public void testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOffInteractive() { 551 disableDoubleTapPowerGesture(); 552 553 long eventTime = INITIAL_EVENT_TIME_MILLIS; 554 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 555 IGNORED_REPEAT); 556 boolean interactive = true; 557 MutableBoolean outLaunched = new MutableBoolean(true); 558 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 559 outLaunched); 560 assertFalse(intercepted); 561 assertFalse(outLaunched.value); 562 563 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1; 564 eventTime += interval; 565 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 566 IGNORED_REPEAT); 567 outLaunched.value = true; 568 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 569 outLaunched); 570 assertFalse(intercepted); 571 assertFalse(outLaunched.value); 572 573 verify(mMetricsLogger, never()) 574 .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); 575 verify(mUiEventLogger, never()).log(any()); 576 577 final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class); 578 verify(mMetricsLogger, times(2)).histogram( 579 eq("power_double_tap_interval"), intervalCaptor.capture()); 580 List<Integer> intervals = intervalCaptor.getAllValues(); 581 assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue()); 582 assertEquals((int) interval, intervals.get(1).intValue()); 583 584 final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class); 585 verify(mMetricsLogger, times(2)).histogram( 586 eq("power_consecutive_short_tap_count"), tapCountCaptor.capture()); 587 List<Integer> tapCounts = tapCountCaptor.getAllValues(); 588 assertEquals(1, tapCounts.get(0).intValue()); 589 assertEquals(2, tapCounts.get(1).intValue()); 590 } 591 592 @Test testInterceptPowerKeyDown_intervalMidBoundsCameraPowerGestureOffInteractive()593 public void testInterceptPowerKeyDown_intervalMidBoundsCameraPowerGestureOffInteractive() { 594 disableDoubleTapPowerGesture(); 595 596 long eventTime = INITIAL_EVENT_TIME_MILLIS; 597 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 598 IGNORED_REPEAT); 599 boolean interactive = true; 600 MutableBoolean outLaunched = new MutableBoolean(true); 601 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 602 outLaunched); 603 assertFalse(intercepted); 604 assertFalse(outLaunched.value); 605 606 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS; 607 eventTime += interval; 608 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 609 IGNORED_REPEAT); 610 outLaunched.value = true; 611 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 612 outLaunched); 613 assertFalse(intercepted); 614 assertFalse(outLaunched.value); 615 616 verify(mMetricsLogger, never()) 617 .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); 618 verify(mUiEventLogger, never()).log(any()); 619 620 final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class); 621 verify(mMetricsLogger, times(2)).histogram( 622 eq("power_double_tap_interval"), intervalCaptor.capture()); 623 List<Integer> intervals = intervalCaptor.getAllValues(); 624 assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue()); 625 assertEquals((int) interval, intervals.get(1).intValue()); 626 627 final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class); 628 verify(mMetricsLogger, times(2)).histogram( 629 eq("power_consecutive_short_tap_count"), tapCountCaptor.capture()); 630 List<Integer> tapCounts = tapCountCaptor.getAllValues(); 631 assertEquals(1, tapCounts.get(0).intValue()); 632 // The interval is too long to launch the camera, but short enough to count as a 633 // sequential tap. 634 assertEquals(2, tapCounts.get(1).intValue()); 635 } 636 637 @Test testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOffInteractive()638 public void testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOffInteractive() { 639 disableDoubleTapPowerGesture(); 640 641 long eventTime = INITIAL_EVENT_TIME_MILLIS; 642 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 643 IGNORED_REPEAT); 644 boolean interactive = true; 645 MutableBoolean outLaunched = new MutableBoolean(true); 646 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 647 outLaunched); 648 assertFalse(intercepted); 649 assertFalse(outLaunched.value); 650 651 long interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS; 652 eventTime += interval; 653 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 654 IGNORED_REPEAT); 655 outLaunched.value = true; 656 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 657 outLaunched); 658 assertFalse(intercepted); 659 assertFalse(outLaunched.value); 660 661 verify(mMetricsLogger, never()) 662 .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); 663 verify(mUiEventLogger, never()).log(any()); 664 665 final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class); 666 verify(mMetricsLogger, times(2)).histogram( 667 eq("power_double_tap_interval"), intervalCaptor.capture()); 668 List<Integer> intervals = intervalCaptor.getAllValues(); 669 assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue()); 670 assertEquals((int) interval, intervals.get(1).intValue()); 671 672 final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class); 673 verify(mMetricsLogger, times(2)).histogram( 674 eq("power_consecutive_short_tap_count"), tapCountCaptor.capture()); 675 List<Integer> tapCounts = tapCountCaptor.getAllValues(); 676 assertEquals(1, tapCounts.get(0).intValue()); 677 assertEquals(1, tapCounts.get(1).intValue()); 678 } 679 680 @Test 681 public void testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnInteractiveSetupComplete()682 testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnInteractiveSetupComplete() { 683 enableCameraGesture(); 684 685 long eventTime = INITIAL_EVENT_TIME_MILLIS; 686 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 687 IGNORED_REPEAT); 688 boolean interactive = true; 689 MutableBoolean outLaunched = new MutableBoolean(true); 690 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 691 outLaunched); 692 assertFalse(intercepted); 693 assertFalse(outLaunched.value); 694 695 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1; 696 eventTime += interval; 697 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 698 IGNORED_REPEAT); 699 outLaunched.value = false; 700 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 701 outLaunched); 702 assertTrue(intercepted); 703 assertTrue(outLaunched.value); 704 705 verify(mStatusBarManagerInternal).onCameraLaunchGestureDetected( 706 StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP); 707 verify(mMetricsLogger) 708 .action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE, (int) interval); 709 verify(mUiEventLogger, times(1)) 710 .log(GestureLauncherService.GestureLauncherEvent.GESTURE_CAMERA_DOUBLE_TAP_POWER); 711 712 final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class); 713 verify(mMetricsLogger, times(2)).histogram( 714 eq("power_double_tap_interval"), intervalCaptor.capture()); 715 List<Integer> intervals = intervalCaptor.getAllValues(); 716 assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue()); 717 assertEquals((int) interval, intervals.get(1).intValue()); 718 719 final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class); 720 verify(mMetricsLogger, times(2)).histogram( 721 eq("power_consecutive_short_tap_count"), tapCountCaptor.capture()); 722 List<Integer> tapCounts = tapCountCaptor.getAllValues(); 723 assertEquals(1, tapCounts.get(0).intValue()); 724 assertEquals(2, tapCounts.get(1).intValue()); 725 } 726 727 @Test 728 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) 729 public void testInterceptPowerKeyDown_fiveInboundPresses_walletAndEmergencyEnabled_bothLaunch()730 testInterceptPowerKeyDown_fiveInboundPresses_walletAndEmergencyEnabled_bothLaunch() { 731 WalletLaunchedReceiver receiver = registerWalletLaunchedReceiver(LAUNCH_TEST_WALLET_ACTION); 732 setUpGetGestureTargetActivityPendingIntent(mGesturePendingIntent); 733 enableEmergencyGesture(); 734 enableWalletGesture(); 735 736 // First event 737 long eventTime = INITIAL_EVENT_TIME_MILLIS; 738 sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, false, false); 739 740 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1; 741 eventTime += interval; 742 sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, true, true); 743 744 if (launchWalletViaSysuiCallbacks()) { 745 verify(mStatusBarManagerInternal).onWalletLaunchGestureDetected(); 746 } else { 747 assertTrue(receiver.waitUntilShown()); 748 } 749 750 // Presses 3 and 4 should not trigger any gesture 751 for (int i = 0; i < 2; i++) { 752 eventTime += interval; 753 sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, true, false); 754 } 755 756 // Fifth button press should trigger the emergency flow 757 eventTime += interval; 758 sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, true, true); 759 760 verify(mUiEventLogger, times(1)) 761 .log(GestureLauncherService.GestureLauncherEvent.GESTURE_EMERGENCY_TAP_POWER); 762 verify(mStatusBarManagerInternal).onEmergencyActionLaunchGestureDetected(); 763 } 764 765 @Test 766 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testInterceptPowerKeyDown_intervalInBoundsWalletPowerGesture()767 public void testInterceptPowerKeyDown_intervalInBoundsWalletPowerGesture() { 768 WalletLaunchedReceiver receiver = registerWalletLaunchedReceiver(LAUNCH_TEST_WALLET_ACTION); 769 setUpGetGestureTargetActivityPendingIntent(mGesturePendingIntent); 770 enableWalletGesture(); 771 enableEmergencyGesture(); 772 773 long eventTime = INITIAL_EVENT_TIME_MILLIS; 774 sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, false, false); 775 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1; 776 eventTime += interval; 777 sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, true, true); 778 779 if (launchWalletViaSysuiCallbacks()) { 780 verify(mStatusBarManagerInternal).onWalletLaunchGestureDetected(); 781 } else { 782 assertTrue(receiver.waitUntilShown()); 783 } 784 } 785 786 @Test 787 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) 788 @RequiresFlagsDisabled(FLAG_LAUNCH_WALLET_VIA_SYSUI_CALLBACKS) testInterceptPowerKeyDown_walletGestureOn_quickAccessWalletServiceUnavailable()789 public void testInterceptPowerKeyDown_walletGestureOn_quickAccessWalletServiceUnavailable() { 790 when(mQuickAccessWalletClient.isWalletServiceAvailable()).thenReturn(false); 791 WalletLaunchedReceiver receiver = registerWalletLaunchedReceiver(LAUNCH_TEST_WALLET_ACTION); 792 setUpGetGestureTargetActivityPendingIntent(mGesturePendingIntent); 793 enableWalletGesture(); 794 795 // First event 796 long eventTime = INITIAL_EVENT_TIME_MILLIS; 797 sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, false, false); 798 799 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1; 800 eventTime += interval; 801 sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, true, false); 802 803 assertFalse(receiver.waitUntilShown()); 804 } 805 806 @Test testInterceptPowerKeyDown_walletGestureOn_userSetupIncomplete()807 public void testInterceptPowerKeyDown_walletGestureOn_userSetupIncomplete() { 808 WalletLaunchedReceiver receiver = registerWalletLaunchedReceiver(LAUNCH_TEST_WALLET_ACTION); 809 setUpGetGestureTargetActivityPendingIntent(mGesturePendingIntent); 810 enableWalletGesture(); 811 withUserSetupCompleteValue(false); 812 813 // First event 814 long eventTime = INITIAL_EVENT_TIME_MILLIS; 815 sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, false, false); 816 817 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1; 818 eventTime += interval; 819 sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, false, false); 820 821 if (launchWalletViaSysuiCallbacks()) { 822 verify(mStatusBarManagerInternal, never()).onWalletLaunchGestureDetected(); 823 } else { 824 assertFalse(receiver.waitUntilShown()); 825 } 826 } 827 828 @Test 829 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) 830 @RequiresFlagsDisabled(FLAG_LAUNCH_WALLET_VIA_SYSUI_CALLBACKS) testInterceptPowerKeyDown_walletPowerGesture_nullPendingIntent()831 public void testInterceptPowerKeyDown_walletPowerGesture_nullPendingIntent() { 832 WalletLaunchedReceiver gestureReceiver = 833 registerWalletLaunchedReceiver(LAUNCH_TEST_WALLET_ACTION); 834 setUpGetGestureTargetActivityPendingIntent(null); 835 WalletLaunchedReceiver fallbackReceiver = 836 registerWalletLaunchedReceiver(LAUNCH_FALLBACK_ACTION); 837 setUpWalletFallbackPendingIntent(mFallbackPendingIntent); 838 enableWalletGesture(); 839 enableEmergencyGesture(); 840 841 // First event 842 long eventTime = INITIAL_EVENT_TIME_MILLIS; 843 sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, false, false); 844 845 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1; 846 eventTime += interval; 847 sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, true, true); 848 849 assertFalse(gestureReceiver.waitUntilShown()); 850 assertTrue(fallbackReceiver.waitUntilShown()); 851 } 852 853 @Test 854 @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) testInterceptPowerKeyDown_walletPowerGesture_intervalOutOfBounds()855 public void testInterceptPowerKeyDown_walletPowerGesture_intervalOutOfBounds() { 856 WalletLaunchedReceiver gestureReceiver = 857 registerWalletLaunchedReceiver(LAUNCH_TEST_WALLET_ACTION); 858 setUpGetGestureTargetActivityPendingIntent(null); 859 WalletLaunchedReceiver fallbackReceiver = 860 registerWalletLaunchedReceiver(LAUNCH_FALLBACK_ACTION); 861 setUpWalletFallbackPendingIntent(mFallbackPendingIntent); 862 enableWalletGesture(); 863 enableEmergencyGesture(); 864 865 // First event 866 long eventTime = INITIAL_EVENT_TIME_MILLIS; 867 sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, false, false); 868 869 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS; 870 eventTime += interval; 871 sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, false, false); 872 873 if (launchWalletViaSysuiCallbacks()) { 874 verify(mStatusBarManagerInternal, never()).onWalletLaunchGestureDetected(); 875 } else { 876 assertFalse(gestureReceiver.waitUntilShown()); 877 assertFalse(fallbackReceiver.waitUntilShown()); 878 } 879 } 880 881 @Test 882 public void testInterceptPowerKeyDown_fiveInboundPresses_cameraAndEmergencyEnabled_bothLaunch()883 testInterceptPowerKeyDown_fiveInboundPresses_cameraAndEmergencyEnabled_bothLaunch() { 884 enableCameraGesture(); 885 enableEmergencyGesture(); 886 887 // First button press does nothing 888 long eventTime = INITIAL_EVENT_TIME_MILLIS; 889 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 890 IGNORED_REPEAT); 891 boolean interactive = true; 892 MutableBoolean outLaunched = new MutableBoolean(true); 893 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 894 outLaunched); 895 assertFalse(intercepted); 896 assertFalse(outLaunched.value); 897 898 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1; 899 900 // 2nd button triggers camera 901 eventTime += interval; 902 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 903 IGNORED_REPEAT); 904 outLaunched.value = false; 905 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 906 outLaunched); 907 assertTrue(intercepted); 908 assertTrue(outLaunched.value); 909 910 // Camera checks 911 verify(mStatusBarManagerInternal).onCameraLaunchGestureDetected( 912 StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP); 913 verify(mMetricsLogger) 914 .action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE, (int) interval); 915 verify(mUiEventLogger, times(1)) 916 .log(GestureLauncherService.GestureLauncherEvent.GESTURE_CAMERA_DOUBLE_TAP_POWER); 917 918 final ArgumentCaptor<Integer> cameraIntervalCaptor = ArgumentCaptor.forClass(Integer.class); 919 verify(mMetricsLogger, times(2)).histogram( 920 eq("power_double_tap_interval"), cameraIntervalCaptor.capture()); 921 List<Integer> cameraIntervals = cameraIntervalCaptor.getAllValues(); 922 assertEquals((int) INITIAL_EVENT_TIME_MILLIS, cameraIntervals.get(0).intValue()); 923 assertEquals((int) interval, cameraIntervals.get(1).intValue()); 924 925 final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class); 926 verify(mMetricsLogger, times(2)).histogram( 927 eq("power_consecutive_short_tap_count"), tapCountCaptor.capture()); 928 List<Integer> tapCounts = tapCountCaptor.getAllValues(); 929 assertEquals(1, tapCounts.get(0).intValue()); 930 assertEquals(2, tapCounts.get(1).intValue()); 931 932 // Continue the button presses for the emergency gesture. 933 934 // Presses 3 and 4 should not trigger any gesture 935 for (int i = 0; i < 2; i++) { 936 eventTime += interval; 937 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 938 IGNORED_REPEAT); 939 outLaunched.value = false; 940 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 941 outLaunched); 942 assertTrue(intercepted); 943 assertFalse(outLaunched.value); 944 } 945 946 // Fifth button press should trigger the emergency flow 947 eventTime += interval; 948 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 949 IGNORED_REPEAT); 950 outLaunched.value = false; 951 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 952 outLaunched); 953 assertTrue(intercepted); 954 assertTrue(outLaunched.value); 955 956 verify(mUiEventLogger, times(1)) 957 .log(GestureLauncherService.GestureLauncherEvent.GESTURE_EMERGENCY_TAP_POWER); 958 verify(mStatusBarManagerInternal).onEmergencyActionLaunchGestureDetected(); 959 960 final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class); 961 verify(mMetricsLogger, times(5)).histogram( 962 eq("power_double_tap_interval"), intervalCaptor.capture()); 963 List<Integer> intervals = intervalCaptor.getAllValues(); 964 assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue()); 965 assertEquals((int) interval, intervals.get(1).intValue()); 966 } 967 968 @Test 969 public void testInterceptPowerKeyDown_fiveInboundPresses_emergencyGestureEnabled_launchesFlow()970 testInterceptPowerKeyDown_fiveInboundPresses_emergencyGestureEnabled_launchesFlow() { 971 withEmergencyGestureEnabledConfigValue(true); 972 withEmergencyGestureEnabledSettingValue(true); 973 mGestureLauncherService.updateEmergencyGestureEnabled(); 974 withUserSetupCompleteValue(true); 975 976 // First button press does nothing 977 long eventTime = INITIAL_EVENT_TIME_MILLIS; 978 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 979 IGNORED_REPEAT); 980 boolean interactive = true; 981 MutableBoolean outLaunched = new MutableBoolean(true); 982 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 983 outLaunched); 984 assertFalse(intercepted); 985 assertFalse(outLaunched.value); 986 987 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1; 988 // 3 more button presses which should not trigger any gesture (camera gesture disabled) 989 for (int i = 0; i < 3; i++) { 990 eventTime += interval; 991 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 992 IGNORED_REPEAT); 993 outLaunched.value = false; 994 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 995 outLaunched); 996 assertTrue(intercepted); 997 assertFalse(outLaunched.value); 998 } 999 1000 // Fifth button press should trigger the emergency flow 1001 eventTime += interval; 1002 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1003 IGNORED_REPEAT); 1004 outLaunched.value = false; 1005 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1006 outLaunched); 1007 assertTrue(outLaunched.value); 1008 assertTrue(intercepted); 1009 1010 verify(mUiEventLogger, times(1)) 1011 .log(GestureLauncherService.GestureLauncherEvent.GESTURE_EMERGENCY_TAP_POWER); 1012 verify(mStatusBarManagerInternal).onEmergencyActionLaunchGestureDetected(); 1013 1014 final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class); 1015 verify(mMetricsLogger, times(5)).histogram( 1016 eq("power_double_tap_interval"), intervalCaptor.capture()); 1017 List<Integer> intervals = intervalCaptor.getAllValues(); 1018 assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue()); 1019 assertEquals((int) interval, intervals.get(1).intValue()); 1020 } 1021 1022 @Test 1023 public void testInterceptPowerKeyDown_tenInboundPresses_emergencyGestureEnabled_keyIntercepted()1024 testInterceptPowerKeyDown_tenInboundPresses_emergencyGestureEnabled_keyIntercepted() { 1025 withEmergencyGestureEnabledConfigValue(true); 1026 withEmergencyGestureEnabledSettingValue(true); 1027 mGestureLauncherService.updateEmergencyGestureEnabled(); 1028 withUserSetupCompleteValue(true); 1029 1030 // First button press does nothing 1031 long eventTime = INITIAL_EVENT_TIME_MILLIS; 1032 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1033 IGNORED_REPEAT); 1034 boolean interactive = true; 1035 MutableBoolean outLaunched = new MutableBoolean(true); 1036 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1037 outLaunched); 1038 assertFalse(intercepted); 1039 assertFalse(outLaunched.value); 1040 1041 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1; 1042 // 3 more button presses which should not trigger any gesture, but intercepts action. 1043 for (int i = 0; i < 3; i++) { 1044 eventTime += interval; 1045 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1046 IGNORED_REPEAT); 1047 outLaunched.value = false; 1048 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1049 outLaunched); 1050 assertTrue(intercepted); 1051 assertFalse(outLaunched.value); 1052 } 1053 1054 // Fifth button press should trigger the emergency flow 1055 eventTime += interval; 1056 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1057 IGNORED_REPEAT); 1058 outLaunched.value = false; 1059 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1060 outLaunched); 1061 assertTrue(outLaunched.value); 1062 assertTrue(intercepted); 1063 1064 // 5 more button presses which should not trigger any gesture, but intercepts action. 1065 for (int i = 0; i < 5; i++) { 1066 eventTime += interval; 1067 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1068 IGNORED_REPEAT); 1069 outLaunched.value = false; 1070 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1071 outLaunched); 1072 assertTrue(intercepted); 1073 assertFalse(outLaunched.value); 1074 } 1075 } 1076 1077 @Test testInterceptPowerKeyDown_triggerEmergency_singleTaps_cooldownTriggered()1078 public void testInterceptPowerKeyDown_triggerEmergency_singleTaps_cooldownTriggered() { 1079 // Enable power button cooldown 1080 withEmergencyGesturePowerButtonCooldownPeriodMsValue(3000); 1081 mGestureLauncherService.updateEmergencyGesturePowerButtonCooldownPeriodMs(); 1082 1083 // Trigger emergency by tapping button 5 times 1084 long eventTime = triggerEmergencyGesture(); 1085 1086 // Add enough interval to reset consecutive tap count 1087 long interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS + 1; 1088 eventTime += interval; 1089 1090 // Subsequent single tap is intercepted, but should not trigger any gesture 1091 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1092 IGNORED_REPEAT); 1093 boolean interactive = true; 1094 MutableBoolean outLaunched = new MutableBoolean(true); 1095 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1096 outLaunched); 1097 assertTrue(intercepted); 1098 assertFalse(outLaunched.value); 1099 1100 // Add enough interval to reset consecutive tap count 1101 interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS + 1; 1102 eventTime += interval; 1103 1104 // Another single tap should be the same (intercepted but should not trigger gesture) 1105 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1106 IGNORED_REPEAT); 1107 interactive = true; 1108 outLaunched = new MutableBoolean(true); 1109 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1110 outLaunched); 1111 assertTrue(intercepted); 1112 assertFalse(outLaunched.value); 1113 } 1114 1115 @Test 1116 public void testInterceptPowerKeyDown_triggerEmergency_cameraGestureEnabled_doubleTap_cooldownTriggered()1117 testInterceptPowerKeyDown_triggerEmergency_cameraGestureEnabled_doubleTap_cooldownTriggered() { 1118 // Enable camera double tap gesture 1119 enableCameraGesture(); 1120 1121 // Enable power button cooldown 1122 withEmergencyGesturePowerButtonCooldownPeriodMsValue(3000); 1123 mGestureLauncherService.updateEmergencyGesturePowerButtonCooldownPeriodMs(); 1124 1125 // Trigger emergency by tapping button 5 times 1126 long eventTime = triggerEmergencyGesture(); 1127 1128 // Add enough interval to reset consecutive tap count 1129 long interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS + 1; 1130 eventTime += interval; 1131 1132 // Subsequent double tap is intercepted, but should not trigger any gesture 1133 for (int i = 0; i < 2; i++) { 1134 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, 1135 IGNORED_CODE, IGNORED_REPEAT); 1136 boolean interactive = true; 1137 MutableBoolean outLaunched = new MutableBoolean(true); 1138 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, 1139 interactive, outLaunched); 1140 assertTrue(intercepted); 1141 assertFalse(outLaunched.value); 1142 interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1; 1143 eventTime += interval; 1144 } 1145 } 1146 1147 @Test testInterceptPowerKeyDown_triggerEmergency_fiveTaps_cooldownTriggered()1148 public void testInterceptPowerKeyDown_triggerEmergency_fiveTaps_cooldownTriggered() { 1149 // Enable power button cooldown 1150 withEmergencyGesturePowerButtonCooldownPeriodMsValue(3000); 1151 mGestureLauncherService.updateEmergencyGesturePowerButtonCooldownPeriodMs(); 1152 1153 // Trigger emergency by tapping button 5 times 1154 long eventTime = triggerEmergencyGesture(); 1155 1156 // Add enough interval to reset consecutive tap count 1157 long interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS + 1; 1158 eventTime += interval; 1159 1160 // Subsequent 5 taps are intercepted, but should not trigger any gesture 1161 for (int i = 0; i < 5; i++) { 1162 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, 1163 IGNORED_CODE, IGNORED_REPEAT); 1164 boolean interactive = true; 1165 MutableBoolean outLaunched = new MutableBoolean(true); 1166 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, 1167 interactive, outLaunched); 1168 assertTrue(intercepted); 1169 assertFalse(outLaunched.value); 1170 interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1; 1171 eventTime += interval; 1172 } 1173 } 1174 1175 @Test testInterceptPowerKeyDown_triggerEmergency_fiveFastTaps_gestureIgnored()1176 public void testInterceptPowerKeyDown_triggerEmergency_fiveFastTaps_gestureIgnored() { 1177 when(mResources.getInteger( 1178 com.android.internal.R.integer.config_defaultMinEmergencyGestureTapDurationMillis)) 1179 .thenReturn(200); 1180 // Trigger emergency by tapping button 5 times 1181 long eventTime = triggerEmergencyGesture(/* tapIntervalMs= */ 1); 1182 1183 // Add 1 more millisecond and send the event again. 1184 eventTime += 1; 1185 1186 // Subsequent long press is intercepted, but should not trigger any gesture 1187 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1188 IGNORED_REPEAT, IGNORED_META_STATE, IGNORED_DEVICE_ID, IGNORED_SCANCODE, 1189 KeyEvent.FLAG_LONG_PRESS); 1190 MutableBoolean outLaunched = new MutableBoolean(true); 1191 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown( 1192 keyEvent, 1193 /* interactive= */ true, 1194 outLaunched); 1195 assertFalse(intercepted); 1196 assertFalse(outLaunched.value); 1197 } 1198 1199 @Test testInterceptPowerKeyDown_triggerEmergency_longPress_cooldownTriggered()1200 public void testInterceptPowerKeyDown_triggerEmergency_longPress_cooldownTriggered() { 1201 // Enable power button cooldown 1202 withEmergencyGesturePowerButtonCooldownPeriodMsValue(3000); 1203 mGestureLauncherService.updateEmergencyGesturePowerButtonCooldownPeriodMs(); 1204 1205 // Trigger emergency by tapping button 5 times 1206 long eventTime = triggerEmergencyGesture(); 1207 1208 // Add enough interval to reset consecutive tap count 1209 long interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS + 1; 1210 eventTime += interval; 1211 1212 // Subsequent long press is intercepted, but should not trigger any gesture 1213 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1214 IGNORED_REPEAT, IGNORED_META_STATE, IGNORED_DEVICE_ID, IGNORED_SCANCODE, 1215 KeyEvent.FLAG_LONG_PRESS); 1216 1217 boolean interactive = true; 1218 MutableBoolean outLaunched = new MutableBoolean(true); 1219 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1220 outLaunched); 1221 assertTrue(intercepted); 1222 assertFalse(outLaunched.value); 1223 } 1224 1225 @Test testInterceptPowerKeyDown_triggerEmergency_cooldownDisabled_cooldownNotTriggered()1226 public void testInterceptPowerKeyDown_triggerEmergency_cooldownDisabled_cooldownNotTriggered() { 1227 // Disable power button cooldown by setting cooldown period to 0 1228 withEmergencyGesturePowerButtonCooldownPeriodMsValue(0); 1229 mGestureLauncherService.updateEmergencyGesturePowerButtonCooldownPeriodMs(); 1230 1231 // Trigger emergency by tapping button 5 times 1232 long eventTime = triggerEmergencyGesture(); 1233 1234 // Add enough interval to reset consecutive tap count 1235 long interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS + 1; 1236 eventTime += interval; 1237 1238 // Subsequent single tap is NOT intercepted 1239 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1240 IGNORED_REPEAT); 1241 boolean interactive = true; 1242 MutableBoolean outLaunched = new MutableBoolean(true); 1243 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1244 outLaunched); 1245 assertFalse(intercepted); 1246 assertFalse(outLaunched.value); 1247 1248 // Add enough interval to reset consecutive tap count 1249 interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS + 1; 1250 eventTime += interval; 1251 1252 // Long press also NOT intercepted 1253 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1254 IGNORED_REPEAT, IGNORED_META_STATE, IGNORED_DEVICE_ID, IGNORED_SCANCODE, 1255 KeyEvent.FLAG_LONG_PRESS); 1256 interactive = true; 1257 outLaunched = new MutableBoolean(true); 1258 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1259 outLaunched); 1260 assertFalse(intercepted); 1261 assertFalse(outLaunched.value); 1262 } 1263 1264 @Test 1265 public void testInterceptPowerKeyDown_triggerEmergency_outsideCooldownPeriod_cooldownNotTriggered()1266 testInterceptPowerKeyDown_triggerEmergency_outsideCooldownPeriod_cooldownNotTriggered() { 1267 // Enable power button cooldown 1268 withEmergencyGesturePowerButtonCooldownPeriodMsValue(5000); 1269 mGestureLauncherService.updateEmergencyGesturePowerButtonCooldownPeriodMs(); 1270 1271 // Trigger emergency by tapping button 5 times 1272 long eventTime = triggerEmergencyGesture(); 1273 1274 // Add enough interval to be outside of cooldown period 1275 long interval = 5001; 1276 eventTime += interval; 1277 1278 // Subsequent single tap is NOT intercepted 1279 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1280 IGNORED_REPEAT); 1281 boolean interactive = true; 1282 MutableBoolean outLaunched = new MutableBoolean(true); 1283 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1284 outLaunched); 1285 assertFalse(intercepted); 1286 assertFalse(outLaunched.value); 1287 1288 // Add enough interval to reset consecutive tap count 1289 interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS + 1; 1290 eventTime += interval; 1291 1292 // Long press also NOT intercepted 1293 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1294 IGNORED_REPEAT, IGNORED_META_STATE, IGNORED_DEVICE_ID, IGNORED_SCANCODE, 1295 KeyEvent.FLAG_LONG_PRESS); 1296 interactive = true; 1297 outLaunched = new MutableBoolean(true); 1298 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1299 outLaunched); 1300 assertFalse(intercepted); 1301 assertFalse(outLaunched.value); 1302 } 1303 1304 @Test testInterceptPowerKeyDown_longpress()1305 public void testInterceptPowerKeyDown_longpress() { 1306 enableCameraGesture(); 1307 1308 long eventTime = INITIAL_EVENT_TIME_MILLIS; 1309 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1310 IGNORED_REPEAT); 1311 boolean interactive = true; 1312 MutableBoolean outLaunched = new MutableBoolean(true); 1313 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1314 outLaunched); 1315 assertFalse(intercepted); 1316 assertFalse(outLaunched.value); 1317 1318 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1; 1319 eventTime += interval; 1320 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1321 IGNORED_REPEAT, IGNORED_META_STATE, IGNORED_DEVICE_ID, IGNORED_SCANCODE, 1322 KeyEvent.FLAG_LONG_PRESS); 1323 outLaunched.value = false; 1324 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1325 outLaunched); 1326 assertFalse(intercepted); 1327 assertFalse(outLaunched.value); 1328 1329 verify(mMetricsLogger, never()) 1330 .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); 1331 verify(mUiEventLogger, never()).log(any()); 1332 1333 final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class); 1334 verify(mMetricsLogger, times(1)).histogram( 1335 eq("power_double_tap_interval"), intervalCaptor.capture()); 1336 List<Integer> intervals = intervalCaptor.getAllValues(); 1337 assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue()); 1338 1339 final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class); 1340 verify(mMetricsLogger, times(1)).histogram( 1341 eq("power_consecutive_short_tap_count"), tapCountCaptor.capture()); 1342 List<Integer> tapCounts = tapCountCaptor.getAllValues(); 1343 assertEquals(1, tapCounts.get(0).intValue()); 1344 } 1345 1346 @Test 1347 public void testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnInteractiveSetupIncomplete()1348 testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnInteractiveSetupIncomplete() { 1349 enableCameraGesture(); 1350 withUserSetupCompleteValue(false); 1351 1352 long eventTime = INITIAL_EVENT_TIME_MILLIS; 1353 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1354 IGNORED_REPEAT); 1355 boolean interactive = true; 1356 MutableBoolean outLaunched = new MutableBoolean(true); 1357 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1358 outLaunched); 1359 assertFalse(intercepted); 1360 assertFalse(outLaunched.value); 1361 1362 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1; 1363 eventTime += interval; 1364 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1365 IGNORED_REPEAT); 1366 outLaunched.value = true; 1367 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1368 outLaunched); 1369 assertFalse(intercepted); 1370 assertFalse(outLaunched.value); 1371 1372 verify(mMetricsLogger, never()) 1373 .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); 1374 verify(mUiEventLogger, never()).log(any()); 1375 1376 final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class); 1377 verify(mMetricsLogger, times(2)).histogram( 1378 eq("power_double_tap_interval"), intervalCaptor.capture()); 1379 List<Integer> intervals = intervalCaptor.getAllValues(); 1380 assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue()); 1381 assertEquals((int) interval, intervals.get(1).intValue()); 1382 1383 final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class); 1384 verify(mMetricsLogger, times(2)).histogram( 1385 eq("power_consecutive_short_tap_count"), tapCountCaptor.capture()); 1386 List<Integer> tapCounts = tapCountCaptor.getAllValues(); 1387 assertEquals(1, tapCounts.get(0).intValue()); 1388 // The interval is too long to launch the camera, but short enough to count as a 1389 // sequential tap. 1390 assertEquals(2, tapCounts.get(1).intValue()); 1391 } 1392 1393 @Test testInterceptPowerKeyDown_intervalMidBoundsCameraPowerGestureOnInteractive()1394 public void testInterceptPowerKeyDown_intervalMidBoundsCameraPowerGestureOnInteractive() { 1395 enableCameraGesture(); 1396 1397 long eventTime = INITIAL_EVENT_TIME_MILLIS; 1398 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1399 IGNORED_REPEAT); 1400 boolean interactive = true; 1401 MutableBoolean outLaunched = new MutableBoolean(true); 1402 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1403 outLaunched); 1404 assertFalse(intercepted); 1405 assertFalse(outLaunched.value); 1406 1407 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS; 1408 eventTime += interval; 1409 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1410 IGNORED_REPEAT); 1411 outLaunched.value = true; 1412 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1413 outLaunched); 1414 assertFalse(intercepted); 1415 assertFalse(outLaunched.value); 1416 1417 verify(mMetricsLogger, never()) 1418 .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); 1419 verify(mUiEventLogger, never()).log(any()); 1420 1421 final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class); 1422 verify(mMetricsLogger, times(2)).histogram( 1423 eq("power_double_tap_interval"), intervalCaptor.capture()); 1424 List<Integer> intervals = intervalCaptor.getAllValues(); 1425 assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue()); 1426 assertEquals((int) interval, intervals.get(1).intValue()); 1427 1428 final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class); 1429 verify(mMetricsLogger, times(2)).histogram( 1430 eq("power_consecutive_short_tap_count"), tapCountCaptor.capture()); 1431 List<Integer> tapCounts = tapCountCaptor.getAllValues(); 1432 assertEquals(1, tapCounts.get(0).intValue()); 1433 // The interval is too long to launch the camera, but short enough to count as a 1434 // sequential tap. 1435 assertEquals(2, tapCounts.get(1).intValue()); 1436 } 1437 1438 @Test testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOnInteractive()1439 public void testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOnInteractive() { 1440 enableCameraGesture(); 1441 1442 long eventTime = INITIAL_EVENT_TIME_MILLIS; 1443 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1444 IGNORED_REPEAT); 1445 boolean interactive = true; 1446 MutableBoolean outLaunched = new MutableBoolean(true); 1447 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1448 outLaunched); 1449 assertFalse(intercepted); 1450 assertFalse(outLaunched.value); 1451 1452 long interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS; 1453 eventTime += interval; 1454 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1455 IGNORED_REPEAT); 1456 outLaunched.value = true; 1457 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1458 outLaunched); 1459 assertFalse(intercepted); 1460 assertFalse(outLaunched.value); 1461 1462 verify(mMetricsLogger, never()) 1463 .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); 1464 verify(mUiEventLogger, never()).log(any()); 1465 1466 final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class); 1467 verify(mMetricsLogger, times(2)).histogram( 1468 eq("power_double_tap_interval"), intervalCaptor.capture()); 1469 List<Integer> intervals = intervalCaptor.getAllValues(); 1470 assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue()); 1471 assertEquals((int) interval, intervals.get(1).intValue()); 1472 1473 final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class); 1474 verify(mMetricsLogger, times(2)).histogram( 1475 eq("power_consecutive_short_tap_count"), tapCountCaptor.capture()); 1476 List<Integer> tapCounts = tapCountCaptor.getAllValues(); 1477 assertEquals(1, tapCounts.get(0).intValue()); 1478 assertEquals(1, tapCounts.get(1).intValue()); 1479 } 1480 1481 @Test testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOffNotInteractive()1482 public void testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOffNotInteractive() { 1483 disableDoubleTapPowerGesture(); 1484 1485 long eventTime = INITIAL_EVENT_TIME_MILLIS; 1486 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1487 IGNORED_REPEAT); 1488 boolean interactive = false; 1489 MutableBoolean outLaunched = new MutableBoolean(true); 1490 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1491 outLaunched); 1492 assertFalse(intercepted); 1493 assertFalse(outLaunched.value); 1494 1495 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1; 1496 eventTime += interval; 1497 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1498 IGNORED_REPEAT); 1499 outLaunched.value = true; 1500 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1501 outLaunched); 1502 assertFalse(intercepted); 1503 assertFalse(outLaunched.value); 1504 1505 verify(mMetricsLogger, never()) 1506 .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); 1507 verify(mUiEventLogger, never()).log(any()); 1508 1509 final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class); 1510 verify(mMetricsLogger, times(2)).histogram( 1511 eq("power_double_tap_interval"), intervalCaptor.capture()); 1512 List<Integer> intervals = intervalCaptor.getAllValues(); 1513 assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue()); 1514 assertEquals((int) interval, intervals.get(1).intValue()); 1515 1516 final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class); 1517 verify(mMetricsLogger, times(2)).histogram( 1518 eq("power_consecutive_short_tap_count"), tapCountCaptor.capture()); 1519 List<Integer> tapCounts = tapCountCaptor.getAllValues(); 1520 assertEquals(1, tapCounts.get(0).intValue()); 1521 assertEquals(2, tapCounts.get(1).intValue()); 1522 } 1523 1524 @Test testInterceptPowerKeyDown_intervalMidBoundsCameraPowerGestureOffNotInteractive()1525 public void testInterceptPowerKeyDown_intervalMidBoundsCameraPowerGestureOffNotInteractive() { 1526 disableDoubleTapPowerGesture(); 1527 1528 long eventTime = INITIAL_EVENT_TIME_MILLIS; 1529 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1530 IGNORED_REPEAT); 1531 boolean interactive = false; 1532 MutableBoolean outLaunched = new MutableBoolean(true); 1533 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1534 outLaunched); 1535 assertFalse(intercepted); 1536 assertFalse(outLaunched.value); 1537 1538 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS; 1539 eventTime += interval; 1540 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1541 IGNORED_REPEAT); 1542 outLaunched.value = true; 1543 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1544 outLaunched); 1545 assertFalse(intercepted); 1546 assertFalse(outLaunched.value); 1547 verify(mMetricsLogger, never()) 1548 .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); 1549 verify(mUiEventLogger, never()).log(any()); 1550 1551 final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class); 1552 verify(mMetricsLogger, times(2)).histogram( 1553 eq("power_double_tap_interval"), intervalCaptor.capture()); 1554 List<Integer> intervals = intervalCaptor.getAllValues(); 1555 assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue()); 1556 assertEquals((int) interval, intervals.get(1).intValue()); 1557 1558 final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class); 1559 verify(mMetricsLogger, times(2)).histogram( 1560 eq("power_consecutive_short_tap_count"), tapCountCaptor.capture()); 1561 List<Integer> tapCounts = tapCountCaptor.getAllValues(); 1562 assertEquals(1, tapCounts.get(0).intValue()); 1563 // The interval is too long to launch the camera, but short enough to count as a 1564 // sequential tap. 1565 assertEquals(2, tapCounts.get(1).intValue()); 1566 } 1567 1568 @Test testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOffNotInteractive()1569 public void testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOffNotInteractive() { 1570 disableDoubleTapPowerGesture(); 1571 1572 long eventTime = INITIAL_EVENT_TIME_MILLIS; 1573 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1574 IGNORED_REPEAT); 1575 boolean interactive = false; 1576 MutableBoolean outLaunched = new MutableBoolean(true); 1577 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1578 outLaunched); 1579 assertFalse(intercepted); 1580 assertFalse(outLaunched.value); 1581 1582 long interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS; 1583 eventTime += interval; 1584 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1585 IGNORED_REPEAT); 1586 outLaunched.value = true; 1587 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1588 outLaunched); 1589 assertFalse(intercepted); 1590 assertFalse(outLaunched.value); 1591 verify(mMetricsLogger, never()) 1592 .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); 1593 verify(mUiEventLogger, never()).log(any()); 1594 1595 final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class); 1596 verify(mMetricsLogger, times(2)).histogram( 1597 eq("power_double_tap_interval"), intervalCaptor.capture()); 1598 List<Integer> intervals = intervalCaptor.getAllValues(); 1599 assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue()); 1600 assertEquals((int) interval, intervals.get(1).intValue()); 1601 1602 final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class); 1603 verify(mMetricsLogger, times(2)).histogram( 1604 eq("power_consecutive_short_tap_count"), tapCountCaptor.capture()); 1605 List<Integer> tapCounts = tapCountCaptor.getAllValues(); 1606 assertEquals(1, tapCounts.get(0).intValue()); 1607 assertEquals(1, tapCounts.get(1).intValue()); 1608 } 1609 1610 @Test 1611 public void testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnNotInteractiveSetupComplete()1612 testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnNotInteractiveSetupComplete() { 1613 enableCameraGesture(); 1614 1615 long eventTime = INITIAL_EVENT_TIME_MILLIS; 1616 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1617 IGNORED_REPEAT); 1618 boolean interactive = false; 1619 MutableBoolean outLaunched = new MutableBoolean(true); 1620 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1621 outLaunched); 1622 assertFalse(intercepted); 1623 assertFalse(outLaunched.value); 1624 1625 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1; 1626 eventTime += interval; 1627 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1628 IGNORED_REPEAT); 1629 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1630 outLaunched); 1631 assertFalse(intercepted); 1632 assertTrue(outLaunched.value); 1633 1634 verify(mStatusBarManagerInternal).onCameraLaunchGestureDetected( 1635 StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP); 1636 verify(mMetricsLogger) 1637 .action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE, (int) interval); 1638 verify(mUiEventLogger, times(1)) 1639 .log(GestureLauncherService.GestureLauncherEvent.GESTURE_CAMERA_DOUBLE_TAP_POWER); 1640 1641 final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class); 1642 verify(mMetricsLogger, times(2)).histogram( 1643 eq("power_double_tap_interval"), intervalCaptor.capture()); 1644 List<Integer> intervals = intervalCaptor.getAllValues(); 1645 assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue()); 1646 assertEquals((int) interval, intervals.get(1).intValue()); 1647 1648 final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class); 1649 verify(mMetricsLogger, times(2)).histogram( 1650 eq("power_consecutive_short_tap_count"), tapCountCaptor.capture()); 1651 List<Integer> tapCounts = tapCountCaptor.getAllValues(); 1652 assertEquals(1, tapCounts.get(0).intValue()); 1653 assertEquals(2, tapCounts.get(1).intValue()); 1654 } 1655 1656 @Test 1657 public void testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnNotInteractiveSetupIncomplete()1658 testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnNotInteractiveSetupIncomplete() { 1659 enableCameraGesture(); 1660 withUserSetupCompleteValue(false); 1661 1662 long eventTime = INITIAL_EVENT_TIME_MILLIS; 1663 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1664 IGNORED_REPEAT); 1665 boolean interactive = false; 1666 MutableBoolean outLaunched = new MutableBoolean(true); 1667 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1668 outLaunched); 1669 assertFalse(intercepted); 1670 assertFalse(outLaunched.value); 1671 1672 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1; 1673 eventTime += interval; 1674 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1675 IGNORED_REPEAT); 1676 outLaunched.value = true; 1677 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1678 outLaunched); 1679 assertFalse(intercepted); 1680 assertFalse(outLaunched.value); 1681 1682 verify(mMetricsLogger, never()) 1683 .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); 1684 verify(mUiEventLogger, never()).log(any()); 1685 1686 final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class); 1687 verify(mMetricsLogger, times(2)).histogram( 1688 eq("power_double_tap_interval"), intervalCaptor.capture()); 1689 List<Integer> intervals = intervalCaptor.getAllValues(); 1690 assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue()); 1691 assertEquals((int) interval, intervals.get(1).intValue()); 1692 1693 final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class); 1694 verify(mMetricsLogger, times(2)).histogram( 1695 eq("power_consecutive_short_tap_count"), tapCountCaptor.capture()); 1696 List<Integer> tapCounts = tapCountCaptor.getAllValues(); 1697 assertEquals(1, tapCounts.get(0).intValue()); 1698 assertEquals(2, tapCounts.get(1).intValue()); 1699 } 1700 1701 @Test testInterceptPowerKeyDown_intervalMidBoundsCameraPowerGestureOnNotInteractive()1702 public void testInterceptPowerKeyDown_intervalMidBoundsCameraPowerGestureOnNotInteractive() { 1703 enableCameraGesture(); 1704 1705 long eventTime = INITIAL_EVENT_TIME_MILLIS; 1706 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1707 IGNORED_REPEAT); 1708 boolean interactive = false; 1709 MutableBoolean outLaunched = new MutableBoolean(true); 1710 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1711 outLaunched); 1712 assertFalse(intercepted); 1713 assertFalse(outLaunched.value); 1714 1715 final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS; 1716 eventTime += interval; 1717 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1718 IGNORED_REPEAT); 1719 outLaunched.value = true; 1720 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1721 outLaunched); 1722 assertFalse(intercepted); 1723 assertFalse(outLaunched.value); 1724 1725 verify(mMetricsLogger, never()) 1726 .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); 1727 verify(mUiEventLogger, never()).log(any()); 1728 1729 final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class); 1730 verify(mMetricsLogger, times(2)).histogram( 1731 eq("power_double_tap_interval"), intervalCaptor.capture()); 1732 List<Integer> intervals = intervalCaptor.getAllValues(); 1733 assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue()); 1734 assertEquals((int) interval, intervals.get(1).intValue()); 1735 1736 final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class); 1737 verify(mMetricsLogger, times(2)).histogram( 1738 eq("power_consecutive_short_tap_count"), tapCountCaptor.capture()); 1739 List<Integer> tapCounts = tapCountCaptor.getAllValues(); 1740 assertEquals(1, tapCounts.get(0).intValue()); 1741 // The interval is too long to launch the camera, but short enough to count as a 1742 // sequential tap. 1743 assertEquals(2, tapCounts.get(1).intValue()); 1744 } 1745 1746 @Test testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOnNotInteractive()1747 public void testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOnNotInteractive() { 1748 enableCameraGesture(); 1749 1750 long eventTime = INITIAL_EVENT_TIME_MILLIS; 1751 KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1752 IGNORED_REPEAT); 1753 boolean interactive = false; 1754 MutableBoolean outLaunched = new MutableBoolean(true); 1755 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1756 outLaunched); 1757 assertFalse(intercepted); 1758 assertFalse(outLaunched.value); 1759 1760 long interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS; 1761 eventTime += interval; 1762 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1763 IGNORED_REPEAT); 1764 outLaunched.value = true; 1765 intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1766 outLaunched); 1767 assertFalse(intercepted); 1768 assertFalse(outLaunched.value); 1769 1770 verify(mMetricsLogger, never()) 1771 .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); 1772 verify(mUiEventLogger, never()).log(any()); 1773 1774 final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class); 1775 verify(mMetricsLogger, times(2)).histogram( 1776 eq("power_double_tap_interval"), intervalCaptor.capture()); 1777 List<Integer> intervals = intervalCaptor.getAllValues(); 1778 assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue()); 1779 assertEquals((int) interval, intervals.get(1).intValue()); 1780 1781 final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class); 1782 verify(mMetricsLogger, times(2)).histogram( 1783 eq("power_consecutive_short_tap_count"), tapCountCaptor.capture()); 1784 List<Integer> tapCounts = tapCountCaptor.getAllValues(); 1785 assertEquals(1, tapCounts.get(0).intValue()); 1786 assertEquals(1, tapCounts.get(1).intValue()); 1787 } 1788 1789 /** 1790 * Helper method to trigger emergency gesture by pressing button for 5 times. 1791 * 1792 * @return last event time. 1793 */ triggerEmergencyGesture()1794 private long triggerEmergencyGesture() { 1795 return triggerEmergencyGesture(POWER_DOUBLE_TAP_MAX_TIME_MS - 1); 1796 } 1797 1798 /** 1799 * Helper method to trigger emergency gesture by pressing button for 5 times with 1800 * specified interval between each tap 1801 * 1802 * @return last event time. 1803 */ triggerEmergencyGesture(long tapIntervalMs)1804 private long triggerEmergencyGesture(long tapIntervalMs) { 1805 // Enable emergency power gesture 1806 withEmergencyGestureEnabledConfigValue(true); 1807 withEmergencyGestureEnabledSettingValue(true); 1808 mGestureLauncherService.updateEmergencyGestureEnabled(); 1809 withUserSetupCompleteValue(true); 1810 1811 // 4 button presses 1812 long eventTime = INITIAL_EVENT_TIME_MILLIS; 1813 boolean interactive = true; 1814 KeyEvent keyEvent; 1815 MutableBoolean outLaunched = new MutableBoolean(false); 1816 for (int i = 0; i < 4; i++) { 1817 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1818 IGNORED_REPEAT); 1819 mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, outLaunched); 1820 eventTime += tapIntervalMs; 1821 } 1822 1823 // 5th button press should trigger the emergency flow 1824 keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, 1825 IGNORED_REPEAT); 1826 outLaunched.value = false; 1827 boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, 1828 outLaunched); 1829 long emergencyGestureTapDetectionMinTimeMs = Settings.Global.getInt( 1830 mContext.getContentResolver(), 1831 Settings.Global.EMERGENCY_GESTURE_TAP_DETECTION_MIN_TIME_MS, 1832 200); 1833 assertTrue(intercepted); 1834 if (tapIntervalMs * 4 > emergencyGestureTapDetectionMinTimeMs) { 1835 assertTrue(outLaunched.value); 1836 verify(mUiEventLogger, times(1)) 1837 .log(GestureLauncherService.GestureLauncherEvent.GESTURE_EMERGENCY_TAP_POWER); 1838 verify(mStatusBarManagerInternal).onEmergencyActionLaunchGestureDetected(); 1839 } else { 1840 assertFalse(outLaunched.value); 1841 verify(mUiEventLogger, never()) 1842 .log(GestureLauncherService.GestureLauncherEvent.GESTURE_EMERGENCY_TAP_POWER); 1843 verify(mStatusBarManagerInternal, never()).onEmergencyActionLaunchGestureDetected(); 1844 } 1845 return eventTime; 1846 } 1847 withCameraDoubleTapPowerEnableConfigValue(boolean enableConfigValue)1848 private void withCameraDoubleTapPowerEnableConfigValue(boolean enableConfigValue) { 1849 when(mResources.getBoolean( 1850 com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled)) 1851 .thenReturn(enableConfigValue); 1852 } 1853 withDoubleTapPowerModeConfigValue( int modeConfigValue)1854 private void withDoubleTapPowerModeConfigValue( 1855 int modeConfigValue) { 1856 when(mResources.getInteger(com.android.internal.R.integer.config_doubleTapPowerGestureMode)) 1857 .thenReturn(modeConfigValue); 1858 } 1859 withMultiTargetDoubleTapPowerGestureEnableSettingValue(boolean enable)1860 private void withMultiTargetDoubleTapPowerGestureEnableSettingValue(boolean enable) { 1861 Settings.Secure.putIntForUser( 1862 mContentResolver, 1863 Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, 1864 enable ? 1 : 0, 1865 UserHandle.USER_CURRENT); 1866 } 1867 withDoubleTapPowerGestureActionSettingValue(int action)1868 private void withDoubleTapPowerGestureActionSettingValue(int action) { 1869 Settings.Secure.putIntForUser( 1870 mContentResolver, 1871 Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE, 1872 action, 1873 UserHandle.USER_CURRENT); 1874 } 1875 withDefaultDoubleTapPowerGestureActionConfig(int action)1876 private void withDefaultDoubleTapPowerGestureActionConfig(int action) { 1877 when(mResources.getInteger( 1878 com.android.internal.R.integer.config_doubleTapPowerGestureMultiTargetDefaultAction 1879 )).thenReturn(action); 1880 } 1881 withEmergencyGestureEnabledConfigValue(boolean enableConfigValue)1882 private void withEmergencyGestureEnabledConfigValue(boolean enableConfigValue) { 1883 when(mResources.getBoolean( 1884 com.android.internal.R.bool.config_emergencyGestureEnabled)) 1885 .thenReturn(enableConfigValue); 1886 } 1887 withCameraDoubleTapPowerDisableSettingValue(int disableSettingValue)1888 private void withCameraDoubleTapPowerDisableSettingValue(int disableSettingValue) { 1889 Settings.Secure.putIntForUser( 1890 mContentResolver, 1891 Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 1892 disableSettingValue, 1893 UserHandle.USER_CURRENT); 1894 } 1895 withEmergencyGestureEnabledSettingValue(boolean enable)1896 private void withEmergencyGestureEnabledSettingValue(boolean enable) { 1897 Settings.Secure.putIntForUser( 1898 mContentResolver, 1899 Settings.Secure.EMERGENCY_GESTURE_ENABLED, 1900 enable ? 1 : 0, 1901 UserHandle.USER_CURRENT); 1902 } 1903 withEmergencyGesturePowerButtonCooldownPeriodMsValue(int period)1904 private void withEmergencyGesturePowerButtonCooldownPeriodMsValue(int period) { 1905 Settings.Global.putInt( 1906 mContentResolver, 1907 Settings.Global.EMERGENCY_GESTURE_POWER_BUTTON_COOLDOWN_PERIOD_MS, 1908 period); 1909 } 1910 withUserSetupCompleteValue(boolean userSetupComplete)1911 private void withUserSetupCompleteValue(boolean userSetupComplete) { 1912 int userSetupCompleteValue = userSetupComplete ? 1 : 0; 1913 Settings.Secure.putIntForUser( 1914 mContentResolver, 1915 Settings.Secure.USER_SETUP_COMPLETE, 1916 userSetupCompleteValue, 1917 UserHandle.USER_CURRENT); 1918 } 1919 setUpGetGestureTargetActivityPendingIntent(PendingIntent pendingIntent)1920 private void setUpGetGestureTargetActivityPendingIntent(PendingIntent pendingIntent) { 1921 doAnswer( 1922 invocation -> { 1923 QuickAccessWalletClient.GesturePendingIntentCallback callback = 1924 (QuickAccessWalletClient.GesturePendingIntentCallback) 1925 invocation.getArguments()[1]; 1926 callback.onGesturePendingIntentRetrieved(pendingIntent); 1927 return null; 1928 }) 1929 .when(mQuickAccessWalletClient) 1930 .getGestureTargetActivityPendingIntent(any(), any()); 1931 } 1932 setUpWalletFallbackPendingIntent(PendingIntent pendingIntent)1933 private void setUpWalletFallbackPendingIntent(PendingIntent pendingIntent) { 1934 doAnswer( 1935 invocation -> { 1936 QuickAccessWalletClient.WalletPendingIntentCallback callback = 1937 (QuickAccessWalletClient.WalletPendingIntentCallback) 1938 invocation.getArguments()[1]; 1939 callback.onWalletPendingIntentRetrieved(pendingIntent); 1940 return null; 1941 }) 1942 .when(mQuickAccessWalletClient) 1943 .getWalletPendingIntent(any(), any()); 1944 } 1945 enableWalletGesture()1946 private void enableWalletGesture() { 1947 withDoubleTapPowerGestureActionSettingValue(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER); 1948 withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); 1949 withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); 1950 1951 mGestureLauncherService.updateWalletDoubleTapPowerEnabled(); 1952 withUserSetupCompleteValue(true); 1953 } 1954 enableEmergencyGesture()1955 private void enableEmergencyGesture() { 1956 withEmergencyGestureEnabledConfigValue(true); 1957 withEmergencyGestureEnabledSettingValue(true); 1958 mGestureLauncherService.updateEmergencyGestureEnabled(); 1959 withUserSetupCompleteValue(true); 1960 } 1961 enableCameraGesture()1962 private void enableCameraGesture() { 1963 if (launchWalletOptionOnPowerDoubleTap()) { 1964 withDoubleTapPowerModeConfigValue( 1965 DOUBLE_TAP_POWER_MULTI_TARGET_MODE); 1966 withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); 1967 withDoubleTapPowerGestureActionSettingValue(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); 1968 } else { 1969 withCameraDoubleTapPowerEnableConfigValue(true); 1970 withCameraDoubleTapPowerDisableSettingValue(0); 1971 } 1972 mGestureLauncherService.updateCameraDoubleTapPowerEnabled(); 1973 withUserSetupCompleteValue(true); 1974 } 1975 disableDoubleTapPowerGesture()1976 private void disableDoubleTapPowerGesture() { 1977 if (launchWalletOptionOnPowerDoubleTap()) { 1978 withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_DISABLED_MODE); 1979 withMultiTargetDoubleTapPowerGestureEnableSettingValue(false); 1980 } else { 1981 withCameraDoubleTapPowerEnableConfigValue(false); 1982 withCameraDoubleTapPowerDisableSettingValue(1); 1983 } 1984 mGestureLauncherService.updateWalletDoubleTapPowerEnabled(); 1985 withUserSetupCompleteValue(true); 1986 } 1987 sendPowerKeyDownToGestureLauncherServiceAndAssertValues( long eventTime, boolean expectedIntercept, boolean expectedOutLaunchedValue)1988 private void sendPowerKeyDownToGestureLauncherServiceAndAssertValues( 1989 long eventTime, boolean expectedIntercept, boolean expectedOutLaunchedValue) { 1990 KeyEvent keyEvent = 1991 new KeyEvent( 1992 IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, IGNORED_REPEAT); 1993 boolean interactive = true; 1994 MutableBoolean outLaunched = new MutableBoolean(true); 1995 boolean intercepted = 1996 mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, outLaunched); 1997 assertEquals(intercepted, expectedIntercept); 1998 assertEquals(outLaunched.value, expectedOutLaunchedValue); 1999 } 2000 } 2001