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