1 /* 2 * Copyright (C) 2021 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.vibrator; 18 19 import static org.junit.Assert.assertArrayEquals; 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertFalse; 22 import static org.junit.Assert.assertNotEquals; 23 import static org.junit.Assert.assertNotNull; 24 import static org.junit.Assert.assertNull; 25 import static org.junit.Assert.assertThrows; 26 import static org.junit.Assert.assertTrue; 27 import static org.mockito.ArgumentMatchers.any; 28 import static org.mockito.ArgumentMatchers.anyInt; 29 import static org.mockito.ArgumentMatchers.anyLong; 30 import static org.mockito.ArgumentMatchers.anyString; 31 import static org.mockito.ArgumentMatchers.eq; 32 import static org.mockito.Mockito.atLeastOnce; 33 import static org.mockito.Mockito.doAnswer; 34 import static org.mockito.Mockito.doNothing; 35 import static org.mockito.Mockito.doThrow; 36 import static org.mockito.Mockito.inOrder; 37 import static org.mockito.Mockito.mock; 38 import static org.mockito.Mockito.never; 39 import static org.mockito.Mockito.spy; 40 import static org.mockito.Mockito.timeout; 41 import static org.mockito.Mockito.times; 42 import static org.mockito.Mockito.verify; 43 import static org.mockito.Mockito.when; 44 45 import android.app.AppOpsManager; 46 import android.content.ComponentName; 47 import android.content.ContentResolver; 48 import android.content.Context; 49 import android.content.ContextWrapper; 50 import android.content.pm.PackageManager; 51 import android.content.pm.PackageManagerInternal; 52 import android.content.res.Resources; 53 import android.frameworks.vibrator.ScaleParam; 54 import android.hardware.input.IInputManager; 55 import android.hardware.input.InputManager; 56 import android.hardware.input.InputManagerGlobal; 57 import android.hardware.vibrator.IVibrator; 58 import android.hardware.vibrator.IVibratorManager; 59 import android.media.AudioAttributes; 60 import android.media.AudioManager; 61 import android.os.CombinedVibration; 62 import android.os.ExternalVibration; 63 import android.os.ExternalVibrationScale; 64 import android.os.Handler; 65 import android.os.IBinder; 66 import android.os.IExternalVibrationController; 67 import android.os.IVibratorStateListener; 68 import android.os.Looper; 69 import android.os.PowerManager; 70 import android.os.PowerManagerInternal; 71 import android.os.PowerSaveState; 72 import android.os.Process; 73 import android.os.SystemClock; 74 import android.os.UserHandle; 75 import android.os.VibrationAttributes; 76 import android.os.VibrationEffect; 77 import android.os.Vibrator; 78 import android.os.VibratorInfo; 79 import android.os.test.FakeVibrator; 80 import android.os.test.TestLooper; 81 import android.os.vibrator.PrebakedSegment; 82 import android.os.vibrator.PrimitiveSegment; 83 import android.os.vibrator.StepSegment; 84 import android.os.vibrator.VibrationConfig; 85 import android.os.vibrator.VibrationEffectSegment; 86 import android.platform.test.annotations.RequiresFlagsDisabled; 87 import android.platform.test.annotations.RequiresFlagsEnabled; 88 import android.platform.test.flag.junit.CheckFlagsRule; 89 import android.platform.test.flag.junit.DeviceFlagsValueProvider; 90 import android.platform.test.flag.junit.SetFlagsRule; 91 import android.provider.Settings; 92 import android.util.SparseArray; 93 import android.util.SparseBooleanArray; 94 import android.view.HapticFeedbackConstants; 95 import android.view.InputDevice; 96 import android.view.flags.Flags; 97 98 import androidx.test.InstrumentationRegistry; 99 100 import com.android.internal.app.IBatteryStats; 101 import com.android.internal.util.FrameworkStatsLog; 102 import com.android.internal.util.test.FakeSettingsProvider; 103 import com.android.internal.util.test.FakeSettingsProviderRule; 104 import com.android.server.LocalServices; 105 import com.android.server.companion.virtual.VirtualDeviceManagerInternal; 106 107 import org.junit.After; 108 import org.junit.Before; 109 import org.junit.Rule; 110 import org.junit.Test; 111 import org.mockito.ArgumentCaptor; 112 import org.mockito.InOrder; 113 import org.mockito.Mock; 114 import org.mockito.junit.MockitoJUnit; 115 import org.mockito.junit.MockitoRule; 116 117 import java.time.Duration; 118 import java.util.ArrayList; 119 import java.util.Arrays; 120 import java.util.HashMap; 121 import java.util.List; 122 import java.util.Map; 123 import java.util.concurrent.CountDownLatch; 124 import java.util.concurrent.TimeUnit; 125 import java.util.function.Predicate; 126 127 public class VibratorManagerServiceTest { 128 129 private static final int TEST_TIMEOUT_MILLIS = 1_000; 130 // Time to allow for a cancellation to complete and the vibrators to become idle. 131 private static final int CLEANUP_TIMEOUT_MILLIS = 100; 132 private static final int UID = Process.ROOT_UID; 133 private static final int VIRTUAL_DEVICE_ID = 1; 134 private static final String PACKAGE_NAME = "package"; 135 private static final PowerSaveState NORMAL_POWER_STATE = new PowerSaveState.Builder().build(); 136 private static final PowerSaveState LOW_POWER_STATE = new PowerSaveState.Builder() 137 .setBatterySaverEnabled(true).build(); 138 private static final AudioAttributes AUDIO_ALARM_ATTRS = 139 new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_ALARM).build(); 140 private static final AudioAttributes AUDIO_NOTIFICATION_ATTRS = 141 new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build(); 142 private static final VibrationAttributes ALARM_ATTRS = 143 new VibrationAttributes.Builder().setUsage(VibrationAttributes.USAGE_ALARM).build(); 144 private static final VibrationAttributes HAPTIC_FEEDBACK_ATTRS = 145 new VibrationAttributes.Builder().setUsage(VibrationAttributes.USAGE_TOUCH).build(); 146 private static final VibrationAttributes NOTIFICATION_ATTRS = 147 new VibrationAttributes.Builder().setUsage( 148 VibrationAttributes.USAGE_NOTIFICATION).build(); 149 private static final VibrationAttributes RINGTONE_ATTRS = 150 new VibrationAttributes.Builder().setUsage( 151 VibrationAttributes.USAGE_RINGTONE).build(); 152 private static final VibrationAttributes UNKNOWN_ATTRS = 153 new VibrationAttributes.Builder().setUsage(VibrationAttributes.USAGE_UNKNOWN).build(); 154 155 @Rule 156 public MockitoRule rule = MockitoJUnit.rule(); 157 @Rule 158 public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule(); 159 @Rule 160 public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); 161 162 @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); 163 164 @Mock 165 private VibratorManagerService.NativeWrapper mNativeWrapperMock; 166 @Mock 167 private PackageManagerInternal mPackageManagerInternalMock; 168 @Mock 169 private PowerManagerInternal mPowerManagerInternalMock; 170 @Mock 171 private PowerSaveState mPowerSaveStateMock; 172 @Mock 173 private AppOpsManager mAppOpsManagerMock; 174 @Mock 175 private IInputManager mIInputManagerMock; 176 @Mock 177 private IBatteryStats mBatteryStatsMock; 178 @Mock 179 private VibratorFrameworkStatsLogger mVibratorFrameworkStatsLoggerMock; 180 @Mock 181 private VirtualDeviceManagerInternal mVirtualDeviceManagerInternalMock; 182 @Mock 183 private AudioManager mAudioManagerMock; 184 185 private final Map<Integer, FakeVibratorControllerProvider> mVibratorProviders = new HashMap<>(); 186 private final SparseArray<VibrationEffect> mHapticFeedbackVibrationMap = new SparseArray<>(); 187 private final List<HalVibration> mPendingVibrations = new ArrayList<>(); 188 189 private VibratorManagerService mService; 190 private Context mContextSpy; 191 private TestLooper mTestLooper; 192 private FakeVibrator mVibrator; 193 private FakeVibratorController mFakeVibratorController; 194 private PowerManagerInternal.LowPowerModeListener mRegisteredPowerModeListener; 195 private VibratorManagerService.ExternalVibratorService mExternalVibratorService; 196 private VibratorControlService mVibratorControlService; 197 private VibrationConfig mVibrationConfig; 198 private InputManagerGlobal.TestSession mInputManagerGlobalSession; 199 private InputManager mInputManager; 200 201 @Before setUp()202 public void setUp() throws Exception { 203 mTestLooper = new TestLooper(); 204 mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext())); 205 mInputManagerGlobalSession = InputManagerGlobal.createTestSession(mIInputManagerMock); 206 mVibrationConfig = new VibrationConfig(mContextSpy.getResources()); 207 mFakeVibratorController = new FakeVibratorController(mTestLooper.getLooper()); 208 209 ContentResolver contentResolver = mSettingsProviderRule.mockContentResolver(mContextSpy); 210 when(mContextSpy.getContentResolver()).thenReturn(contentResolver); 211 212 mVibrator = new FakeVibrator(mContextSpy); 213 when(mContextSpy.getSystemService(eq(Context.VIBRATOR_SERVICE))).thenReturn(mVibrator); 214 215 mInputManager = new InputManager(mContextSpy); 216 when(mContextSpy.getSystemService(eq(Context.INPUT_SERVICE))) 217 .thenReturn(mInputManager); 218 when(mContextSpy.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManagerMock); 219 when(mContextSpy.getSystemService(eq(Context.AUDIO_SERVICE))).thenReturn(mAudioManagerMock); 220 when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[0]); 221 when(mPackageManagerInternalMock.getSystemUiServiceComponent()) 222 .thenReturn(new ComponentName("", "")); 223 when(mPowerManagerInternalMock.getLowPowerState(PowerManager.ServiceType.VIBRATION)) 224 .thenReturn(mPowerSaveStateMock); 225 doAnswer(invocation -> { 226 mRegisteredPowerModeListener = invocation.getArgument(0); 227 return null; 228 }).when(mPowerManagerInternalMock).registerLowPowerModeObserver(any()); 229 230 setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1); 231 setUserSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED, 1); 232 setUserSetting(Settings.System.ALARM_VIBRATION_INTENSITY, 233 Vibrator.VIBRATION_INTENSITY_MEDIUM); 234 setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY, 235 Vibrator.VIBRATION_INTENSITY_MEDIUM); 236 setUserSetting(Settings.System.MEDIA_VIBRATION_INTENSITY, 237 Vibrator.VIBRATION_INTENSITY_MEDIUM); 238 setUserSetting(Settings.System.RING_VIBRATION_INTENSITY, 239 Vibrator.VIBRATION_INTENSITY_MEDIUM); 240 setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, 241 Vibrator.VIBRATION_INTENSITY_MEDIUM); 242 setRingerMode(AudioManager.RINGER_MODE_NORMAL); 243 addLocalServiceMock(PackageManagerInternal.class, mPackageManagerInternalMock); 244 addLocalServiceMock(PowerManagerInternal.class, mPowerManagerInternalMock); 245 addLocalServiceMock(VirtualDeviceManagerInternal.class, mVirtualDeviceManagerInternalMock); 246 247 mTestLooper.startAutoDispatch(); 248 } 249 250 @After tearDown()251 public void tearDown() throws Exception { 252 if (mService != null) { 253 if (!mPendingVibrations.stream().allMatch(HalVibration::hasEnded)) { 254 // Cancel any pending vibration from tests. 255 cancelVibrate(mService); 256 for (HalVibration vibration : mPendingVibrations) { 257 vibration.waitForEnd(); 258 } 259 } 260 // Wait until all vibrators have stopped vibrating, waiting for ramp-down. 261 // Note: if a test is flaky here something is wrong with the vibration finalization. 262 assertTrue(waitUntil(s -> { 263 for (int vibratorId : mService.getVibratorIds()) { 264 if (s.isVibrating(vibratorId)) { 265 return false; 266 } 267 } 268 return true; 269 }, mService, mVibrationConfig.getRampDownDurationMs() + CLEANUP_TIMEOUT_MILLIS)); 270 } 271 272 LocalServices.removeServiceForTest(PackageManagerInternal.class); 273 LocalServices.removeServiceForTest(PowerManagerInternal.class); 274 LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class); 275 // Ignore potential exceptions about the looper having never dispatched any messages. 276 mTestLooper.stopAutoDispatchAndIgnoreExceptions(); 277 if (mInputManagerGlobalSession != null) { 278 mInputManagerGlobalSession.close(); 279 } 280 } 281 createSystemReadyService()282 private VibratorManagerService createSystemReadyService() { 283 VibratorManagerService service = createService(); 284 service.systemReady(); 285 return service; 286 } 287 createService()288 private VibratorManagerService createService() { 289 mService = new VibratorManagerService( 290 mContextSpy, 291 new VibratorManagerService.Injector() { 292 @Override 293 VibratorManagerService.NativeWrapper getNativeWrapper() { 294 return mNativeWrapperMock; 295 } 296 297 @Override 298 Handler createHandler(Looper looper) { 299 return new Handler(mTestLooper.getLooper()); 300 } 301 302 @Override 303 IBatteryStats getBatteryStatsService() { 304 return mBatteryStatsMock; 305 } 306 307 @Override 308 VibratorFrameworkStatsLogger getFrameworkStatsLogger(Handler handler) { 309 return mVibratorFrameworkStatsLoggerMock; 310 } 311 312 @Override 313 VibratorController createVibratorController(int vibratorId, 314 VibratorController.OnVibrationCompleteListener listener) { 315 return mVibratorProviders.get(vibratorId) 316 .newVibratorController(vibratorId, listener); 317 } 318 319 @Override 320 void addService(String name, IBinder service) { 321 if (service instanceof VibratorManagerService.ExternalVibratorService) { 322 mExternalVibratorService = 323 (VibratorManagerService.ExternalVibratorService) service; 324 } else if (service instanceof VibratorControlService) { 325 mVibratorControlService = (VibratorControlService) service; 326 mFakeVibratorController.setVibratorControlService( 327 mVibratorControlService); 328 } 329 } 330 331 @Override 332 HapticFeedbackVibrationProvider createHapticFeedbackVibrationProvider( 333 Resources resources, VibratorInfo vibratorInfo) { 334 return new HapticFeedbackVibrationProvider( 335 resources, vibratorInfo, mHapticFeedbackVibrationMap); 336 } 337 338 @Override 339 VibratorControllerHolder createVibratorControllerHolder() { 340 VibratorControllerHolder holder = new VibratorControllerHolder(); 341 holder.setVibratorController(mFakeVibratorController); 342 return holder; 343 } 344 345 @Override 346 boolean isServiceDeclared(String name) { 347 return true; 348 } 349 }); 350 return mService; 351 } 352 353 @Test createService_initializesNativeManagerServiceAndVibrators()354 public void createService_initializesNativeManagerServiceAndVibrators() { 355 mockVibrators(1, 2); 356 createService(); 357 verify(mNativeWrapperMock).init(any()); 358 assertTrue(mVibratorProviders.get(1).isInitialized()); 359 assertTrue(mVibratorProviders.get(2).isInitialized()); 360 } 361 362 @Test createService_resetsVibrators()363 public void createService_resetsVibrators() { 364 mockVibrators(1, 2); 365 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL); 366 mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL); 367 368 createService(); 369 assertEquals(1, mVibratorProviders.get(1).getOffCount()); 370 assertEquals(1, mVibratorProviders.get(2).getOffCount()); 371 assertEquals(Arrays.asList(false), mVibratorProviders.get(1).getExternalControlStates()); 372 assertEquals(Arrays.asList(false), mVibratorProviders.get(2).getExternalControlStates()); 373 } 374 375 @Test createService_doNotCrashIfUsedBeforeSystemReady()376 public void createService_doNotCrashIfUsedBeforeSystemReady() { 377 mockVibrators(1, 2); 378 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL); 379 mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL); 380 VibratorManagerService service = createService(); 381 382 assertNotNull(service.getVibratorIds()); 383 assertNotNull(service.getVibratorInfo(1)); 384 assertFalse(service.isVibrating(1)); 385 386 CombinedVibration effect = CombinedVibration.createParallel( 387 VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)); 388 vibrate(service, effect, HAPTIC_FEEDBACK_ATTRS); 389 service.cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, service); 390 391 assertTrue(service.setAlwaysOnEffect(UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS)); 392 393 IVibratorStateListener listener = mockVibratorStateListener(); 394 assertTrue(service.registerVibratorStateListener(1, listener)); 395 assertTrue(service.unregisterVibratorStateListener(1, listener)); 396 } 397 398 @Test getVibratorIds_withNullResultFromNative_returnsEmptyArray()399 public void getVibratorIds_withNullResultFromNative_returnsEmptyArray() { 400 when(mNativeWrapperMock.getVibratorIds()).thenReturn(null); 401 assertArrayEquals(new int[0], createSystemReadyService().getVibratorIds()); 402 } 403 404 @Test getVibratorIds_withNonEmptyResultFromNative_returnsSameArray()405 public void getVibratorIds_withNonEmptyResultFromNative_returnsSameArray() { 406 mockVibrators(2, 1); 407 assertArrayEquals(new int[]{2, 1}, createSystemReadyService().getVibratorIds()); 408 } 409 410 @Test getVibratorInfo_withMissingVibratorId_returnsNull()411 public void getVibratorInfo_withMissingVibratorId_returnsNull() { 412 mockVibrators(1); 413 assertNull(createSystemReadyService().getVibratorInfo(2)); 414 } 415 416 @Test getVibratorInfo_vibratorFailedLoadBeforeSystemReady_returnsNull()417 public void getVibratorInfo_vibratorFailedLoadBeforeSystemReady_returnsNull() { 418 mockVibrators(1); 419 mVibratorProviders.get(1).setVibratorInfoLoadSuccessful(false); 420 assertNull(createService().getVibratorInfo(1)); 421 } 422 423 @Test getVibratorInfo_vibratorFailedLoadAfterSystemReady_returnsInfoForVibrator()424 public void getVibratorInfo_vibratorFailedLoadAfterSystemReady_returnsInfoForVibrator() { 425 mockVibrators(1); 426 mVibratorProviders.get(1).setVibratorInfoLoadSuccessful(false); 427 mVibratorProviders.get(1).setResonantFrequency(123.f); 428 VibratorInfo info = createSystemReadyService().getVibratorInfo(1); 429 430 assertNotNull(info); 431 assertEquals(1, info.getId()); 432 assertEquals(123.f, info.getResonantFrequencyHz(), 0.01 /*tolerance*/); 433 } 434 435 @Test getVibratorInfo_vibratorSuccessfulLoadBeforeSystemReady_returnsInfoForVibrator()436 public void getVibratorInfo_vibratorSuccessfulLoadBeforeSystemReady_returnsInfoForVibrator() { 437 mockVibrators(1); 438 FakeVibratorControllerProvider vibrator = mVibratorProviders.get(1); 439 vibrator.setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS, IVibrator.CAP_AMPLITUDE_CONTROL); 440 vibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK); 441 vibrator.setSupportedPrimitives(VibrationEffect.Composition.PRIMITIVE_CLICK); 442 vibrator.setResonantFrequency(123.f); 443 vibrator.setQFactor(Float.NaN); 444 VibratorInfo info = createService().getVibratorInfo(1); 445 446 assertNotNull(info); 447 assertEquals(1, info.getId()); 448 assertTrue(info.hasAmplitudeControl()); 449 assertTrue(info.hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)); 450 assertFalse(info.hasCapability(IVibrator.CAP_ON_CALLBACK)); 451 assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_YES, 452 info.isEffectSupported(VibrationEffect.EFFECT_CLICK)); 453 assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_NO, 454 info.isEffectSupported(VibrationEffect.EFFECT_TICK)); 455 assertTrue(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_CLICK)); 456 assertFalse(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_TICK)); 457 assertEquals(123.f, info.getResonantFrequencyHz(), 0.01 /*tolerance*/); 458 assertTrue(Float.isNaN(info.getQFactor())); 459 } 460 461 @Test getVibratorInfo_vibratorFailedThenSuccessfulLoad_returnsNullThenInfo()462 public void getVibratorInfo_vibratorFailedThenSuccessfulLoad_returnsNullThenInfo() { 463 mockVibrators(1); 464 mVibratorProviders.get(1).setVibratorInfoLoadSuccessful(false); 465 466 VibratorManagerService service = createService(); 467 assertNull(createService().getVibratorInfo(1)); 468 469 mVibratorProviders.get(1).setVibratorInfoLoadSuccessful(true); 470 mVibratorProviders.get(1).setResonantFrequency(123.f); 471 service.systemReady(); 472 473 VibratorInfo info = createService().getVibratorInfo(1); 474 assertNotNull(info); 475 assertEquals(1, info.getId()); 476 assertEquals(123.f, info.getResonantFrequencyHz(), 0.01 /*tolerance*/); 477 } 478 479 @Test registerVibratorStateListener_callbacksAreTriggered()480 public void registerVibratorStateListener_callbacksAreTriggered() throws Exception { 481 mockVibrators(1); 482 VibratorManagerService service = createSystemReadyService(); 483 IVibratorStateListener listenerMock = mockVibratorStateListener(); 484 service.registerVibratorStateListener(1, listenerMock); 485 486 long oneShotDuration = 20; 487 vibrateAndWaitUntilFinished(service, 488 VibrationEffect.createOneShot(oneShotDuration, VibrationEffect.DEFAULT_AMPLITUDE), 489 ALARM_ATTRS); 490 491 InOrder inOrderVerifier = inOrder(listenerMock); 492 // First notification done when listener is registered. 493 inOrderVerifier.verify(listenerMock).onVibrating(eq(false)); 494 // Vibrator on notification done before vibration ended, no need to wait. 495 inOrderVerifier.verify(listenerMock).onVibrating(eq(true)); 496 // Vibrator off notification done after vibration completed, wait for notification. 497 inOrderVerifier.verify(listenerMock, timeout(TEST_TIMEOUT_MILLIS)).onVibrating(eq(false)); 498 inOrderVerifier.verifyNoMoreInteractions(); 499 500 InOrder batteryVerifier = inOrder(mBatteryStatsMock); 501 batteryVerifier.verify(mBatteryStatsMock) 502 .noteVibratorOn(UID, oneShotDuration + mVibrationConfig.getRampDownDurationMs()); 503 batteryVerifier 504 .verify(mBatteryStatsMock, timeout(TEST_TIMEOUT_MILLIS)).noteVibratorOff(UID); 505 } 506 507 @Test unregisterVibratorStateListener_callbackNotTriggeredAfter()508 public void unregisterVibratorStateListener_callbackNotTriggeredAfter() throws Exception { 509 mockVibrators(1); 510 VibratorManagerService service = createSystemReadyService(); 511 IVibratorStateListener listenerMock = mockVibratorStateListener(); 512 service.registerVibratorStateListener(1, listenerMock); 513 514 vibrate(service, VibrationEffect.createOneShot(40, 100), ALARM_ATTRS); 515 516 // Wait until service knows vibrator is on. 517 assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 518 519 service.unregisterVibratorStateListener(1, listenerMock); 520 521 // Wait until vibrator is off. 522 assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 523 524 InOrder inOrderVerifier = inOrder(listenerMock); 525 // First notification done when listener is registered. 526 inOrderVerifier.verify(listenerMock).onVibrating(eq(false)); 527 // Vibrator on notification done before vibration ended, no need to wait. 528 inOrderVerifier.verify(listenerMock).onVibrating(eq(true)); 529 inOrderVerifier.verify(listenerMock, atLeastOnce()).asBinder(); // unregister 530 inOrderVerifier.verifyNoMoreInteractions(); 531 } 532 533 @Test registerVibratorStateListener_multipleVibratorsAreTriggered()534 public void registerVibratorStateListener_multipleVibratorsAreTriggered() throws Exception { 535 mockVibrators(0, 1, 2); 536 mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK); 537 VibratorManagerService service = createSystemReadyService(); 538 IVibratorStateListener[] listeners = new IVibratorStateListener[3]; 539 for (int i = 0; i < 3; i++) { 540 listeners[i] = mockVibratorStateListener(); 541 service.registerVibratorStateListener(i, listeners[i]); 542 } 543 544 vibrateAndWaitUntilFinished(service, CombinedVibration.startParallel() 545 .addVibrator(0, VibrationEffect.createOneShot(40, 100)) 546 .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK)) 547 .combine(), ALARM_ATTRS); 548 549 verify(listeners[0]).onVibrating(eq(true)); 550 verify(listeners[1]).onVibrating(eq(true)); 551 verify(listeners[2], never()).onVibrating(eq(true)); 552 } 553 554 @Test setAlwaysOnEffect_withMono_enablesAlwaysOnEffectToAllVibratorsWithCapability()555 public void setAlwaysOnEffect_withMono_enablesAlwaysOnEffectToAllVibratorsWithCapability() { 556 mockVibrators(1, 2, 3); 557 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL); 558 mVibratorProviders.get(3).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL); 559 560 CombinedVibration effect = CombinedVibration.createParallel( 561 VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)); 562 assertTrue(createSystemReadyService().setAlwaysOnEffect( 563 UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS)); 564 565 PrebakedSegment expected = new PrebakedSegment( 566 VibrationEffect.EFFECT_CLICK, false, VibrationEffect.EFFECT_STRENGTH_MEDIUM); 567 568 // Only vibrators 1 and 3 have always-on capabilities. 569 assertEquals(mVibratorProviders.get(1).getAlwaysOnEffect(1), expected); 570 assertNull(mVibratorProviders.get(2).getAlwaysOnEffect(1)); 571 assertEquals(mVibratorProviders.get(3).getAlwaysOnEffect(1), expected); 572 } 573 574 @Test setAlwaysOnEffect_withStereo_enablesAlwaysOnEffectToAllVibratorsWithCapability()575 public void setAlwaysOnEffect_withStereo_enablesAlwaysOnEffectToAllVibratorsWithCapability() { 576 mockVibrators(1, 2, 3, 4); 577 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL); 578 mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL); 579 mVibratorProviders.get(4).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL); 580 581 CombinedVibration effect = CombinedVibration.startParallel() 582 .addVibrator(1, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)) 583 .addVibrator(2, VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK)) 584 .addVibrator(3, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)) 585 .combine(); 586 assertTrue(createSystemReadyService().setAlwaysOnEffect( 587 UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS)); 588 589 PrebakedSegment expectedClick = new PrebakedSegment( 590 VibrationEffect.EFFECT_CLICK, false, VibrationEffect.EFFECT_STRENGTH_MEDIUM); 591 592 PrebakedSegment expectedTick = new PrebakedSegment( 593 VibrationEffect.EFFECT_TICK, false, VibrationEffect.EFFECT_STRENGTH_MEDIUM); 594 595 // Enables click on vibrator 1 and tick on vibrator 2 only. 596 assertEquals(mVibratorProviders.get(1).getAlwaysOnEffect(1), expectedClick); 597 assertEquals(mVibratorProviders.get(2).getAlwaysOnEffect(1), expectedTick); 598 assertNull(mVibratorProviders.get(3).getAlwaysOnEffect(1)); 599 assertNull(mVibratorProviders.get(4).getAlwaysOnEffect(1)); 600 } 601 602 @Test setAlwaysOnEffect_withNullEffect_disablesAlwaysOnEffects()603 public void setAlwaysOnEffect_withNullEffect_disablesAlwaysOnEffects() { 604 mockVibrators(1, 2, 3); 605 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL); 606 mVibratorProviders.get(3).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL); 607 608 CombinedVibration effect = CombinedVibration.createParallel( 609 VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)); 610 assertTrue(createSystemReadyService().setAlwaysOnEffect( 611 UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS)); 612 613 assertTrue(createSystemReadyService().setAlwaysOnEffect( 614 UID, PACKAGE_NAME, 1, null, ALARM_ATTRS)); 615 616 assertNull(mVibratorProviders.get(1).getAlwaysOnEffect(1)); 617 assertNull(mVibratorProviders.get(2).getAlwaysOnEffect(1)); 618 assertNull(mVibratorProviders.get(3).getAlwaysOnEffect(1)); 619 } 620 621 @Test setAlwaysOnEffect_withNonPrebakedEffect_ignoresEffect()622 public void setAlwaysOnEffect_withNonPrebakedEffect_ignoresEffect() { 623 mockVibrators(1); 624 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL); 625 626 CombinedVibration effect = CombinedVibration.createParallel( 627 VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE)); 628 assertFalse(createSystemReadyService().setAlwaysOnEffect( 629 UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS)); 630 631 assertNull(mVibratorProviders.get(1).getAlwaysOnEffect(1)); 632 } 633 634 @Test setAlwaysOnEffect_withNonSyncedEffect_ignoresEffect()635 public void setAlwaysOnEffect_withNonSyncedEffect_ignoresEffect() { 636 mockVibrators(1); 637 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL); 638 639 CombinedVibration effect = CombinedVibration.startSequential() 640 .addNext(0, VibrationEffect.get(VibrationEffect.EFFECT_CLICK)) 641 .combine(); 642 assertFalse(createSystemReadyService().setAlwaysOnEffect( 643 UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS)); 644 645 assertNull(mVibratorProviders.get(1).getAlwaysOnEffect(1)); 646 } 647 648 @Test setAlwaysOnEffect_withNoVibratorWithCapability_ignoresEffect()649 public void setAlwaysOnEffect_withNoVibratorWithCapability_ignoresEffect() { 650 mockVibrators(1); 651 VibratorManagerService service = createSystemReadyService(); 652 653 CombinedVibration mono = CombinedVibration.createParallel( 654 VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)); 655 CombinedVibration stereo = CombinedVibration.startParallel() 656 .addVibrator(0, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)) 657 .combine(); 658 assertFalse(service.setAlwaysOnEffect(UID, PACKAGE_NAME, 1, mono, ALARM_ATTRS)); 659 assertFalse(service.setAlwaysOnEffect(UID, PACKAGE_NAME, 2, stereo, ALARM_ATTRS)); 660 661 assertNull(mVibratorProviders.get(1).getAlwaysOnEffect(1)); 662 } 663 664 @Test vibrate_withoutVibratePermission_throwsSecurityException()665 public void vibrate_withoutVibratePermission_throwsSecurityException() { 666 denyPermission(android.Manifest.permission.VIBRATE); 667 VibratorManagerService service = createSystemReadyService(); 668 669 assertThrows("Expected vibrating without permission to fail!", 670 SecurityException.class, 671 () -> vibrate(service, 672 VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK), 673 VibrationAttributes.createForUsage(VibrationAttributes.USAGE_TOUCH))); 674 } 675 676 @Test vibrate_withoutBypassFlagsPermissions_bypassFlagsNotApplied()677 public void vibrate_withoutBypassFlagsPermissions_bypassFlagsNotApplied() throws Exception { 678 denyPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS); 679 denyPermission(android.Manifest.permission.MODIFY_PHONE_STATE); 680 denyPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING); 681 682 assertCanVibrateWithBypassFlags(false); 683 } 684 685 @Test vibrate_withSecureSettingsPermission_bypassFlagsApplied()686 public void vibrate_withSecureSettingsPermission_bypassFlagsApplied() throws Exception { 687 grantPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS); 688 denyPermission(android.Manifest.permission.MODIFY_PHONE_STATE); 689 denyPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING); 690 691 assertCanVibrateWithBypassFlags(true); 692 } 693 694 @Test vibrate_withModifyPhoneStatePermission_bypassFlagsApplied()695 public void vibrate_withModifyPhoneStatePermission_bypassFlagsApplied() throws Exception { 696 denyPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS); 697 grantPermission(android.Manifest.permission.MODIFY_PHONE_STATE); 698 denyPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING); 699 700 assertCanVibrateWithBypassFlags(true); 701 } 702 703 @Test vibrate_withModifyAudioRoutingPermission_bypassFlagsApplied()704 public void vibrate_withModifyAudioRoutingPermission_bypassFlagsApplied() throws Exception { 705 denyPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS); 706 denyPermission(android.Manifest.permission.MODIFY_PHONE_STATE); 707 grantPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING); 708 709 assertCanVibrateWithBypassFlags(true); 710 } 711 712 @Test vibrate_withRingtone_usesRingerModeSettings()713 public void vibrate_withRingtone_usesRingerModeSettings() throws Exception { 714 mockVibrators(1); 715 FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); 716 fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK, 717 VibrationEffect.EFFECT_HEAVY_CLICK, VibrationEffect.EFFECT_DOUBLE_CLICK); 718 719 setRingerMode(AudioManager.RINGER_MODE_SILENT); 720 VibratorManagerService service = createSystemReadyService(); 721 vibrateAndWaitUntilFinished(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), 722 RINGTONE_ATTRS); 723 724 setRingerMode(AudioManager.RINGER_MODE_NORMAL); 725 service = createSystemReadyService(); 726 vibrateAndWaitUntilFinished( 727 service, VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK), RINGTONE_ATTRS); 728 729 setRingerMode(AudioManager.RINGER_MODE_VIBRATE); 730 service = createSystemReadyService(); 731 vibrateAndWaitUntilFinished( 732 service, VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK), RINGTONE_ATTRS); 733 734 assertEquals( 735 Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_HEAVY_CLICK), 736 expectedPrebaked(VibrationEffect.EFFECT_DOUBLE_CLICK)), 737 mVibratorProviders.get(1).getAllEffectSegments()); 738 } 739 740 @Test vibrate_withPowerMode_usesPowerModeState()741 public void vibrate_withPowerMode_usesPowerModeState() throws Exception { 742 mockVibrators(1); 743 FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); 744 fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_TICK, VibrationEffect.EFFECT_CLICK, 745 VibrationEffect.EFFECT_HEAVY_CLICK, VibrationEffect.EFFECT_DOUBLE_CLICK); 746 VibratorManagerService service = createSystemReadyService(); 747 748 mRegisteredPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE); 749 vibrateAndWaitUntilFinished(service, VibrationEffect.get(VibrationEffect.EFFECT_TICK), 750 HAPTIC_FEEDBACK_ATTRS); 751 vibrateAndWaitUntilFinished(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), 752 RINGTONE_ATTRS); 753 754 mRegisteredPowerModeListener.onLowPowerModeChanged(NORMAL_POWER_STATE); 755 vibrateAndWaitUntilFinished(service, 756 VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK), /* attrs= */ null); 757 vibrateAndWaitUntilFinished(service, 758 VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK), NOTIFICATION_ATTRS); 759 760 assertEquals( 761 Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK), 762 expectedPrebaked(VibrationEffect.EFFECT_HEAVY_CLICK), 763 expectedPrebaked(VibrationEffect.EFFECT_DOUBLE_CLICK)), 764 mVibratorProviders.get(1).getAllEffectSegments()); 765 } 766 767 @Test vibrate_withAudioAttributes_usesOriginalAudioUsageInAppOpsManager()768 public void vibrate_withAudioAttributes_usesOriginalAudioUsageInAppOpsManager() { 769 VibratorManagerService service = createSystemReadyService(); 770 771 VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK); 772 AudioAttributes audioAttributes = new AudioAttributes.Builder() 773 .setUsage(AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY).build(); 774 VibrationAttributes vibrationAttributes = 775 new VibrationAttributes.Builder(audioAttributes).build(); 776 777 vibrate(service, effect, vibrationAttributes); 778 779 verify(mAppOpsManagerMock).checkAudioOpNoThrow(eq(AppOpsManager.OP_VIBRATE), 780 eq(AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY), anyInt(), anyString()); 781 } 782 783 @Test vibrate_withVibrationAttributes_usesCorrespondingAudioUsageInAppOpsManager()784 public void vibrate_withVibrationAttributes_usesCorrespondingAudioUsageInAppOpsManager() { 785 VibratorManagerService service = createSystemReadyService(); 786 787 vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), ALARM_ATTRS); 788 vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_TICK), NOTIFICATION_ATTRS); 789 vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), RINGTONE_ATTRS); 790 vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_TICK), HAPTIC_FEEDBACK_ATTRS); 791 vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), 792 new VibrationAttributes.Builder().setUsage( 793 VibrationAttributes.USAGE_COMMUNICATION_REQUEST).build()); 794 vibrate(service, VibrationEffect.createOneShot(2000, 200), 795 new VibrationAttributes.Builder().setUsage( 796 VibrationAttributes.USAGE_UNKNOWN).build()); 797 798 InOrder inOrderVerifier = inOrder(mAppOpsManagerMock); 799 inOrderVerifier.verify(mAppOpsManagerMock).checkAudioOpNoThrow(eq(AppOpsManager.OP_VIBRATE), 800 eq(AudioAttributes.USAGE_ALARM), anyInt(), anyString()); 801 inOrderVerifier.verify(mAppOpsManagerMock).checkAudioOpNoThrow(eq(AppOpsManager.OP_VIBRATE), 802 eq(AudioAttributes.USAGE_NOTIFICATION), anyInt(), anyString()); 803 inOrderVerifier.verify(mAppOpsManagerMock).checkAudioOpNoThrow(eq(AppOpsManager.OP_VIBRATE), 804 eq(AudioAttributes.USAGE_NOTIFICATION_RINGTONE), anyInt(), anyString()); 805 inOrderVerifier.verify(mAppOpsManagerMock).checkAudioOpNoThrow(eq(AppOpsManager.OP_VIBRATE), 806 eq(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION), anyInt(), anyString()); 807 inOrderVerifier.verify(mAppOpsManagerMock).checkAudioOpNoThrow(eq(AppOpsManager.OP_VIBRATE), 808 eq(AudioAttributes.USAGE_VOICE_COMMUNICATION), 809 anyInt(), anyString()); 810 inOrderVerifier.verify(mAppOpsManagerMock).checkAudioOpNoThrow(eq(AppOpsManager.OP_VIBRATE), 811 eq(AudioAttributes.USAGE_UNKNOWN), anyInt(), anyString()); 812 } 813 814 @Test vibrate_withVibrationAttributesEnforceFreshSettings_refreshesVibrationSettings()815 public void vibrate_withVibrationAttributesEnforceFreshSettings_refreshesVibrationSettings() 816 throws Exception { 817 mockVibrators(0); 818 mVibratorProviders.get(0).setSupportedEffects(VibrationEffect.EFFECT_CLICK, 819 VibrationEffect.EFFECT_TICK); 820 setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY, 821 Vibrator.VIBRATION_INTENSITY_HIGH); 822 VibratorManagerService service = createSystemReadyService(); 823 824 VibrationAttributes notificationWithFreshAttrs = new VibrationAttributes.Builder() 825 .setUsage(VibrationAttributes.USAGE_NOTIFICATION) 826 .setFlags(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE) 827 .build(); 828 829 setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY, 830 Vibrator.VIBRATION_INTENSITY_LOW); 831 vibrateAndWaitUntilFinished(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), 832 NOTIFICATION_ATTRS); 833 vibrateAndWaitUntilFinished(service, VibrationEffect.get(VibrationEffect.EFFECT_TICK), 834 notificationWithFreshAttrs); 835 836 assertEquals( 837 Arrays.asList( 838 expectedPrebaked(VibrationEffect.EFFECT_CLICK, 839 VibrationEffect.EFFECT_STRENGTH_STRONG), 840 expectedPrebaked(VibrationEffect.EFFECT_TICK, 841 VibrationEffect.EFFECT_STRENGTH_LIGHT)), 842 mVibratorProviders.get(0).getAllEffectSegments()); 843 } 844 845 @Test vibrate_withAttributesUnknownUsage_usesEffectToIdentifyTouchUsage()846 public void vibrate_withAttributesUnknownUsage_usesEffectToIdentifyTouchUsage() { 847 VibratorManagerService service = createSystemReadyService(); 848 849 VibrationAttributes unknownAttributes = VibrationAttributes.createForUsage( 850 VibrationAttributes.USAGE_UNKNOWN); 851 vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), unknownAttributes); 852 vibrate(service, VibrationEffect.createOneShot(200, 200), unknownAttributes); 853 vibrate(service, VibrationEffect.createWaveform( 854 new long[] { 100, 200, 300 }, new int[] {1, 2, 3}, -1), unknownAttributes); 855 vibrate(service, 856 VibrationEffect.startComposition() 857 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_RISE) 858 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_FALL) 859 .compose(), 860 unknownAttributes); 861 862 verify(mAppOpsManagerMock, times(4)) 863 .checkAudioOpNoThrow(eq(AppOpsManager.OP_VIBRATE), 864 eq(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION), anyInt(), anyString()); 865 verify(mAppOpsManagerMock, never()) 866 .checkAudioOpNoThrow(eq(AppOpsManager.OP_VIBRATE), 867 eq(AudioAttributes.USAGE_UNKNOWN), anyInt(), anyString()); 868 } 869 870 @Test vibrate_withAttributesUnknownUsage_ignoresEffectIfNotHapticFeedbackCandidate()871 public void vibrate_withAttributesUnknownUsage_ignoresEffectIfNotHapticFeedbackCandidate() { 872 VibratorManagerService service = createSystemReadyService(); 873 874 VibrationAttributes unknownAttributes = VibrationAttributes.createForUsage( 875 VibrationAttributes.USAGE_UNKNOWN); 876 vibrate(service, VibrationEffect.get(VibrationEffect.RINGTONES[0]), unknownAttributes); 877 vibrate(service, VibrationEffect.createOneShot(2000, 200), unknownAttributes); 878 vibrate(service, VibrationEffect.createWaveform( 879 new long[] { 100, 200, 300 }, new int[] {1, 2, 3}, 0), unknownAttributes); 880 vibrate(service, 881 VibrationEffect.startComposition() 882 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_RISE) 883 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_FALL) 884 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_SPIN) 885 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_THUD) 886 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK) 887 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK) 888 .compose(), 889 unknownAttributes); 890 891 verify(mAppOpsManagerMock, never()) 892 .checkAudioOpNoThrow(eq(AppOpsManager.OP_VIBRATE), 893 eq(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION), anyInt(), anyString()); 894 verify(mAppOpsManagerMock, times(4)) 895 .checkAudioOpNoThrow(eq(AppOpsManager.OP_VIBRATE), 896 eq(AudioAttributes.USAGE_UNKNOWN), anyInt(), anyString()); 897 } 898 899 @Test vibrate_withOngoingRepeatingVibration_ignoresEffect()900 public void vibrate_withOngoingRepeatingVibration_ignoresEffect() throws Exception { 901 mockVibrators(1); 902 FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); 903 fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); 904 VibratorManagerService service = createSystemReadyService(); 905 906 VibrationEffect repeatingEffect = VibrationEffect.createWaveform( 907 new long[]{10, 10_000}, new int[]{128, 255}, 1); 908 vibrate(service, repeatingEffect, 909 new VibrationAttributes.Builder() 910 .setUsage(VibrationAttributes.USAGE_UNKNOWN) 911 .build()); 912 913 // VibrationThread will start this vibration async. 914 // Wait until second step started to ensure the noteVibratorOn was triggered. 915 assertTrue(waitUntil(s -> fakeVibrator.getAmplitudes().size() == 2, service, 916 TEST_TIMEOUT_MILLIS)); 917 918 vibrateAndWaitUntilFinished(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), 919 HAPTIC_FEEDBACK_ATTRS); 920 921 // The time estimate is recorded when the vibration starts, repeating vibrations 922 // are capped at BATTERY_STATS_REPEATING_VIBRATION_DURATION (=5000). 923 verify(mBatteryStatsMock).noteVibratorOn(UID, 5000); 924 // The second vibration shouldn't have recorded that the vibrators were turned on. 925 verify(mBatteryStatsMock, times(1)).noteVibratorOn(anyInt(), anyLong()); 926 // No segment played is the prebaked CLICK from the second vibration. 927 assertFalse(fakeVibrator.getAllEffectSegments().stream() 928 .anyMatch(PrebakedSegment.class::isInstance)); 929 } 930 931 @Test vibrate_withOngoingRepeatingVibrationBeingCancelled_playsAfterPreviousIsCancelled()932 public void vibrate_withOngoingRepeatingVibrationBeingCancelled_playsAfterPreviousIsCancelled() 933 throws Exception { 934 mockVibrators(1); 935 FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); 936 fakeVibrator.setOffLatency(50); // Add latency so cancellation is slow. 937 fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); 938 fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK); 939 VibratorManagerService service = createSystemReadyService(); 940 941 VibrationEffect repeatingEffect = VibrationEffect.createWaveform( 942 new long[]{10, 10_000}, new int[]{128, 255}, 1); 943 vibrate(service, repeatingEffect, ALARM_ATTRS); 944 945 // VibrationThread will start this vibration async. 946 // Wait until second step started to ensure the noteVibratorOn was triggered. 947 assertTrue(waitUntil(s -> fakeVibrator.getAmplitudes().size() == 2, service, 948 TEST_TIMEOUT_MILLIS)); 949 950 // Cancel vibration right before requesting a new one. 951 // This should trigger slow IVibrator.off before setting the vibration status to cancelled. 952 cancelVibrate(service); 953 vibrateAndWaitUntilFinished(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), 954 ALARM_ATTRS); 955 956 // The second vibration should have recorded that the vibrators were turned on. 957 verify(mBatteryStatsMock, times(2)).noteVibratorOn(anyInt(), anyLong()); 958 // Check that second vibration was played. 959 assertTrue(fakeVibrator.getAllEffectSegments().stream() 960 .anyMatch(PrebakedSegment.class::isInstance)); 961 } 962 963 @Test vibrate_withNewSameImportanceVibrationAndBothRepeating_cancelsOngoingEffect()964 public void vibrate_withNewSameImportanceVibrationAndBothRepeating_cancelsOngoingEffect() 965 throws Exception { 966 mockVibrators(1); 967 FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); 968 fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); 969 VibratorManagerService service = createSystemReadyService(); 970 971 VibrationEffect repeatingEffect = VibrationEffect.createWaveform( 972 new long[]{10, 10_000}, new int[]{128, 255}, 1); 973 vibrate(service, repeatingEffect, ALARM_ATTRS); 974 975 // VibrationThread will start this vibration async. 976 // Wait until second step started to ensure the noteVibratorOn was triggered. 977 assertTrue(waitUntil(s -> fakeVibrator.getAmplitudes().size() == 2, service, 978 TEST_TIMEOUT_MILLIS)); 979 980 VibrationEffect repeatingEffect2 = VibrationEffect.createWaveform( 981 new long[]{10, 10_000}, new int[]{255, 128}, 1); 982 vibrate(service, repeatingEffect2, ALARM_ATTRS); 983 984 // VibrationThread will start this vibration async. 985 // Wait until second step started to ensure the noteVibratorOn was triggered. 986 assertTrue(waitUntil(s -> fakeVibrator.getAmplitudes().size() == 4, service, 987 TEST_TIMEOUT_MILLIS)); 988 989 // The second vibration should have recorded that the vibrators were turned on. 990 verify(mBatteryStatsMock, times(2)).noteVibratorOn(anyInt(), anyLong()); 991 } 992 993 @Test vibrate_withNewSameImportanceVibrationButOngoingIsRepeating_ignoreNewVibration()994 public void vibrate_withNewSameImportanceVibrationButOngoingIsRepeating_ignoreNewVibration() 995 throws Exception { 996 mockVibrators(1); 997 FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); 998 fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); 999 VibratorManagerService service = createSystemReadyService(); 1000 1001 VibrationEffect repeatingEffect = VibrationEffect.createWaveform( 1002 new long[]{10, 10_000}, new int[]{128, 255}, 1); 1003 vibrate(service, repeatingEffect, ALARM_ATTRS); 1004 1005 // VibrationThread will start this vibration async. 1006 // Wait until second step started to ensure the noteVibratorOn was triggered. 1007 assertTrue(waitUntil(s -> fakeVibrator.getAmplitudes().size() == 2, service, 1008 TEST_TIMEOUT_MILLIS)); 1009 1010 vibrateAndWaitUntilFinished(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), 1011 ALARM_ATTRS); 1012 1013 // The second vibration shouldn't have recorded that the vibrators were turned on. 1014 verify(mBatteryStatsMock, times(1)).noteVibratorOn(anyInt(), anyLong()); 1015 // The second vibration shouldn't have played any prebaked segment. 1016 assertFalse(fakeVibrator.getAllEffectSegments().stream() 1017 .anyMatch(PrebakedSegment.class::isInstance)); 1018 } 1019 1020 @Test vibrate_withNewUnknownUsageVibrationAndRepeating_cancelsOngoingEffect()1021 public void vibrate_withNewUnknownUsageVibrationAndRepeating_cancelsOngoingEffect() 1022 throws Exception { 1023 mockVibrators(1); 1024 FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); 1025 fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); 1026 VibratorManagerService service = createSystemReadyService(); 1027 1028 VibrationEffect repeatingEffect = VibrationEffect.createWaveform( 1029 new long[]{10, 10_000}, new int[]{128, 255}, 1); 1030 vibrate(service, repeatingEffect, ALARM_ATTRS); 1031 1032 // VibrationThread will start this vibration async. 1033 // Wait until second step started to ensure the noteVibratorOn was triggered. 1034 assertTrue(waitUntil(s -> fakeVibrator.getAmplitudes().size() == 2, service, 1035 TEST_TIMEOUT_MILLIS)); 1036 1037 VibrationEffect repeatingEffect2 = VibrationEffect.createWaveform( 1038 new long[]{10, 10_000}, new int[]{255, 128}, 1); 1039 vibrate(service, repeatingEffect2, UNKNOWN_ATTRS); 1040 1041 // VibrationThread will start this vibration async. 1042 // Wait until second step started to ensure the noteVibratorOn was triggered. 1043 assertTrue(waitUntil(s -> fakeVibrator.getAmplitudes().size() == 4, service, 1044 TEST_TIMEOUT_MILLIS)); 1045 1046 // The second vibration should have recorded that the vibrators were turned on. 1047 verify(mBatteryStatsMock, times(2)).noteVibratorOn(anyInt(), anyLong()); 1048 } 1049 1050 @Test vibrate_withNewUnknownUsageVibrationAndNotRepeating_ignoreNewVibration()1051 public void vibrate_withNewUnknownUsageVibrationAndNotRepeating_ignoreNewVibration() 1052 throws Exception { 1053 mockVibrators(1); 1054 FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); 1055 fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); 1056 VibratorManagerService service = createSystemReadyService(); 1057 1058 VibrationEffect alarmEffect = VibrationEffect.createWaveform( 1059 new long[]{10, 10_000}, new int[]{128, 255}, -1); 1060 vibrate(service, alarmEffect, ALARM_ATTRS); 1061 1062 // VibrationThread will start this vibration async. 1063 // Wait until second step started to ensure the noteVibratorOn was triggered. 1064 assertTrue(waitUntil(s -> fakeVibrator.getAmplitudes().size() == 2, service, 1065 TEST_TIMEOUT_MILLIS)); 1066 1067 vibrateAndWaitUntilFinished(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), 1068 UNKNOWN_ATTRS); 1069 1070 // The second vibration shouldn't have recorded that the vibrators were turned on. 1071 verify(mBatteryStatsMock, times(1)).noteVibratorOn(anyInt(), anyLong()); 1072 // The second vibration shouldn't have played any prebaked segment. 1073 assertFalse(fakeVibrator.getAllEffectSegments().stream() 1074 .anyMatch(PrebakedSegment.class::isInstance)); 1075 } 1076 1077 @Test vibrate_withOngoingHigherImportanceVibration_ignoresEffect()1078 public void vibrate_withOngoingHigherImportanceVibration_ignoresEffect() throws Exception { 1079 mockVibrators(1); 1080 FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); 1081 fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); 1082 VibratorManagerService service = createSystemReadyService(); 1083 1084 VibrationEffect effect = VibrationEffect.createWaveform( 1085 new long[]{10, 10_000}, new int[]{128, 255}, -1); 1086 vibrate(service, effect, ALARM_ATTRS); 1087 1088 // VibrationThread will start this vibration async. 1089 // Wait until second step started to ensure the noteVibratorOn was triggered. 1090 assertTrue(waitUntil(s -> fakeVibrator.getAmplitudes().size() == 2, 1091 service, TEST_TIMEOUT_MILLIS)); 1092 1093 vibrateAndWaitUntilFinished(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), 1094 HAPTIC_FEEDBACK_ATTRS); 1095 1096 // The second vibration shouldn't have recorded that the vibrators were turned on. 1097 verify(mBatteryStatsMock, times(1)).noteVibratorOn(anyInt(), anyLong()); 1098 // The second vibration shouldn't have played any prebaked segment. 1099 assertFalse(fakeVibrator.getAllEffectSegments().stream() 1100 .anyMatch(PrebakedSegment.class::isInstance)); 1101 } 1102 1103 @Test vibrate_withOngoingLowerImportanceVibration_cancelsOngoingEffect()1104 public void vibrate_withOngoingLowerImportanceVibration_cancelsOngoingEffect() 1105 throws Exception { 1106 mockVibrators(1); 1107 FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); 1108 fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); 1109 fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK); 1110 VibratorManagerService service = createSystemReadyService(); 1111 1112 VibrationEffect effect = VibrationEffect.createWaveform( 1113 new long[]{10, 10_000}, new int[]{128, 255}, -1); 1114 vibrate(service, effect, HAPTIC_FEEDBACK_ATTRS); 1115 1116 // VibrationThread will start this vibration async. 1117 // Wait until second step started to ensure the noteVibratorOn was triggered. 1118 assertTrue(waitUntil(s -> fakeVibrator.getAmplitudes().size() == 2, service, 1119 TEST_TIMEOUT_MILLIS)); 1120 1121 vibrateAndWaitUntilFinished(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), 1122 RINGTONE_ATTRS); 1123 1124 // The second vibration should have recorded that the vibrators were turned on. 1125 verify(mBatteryStatsMock, times(2)).noteVibratorOn(anyInt(), anyLong()); 1126 // One segment played is the prebaked CLICK from the second vibration. 1127 assertEquals(1, fakeVibrator.getAllEffectSegments().stream() 1128 .filter(PrebakedSegment.class::isInstance).count()); 1129 } 1130 1131 @Test vibrate_withOngoingLowerImportanceExternalVibration_cancelsOngoingVibration()1132 public void vibrate_withOngoingLowerImportanceExternalVibration_cancelsOngoingVibration() 1133 throws Exception { 1134 mockVibrators(1); 1135 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL); 1136 mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK); 1137 setRingerMode(AudioManager.RINGER_MODE_NORMAL); 1138 VibratorManagerService service = createSystemReadyService(); 1139 1140 IBinder firstToken = mock(IBinder.class); 1141 IExternalVibrationController controller = mock(IExternalVibrationController.class); 1142 ExternalVibration externalVibration = new ExternalVibration(UID, PACKAGE_NAME, 1143 AUDIO_ALARM_ATTRS, 1144 controller, firstToken); 1145 ExternalVibrationScale scale = 1146 mExternalVibratorService.onExternalVibrationStart(externalVibration); 1147 1148 vibrateAndWaitUntilFinished(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), 1149 RINGTONE_ATTRS); 1150 1151 assertNotEquals(ExternalVibrationScale.ScaleLevel.SCALE_MUTE, scale.scaleLevel); 1152 // The external vibration should have been cancelled 1153 verify(controller).mute(); 1154 assertEquals(Arrays.asList(false, true, false), 1155 mVibratorProviders.get(1).getExternalControlStates()); 1156 // The new vibration should have recorded that the vibrators were turned on. 1157 verify(mBatteryStatsMock, times(1)).noteVibratorOn(anyInt(), anyLong()); 1158 // One segment played is the prebaked CLICK from the new vibration. 1159 assertEquals(1, mVibratorProviders.get(1).getAllEffectSegments().stream() 1160 .filter(PrebakedSegment.class::isInstance).count()); 1161 } 1162 1163 @Test vibrate_withOngoingSameImportancePipelinedVibration_continuesOngoingEffect()1164 public void vibrate_withOngoingSameImportancePipelinedVibration_continuesOngoingEffect() 1165 throws Exception { 1166 VibrationAttributes pipelineAttrs = new VibrationAttributes.Builder(HAPTIC_FEEDBACK_ATTRS) 1167 .setFlags(VibrationAttributes.FLAG_PIPELINED_EFFECT) 1168 .build(); 1169 1170 mockVibrators(1); 1171 FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); 1172 fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); 1173 fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK); 1174 VibratorManagerService service = createSystemReadyService(); 1175 1176 VibrationEffect effect = VibrationEffect.createWaveform( 1177 new long[]{100, 100}, new int[]{128, 255}, -1); 1178 vibrate(service, effect, pipelineAttrs); 1179 // This vibration will be enqueued, but evicted by the EFFECT_CLICK. 1180 vibrate(service, VibrationEffect.startComposition() 1181 .addOffDuration(Duration.ofSeconds(10)) 1182 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_SLOW_RISE) 1183 .compose(), pipelineAttrs); // This will queue and be evicted for the click. 1184 1185 vibrateAndWaitUntilFinished(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), 1186 pipelineAttrs); 1187 1188 // The second vibration should have recorded that the vibrators were turned on. 1189 verify(mBatteryStatsMock, times(2)).noteVibratorOn(anyInt(), anyLong()); 1190 // One step segment (with several amplitudes) and one click should have played. Notably 1191 // there is no primitive segment. 1192 List<VibrationEffectSegment> played = fakeVibrator.getAllEffectSegments(); 1193 assertEquals(2, played.size()); 1194 assertEquals(1, played.stream().filter(StepSegment.class::isInstance).count()); 1195 assertEquals(1, played.stream().filter(PrebakedSegment.class::isInstance).count()); 1196 } 1197 1198 @Test vibrate_withInputDevices_vibratesInputDevices()1199 public void vibrate_withInputDevices_vibratesInputDevices() throws Exception { 1200 mockVibrators(1); 1201 FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); 1202 fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); 1203 fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK); 1204 when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1}); 1205 when(mIInputManagerMock.getVibratorIds(eq(1))).thenReturn(new int[]{1}); 1206 when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1)); 1207 setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1); 1208 // Mock alarm intensity equals to default value to avoid scaling in this test. 1209 setUserSetting(Settings.System.ALARM_VIBRATION_INTENSITY, 1210 mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_ALARM)); 1211 VibratorManagerService service = createSystemReadyService(); 1212 1213 CombinedVibration effect = CombinedVibration.createParallel( 1214 VibrationEffect.createOneShot(10, 10)); 1215 vibrateAndWaitUntilFinished(service, effect, ALARM_ATTRS); 1216 1217 verify(mIInputManagerMock).vibrateCombined(eq(1), eq(effect), any()); 1218 assertTrue(fakeVibrator.getAllEffectSegments().isEmpty()); 1219 } 1220 1221 @Test vibrate_withNativeCallbackTriggered_finishesVibration()1222 public void vibrate_withNativeCallbackTriggered_finishesVibration() throws Exception { 1223 mockVibrators(1); 1224 mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK); 1225 VibratorManagerService service = createSystemReadyService(); 1226 // The native callback will be dispatched manually in this test. 1227 mTestLooper.stopAutoDispatchAndIgnoreExceptions(); 1228 1229 vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), ALARM_ATTRS); 1230 1231 // VibrationThread will start this vibration async, so wait before triggering callbacks. 1232 assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 1233 1234 // Trigger callbacks from controller. 1235 mTestLooper.moveTimeForward(50); 1236 mTestLooper.dispatchAll(); 1237 1238 // VibrationThread needs some time to react to native callbacks and stop the vibrator. 1239 assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 1240 } 1241 1242 @Test vibrate_withriggerCallback_finishesVibration()1243 public void vibrate_withriggerCallback_finishesVibration() throws Exception { 1244 mockCapabilities(IVibratorManager.CAP_SYNC, IVibratorManager.CAP_PREPARE_COMPOSE); 1245 mockVibrators(1, 2); 1246 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); 1247 mVibratorProviders.get(1).setSupportedPrimitives( 1248 VibrationEffect.Composition.PRIMITIVE_CLICK); 1249 mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); 1250 mVibratorProviders.get(2).setSupportedPrimitives( 1251 VibrationEffect.Composition.PRIMITIVE_CLICK); 1252 // Mock alarm intensity equals to default value to avoid scaling in this test. 1253 setUserSetting(Settings.System.ALARM_VIBRATION_INTENSITY, 1254 mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_ALARM)); 1255 VibratorManagerService service = createSystemReadyService(); 1256 // The native callback will be dispatched manually in this test. 1257 mTestLooper.stopAutoDispatchAndIgnoreExceptions(); 1258 1259 ArgumentCaptor<VibratorManagerService.OnSyncedVibrationCompleteListener> listenerCaptor = 1260 ArgumentCaptor.forClass( 1261 VibratorManagerService.OnSyncedVibrationCompleteListener.class); 1262 verify(mNativeWrapperMock).init(listenerCaptor.capture()); 1263 1264 CountDownLatch triggerCountDown = new CountDownLatch(1); 1265 // Mock trigger callback on registered listener right after the synced vibration starts. 1266 when(mNativeWrapperMock.prepareSynced(eq(new int[]{1, 2}))).thenReturn(true); 1267 when(mNativeWrapperMock.triggerSynced(anyLong())).then(answer -> { 1268 listenerCaptor.getValue().onComplete(answer.getArgument(0)); 1269 triggerCountDown.countDown(); 1270 return true; 1271 }); 1272 1273 VibrationEffect composed = VibrationEffect.startComposition() 1274 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 100) 1275 .compose(); 1276 CombinedVibration effect = CombinedVibration.createParallel(composed); 1277 1278 vibrate(service, effect, ALARM_ATTRS); 1279 // VibrationThread will start this vibration async, so wait until vibration is triggered. 1280 triggerCountDown.await(TEST_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); 1281 1282 verify(mNativeWrapperMock).prepareSynced(eq(new int[]{1, 2})); 1283 verify(mNativeWrapperMock).triggerSynced(anyLong()); 1284 PrimitiveSegment expected = new PrimitiveSegment( 1285 VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 100); 1286 assertEquals(Arrays.asList(expected), mVibratorProviders.get(1).getAllEffectSegments()); 1287 assertEquals(Arrays.asList(expected), mVibratorProviders.get(2).getAllEffectSegments()); 1288 1289 // VibrationThread needs some time to react to native callbacks and stop the vibrator. 1290 assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 1291 } 1292 1293 @Test vibrate_withMultipleVibratorsAndCapabilities_prepareAndTriggerCalled()1294 public void vibrate_withMultipleVibratorsAndCapabilities_prepareAndTriggerCalled() 1295 throws Exception { 1296 mockCapabilities(IVibratorManager.CAP_SYNC, IVibratorManager.CAP_PREPARE_PERFORM, 1297 IVibratorManager.CAP_PREPARE_COMPOSE, IVibratorManager.CAP_MIXED_TRIGGER_PERFORM, 1298 IVibratorManager.CAP_MIXED_TRIGGER_COMPOSE); 1299 mockVibrators(1, 2); 1300 when(mNativeWrapperMock.prepareSynced(eq(new int[]{1, 2}))).thenReturn(true); 1301 when(mNativeWrapperMock.triggerSynced(anyLong())).thenReturn(true); 1302 FakeVibratorControllerProvider fakeVibrator1 = mVibratorProviders.get(1); 1303 fakeVibrator1.setSupportedEffects(VibrationEffect.EFFECT_CLICK); 1304 mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); 1305 VibratorManagerService service = createSystemReadyService(); 1306 1307 CombinedVibration effect = CombinedVibration.startParallel() 1308 .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK)) 1309 .addVibrator(2, VibrationEffect.startComposition() 1310 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK) 1311 .compose()) 1312 .combine(); 1313 vibrateAndWaitUntilFinished(service, effect, ALARM_ATTRS); 1314 1315 verify(mNativeWrapperMock).prepareSynced(eq(new int[]{1, 2})); 1316 verify(mNativeWrapperMock).triggerSynced(anyLong()); 1317 verify(mNativeWrapperMock).cancelSynced(); // Trigger on service creation only. 1318 } 1319 1320 @Test vibrate_withMultipleVibratorsWithoutCapabilities_skipPrepareAndTrigger()1321 public void vibrate_withMultipleVibratorsWithoutCapabilities_skipPrepareAndTrigger() 1322 throws Exception { 1323 // Missing CAP_MIXED_TRIGGER_ON and CAP_MIXED_TRIGGER_PERFORM. 1324 mockCapabilities(IVibratorManager.CAP_SYNC, IVibratorManager.CAP_PREPARE_ON, 1325 IVibratorManager.CAP_PREPARE_PERFORM); 1326 mockVibrators(1, 2); 1327 FakeVibratorControllerProvider fakeVibrator1 = mVibratorProviders.get(1); 1328 fakeVibrator1.setSupportedEffects(VibrationEffect.EFFECT_CLICK); 1329 VibratorManagerService service = createSystemReadyService(); 1330 1331 CombinedVibration effect = CombinedVibration.startParallel() 1332 .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK)) 1333 .addVibrator(2, VibrationEffect.createOneShot(10, 100)) 1334 .combine(); 1335 vibrateAndWaitUntilFinished(service, effect, ALARM_ATTRS); 1336 1337 verify(mNativeWrapperMock, never()).prepareSynced(any()); 1338 verify(mNativeWrapperMock, never()).triggerSynced(anyLong()); 1339 verify(mNativeWrapperMock).cancelSynced(); // Trigger on service creation only. 1340 } 1341 1342 @Test vibrate_withMultipleVibratorsPrepareFailed_skipTrigger()1343 public void vibrate_withMultipleVibratorsPrepareFailed_skipTrigger() throws Exception { 1344 mockCapabilities(IVibratorManager.CAP_SYNC, IVibratorManager.CAP_PREPARE_ON); 1345 mockVibrators(1, 2); 1346 when(mNativeWrapperMock.prepareSynced(any())).thenReturn(false); 1347 VibratorManagerService service = createSystemReadyService(); 1348 1349 CombinedVibration effect = CombinedVibration.startParallel() 1350 .addVibrator(1, VibrationEffect.createOneShot(10, 50)) 1351 .addVibrator(2, VibrationEffect.createOneShot(10, 100)) 1352 .combine(); 1353 vibrateAndWaitUntilFinished(service, effect, ALARM_ATTRS); 1354 1355 verify(mNativeWrapperMock).prepareSynced(eq(new int[]{1, 2})); 1356 verify(mNativeWrapperMock, never()).triggerSynced(anyLong()); 1357 verify(mNativeWrapperMock).cancelSynced(); // Trigger on service creation only. 1358 } 1359 1360 @Test vibrate_withMultipleVibratorsTriggerFailed_cancelPreparedSynced()1361 public void vibrate_withMultipleVibratorsTriggerFailed_cancelPreparedSynced() throws Exception { 1362 mockCapabilities(IVibratorManager.CAP_SYNC, IVibratorManager.CAP_PREPARE_ON); 1363 mockVibrators(1, 2); 1364 when(mNativeWrapperMock.prepareSynced(eq(new int[]{1, 2}))).thenReturn(true); 1365 when(mNativeWrapperMock.triggerSynced(anyLong())).thenReturn(false); 1366 VibratorManagerService service = createSystemReadyService(); 1367 1368 CombinedVibration effect = CombinedVibration.startParallel() 1369 .addVibrator(1, VibrationEffect.createOneShot(10, 50)) 1370 .addVibrator(2, VibrationEffect.createOneShot(10, 100)) 1371 .combine(); 1372 vibrateAndWaitUntilFinished(service, effect, ALARM_ATTRS); 1373 1374 verify(mNativeWrapperMock).prepareSynced(eq(new int[]{1, 2})); 1375 verify(mNativeWrapperMock).triggerSynced(anyLong()); 1376 verify(mNativeWrapperMock, times(2)).cancelSynced(); // Trigger on service creation too. 1377 } 1378 1379 @Test performHapticFeedback_doesNotRequireVibrateOrBypassPermissions()1380 public void performHapticFeedback_doesNotRequireVibrateOrBypassPermissions() throws Exception { 1381 // Deny permissions that would have been required for regular vibrations, and check that 1382 // the vibration proceed as expected to verify that haptic feedback does not need these 1383 // permissions. 1384 denyPermission(android.Manifest.permission.VIBRATE); 1385 denyPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS); 1386 denyPermission(android.Manifest.permission.MODIFY_PHONE_STATE); 1387 denyPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING); 1388 // Flag override to enable the scroll feedack constants to bypass interruption policies. 1389 mSetFlagsRule.enableFlags(Flags.FLAG_SCROLL_FEEDBACK_API); 1390 mHapticFeedbackVibrationMap.put( 1391 HapticFeedbackConstants.SCROLL_TICK, 1392 VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)); 1393 mockVibrators(1); 1394 FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); 1395 fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK); 1396 VibratorManagerService service = createSystemReadyService(); 1397 1398 HalVibration vibration = 1399 performHapticFeedbackAndWaitUntilFinished( 1400 service, HapticFeedbackConstants.SCROLL_TICK, /* always= */ true); 1401 1402 List<VibrationEffectSegment> playedSegments = fakeVibrator.getAllEffectSegments(); 1403 assertEquals(1, playedSegments.size()); 1404 PrebakedSegment segment = (PrebakedSegment) playedSegments.get(0); 1405 assertEquals(VibrationEffect.EFFECT_CLICK, segment.getEffectId()); 1406 VibrationAttributes attrs = vibration.callerInfo.attrs; 1407 assertEquals(VibrationAttributes.USAGE_HARDWARE_FEEDBACK, attrs.getUsage()); 1408 assertTrue(attrs.isFlagSet(VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)); 1409 assertTrue(attrs.isFlagSet(VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY)); 1410 } 1411 1412 @Test performHapticFeedback_restrictedConstantsWithoutPermission_doesNotVibrate()1413 public void performHapticFeedback_restrictedConstantsWithoutPermission_doesNotVibrate() 1414 throws Exception { 1415 // Deny permission to vibrate with restricted constants 1416 denyPermission(android.Manifest.permission.VIBRATE_SYSTEM_CONSTANTS); 1417 // Public constant, no permission required 1418 mHapticFeedbackVibrationMap.put( 1419 HapticFeedbackConstants.CONFIRM, 1420 VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)); 1421 // Hidden system-only constant, permission required 1422 mHapticFeedbackVibrationMap.put( 1423 HapticFeedbackConstants.BIOMETRIC_CONFIRM, 1424 VibrationEffect.createPredefined(VibrationEffect.EFFECT_HEAVY_CLICK)); 1425 mockVibrators(1); 1426 FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); 1427 fakeVibrator.setSupportedEffects( 1428 VibrationEffect.EFFECT_CLICK, VibrationEffect.EFFECT_HEAVY_CLICK); 1429 VibratorManagerService service = createSystemReadyService(); 1430 1431 performHapticFeedbackAndWaitUntilFinished( 1432 service, HapticFeedbackConstants.CONFIRM, /* always= */ false); 1433 1434 performHapticFeedbackAndWaitUntilFinished( 1435 service, HapticFeedbackConstants.BIOMETRIC_CONFIRM, /* always= */ false); 1436 1437 List<VibrationEffectSegment> playedSegments = fakeVibrator.getAllEffectSegments(); 1438 assertEquals(1, playedSegments.size()); 1439 PrebakedSegment segment = (PrebakedSegment) playedSegments.get(0); 1440 assertEquals(VibrationEffect.EFFECT_CLICK, segment.getEffectId()); 1441 } 1442 1443 @Test performHapticFeedback_restrictedConstantsWithPermission_playsVibration()1444 public void performHapticFeedback_restrictedConstantsWithPermission_playsVibration() 1445 throws Exception { 1446 // Grant permission to vibrate with restricted constants 1447 grantPermission(android.Manifest.permission.VIBRATE_SYSTEM_CONSTANTS); 1448 // Public constant, no permission required 1449 mHapticFeedbackVibrationMap.put( 1450 HapticFeedbackConstants.CONFIRM, 1451 VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)); 1452 // Hidden system-only constant, permission required 1453 mHapticFeedbackVibrationMap.put( 1454 HapticFeedbackConstants.BIOMETRIC_CONFIRM, 1455 VibrationEffect.createPredefined(VibrationEffect.EFFECT_HEAVY_CLICK)); 1456 mockVibrators(1); 1457 FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); 1458 fakeVibrator.setSupportedEffects( 1459 VibrationEffect.EFFECT_CLICK, VibrationEffect.EFFECT_HEAVY_CLICK); 1460 VibratorManagerService service = createSystemReadyService(); 1461 1462 performHapticFeedbackAndWaitUntilFinished( 1463 service, HapticFeedbackConstants.CONFIRM, /* always= */ false); 1464 1465 performHapticFeedbackAndWaitUntilFinished( 1466 service, HapticFeedbackConstants.BIOMETRIC_CONFIRM, /* always= */ false); 1467 1468 List<VibrationEffectSegment> playedSegments = fakeVibrator.getAllEffectSegments(); 1469 assertEquals(2, playedSegments.size()); 1470 assertEquals(VibrationEffect.EFFECT_CLICK, 1471 ((PrebakedSegment) playedSegments.get(0)).getEffectId()); 1472 assertEquals(VibrationEffect.EFFECT_HEAVY_CLICK, 1473 ((PrebakedSegment) playedSegments.get(1)).getEffectId()); 1474 } 1475 1476 @Test performHapticFeedback_doesNotVibrateWhenVibratorInfoNotReady()1477 public void performHapticFeedback_doesNotVibrateWhenVibratorInfoNotReady() throws Exception { 1478 denyPermission(android.Manifest.permission.VIBRATE); 1479 mHapticFeedbackVibrationMap.put( 1480 HapticFeedbackConstants.KEYBOARD_TAP, 1481 VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)); 1482 mockVibrators(1); 1483 FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); 1484 fakeVibrator.setVibratorInfoLoadSuccessful(false); 1485 fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK); 1486 VibratorManagerService service = createService(); 1487 1488 performHapticFeedbackAndWaitUntilFinished( 1489 service, HapticFeedbackConstants.KEYBOARD_TAP, /* always= */ true); 1490 1491 assertTrue(fakeVibrator.getAllEffectSegments().isEmpty()); 1492 } 1493 1494 @Test performHapticFeedback_doesNotVibrateForInvalidConstant()1495 public void performHapticFeedback_doesNotVibrateForInvalidConstant() throws Exception { 1496 denyPermission(android.Manifest.permission.VIBRATE); 1497 mockVibrators(1); 1498 VibratorManagerService service = createSystemReadyService(); 1499 1500 // These are bad haptic feedback IDs, so expect no vibration played. 1501 performHapticFeedbackAndWaitUntilFinished(service, /* constant= */ -1, /* always= */ false); 1502 performHapticFeedbackAndWaitUntilFinished( 1503 service, HapticFeedbackConstants.NO_HAPTICS, /* always= */ true); 1504 1505 assertTrue(mVibratorProviders.get(1).getAllEffectSegments().isEmpty()); 1506 } 1507 1508 @Test performHapticFeedback_usesServiceAsToken()1509 public void performHapticFeedback_usesServiceAsToken() throws Exception { 1510 VibratorManagerService service = createSystemReadyService(); 1511 1512 HalVibration vibration = 1513 performHapticFeedbackAndWaitUntilFinished( 1514 service, HapticFeedbackConstants.SCROLL_TICK, /* always= */ true); 1515 1516 assertTrue(vibration.callerToken == service); 1517 } 1518 1519 @Test vibrate_withIntensitySettings_appliesSettingsToScaleVibrations()1520 public void vibrate_withIntensitySettings_appliesSettingsToScaleVibrations() throws Exception { 1521 int defaultNotificationIntensity = 1522 mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_NOTIFICATION); 1523 // This will scale up notification vibrations. 1524 setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY, 1525 defaultNotificationIntensity < Vibrator.VIBRATION_INTENSITY_HIGH 1526 ? defaultNotificationIntensity + 1 1527 : defaultNotificationIntensity); 1528 1529 int defaultTouchIntensity = 1530 mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH); 1531 // This will scale down touch vibrations. 1532 setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, 1533 defaultTouchIntensity > Vibrator.VIBRATION_INTENSITY_LOW 1534 ? defaultTouchIntensity - 1 1535 : defaultTouchIntensity); 1536 1537 setUserSetting(Settings.System.ALARM_VIBRATION_INTENSITY, 1538 mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_ALARM)); 1539 setUserSetting(Settings.System.MEDIA_VIBRATION_INTENSITY, 1540 Vibrator.VIBRATION_INTENSITY_HIGH); 1541 setUserSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF); 1542 1543 mockVibrators(1); 1544 FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); 1545 fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL, 1546 IVibrator.CAP_COMPOSE_EFFECTS); 1547 fakeVibrator.setSupportedPrimitives(VibrationEffect.Composition.PRIMITIVE_CLICK, 1548 VibrationEffect.Composition.PRIMITIVE_TICK); 1549 VibratorManagerService service = createSystemReadyService(); 1550 1551 vibrateAndWaitUntilFinished(service, VibrationEffect.startComposition() 1552 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f) 1553 .compose(), HAPTIC_FEEDBACK_ATTRS); 1554 1555 vibrateAndWaitUntilFinished(service, CombinedVibration.startSequential() 1556 .addNext(1, VibrationEffect.createOneShot(100, 125)) 1557 .combine(), NOTIFICATION_ATTRS); 1558 1559 vibrateAndWaitUntilFinished(service, VibrationEffect.startComposition() 1560 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f) 1561 .compose(), ALARM_ATTRS); 1562 1563 // Ring vibrations have intensity OFF and are not played. 1564 vibrateAndWaitUntilFinished(service, VibrationEffect.createOneShot(100, 125), 1565 RINGTONE_ATTRS); 1566 1567 // Only 3 effects played successfully. 1568 assertEquals(3, fakeVibrator.getAllEffectSegments().size()); 1569 1570 // Haptic feedback vibrations will be scaled with SCALE_LOW or none if default is low. 1571 assertEquals(defaultTouchIntensity > Vibrator.VIBRATION_INTENSITY_LOW, 1572 0.5 > ((PrimitiveSegment) fakeVibrator.getAllEffectSegments().get(0)).getScale()); 1573 1574 // Notification vibrations will be scaled with SCALE_HIGH or none if default is high. 1575 assertEquals(defaultNotificationIntensity < Vibrator.VIBRATION_INTENSITY_HIGH, 1576 0.6 < fakeVibrator.getAmplitudes().get(0)); 1577 1578 // Alarm vibration will be scaled with SCALE_NONE. 1579 assertEquals(1f, 1580 ((PrimitiveSegment) fakeVibrator.getAllEffectSegments().get(2)).getScale(), 1e-5); 1581 } 1582 1583 @Test 1584 public void vibrate_withBypassScaleFlag_ignoresIntensitySettingsAndResolvesAmplitude() 1585 throws Exception { 1586 // Permission needed for bypassing user settings 1587 grantPermission(android.Manifest.permission.MODIFY_PHONE_STATE); 1588 1589 int defaultTouchIntensity = 1590 mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH); 1591 // This will scale down touch vibrations. 1592 setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, 1593 defaultTouchIntensity > Vibrator.VIBRATION_INTENSITY_LOW 1594 ? defaultTouchIntensity - 1 1595 : defaultTouchIntensity); 1596 1597 int defaultAmplitude = mContextSpy.getResources().getInteger( 1598 com.android.internal.R.integer.config_defaultVibrationAmplitude); 1599 1600 mockVibrators(1); 1601 FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); 1602 fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); 1603 VibratorManagerService service = createSystemReadyService(); 1604 1605 vibrateAndWaitUntilFinished(service, 1606 VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE), 1607 new VibrationAttributes.Builder() 1608 .setUsage(VibrationAttributes.USAGE_TOUCH) 1609 .setFlags(VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE) 1610 .build()); 1611 1612 assertEquals(1, fakeVibrator.getAllEffectSegments().size()); 1613 1614 assertEquals(defaultAmplitude / 255f, fakeVibrator.getAmplitudes().get(0), 1e-5); 1615 } 1616 1617 @Test 1618 @RequiresFlagsEnabled(android.os.vibrator.Flags.FLAG_ADAPTIVE_HAPTICS_ENABLED) 1619 public void vibrate_withAdaptiveHaptics_appliesCorrectAdaptiveScales() throws Exception { 1620 // Keep user settings the same as device default so only adaptive scale is applied. 1621 setUserSetting(Settings.System.ALARM_VIBRATION_INTENSITY, 1622 mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_ALARM)); 1623 setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY, 1624 mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_NOTIFICATION)); 1625 setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, 1626 mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH)); 1627 1628 mockVibrators(1); 1629 FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); 1630 fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); 1631 fakeVibrator.setSupportedPrimitives(VibrationEffect.Composition.PRIMITIVE_CLICK); 1632 VibratorManagerService service = createSystemReadyService(); 1633 1634 SparseArray<Float> vibrationScales = new SparseArray<>(); 1635 vibrationScales.put(ScaleParam.TYPE_ALARM, 0.7f); 1636 vibrationScales.put(ScaleParam.TYPE_NOTIFICATION, 0.4f); 1637 1638 mVibratorControlService.setVibrationParams( 1639 VibrationParamGenerator.generateVibrationParams(vibrationScales), 1640 mFakeVibratorController); 1641 1642 VibrationEffect effect = VibrationEffect.startComposition() 1643 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK) 1644 .compose(); 1645 vibrateAndWaitUntilFinished(service, effect, ALARM_ATTRS); 1646 vibrateAndWaitUntilFinished(service, effect, NOTIFICATION_ATTRS); 1647 vibrateAndWaitUntilFinished(service, effect, HAPTIC_FEEDBACK_ATTRS); 1648 1649 List<VibrationEffectSegment> segments = fakeVibrator.getAllEffectSegments(); 1650 assertEquals(3, segments.size()); 1651 assertEquals(0.7f, ((PrimitiveSegment) segments.get(0)).getScale(), 1e-5); 1652 assertEquals(0.4f, ((PrimitiveSegment) segments.get(1)).getScale(), 1e-5); 1653 assertEquals(1f, ((PrimitiveSegment) segments.get(2)).getScale(), 1e-5); 1654 verify(mVibratorFrameworkStatsLoggerMock).logVibrationAdaptiveHapticScale(UID, 0.7f); 1655 verify(mVibratorFrameworkStatsLoggerMock).logVibrationAdaptiveHapticScale(UID, 0.4f); 1656 verify(mVibratorFrameworkStatsLoggerMock, 1657 timeout(TEST_TIMEOUT_MILLIS)).logVibrationAdaptiveHapticScale(UID, 1f); 1658 } 1659 1660 @Test 1661 public void vibrate_withPowerModeChange_cancelVibrationIfNotAllowed() throws Exception { 1662 mockVibrators(1, 2); 1663 VibratorManagerService service = createSystemReadyService(); 1664 vibrate(service, 1665 CombinedVibration.startParallel() 1666 .addVibrator(1, VibrationEffect.createOneShot(1000, 100)) 1667 .combine(), 1668 HAPTIC_FEEDBACK_ATTRS); 1669 1670 // VibrationThread will start this vibration async, so wait until vibration is triggered. 1671 assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 1672 1673 mRegisteredPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE); 1674 1675 // Haptic feedback cancelled on low power mode. 1676 assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 1677 } 1678 1679 @Test vibrate_withSettingsChange_doNotCancelVibration()1680 public void vibrate_withSettingsChange_doNotCancelVibration() throws Exception { 1681 mockVibrators(1); 1682 VibratorManagerService service = createSystemReadyService(); 1683 1684 vibrate(service, VibrationEffect.createOneShot(1000, 100), HAPTIC_FEEDBACK_ATTRS); 1685 1686 // VibrationThread will start this vibration async, so wait until vibration is triggered. 1687 assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 1688 1689 service.updateServiceState(); 1690 1691 // Vibration is not stopped nearly after updating service. 1692 assertFalse(waitUntil(s -> !s.isVibrating(1), service, 50)); 1693 } 1694 1695 @Test vibrate_ignoreVibrationFromVirtualDevice()1696 public void vibrate_ignoreVibrationFromVirtualDevice() throws Exception { 1697 mockVibrators(1); 1698 VibratorManagerService service = createSystemReadyService(); 1699 1700 vibrateWithDevice(service, 1701 VIRTUAL_DEVICE_ID, 1702 CombinedVibration.startParallel() 1703 .addVibrator(1, VibrationEffect.createOneShot(1000, 100)) 1704 .combine(), 1705 HAPTIC_FEEDBACK_ATTRS); 1706 1707 // Haptic feedback ignored when it's from a virtual device. 1708 assertFalse(waitUntil(s -> s.isVibrating(1), service, /* timeout= */ 50)); 1709 1710 vibrateWithDevice(service, 1711 Context.DEVICE_ID_DEFAULT, 1712 CombinedVibration.startParallel() 1713 .addVibrator(1, VibrationEffect.createOneShot(1000, 100)) 1714 .combine(), 1715 HAPTIC_FEEDBACK_ATTRS); 1716 // Haptic feedback played normally when it's from the default device. 1717 assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 1718 } 1719 1720 @Test vibrate_prebakedAndComposedVibrationsWithFallbacks_playsFallbackOnlyForPredefined()1721 public void vibrate_prebakedAndComposedVibrationsWithFallbacks_playsFallbackOnlyForPredefined() 1722 throws Exception { 1723 mockVibrators(1); 1724 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); 1725 mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK); 1726 mVibratorProviders.get(1).setSupportedPrimitives( 1727 VibrationEffect.Composition.PRIMITIVE_CLICK); 1728 1729 VibratorManagerService service = createSystemReadyService(); 1730 vibrateAndWaitUntilFinished(service, 1731 VibrationEffect.startComposition() 1732 .addEffect(VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)) 1733 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK) 1734 .addEffect(VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK)) 1735 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK) 1736 .compose(), 1737 ALARM_ATTRS); 1738 1739 List<VibrationEffectSegment> segments = mVibratorProviders.get(1).getAllEffectSegments(); 1740 // At least one step segment played as fallback for unusupported vibration effect 1741 assertTrue(segments.size() > 2); 1742 // 0: Supported effect played 1743 assertTrue(segments.get(0) instanceof PrebakedSegment); 1744 // 1: No segment for unsupported primitive 1745 // 2: One or more intermediate step segments as fallback for unsupported effect 1746 for (int i = 1; i < segments.size() - 1; i++) { 1747 assertTrue(segments.get(i) instanceof StepSegment); 1748 } 1749 // 3: Supported primitive played 1750 assertTrue(segments.get(segments.size() - 1) instanceof PrimitiveSegment); 1751 } 1752 1753 @Test cancelVibrate_withoutUsageFilter_stopsVibrating()1754 public void cancelVibrate_withoutUsageFilter_stopsVibrating() throws Exception { 1755 mockVibrators(1); 1756 VibratorManagerService service = createSystemReadyService(); 1757 1758 service.cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, service); 1759 assertFalse(service.isVibrating(1)); 1760 1761 vibrate(service, VibrationEffect.createOneShot(10 * TEST_TIMEOUT_MILLIS, 100), ALARM_ATTRS); 1762 1763 // VibrationThread will start this vibration async, so wait until vibration is triggered. 1764 assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 1765 1766 service.cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, service); 1767 1768 // Alarm cancelled on filter match all. 1769 assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 1770 } 1771 1772 @Test cancelVibrate_withFilter_onlyCancelsVibrationWithFilteredUsage()1773 public void cancelVibrate_withFilter_onlyCancelsVibrationWithFilteredUsage() throws Exception { 1774 mockVibrators(1); 1775 VibratorManagerService service = createSystemReadyService(); 1776 1777 vibrate(service, VibrationEffect.createOneShot(10 * TEST_TIMEOUT_MILLIS, 100), ALARM_ATTRS); 1778 1779 // VibrationThread will start this vibration async, so wait until vibration is triggered. 1780 assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 1781 1782 // Vibration is not cancelled with a different usage. 1783 service.cancelVibrate(VibrationAttributes.USAGE_RINGTONE, service); 1784 assertFalse(waitUntil(s -> !s.isVibrating(1), service, /* timeout= */ 50)); 1785 1786 // Vibration is not cancelled with a different usage class used as filter. 1787 service.cancelVibrate( 1788 VibrationAttributes.USAGE_CLASS_FEEDBACK | ~VibrationAttributes.USAGE_CLASS_MASK, 1789 service); 1790 assertFalse(waitUntil(s -> !s.isVibrating(1), service, /* timeout= */ 50)); 1791 1792 // Vibration is cancelled with usage class as filter. 1793 service.cancelVibrate( 1794 VibrationAttributes.USAGE_CLASS_ALARM | ~VibrationAttributes.USAGE_CLASS_MASK, 1795 service); 1796 assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 1797 } 1798 1799 @Test cancelVibrate_withoutUnknownUsage_onlyStopsIfFilteringUnknownOrAllUsages()1800 public void cancelVibrate_withoutUnknownUsage_onlyStopsIfFilteringUnknownOrAllUsages() 1801 throws Exception { 1802 mockVibrators(1); 1803 VibrationAttributes attrs = new VibrationAttributes.Builder() 1804 .setUsage(VibrationAttributes.USAGE_UNKNOWN) 1805 .build(); 1806 VibratorManagerService service = createSystemReadyService(); 1807 1808 vibrate(service, VibrationEffect.createOneShot(10 * TEST_TIMEOUT_MILLIS, 100), attrs); 1809 1810 // VibrationThread will start this vibration async, so wait until vibration is triggered. 1811 assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 1812 1813 // Do not cancel UNKNOWN vibration when filter is being applied for other usages. 1814 service.cancelVibrate(VibrationAttributes.USAGE_RINGTONE, service); 1815 assertFalse(waitUntil(s -> !s.isVibrating(1), service, /* timeout= */ 50)); 1816 1817 service.cancelVibrate( 1818 VibrationAttributes.USAGE_CLASS_ALARM | ~VibrationAttributes.USAGE_CLASS_MASK, 1819 service); 1820 assertFalse(waitUntil(s -> !s.isVibrating(1), service, /* timeout= */ 50)); 1821 1822 // Cancel UNKNOWN vibration when filtered for that vibration specifically. 1823 service.cancelVibrate(VibrationAttributes.USAGE_UNKNOWN, service); 1824 assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 1825 1826 vibrate(service, VibrationEffect.createOneShot(10 * TEST_TIMEOUT_MILLIS, 100), attrs); 1827 1828 // VibrationThread will start this vibration async, so wait until vibration is triggered. 1829 assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 1830 1831 // Cancel UNKNOWN vibration when all vibrations are being cancelled. 1832 service.cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, service); 1833 assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 1834 } 1835 1836 @Test onExternalVibration_ignoreVibrationFromVirtualDevices()1837 public void onExternalVibration_ignoreVibrationFromVirtualDevices() { 1838 mockVibrators(1); 1839 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL); 1840 createSystemReadyService(); 1841 1842 IBinder binderToken = mock(IBinder.class); 1843 ExternalVibration externalVibration = new ExternalVibration(UID, PACKAGE_NAME, 1844 AUDIO_ALARM_ATTRS, 1845 mock(IExternalVibrationController.class), binderToken); 1846 ExternalVibrationScale scale = mExternalVibratorService.onExternalVibrationStart( 1847 externalVibration); 1848 assertNotEquals(ExternalVibrationScale.ScaleLevel.SCALE_MUTE, scale.scaleLevel); 1849 1850 when(mVirtualDeviceManagerInternalMock.isAppRunningOnAnyVirtualDevice(UID)) 1851 .thenReturn(true); 1852 scale = mExternalVibratorService.onExternalVibrationStart(externalVibration); 1853 assertEquals(ExternalVibrationScale.ScaleLevel.SCALE_MUTE, scale.scaleLevel); 1854 } 1855 1856 @Test onExternalVibration_setsExternalControl()1857 public void onExternalVibration_setsExternalControl() throws Exception { 1858 mockVibrators(1); 1859 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL); 1860 createSystemReadyService(); 1861 1862 IBinder binderToken = mock(IBinder.class); 1863 ExternalVibration externalVibration = new ExternalVibration(UID, PACKAGE_NAME, 1864 AUDIO_ALARM_ATTRS, 1865 mock(IExternalVibrationController.class), binderToken); 1866 ExternalVibrationScale scale = mExternalVibratorService.onExternalVibrationStart( 1867 externalVibration); 1868 mExternalVibratorService.onExternalVibrationStop(externalVibration); 1869 1870 assertNotEquals(ExternalVibrationScale.ScaleLevel.SCALE_MUTE, scale.scaleLevel); 1871 assertEquals(Arrays.asList(false, true, false), 1872 mVibratorProviders.get(1).getExternalControlStates()); 1873 1874 verify(binderToken).linkToDeath(any(), eq(0)); 1875 verify(binderToken).unlinkToDeath(any(), eq(0)); 1876 } 1877 1878 @Test onExternalVibration_withOngoingExternalVibration_mutesPreviousVibration()1879 public void onExternalVibration_withOngoingExternalVibration_mutesPreviousVibration() 1880 throws Exception { 1881 mockVibrators(1); 1882 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL); 1883 setRingerMode(AudioManager.RINGER_MODE_NORMAL); 1884 createSystemReadyService(); 1885 1886 IBinder firstToken = mock(IBinder.class); 1887 IBinder secondToken = mock(IBinder.class); 1888 IExternalVibrationController firstController = mock(IExternalVibrationController.class); 1889 IExternalVibrationController secondController = mock(IExternalVibrationController.class); 1890 ExternalVibration firstVibration = new ExternalVibration(UID, PACKAGE_NAME, 1891 AUDIO_ALARM_ATTRS, 1892 firstController, firstToken); 1893 ExternalVibrationScale firstScale = 1894 mExternalVibratorService.onExternalVibrationStart(firstVibration); 1895 1896 AudioAttributes ringtoneAudioAttrs = new AudioAttributes.Builder() 1897 .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE) 1898 .build(); 1899 ExternalVibration secondVibration = new ExternalVibration(UID, PACKAGE_NAME, 1900 ringtoneAudioAttrs, secondController, secondToken); 1901 ExternalVibrationScale secondScale = 1902 mExternalVibratorService.onExternalVibrationStart(secondVibration); 1903 1904 assertNotEquals(ExternalVibrationScale.ScaleLevel.SCALE_MUTE, firstScale.scaleLevel); 1905 assertNotEquals(ExternalVibrationScale.ScaleLevel.SCALE_MUTE, secondScale.scaleLevel); 1906 verify(firstController).mute(); 1907 verify(secondController, never()).mute(); 1908 // Set external control called only once. 1909 assertEquals(Arrays.asList(false, true), 1910 mVibratorProviders.get(1).getExternalControlStates()); 1911 1912 mExternalVibratorService.onExternalVibrationStop(secondVibration); 1913 mExternalVibratorService.onExternalVibrationStop(firstVibration); 1914 assertEquals(Arrays.asList(false, true, false), 1915 mVibratorProviders.get(1).getExternalControlStates()); 1916 1917 verify(firstToken).linkToDeath(any(), eq(0)); 1918 verify(firstToken).unlinkToDeath(any(), eq(0)); 1919 1920 verify(secondToken).linkToDeath(any(), eq(0)); 1921 verify(secondToken).unlinkToDeath(any(), eq(0)); 1922 } 1923 1924 @Test onExternalVibration_withOngoingVibration_cancelsOngoingVibrationImmediately()1925 public void onExternalVibration_withOngoingVibration_cancelsOngoingVibrationImmediately() 1926 throws Exception { 1927 mockVibrators(1); 1928 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL, 1929 IVibrator.CAP_AMPLITUDE_CONTROL); 1930 VibratorManagerService service = createSystemReadyService(); 1931 1932 VibrationEffect effect = VibrationEffect.createOneShot(10 * TEST_TIMEOUT_MILLIS, 100); 1933 vibrate(service, effect, HAPTIC_FEEDBACK_ATTRS); 1934 1935 // VibrationThread will start this vibration async, so wait until vibration is triggered. 1936 assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 1937 1938 ExternalVibration externalVibration = new ExternalVibration(UID, PACKAGE_NAME, 1939 AUDIO_ALARM_ATTRS, 1940 mock(IExternalVibrationController.class)); 1941 ExternalVibrationScale scale = 1942 mExternalVibratorService.onExternalVibrationStart(externalVibration); 1943 assertNotEquals(ExternalVibrationScale.ScaleLevel.SCALE_MUTE, scale.scaleLevel); 1944 1945 // Vibration is cancelled. 1946 assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 1947 assertEquals(Arrays.asList(false, true), 1948 mVibratorProviders.get(1).getExternalControlStates()); 1949 } 1950 1951 @Test onExternalVibration_withOngoingHigherImportanceVibration_ignoreNewVibration()1952 public void onExternalVibration_withOngoingHigherImportanceVibration_ignoreNewVibration() 1953 throws Exception { 1954 mockVibrators(1); 1955 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL, 1956 IVibrator.CAP_AMPLITUDE_CONTROL); 1957 VibratorManagerService service = createSystemReadyService(); 1958 1959 VibrationEffect effect = VibrationEffect.createOneShot(10 * TEST_TIMEOUT_MILLIS, 100); 1960 vibrate(service, effect, RINGTONE_ATTRS); 1961 1962 // VibrationThread will start this vibration async, so wait until vibration is triggered. 1963 assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 1964 1965 ExternalVibration externalVibration = new ExternalVibration(UID, PACKAGE_NAME, 1966 AUDIO_ALARM_ATTRS, 1967 mock(IExternalVibrationController.class)); 1968 ExternalVibrationScale scale = 1969 mExternalVibratorService.onExternalVibrationStart(externalVibration); 1970 // External vibration is ignored. 1971 assertEquals(ExternalVibrationScale.ScaleLevel.SCALE_MUTE, scale.scaleLevel); 1972 1973 // Vibration is not cancelled. 1974 assertEquals(Arrays.asList(false), mVibratorProviders.get(1).getExternalControlStates()); 1975 } 1976 1977 @Test onExternalVibration_withNewSameImportanceButRepeating_cancelsOngoingVibration()1978 public void onExternalVibration_withNewSameImportanceButRepeating_cancelsOngoingVibration() 1979 throws Exception { 1980 mockVibrators(1); 1981 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL, 1982 IVibrator.CAP_AMPLITUDE_CONTROL); 1983 VibratorManagerService service = createSystemReadyService(); 1984 1985 VibrationEffect repeatingEffect = VibrationEffect.createWaveform( 1986 new long[]{100, 200, 300}, new int[]{128, 255, 255}, 1); 1987 vibrate(service, repeatingEffect, ALARM_ATTRS); 1988 1989 // VibrationThread will start this vibration async, so wait until vibration is triggered. 1990 assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 1991 1992 ExternalVibration externalVibration = new ExternalVibration(UID, PACKAGE_NAME, 1993 AUDIO_ALARM_ATTRS, mock(IExternalVibrationController.class)); 1994 ExternalVibrationScale scale = 1995 mExternalVibratorService.onExternalVibrationStart(externalVibration); 1996 assertNotEquals(ExternalVibrationScale.ScaleLevel.SCALE_MUTE, scale.scaleLevel); 1997 1998 // Vibration is cancelled. 1999 assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 2000 assertEquals(Arrays.asList(false, true), 2001 mVibratorProviders.get(1).getExternalControlStates()); 2002 } 2003 2004 @Test onExternalVibration_withNewSameImportanceButOngoingIsRepeating_ignoreNewVibration()2005 public void onExternalVibration_withNewSameImportanceButOngoingIsRepeating_ignoreNewVibration() 2006 throws Exception { 2007 mockVibrators(1); 2008 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL, 2009 IVibrator.CAP_AMPLITUDE_CONTROL); 2010 VibratorManagerService service = createSystemReadyService(); 2011 2012 VibrationEffect repeatingEffect = VibrationEffect.createWaveform( 2013 new long[]{10_000, 10_000}, new int[]{128, 255}, 1); 2014 vibrate(service, repeatingEffect, NOTIFICATION_ATTRS); 2015 2016 // VibrationThread will start this vibration async, so wait until vibration is triggered. 2017 assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); 2018 2019 ExternalVibration externalVibration = new ExternalVibration(UID, PACKAGE_NAME, 2020 AUDIO_NOTIFICATION_ATTRS, 2021 mock(IExternalVibrationController.class)); 2022 ExternalVibrationScale scale = 2023 mExternalVibratorService.onExternalVibrationStart(externalVibration); 2024 // New vibration is ignored. 2025 assertEquals(ExternalVibrationScale.ScaleLevel.SCALE_MUTE, scale.scaleLevel); 2026 2027 // Vibration is not cancelled. 2028 assertEquals(Arrays.asList(false), mVibratorProviders.get(1).getExternalControlStates()); 2029 } 2030 2031 @Test onExternalVibration_withRingtone_usesRingerModeSettings()2032 public void onExternalVibration_withRingtone_usesRingerModeSettings() { 2033 mockVibrators(1); 2034 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL); 2035 AudioAttributes audioAttrs = new AudioAttributes.Builder() 2036 .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE) 2037 .build(); 2038 ExternalVibration externalVibration = new ExternalVibration(UID, PACKAGE_NAME, audioAttrs, 2039 mock(IExternalVibrationController.class)); 2040 2041 setRingerMode(AudioManager.RINGER_MODE_SILENT); 2042 createSystemReadyService(); 2043 ExternalVibrationScale scale = 2044 mExternalVibratorService.onExternalVibrationStart(externalVibration); 2045 assertEquals(ExternalVibrationScale.ScaleLevel.SCALE_MUTE, scale.scaleLevel); 2046 2047 setRingerMode(AudioManager.RINGER_MODE_NORMAL); 2048 createSystemReadyService(); 2049 scale = mExternalVibratorService.onExternalVibrationStart(externalVibration); 2050 assertNotEquals(ExternalVibrationScale.ScaleLevel.SCALE_MUTE, scale.scaleLevel); 2051 2052 setRingerMode(AudioManager.RINGER_MODE_VIBRATE); 2053 createSystemReadyService(); 2054 scale = mExternalVibratorService.onExternalVibrationStart(externalVibration); 2055 assertNotEquals(ExternalVibrationScale.ScaleLevel.SCALE_MUTE, scale.scaleLevel); 2056 } 2057 2058 @Test onExternalVibration_withBypassMuteAudioFlag_ignoresUserSettings()2059 public void onExternalVibration_withBypassMuteAudioFlag_ignoresUserSettings() { 2060 // Permission needed for bypassing user settings 2061 grantPermission(android.Manifest.permission.MODIFY_PHONE_STATE); 2062 2063 mockVibrators(1); 2064 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL); 2065 setUserSetting(Settings.System.ALARM_VIBRATION_INTENSITY, 2066 Vibrator.VIBRATION_INTENSITY_OFF); 2067 AudioAttributes audioAttrs = new AudioAttributes.Builder() 2068 .setUsage(AudioAttributes.USAGE_ALARM) 2069 .build(); 2070 AudioAttributes flaggedAudioAttrs = new AudioAttributes.Builder() 2071 .setUsage(AudioAttributes.USAGE_ALARM) 2072 .setFlags(AudioAttributes.FLAG_BYPASS_MUTE) 2073 .build(); 2074 createSystemReadyService(); 2075 2076 ExternalVibration vib = new ExternalVibration(UID, PACKAGE_NAME, audioAttrs, 2077 mock(IExternalVibrationController.class)); 2078 ExternalVibrationScale scale = mExternalVibratorService.onExternalVibrationStart(vib); 2079 assertEquals(ExternalVibrationScale.ScaleLevel.SCALE_MUTE, scale.scaleLevel); 2080 2081 mExternalVibratorService.onExternalVibrationStop(vib); 2082 scale = mExternalVibratorService.onExternalVibrationStart( 2083 new ExternalVibration(UID, PACKAGE_NAME, flaggedAudioAttrs, 2084 mock(IExternalVibrationController.class))); 2085 assertNotEquals(ExternalVibrationScale.ScaleLevel.SCALE_MUTE, scale.scaleLevel); 2086 } 2087 2088 @Test onExternalVibration_withUnknownUsage_appliesMediaSettings()2089 public void onExternalVibration_withUnknownUsage_appliesMediaSettings() { 2090 mockVibrators(1); 2091 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL); 2092 setUserSetting(Settings.System.MEDIA_VIBRATION_INTENSITY, 2093 Vibrator.VIBRATION_INTENSITY_OFF); 2094 AudioAttributes flaggedAudioAttrs = new AudioAttributes.Builder() 2095 .setUsage(AudioAttributes.USAGE_UNKNOWN) 2096 .build(); 2097 createSystemReadyService(); 2098 2099 ExternalVibrationScale scale = 2100 mExternalVibratorService.onExternalVibrationStart( 2101 new ExternalVibration(/* uid= */ 123, PACKAGE_NAME, flaggedAudioAttrs, 2102 mock(IExternalVibrationController.class))); 2103 assertEquals(ExternalVibrationScale.ScaleLevel.SCALE_MUTE, scale.scaleLevel); 2104 } 2105 2106 @Test 2107 @RequiresFlagsEnabled(android.os.vibrator.Flags.FLAG_ADAPTIVE_HAPTICS_ENABLED) onExternalVibration_withAdaptiveHaptics_returnsCorrectAdaptiveScales()2108 public void onExternalVibration_withAdaptiveHaptics_returnsCorrectAdaptiveScales() { 2109 mockVibrators(1); 2110 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL, 2111 IVibrator.CAP_AMPLITUDE_CONTROL); 2112 createSystemReadyService(); 2113 2114 SparseArray<Float> vibrationScales = new SparseArray<>(); 2115 vibrationScales.put(ScaleParam.TYPE_ALARM, 0.7f); 2116 vibrationScales.put(ScaleParam.TYPE_NOTIFICATION, 0.4f); 2117 2118 mVibratorControlService.setVibrationParams( 2119 VibrationParamGenerator.generateVibrationParams(vibrationScales), 2120 mFakeVibratorController); 2121 ExternalVibration externalVibration = new ExternalVibration(UID, PACKAGE_NAME, 2122 AUDIO_ALARM_ATTRS, 2123 mock(IExternalVibrationController.class)); 2124 ExternalVibrationScale scale = 2125 mExternalVibratorService.onExternalVibrationStart(externalVibration); 2126 mExternalVibratorService.onExternalVibrationStop(externalVibration); 2127 2128 assertEquals(scale.adaptiveHapticsScale, 0.7f, 0); 2129 verify(mVibratorFrameworkStatsLoggerMock).logVibrationAdaptiveHapticScale(UID, 0.7f); 2130 2131 externalVibration = new ExternalVibration(UID, PACKAGE_NAME, 2132 AUDIO_NOTIFICATION_ATTRS, 2133 mock(IExternalVibrationController.class)); 2134 scale = mExternalVibratorService.onExternalVibrationStart(externalVibration); 2135 mExternalVibratorService.onExternalVibrationStop(externalVibration); 2136 2137 assertEquals(scale.adaptiveHapticsScale, 0.4f, 0); 2138 verify(mVibratorFrameworkStatsLoggerMock).logVibrationAdaptiveHapticScale(UID, 0.4f); 2139 2140 AudioAttributes ringtoneAudioAttrs = new AudioAttributes.Builder() 2141 .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE) 2142 .build(); 2143 externalVibration = new ExternalVibration(UID, PACKAGE_NAME, 2144 ringtoneAudioAttrs, 2145 mock(IExternalVibrationController.class)); 2146 scale = mExternalVibratorService.onExternalVibrationStart(externalVibration); 2147 mExternalVibratorService.onExternalVibrationStop(externalVibration); 2148 2149 assertEquals(scale.adaptiveHapticsScale, 1f, 0); 2150 verify(mVibratorFrameworkStatsLoggerMock).logVibrationAdaptiveHapticScale(UID, 1f); 2151 } 2152 2153 @Test 2154 @RequiresFlagsDisabled(android.os.vibrator.Flags.FLAG_ADAPTIVE_HAPTICS_ENABLED) onExternalVibration_withAdaptiveHapticsFlagDisabled_alwaysReturnScaleNone()2155 public void onExternalVibration_withAdaptiveHapticsFlagDisabled_alwaysReturnScaleNone() { 2156 mockVibrators(1); 2157 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL, 2158 IVibrator.CAP_AMPLITUDE_CONTROL); 2159 createSystemReadyService(); 2160 2161 SparseArray<Float> vibrationScales = new SparseArray<>(); 2162 vibrationScales.put(ScaleParam.TYPE_ALARM, 0.7f); 2163 vibrationScales.put(ScaleParam.TYPE_NOTIFICATION, 0.4f); 2164 2165 mVibratorControlService.setVibrationParams( 2166 VibrationParamGenerator.generateVibrationParams(vibrationScales), 2167 mFakeVibratorController); 2168 ExternalVibration externalVibration = new ExternalVibration(UID, PACKAGE_NAME, 2169 AUDIO_ALARM_ATTRS, 2170 mock(IExternalVibrationController.class)); 2171 ExternalVibrationScale scale = 2172 mExternalVibratorService.onExternalVibrationStart(externalVibration); 2173 mExternalVibratorService.onExternalVibrationStop(externalVibration); 2174 2175 assertEquals(scale.adaptiveHapticsScale, 1f, 0); 2176 2177 externalVibration = new ExternalVibration(UID, PACKAGE_NAME, 2178 AUDIO_NOTIFICATION_ATTRS, 2179 mock(IExternalVibrationController.class)); 2180 scale = mExternalVibratorService.onExternalVibrationStart(externalVibration); 2181 mExternalVibratorService.onExternalVibrationStop(externalVibration); 2182 2183 assertEquals(scale.adaptiveHapticsScale, 1f, 0); 2184 verify(mVibratorFrameworkStatsLoggerMock, times(2)) 2185 .logVibrationAdaptiveHapticScale(UID, 1f); 2186 } 2187 2188 @Test frameworkStats_externalVibration_reportsAllMetrics()2189 public void frameworkStats_externalVibration_reportsAllMetrics() throws Exception { 2190 mockVibrators(1); 2191 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL); 2192 createSystemReadyService(); 2193 2194 AudioAttributes audioAttrs = new AudioAttributes.Builder() 2195 .setUsage(AudioAttributes.USAGE_ALARM) 2196 .build(); 2197 2198 ExternalVibration vib = new ExternalVibration(UID, PACKAGE_NAME, audioAttrs, 2199 mock(IExternalVibrationController.class)); 2200 mExternalVibratorService.onExternalVibrationStart(vib); 2201 2202 Thread.sleep(10); 2203 mExternalVibratorService.onExternalVibrationStop(vib); 2204 2205 ArgumentCaptor<VibrationStats.StatsInfo> argumentCaptor = 2206 ArgumentCaptor.forClass(VibrationStats.StatsInfo.class); 2207 verify(mVibratorFrameworkStatsLoggerMock, timeout(TEST_TIMEOUT_MILLIS)) 2208 .writeVibrationReportedAsync(argumentCaptor.capture()); 2209 2210 VibrationStats.StatsInfo statsInfo = argumentCaptor.getValue(); 2211 assertEquals(UID, statsInfo.uid); 2212 assertEquals(FrameworkStatsLog.VIBRATION_REPORTED__VIBRATION_TYPE__EXTERNAL, 2213 statsInfo.vibrationType); 2214 assertEquals(VibrationAttributes.USAGE_ALARM, statsInfo.usage); 2215 assertEquals(Vibration.Status.FINISHED.getProtoEnumValue(), statsInfo.status); 2216 assertTrue(statsInfo.totalDurationMillis > 0); 2217 assertTrue( 2218 "Expected vibrator ON for at least 10ms, got " + statsInfo.vibratorOnMillis + "ms", 2219 statsInfo.vibratorOnMillis >= 10); 2220 assertEquals(2, statsInfo.halSetExternalControlCount); 2221 } 2222 2223 @Test frameworkStats_waveformVibration_reportsAllMetrics()2224 public void frameworkStats_waveformVibration_reportsAllMetrics() throws Exception { 2225 mockVibrators(1); 2226 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); 2227 2228 VibratorManagerService service = createSystemReadyService(); 2229 vibrateAndWaitUntilFinished(service, 2230 VibrationEffect.createWaveform(new long[] {0, 10, 20, 10}, -1), RINGTONE_ATTRS); 2231 2232 verify(mVibratorFrameworkStatsLoggerMock, timeout(TEST_TIMEOUT_MILLIS)) 2233 .writeVibratorStateOnAsync(eq(UID), anyLong()); 2234 verify(mVibratorFrameworkStatsLoggerMock, timeout(TEST_TIMEOUT_MILLIS)) 2235 .writeVibratorStateOffAsync(eq(UID)); 2236 2237 ArgumentCaptor<VibrationStats.StatsInfo> argumentCaptor = 2238 ArgumentCaptor.forClass(VibrationStats.StatsInfo.class); 2239 verify(mVibratorFrameworkStatsLoggerMock, timeout(TEST_TIMEOUT_MILLIS)) 2240 .writeVibrationReportedAsync(argumentCaptor.capture()); 2241 2242 VibrationStats.StatsInfo metrics = argumentCaptor.getValue(); 2243 assertEquals(UID, metrics.uid); 2244 assertEquals(FrameworkStatsLog.VIBRATION_REPORTED__VIBRATION_TYPE__SINGLE, 2245 metrics.vibrationType); 2246 assertEquals(VibrationAttributes.USAGE_RINGTONE, metrics.usage); 2247 assertEquals(Vibration.Status.FINISHED.getProtoEnumValue(), metrics.status); 2248 assertTrue("Total duration was too low, " + metrics.totalDurationMillis + "ms", 2249 metrics.totalDurationMillis >= 20); 2250 assertTrue("Vibrator ON duration was too low, " + metrics.vibratorOnMillis + "ms", 2251 metrics.vibratorOnMillis >= 20); 2252 2253 // All unrelated metrics are empty. 2254 assertEquals(0, metrics.repeatCount); 2255 assertEquals(0, metrics.halComposeCount); 2256 assertEquals(0, metrics.halComposePwleCount); 2257 assertEquals(0, metrics.halPerformCount); 2258 assertEquals(0, metrics.halSetExternalControlCount); 2259 assertEquals(0, metrics.halCompositionSize); 2260 assertEquals(0, metrics.halPwleSize); 2261 assertNull(metrics.halSupportedCompositionPrimitivesUsed); 2262 assertNull(metrics.halSupportedEffectsUsed); 2263 assertNull(metrics.halUnsupportedCompositionPrimitivesUsed); 2264 assertNull(metrics.halUnsupportedEffectsUsed); 2265 2266 // Accommodate for ramping off config that might add extra setAmplitudes. 2267 assertEquals(2, metrics.halOnCount); 2268 assertTrue(metrics.halOffCount > 0); 2269 assertTrue(metrics.halSetAmplitudeCount >= 2); 2270 } 2271 2272 @Test frameworkStats_repeatingVibration_reportsAllMetrics()2273 public void frameworkStats_repeatingVibration_reportsAllMetrics() throws Exception { 2274 mockVibrators(1); 2275 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); 2276 2277 VibratorManagerService service = createSystemReadyService(); 2278 vibrate(service, VibrationEffect.createWaveform(new long[] {10, 100}, 1), RINGTONE_ATTRS); 2279 2280 verify(mVibratorFrameworkStatsLoggerMock, timeout(TEST_TIMEOUT_MILLIS)) 2281 .writeVibratorStateOnAsync(eq(UID), anyLong()); 2282 2283 // Wait for at least one loop before cancelling it. 2284 Thread.sleep(100); 2285 service.cancelVibrate(VibrationAttributes.USAGE_RINGTONE, service); 2286 2287 verify(mVibratorFrameworkStatsLoggerMock, timeout(TEST_TIMEOUT_MILLIS)) 2288 .writeVibratorStateOffAsync(eq(UID)); 2289 2290 ArgumentCaptor<VibrationStats.StatsInfo> argumentCaptor = 2291 ArgumentCaptor.forClass(VibrationStats.StatsInfo.class); 2292 verify(mVibratorFrameworkStatsLoggerMock, timeout(TEST_TIMEOUT_MILLIS)) 2293 .writeVibrationReportedAsync(argumentCaptor.capture()); 2294 2295 VibrationStats.StatsInfo metrics = argumentCaptor.getValue(); 2296 assertEquals(UID, metrics.uid); 2297 assertEquals(FrameworkStatsLog.VIBRATION_REPORTED__VIBRATION_TYPE__REPEATED, 2298 metrics.vibrationType); 2299 assertEquals(VibrationAttributes.USAGE_RINGTONE, metrics.usage); 2300 assertEquals(Vibration.Status.CANCELLED_BY_USER.getProtoEnumValue(), metrics.status); 2301 assertTrue("Total duration was too low, " + metrics.totalDurationMillis + "ms", 2302 metrics.totalDurationMillis >= 100); 2303 assertTrue("Vibrator ON duration was too low, " + metrics.vibratorOnMillis + "ms", 2304 metrics.vibratorOnMillis >= 100); 2305 2306 // All unrelated metrics are empty. 2307 assertTrue(metrics.repeatCount > 0); 2308 assertEquals(0, metrics.halComposeCount); 2309 assertEquals(0, metrics.halComposePwleCount); 2310 assertEquals(0, metrics.halPerformCount); 2311 assertEquals(0, metrics.halSetExternalControlCount); 2312 assertEquals(0, metrics.halCompositionSize); 2313 assertEquals(0, metrics.halPwleSize); 2314 assertNull(metrics.halSupportedCompositionPrimitivesUsed); 2315 assertNull(metrics.halSupportedEffectsUsed); 2316 assertNull(metrics.halUnsupportedCompositionPrimitivesUsed); 2317 assertNull(metrics.halUnsupportedEffectsUsed); 2318 2319 // Accommodate for ramping off config that might add extra setAmplitudes. 2320 assertTrue(metrics.halOnCount > 0); 2321 assertTrue(metrics.halOffCount > 0); 2322 assertTrue(metrics.halSetAmplitudeCount > 0); 2323 } 2324 2325 @Test frameworkStats_prebakedAndComposedVibrations_reportsAllMetrics()2326 public void frameworkStats_prebakedAndComposedVibrations_reportsAllMetrics() throws Exception { 2327 mockVibrators(1); 2328 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); 2329 mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK); 2330 mVibratorProviders.get(1).setSupportedPrimitives( 2331 VibrationEffect.Composition.PRIMITIVE_TICK); 2332 2333 VibratorManagerService service = createSystemReadyService(); 2334 vibrateAndWaitUntilFinished(service, 2335 VibrationEffect.startComposition() 2336 .addEffect(VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)) 2337 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK) 2338 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK) 2339 .addEffect(VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)) 2340 .addEffect(VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK)) 2341 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK) 2342 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK) 2343 .compose(), 2344 ALARM_ATTRS); 2345 2346 verify(mVibratorFrameworkStatsLoggerMock, timeout(TEST_TIMEOUT_MILLIS)) 2347 .writeVibratorStateOnAsync(eq(UID), anyLong()); 2348 verify(mVibratorFrameworkStatsLoggerMock, timeout(TEST_TIMEOUT_MILLIS)) 2349 .writeVibratorStateOffAsync(eq(UID)); 2350 2351 ArgumentCaptor<VibrationStats.StatsInfo> argumentCaptor = 2352 ArgumentCaptor.forClass(VibrationStats.StatsInfo.class); 2353 verify(mVibratorFrameworkStatsLoggerMock, timeout(TEST_TIMEOUT_MILLIS)) 2354 .writeVibrationReportedAsync(argumentCaptor.capture()); 2355 2356 VibrationStats.StatsInfo metrics = argumentCaptor.getValue(); 2357 assertEquals(UID, metrics.uid); 2358 assertEquals(FrameworkStatsLog.VIBRATION_REPORTED__VIBRATION_TYPE__SINGLE, 2359 metrics.vibrationType); 2360 assertEquals(VibrationAttributes.USAGE_ALARM, metrics.usage); 2361 assertEquals(Vibration.Status.FINISHED.getProtoEnumValue(), metrics.status); 2362 2363 // At least 4 effect/primitive played, 20ms each, plus configured fallback. 2364 assertTrue("Total duration was too low, " + metrics.totalDurationMillis + "ms", 2365 metrics.totalDurationMillis >= 80); 2366 assertTrue("Vibrator ON duration was too low, " + metrics.vibratorOnMillis + "ms", 2367 metrics.vibratorOnMillis >= 80); 2368 2369 // Related metrics were collected. 2370 assertEquals(2, metrics.halComposeCount); // TICK+TICK, then CLICK+CLICK 2371 assertEquals(3, metrics.halPerformCount); // CLICK, TICK, then CLICK 2372 assertEquals(4, metrics.halCompositionSize); // 2*TICK + 2*CLICK 2373 // No repetitions in reported effect/primitive IDs. 2374 assertArrayEquals(new int[] {VibrationEffect.Composition.PRIMITIVE_TICK}, 2375 metrics.halSupportedCompositionPrimitivesUsed); 2376 assertArrayEquals(new int[] {VibrationEffect.Composition.PRIMITIVE_CLICK}, 2377 metrics.halUnsupportedCompositionPrimitivesUsed); 2378 assertArrayEquals(new int[] {VibrationEffect.EFFECT_CLICK}, 2379 metrics.halSupportedEffectsUsed); 2380 assertArrayEquals(new int[] {VibrationEffect.EFFECT_TICK}, 2381 metrics.halUnsupportedEffectsUsed); 2382 2383 // All unrelated metrics are empty. 2384 assertEquals(0, metrics.repeatCount); 2385 assertEquals(0, metrics.halComposePwleCount); 2386 assertEquals(0, metrics.halSetExternalControlCount); 2387 assertEquals(0, metrics.halPwleSize); 2388 2389 // Accommodate for ramping off config that might add extra setAmplitudes 2390 // for the effect that plays the fallback instead of "perform". 2391 assertTrue(metrics.halOnCount > 0); 2392 assertTrue(metrics.halOffCount > 0); 2393 assertTrue(metrics.halSetAmplitudeCount > 0); 2394 } 2395 2396 @Test frameworkStats_interruptingVibrations_reportsAllMetrics()2397 public void frameworkStats_interruptingVibrations_reportsAllMetrics() throws Exception { 2398 mockVibrators(1); 2399 VibratorManagerService service = createSystemReadyService(); 2400 2401 vibrate(service, VibrationEffect.createOneShot(1_000, 128), HAPTIC_FEEDBACK_ATTRS); 2402 2403 // VibrationThread will start this vibration async, so wait until vibration is triggered. 2404 assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getAllEffectSegments().isEmpty(), 2405 service, TEST_TIMEOUT_MILLIS)); 2406 2407 vibrateAndWaitUntilFinished(service, VibrationEffect.createOneShot(10, 255), ALARM_ATTRS); 2408 2409 ArgumentCaptor<VibrationStats.StatsInfo> argumentCaptor = 2410 ArgumentCaptor.forClass(VibrationStats.StatsInfo.class); 2411 verify(mVibratorFrameworkStatsLoggerMock, timeout(TEST_TIMEOUT_MILLIS).times(2)) 2412 .writeVibrationReportedAsync(argumentCaptor.capture()); 2413 2414 VibrationStats.StatsInfo touchMetrics = argumentCaptor.getAllValues().get(0); 2415 assertEquals(UID, touchMetrics.uid); 2416 assertEquals(VibrationAttributes.USAGE_TOUCH, touchMetrics.usage); 2417 assertEquals(Vibration.Status.CANCELLED_SUPERSEDED.getProtoEnumValue(), 2418 touchMetrics.status); 2419 assertTrue(touchMetrics.endedBySameUid); 2420 assertEquals(VibrationAttributes.USAGE_ALARM, touchMetrics.endedByUsage); 2421 assertEquals(-1, touchMetrics.interruptedUsage); 2422 2423 VibrationStats.StatsInfo alarmMetrics = argumentCaptor.getAllValues().get(1); 2424 assertEquals(UID, alarmMetrics.uid); 2425 assertEquals(VibrationAttributes.USAGE_ALARM, alarmMetrics.usage); 2426 assertEquals(Vibration.Status.FINISHED.getProtoEnumValue(), alarmMetrics.status); 2427 assertFalse(alarmMetrics.endedBySameUid); 2428 assertEquals(-1, alarmMetrics.endedByUsage); 2429 assertEquals(VibrationAttributes.USAGE_TOUCH, alarmMetrics.interruptedUsage); 2430 } 2431 2432 @Test frameworkStats_ignoredVibration_reportsStatus()2433 public void frameworkStats_ignoredVibration_reportsStatus() throws Exception { 2434 setUserSetting(Settings.System.RING_VIBRATION_INTENSITY, 2435 Vibrator.VIBRATION_INTENSITY_OFF); 2436 2437 mockVibrators(1); 2438 VibratorManagerService service = createSystemReadyService(); 2439 mRegisteredPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE); 2440 2441 // Haptic feedback ignored in low power state 2442 vibrateAndWaitUntilFinished(service, VibrationEffect.createOneShot(100, 128), 2443 HAPTIC_FEEDBACK_ATTRS); 2444 // Ringtone vibration user settings are off 2445 vibrateAndWaitUntilFinished(service, VibrationEffect.createOneShot(200, 128), 2446 RINGTONE_ATTRS); 2447 2448 ArgumentCaptor<VibrationStats.StatsInfo> argumentCaptor = 2449 ArgumentCaptor.forClass(VibrationStats.StatsInfo.class); 2450 verify(mVibratorFrameworkStatsLoggerMock, timeout(TEST_TIMEOUT_MILLIS).times(2)) 2451 .writeVibrationReportedAsync(argumentCaptor.capture()); 2452 2453 VibrationStats.StatsInfo touchMetrics = argumentCaptor.getAllValues().get(0); 2454 assertEquals(UID, touchMetrics.uid); 2455 assertEquals(VibrationAttributes.USAGE_TOUCH, touchMetrics.usage); 2456 assertEquals(Vibration.Status.IGNORED_FOR_POWER.getProtoEnumValue(), touchMetrics.status); 2457 2458 VibrationStats.StatsInfo ringtoneMetrics = argumentCaptor.getAllValues().get(1); 2459 assertEquals(UID, ringtoneMetrics.uid); 2460 assertEquals(VibrationAttributes.USAGE_RINGTONE, ringtoneMetrics.usage); 2461 assertEquals(Vibration.Status.IGNORED_FOR_SETTINGS.getProtoEnumValue(), 2462 ringtoneMetrics.status); 2463 2464 for (VibrationStats.StatsInfo metrics : argumentCaptor.getAllValues()) { 2465 // Latencies are empty since vibrations never started 2466 assertEquals(0, metrics.startLatencyMillis); 2467 assertEquals(0, metrics.endLatencyMillis); 2468 assertEquals(0, metrics.vibratorOnMillis); 2469 2470 // All unrelated metrics are empty. 2471 assertEquals(0, metrics.repeatCount); 2472 assertEquals(0, metrics.halComposeCount); 2473 assertEquals(0, metrics.halComposePwleCount); 2474 assertEquals(0, metrics.halOffCount); 2475 assertEquals(0, metrics.halOnCount); 2476 assertEquals(0, metrics.halPerformCount); 2477 assertEquals(0, metrics.halSetExternalControlCount); 2478 assertEquals(0, metrics.halCompositionSize); 2479 assertEquals(0, metrics.halPwleSize); 2480 assertNull(metrics.halSupportedCompositionPrimitivesUsed); 2481 assertNull(metrics.halSupportedEffectsUsed); 2482 assertNull(metrics.halUnsupportedCompositionPrimitivesUsed); 2483 assertNull(metrics.halUnsupportedEffectsUsed); 2484 } 2485 } 2486 2487 @Test frameworkStats_multiVibrators_reportsAllMetrics()2488 public void frameworkStats_multiVibrators_reportsAllMetrics() throws Exception { 2489 mockVibrators(1, 2); 2490 mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); 2491 mVibratorProviders.get(1).setSupportedPrimitives( 2492 VibrationEffect.Composition.PRIMITIVE_TICK); 2493 mVibratorProviders.get(2).setSupportedEffects(VibrationEffect.EFFECT_TICK); 2494 2495 VibratorManagerService service = createSystemReadyService(); 2496 vibrateAndWaitUntilFinished(service, 2497 CombinedVibration.startParallel() 2498 .addVibrator(1, 2499 VibrationEffect.startComposition() 2500 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK) 2501 .compose()) 2502 .addVibrator(2, 2503 VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK)) 2504 .combine(), 2505 NOTIFICATION_ATTRS); 2506 2507 SparseBooleanArray expectedEffectsUsed = new SparseBooleanArray(); 2508 expectedEffectsUsed.put(VibrationEffect.EFFECT_TICK, true); 2509 2510 SparseBooleanArray expectedPrimitivesUsed = new SparseBooleanArray(); 2511 expectedPrimitivesUsed.put(VibrationEffect.Composition.PRIMITIVE_TICK, true); 2512 2513 verify(mVibratorFrameworkStatsLoggerMock, timeout(TEST_TIMEOUT_MILLIS)) 2514 .writeVibratorStateOnAsync(eq(UID), anyLong()); 2515 verify(mVibratorFrameworkStatsLoggerMock, timeout(TEST_TIMEOUT_MILLIS)) 2516 .writeVibratorStateOffAsync(eq(UID)); 2517 2518 ArgumentCaptor<VibrationStats.StatsInfo> argumentCaptor = 2519 ArgumentCaptor.forClass(VibrationStats.StatsInfo.class); 2520 verify(mVibratorFrameworkStatsLoggerMock, timeout(TEST_TIMEOUT_MILLIS)) 2521 .writeVibrationReportedAsync(argumentCaptor.capture()); 2522 2523 VibrationStats.StatsInfo metrics = argumentCaptor.getValue(); 2524 assertEquals(UID, metrics.uid); 2525 assertEquals(FrameworkStatsLog.VIBRATION_REPORTED__VIBRATION_TYPE__SINGLE, 2526 metrics.vibrationType); 2527 assertEquals(VibrationAttributes.USAGE_NOTIFICATION, metrics.usage); 2528 assertEquals(Vibration.Status.FINISHED.getProtoEnumValue(), metrics.status); 2529 assertTrue(metrics.totalDurationMillis >= 20); 2530 2531 // vibratorOnMillis accumulates both vibrators, it's 20 for each constant. 2532 assertEquals(40, metrics.vibratorOnMillis); 2533 2534 // Related metrics were collected. 2535 assertEquals(1, metrics.halComposeCount); 2536 assertEquals(1, metrics.halPerformCount); 2537 assertEquals(1, metrics.halCompositionSize); 2538 assertEquals(2, metrics.halOffCount); 2539 assertArrayEquals(new int[] {VibrationEffect.Composition.PRIMITIVE_TICK}, 2540 metrics.halSupportedCompositionPrimitivesUsed); 2541 assertArrayEquals(new int[] {VibrationEffect.EFFECT_TICK}, 2542 metrics.halSupportedEffectsUsed); 2543 2544 // All unrelated metrics are empty. 2545 assertEquals(0, metrics.repeatCount); 2546 assertEquals(0, metrics.halComposePwleCount); 2547 assertEquals(0, metrics.halOnCount); 2548 assertEquals(0, metrics.halSetAmplitudeCount); 2549 assertEquals(0, metrics.halSetExternalControlCount); 2550 assertEquals(0, metrics.halPwleSize); 2551 assertNull(metrics.halUnsupportedCompositionPrimitivesUsed); 2552 assertNull(metrics.halUnsupportedEffectsUsed); 2553 } 2554 assertCanVibrateWithBypassFlags(boolean expectedCanApplyBypassFlags)2555 private void assertCanVibrateWithBypassFlags(boolean expectedCanApplyBypassFlags) 2556 throws Exception { 2557 mockVibrators(1); 2558 mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK); 2559 VibratorManagerService service = createSystemReadyService(); 2560 2561 HalVibration vibration = vibrateAndWaitUntilFinished( 2562 service, 2563 VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK), 2564 new VibrationAttributes.Builder() 2565 .setUsage(VibrationAttributes.USAGE_TOUCH) 2566 .setFlags( 2567 VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF 2568 | VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) 2569 .build()); 2570 2571 VibrationAttributes attrs = vibration.callerInfo.attrs; 2572 assertEquals( 2573 expectedCanApplyBypassFlags, 2574 attrs.isFlagSet(VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)); 2575 assertEquals( 2576 expectedCanApplyBypassFlags, 2577 attrs.isFlagSet(VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY)); 2578 } 2579 expectedPrebaked(int effectId)2580 private VibrationEffectSegment expectedPrebaked(int effectId) { 2581 return expectedPrebaked(effectId, VibrationEffect.EFFECT_STRENGTH_MEDIUM); 2582 } 2583 expectedPrebaked(int effectId, int effectStrength)2584 private VibrationEffectSegment expectedPrebaked(int effectId, int effectStrength) { 2585 return new PrebakedSegment(effectId, false, effectStrength); 2586 } 2587 mockCapabilities(long... capabilities)2588 private void mockCapabilities(long... capabilities) { 2589 when(mNativeWrapperMock.getCapabilities()).thenReturn( 2590 Arrays.stream(capabilities).reduce(0, (a, b) -> a | b)); 2591 } 2592 mockVibrators(int... vibratorIds)2593 private void mockVibrators(int... vibratorIds) { 2594 for (int vibratorId : vibratorIds) { 2595 mVibratorProviders.put(vibratorId, 2596 new FakeVibratorControllerProvider(mTestLooper.getLooper())); 2597 } 2598 when(mNativeWrapperMock.getVibratorIds()).thenReturn(vibratorIds); 2599 } 2600 cancelVibrate(VibratorManagerService service)2601 private void cancelVibrate(VibratorManagerService service) { 2602 service.cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, service); 2603 } 2604 mockVibratorStateListener()2605 private IVibratorStateListener mockVibratorStateListener() { 2606 IVibratorStateListener listenerMock = mock(IVibratorStateListener.class); 2607 IBinder binderMock = mock(IBinder.class); 2608 when(listenerMock.asBinder()).thenReturn(binderMock); 2609 return listenerMock; 2610 } 2611 createInputDeviceWithVibrator(int id)2612 private InputDevice createInputDeviceWithVibrator(int id) { 2613 return new InputDevice.Builder() 2614 .setId(id) 2615 .setName("Test Device " + id) 2616 .setHasVibrator(true) 2617 .build(); 2618 } 2619 addLocalServiceMock(Class<T> clazz, T mock)2620 private static <T> void addLocalServiceMock(Class<T> clazz, T mock) { 2621 LocalServices.removeServiceForTest(clazz); 2622 LocalServices.addService(clazz, mock); 2623 } 2624 setRingerMode(int ringerMode)2625 private void setRingerMode(int ringerMode) { 2626 when(mAudioManagerMock.getRingerModeInternal()).thenReturn(ringerMode); 2627 } 2628 setUserSetting(String settingName, int value)2629 private void setUserSetting(String settingName, int value) { 2630 Settings.System.putIntForUser( 2631 mContextSpy.getContentResolver(), settingName, value, UserHandle.USER_CURRENT); 2632 } 2633 performHapticFeedbackAndWaitUntilFinished(VibratorManagerService service, int constant, boolean always)2634 private HalVibration performHapticFeedbackAndWaitUntilFinished(VibratorManagerService service, 2635 int constant, boolean always) throws InterruptedException { 2636 HalVibration vib = 2637 service.performHapticFeedbackInternal(UID, Context.DEVICE_ID_DEFAULT, PACKAGE_NAME, 2638 constant, always, "some reason", service, false /* fromIme */); 2639 if (vib != null) { 2640 vib.waitForEnd(); 2641 } 2642 2643 return vib; 2644 } 2645 vibrateAndWaitUntilFinished(VibratorManagerService service, VibrationEffect effect, VibrationAttributes attrs)2646 private HalVibration vibrateAndWaitUntilFinished(VibratorManagerService service, 2647 VibrationEffect effect, VibrationAttributes attrs) throws InterruptedException { 2648 return vibrateAndWaitUntilFinished( 2649 service, CombinedVibration.createParallel(effect), attrs); 2650 } 2651 vibrateAndWaitUntilFinished(VibratorManagerService service, CombinedVibration effect, VibrationAttributes attrs)2652 private HalVibration vibrateAndWaitUntilFinished(VibratorManagerService service, 2653 CombinedVibration effect, VibrationAttributes attrs) throws InterruptedException { 2654 HalVibration vib = vibrate(service, effect, attrs); 2655 if (vib != null) { 2656 vib.waitForEnd(); 2657 } 2658 return vib; 2659 } 2660 vibrate(VibratorManagerService service, VibrationEffect effect, VibrationAttributes attrs)2661 private HalVibration vibrate(VibratorManagerService service, VibrationEffect effect, 2662 VibrationAttributes attrs) { 2663 return vibrate(service, CombinedVibration.createParallel(effect), attrs); 2664 } 2665 vibrate(VibratorManagerService service, CombinedVibration effect, VibrationAttributes attrs)2666 private HalVibration vibrate(VibratorManagerService service, CombinedVibration effect, 2667 VibrationAttributes attrs) { 2668 return vibrateWithDevice(service, Context.DEVICE_ID_DEFAULT, effect, attrs); 2669 } 2670 vibrateWithDevice(VibratorManagerService service, int deviceId, CombinedVibration effect, VibrationAttributes attrs)2671 private HalVibration vibrateWithDevice(VibratorManagerService service, int deviceId, 2672 CombinedVibration effect, VibrationAttributes attrs) { 2673 HalVibration vib = service.vibrateWithPermissionCheck(UID, deviceId, PACKAGE_NAME, effect, 2674 attrs, "some reason", service); 2675 mPendingVibrations.add(vib); 2676 return vib; 2677 } 2678 waitUntil(Predicate<VibratorManagerService> predicate, VibratorManagerService service, long timeout)2679 private boolean waitUntil(Predicate<VibratorManagerService> predicate, 2680 VibratorManagerService service, long timeout) throws InterruptedException { 2681 long timeoutTimestamp = SystemClock.uptimeMillis() + timeout; 2682 boolean predicateResult = false; 2683 while (!predicateResult && SystemClock.uptimeMillis() < timeoutTimestamp) { 2684 Thread.sleep(10); 2685 predicateResult = predicate.test(service); 2686 } 2687 return predicateResult; 2688 } 2689 grantPermission(String permission)2690 private void grantPermission(String permission) { 2691 when(mContextSpy.checkCallingOrSelfPermission(permission)) 2692 .thenReturn(PackageManager.PERMISSION_GRANTED); 2693 doNothing().when(mContextSpy).enforceCallingOrSelfPermission(eq(permission), anyString()); 2694 } 2695 denyPermission(String permission)2696 private void denyPermission(String permission) { 2697 when(mContextSpy.checkCallingOrSelfPermission(permission)) 2698 .thenReturn(PackageManager.PERMISSION_DENIED); 2699 doThrow(new SecurityException()).when(mContextSpy) 2700 .enforceCallingOrSelfPermission(eq(permission), anyString()); 2701 } 2702 } 2703