Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 122f12d0 authored by Lais Andrade's avatar Lais Andrade
Browse files

Use vibration id as callback reference in VibratorService

Instead of creating a new global reference for each Vibration jobject
for native callback we are now only keeping a local copy of a jlong
vibrationId to be passed back to a method from VibrationService.

The single global reference to VibrationService is created in
vibratorInit and used in all callbacks.

Fix: 163901838
Fix: 165045639
Fix: 164290392
Bug: 153418251
Test: atest FrameworksServicesTests:VibratorServiceTest
      atest CorePerfTests:ViewPerfTest
      atest CorePerfTests:VibratorPerfTest
Change-Id: I91791d0a8c524f09167bf6256faa751b957f3056
parent e92740ab
Loading
Loading
Loading
Loading
+71 −57
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class VibratorService extends IVibratorService.Stub
        implements InputManager.InputDeviceListener {
@@ -114,6 +115,9 @@ public class VibratorService extends IVibratorService.Stub
    private static final VibrationAttributes DEFAULT_ATTRIBUTES =
            new VibrationAttributes.Builder().build();

    // Used to generate globally unique vibration ids.
    private final AtomicInteger mNextVibrationId = new AtomicInteger(1); // 0 = no callback

    // A mapping from the intensity adjustment to the scaling to apply, where the intensity
    // adjustment is defined as the delta between the default intensity level and the user selected
    // intensity level. It's important that we apply the scaling on the delta between the two so
@@ -171,34 +175,34 @@ public class VibratorService extends IVibratorService.Stub
    private int mRingIntensity;
    private SparseArray<Vibration> mAlwaysOnEffects = new SparseArray<>();

    static native long vibratorInit();
    static native long vibratorInit(OnCompleteListener listener);

    static native long vibratorGetFinalizer();

    static native boolean vibratorExists(long controllerPtr);
    static native boolean vibratorExists(long nativeServicePtr);

    static native void vibratorOn(long controllerPtr, long milliseconds, Vibration vibration);
    static native void vibratorOn(long nativeServicePtr, long milliseconds, long vibrationId);

    static native void vibratorOff(long controllerPtr);
    static native void vibratorOff(long nativeServicePtr);

    static native void vibratorSetAmplitude(long controllerPtr, int amplitude);
    static native void vibratorSetAmplitude(long nativeServicePtr, int amplitude);

    static native int[] vibratorGetSupportedEffects(long controllerPtr);
    static native int[] vibratorGetSupportedEffects(long nativeServicePtr);

    static native int[] vibratorGetSupportedPrimitives(long controllerPtr);
    static native int[] vibratorGetSupportedPrimitives(long nativeServicePtr);

    static native long vibratorPerformEffect(
            long controllerPtr, long effect, long strength, Vibration vibration);
            long nativeServicePtr, long effect, long strength, long vibrationId);

    static native void vibratorPerformComposedEffect(long controllerPtr,
            VibrationEffect.Composition.PrimitiveEffect[] effect, Vibration vibration);
    static native void vibratorPerformComposedEffect(long nativeServicePtr,
            VibrationEffect.Composition.PrimitiveEffect[] effect, long vibrationId);

    static native void vibratorSetExternalControl(long controllerPtr, boolean enabled);
    static native void vibratorSetExternalControl(long nativeServicePtr, boolean enabled);

    static native long vibratorGetCapabilities(long controllerPtr);
    static native void vibratorAlwaysOnEnable(long controllerPtr, long id, long effect,
    static native long vibratorGetCapabilities(long nativeServicePtr);
    static native void vibratorAlwaysOnEnable(long nativeServicePtr, long id, long effect,
            long strength);
    static native void vibratorAlwaysOnDisable(long controllerPtr, long id);
    static native void vibratorAlwaysOnDisable(long nativeServicePtr, long id);

    private final IUidObserver mUidObserver = new IUidObserver.Stub() {
        @Override public void onUidStateChanged(int uid, int procState, long procStateSeq,
@@ -220,12 +224,19 @@ public class VibratorService extends IVibratorService.Stub
        }
    };

    /** Listener for vibration completion callbacks from native. */
    public interface OnCompleteListener {

        /** Callback triggered when vibration is complete, identified by {@link Vibration#id}. */
        void onComplete(long vibrationId);
    }

    /**
     * Holder for a vibration to be played. This class can be shared with native methods for
     * hardware callback support.
     */
    @VisibleForTesting
    public final class Vibration implements IBinder.DeathRecipient {
    private final class Vibration implements IBinder.DeathRecipient {

        public final IBinder token;
        // Start time in CLOCK_BOOTTIME base.
        public final long startTime;
@@ -234,6 +245,7 @@ public class VibratorService extends IVibratorService.Stub
        // not to be affected by discontinuities created by RTC adjustments.
        public final long startTimeDebug;
        public final VibrationAttributes attrs;
        public final long id;
        public final int uid;
        public final String opPkg;
        public final String reason;
@@ -248,6 +260,7 @@ public class VibratorService extends IVibratorService.Stub
                VibrationAttributes attrs, int uid, String opPkg, String reason) {
            this.token = token;
            this.effect = effect;
            this.id = mNextVibrationId.getAndIncrement();
            this.startTime = SystemClock.elapsedRealtime();
            this.startTimeDebug = System.currentTimeMillis();
            this.attrs = attrs;
@@ -268,19 +281,6 @@ public class VibratorService extends IVibratorService.Stub
            }
        }

        /** Callback for when vibration is complete, to be called by native. */
        @VisibleForTesting
        public void onComplete() {
            synchronized (mLock) {
                if (this == mCurrentVibration) {
                    if (DEBUG) {
                        Slog.d(TAG, "Vibration finished by callback, cleaning up");
                    }
                    doCancelVibrateLocked();
                }
            }
        }

        public boolean hasTimeoutLongerThan(long millis) {
            final long duration = effect.getDuration();
            return duration >= 0 && duration > millis;
@@ -385,14 +385,14 @@ public class VibratorService extends IVibratorService.Stub
        mNativeWrapper = injector.getNativeWrapper();
        mH = injector.createHandler(Looper.myLooper());

        long controllerPtr = mNativeWrapper.vibratorInit();
        long nativeServicePtr = mNativeWrapper.vibratorInit(this::onVibrationComplete);
        long finalizerPtr = mNativeWrapper.vibratorGetFinalizer();

        if (finalizerPtr != 0) {
            NativeAllocationRegistry registry =
                    NativeAllocationRegistry.createMalloced(
                            VibratorService.class.getClassLoader(), finalizerPtr);
            registry.registerNativeAllocation(this, controllerPtr);
            registry.registerNativeAllocation(this, nativeServicePtr);
        }

        // Reset the hardware to a default state, in case this is a runtime
@@ -549,6 +549,19 @@ public class VibratorService extends IVibratorService.Stub
        }
    }

    /** Callback for when vibration is complete, to be called by native. */
    @VisibleForTesting
    public void onVibrationComplete(long vibrationId) {
        synchronized (mLock) {
            if (mCurrentVibration != null && mCurrentVibration.id == vibrationId) {
                if (DEBUG) {
                    Slog.d(TAG, "Vibration finished by callback, cleaning up");
                }
                doCancelVibrateLocked();
            }
        }
    }

    @Override // Binder call
    public boolean hasVibrator() {
        return doVibratorExists();
@@ -1266,18 +1279,18 @@ public class VibratorService extends IVibratorService.Stub
        return mNativeWrapper.vibratorExists();
    }

    /** Vibrates with native callback trigger for {@link Vibration#onComplete()}. */
    /** Vibrates with native callback trigger for {@link #onVibrationComplete(long)}. */
    private void doVibratorOn(long millis, int amplitude, Vibration vib) {
        doVibratorOn(millis, amplitude, vib.uid, vib.attrs, vib);
        doVibratorOn(millis, amplitude, vib.uid, vib.attrs, vib.id);
    }

    /** Vibrates without native callback. */
    private void doVibratorOn(long millis, int amplitude, int uid, VibrationAttributes attrs) {
        doVibratorOn(millis, amplitude, uid, attrs, /* vib= */ null);
        doVibratorOn(millis, amplitude, uid, attrs, /* vibrationId= */ 0);
    }

    private void doVibratorOn(long millis, int amplitude, int uid, VibrationAttributes attrs,
            @Nullable Vibration vib) {
            long vibrationId) {
        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorOn");
        try {
            synchronized (mInputDeviceVibrators) {
@@ -1299,7 +1312,7 @@ public class VibratorService extends IVibratorService.Stub
                    // Note: ordering is important here! Many haptic drivers will reset their
                    // amplitude when enabled, so we always have to enable first, then set the
                    // amplitude.
                    mNativeWrapper.vibratorOn(millis, vib);
                    mNativeWrapper.vibratorOn(millis, vibrationId);
                    doVibratorSetAmplitude(amplitude);
                }
            }
@@ -1348,7 +1361,7 @@ public class VibratorService extends IVibratorService.Stub
            // Input devices don't support prebaked effect, so skip trying it with them.
            if (!usingInputDeviceVibrators) {
                long duration = mNativeWrapper.vibratorPerformEffect(
                        prebaked.getId(), prebaked.getEffectStrength(), vib);
                        prebaked.getId(), prebaked.getEffectStrength(), vib.id);
                if (duration > 0) {
                    noteVibratorOnLocked(vib.uid, duration);
                    return;
@@ -1395,7 +1408,7 @@ public class VibratorService extends IVibratorService.Stub

            PrimitiveEffect[] primitiveEffects =
                    composed.getPrimitiveEffects().toArray(new PrimitiveEffect[0]);
            mNativeWrapper.vibratorPerformComposedEffect(primitiveEffects, vib);
            mNativeWrapper.vibratorPerformComposedEffect(primitiveEffects, vib.id);

            // Composed effects don't actually give us an estimated duration, so we just guess here.
            noteVibratorOnLocked(vib.uid, 10 * primitiveEffects.length);
@@ -1726,20 +1739,20 @@ public class VibratorService extends IVibratorService.Stub
    @VisibleForTesting
    public static class NativeWrapper {

        private long mNativeControllerPtr = 0;
        private long mNativeServicePtr = 0;

        /** Checks if vibrator exists on device. */
        public boolean vibratorExists() {
            return VibratorService.vibratorExists(mNativeControllerPtr);
            return VibratorService.vibratorExists(mNativeServicePtr);
        }

        /**
         * Returns native pointer to newly created controller and initializes connection to vibrator
         * HAL service.
         */
        public long vibratorInit() {
            mNativeControllerPtr = VibratorService.vibratorInit();
            return mNativeControllerPtr;
        public long vibratorInit(OnCompleteListener listener) {
            mNativeServicePtr = VibratorService.vibratorInit(listener);
            return mNativeServicePtr;
        }

        /** Returns pointer to native finalizer function to be called by GC. */
@@ -1748,60 +1761,61 @@ public class VibratorService extends IVibratorService.Stub
        }

        /** Turns vibrator on for given time. */
        public void vibratorOn(long milliseconds, @Nullable Vibration vibration) {
            VibratorService.vibratorOn(mNativeControllerPtr, milliseconds, vibration);
        public void vibratorOn(long milliseconds, long vibrationId) {
            VibratorService.vibratorOn(mNativeServicePtr, milliseconds, vibrationId);
        }

        /** Turns vibrator off. */
        public void vibratorOff() {
            VibratorService.vibratorOff(mNativeControllerPtr);
            VibratorService.vibratorOff(mNativeServicePtr);
        }

        /** Sets the amplitude for the vibrator to run. */
        public void vibratorSetAmplitude(int amplitude) {
            VibratorService.vibratorSetAmplitude(mNativeControllerPtr, amplitude);
            VibratorService.vibratorSetAmplitude(mNativeServicePtr, amplitude);
        }

        /** Returns all predefined effects supported by the device vibrator. */
        public int[] vibratorGetSupportedEffects() {
            return VibratorService.vibratorGetSupportedEffects(mNativeControllerPtr);
            return VibratorService.vibratorGetSupportedEffects(mNativeServicePtr);
        }

        /** Returns all compose primitives supported by the device vibrator. */
        public int[] vibratorGetSupportedPrimitives() {
            return VibratorService.vibratorGetSupportedPrimitives(mNativeControllerPtr);
            return VibratorService.vibratorGetSupportedPrimitives(mNativeServicePtr);
        }

        /** Turns vibrator on to perform one of the supported effects. */
        public long vibratorPerformEffect(long effect, long strength, Vibration vibration) {
        public long vibratorPerformEffect(long effect, long strength, long vibrationId) {
            return VibratorService.vibratorPerformEffect(
                    mNativeControllerPtr, effect, strength, vibration);
                    mNativeServicePtr, effect, strength, vibrationId);
        }

        /** Turns vibrator on to perform one of the supported composed effects. */
        public void vibratorPerformComposedEffect(
                VibrationEffect.Composition.PrimitiveEffect[] effect, Vibration vibration) {
            VibratorService.vibratorPerformComposedEffect(mNativeControllerPtr, effect, vibration);
                VibrationEffect.Composition.PrimitiveEffect[] effect, long vibrationId) {
            VibratorService.vibratorPerformComposedEffect(mNativeServicePtr, effect,
                    vibrationId);
        }

        /** Enabled the device vibrator to be controlled by another service. */
        public void vibratorSetExternalControl(boolean enabled) {
            VibratorService.vibratorSetExternalControl(mNativeControllerPtr, enabled);
            VibratorService.vibratorSetExternalControl(mNativeServicePtr, enabled);
        }

        /** Returns all capabilities of the device vibrator. */
        public long vibratorGetCapabilities() {
            return VibratorService.vibratorGetCapabilities(mNativeControllerPtr);
            return VibratorService.vibratorGetCapabilities(mNativeServicePtr);
        }

        /** Enable always-on vibration with given id and effect. */
        public void vibratorAlwaysOnEnable(long id, long effect, long strength) {
            VibratorService.vibratorAlwaysOnEnable(mNativeControllerPtr, id, effect, strength);
            VibratorService.vibratorAlwaysOnEnable(mNativeServicePtr, id, effect, strength);
        }

        /** Disable always-on vibration for given id. */
        public void vibratorAlwaysOnDisable(long id) {
            VibratorService.vibratorAlwaysOnDisable(mNativeControllerPtr, id);
            VibratorService.vibratorAlwaysOnDisable(mNativeServicePtr, id);
        }
    }

+121 −111

File changed.

Preview size limit exceeded, changes collapsed.

+30 −59
Original line number Diff line number Diff line
@@ -20,12 +20,13 @@ import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.AdditionalMatchers.gt;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.intThat;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.ArgumentMatchers.notNull;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.never;
@@ -167,7 +168,7 @@ public class VibratorServiceTest {
    @Test
    public void createService_initializesNativeService() {
        createService();
        verify(mNativeWrapperMock).vibratorInit();
        verify(mNativeWrapperMock).vibratorInit(notNull());
        verify(mNativeWrapperMock).vibratorOff();
    }

@@ -294,7 +295,7 @@ public class VibratorServiceTest {
        assertTrue(service.isVibrating());

        verify(mNativeWrapperMock).vibratorOff();
        verify(mNativeWrapperMock).vibratorOn(eq(100L), any(VibratorService.Vibration.class));
        verify(mNativeWrapperMock).vibratorOn(eq(100L), gt(0L));
        verify(mNativeWrapperMock).vibratorSetAmplitude(eq(128));
    }

@@ -307,7 +308,7 @@ public class VibratorServiceTest {
        assertTrue(service.isVibrating());

        verify(mNativeWrapperMock).vibratorOff();
        verify(mNativeWrapperMock).vibratorOn(eq(100L), any(VibratorService.Vibration.class));
        verify(mNativeWrapperMock).vibratorOn(eq(100L), gt(0L));
        verify(mNativeWrapperMock, never()).vibratorSetAmplitude(anyInt());
    }

@@ -321,10 +322,8 @@ public class VibratorServiceTest {
        vibrate(service, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));

        verify(mNativeWrapperMock).vibratorOff();
        verify(mNativeWrapperMock).vibratorPerformEffect(
                eq((long) VibrationEffect.EFFECT_CLICK),
                eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG),
                any(VibratorService.Vibration.class));
        verify(mNativeWrapperMock).vibratorPerformEffect(eq((long) VibrationEffect.EFFECT_CLICK),
                eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG), gt(0L));
    }

    @Test
@@ -343,7 +342,7 @@ public class VibratorServiceTest {

        verify(mNativeWrapperMock).vibratorOff();
        verify(mNativeWrapperMock).vibratorPerformComposedEffect(
                primitivesCaptor.capture(), any(VibratorService.Vibration.class));
                primitivesCaptor.capture(), gt(0L));

        // Check all primitive effect fields are passed down to the HAL.
        assertEquals(1, primitivesCaptor.getValue().length);
@@ -368,7 +367,7 @@ public class VibratorServiceTest {

        // Wait for VibrateThread to turn vibrator ON with total timing and no callback.
        Thread.sleep(5);
        verify(mNativeWrapperMock).vibratorOn(eq(30L), isNull());
        verify(mNativeWrapperMock).vibratorOn(eq(30L), eq(0L));

        // First amplitude set right away.
        verify(mNativeWrapperMock).vibratorSetAmplitude(eq(100));
@@ -384,11 +383,11 @@ public class VibratorServiceTest {

    @Test
    public void vibrate_withOneShotAndNativeCallbackTriggered_finishesVibration() {
        VibratorService service = createService();
        doAnswer(invocation -> {
            ((VibratorService.Vibration) invocation.getArgument(1)).onComplete();
            service.onVibrationComplete(invocation.getArgument(1));
            return null;
        }).when(mNativeWrapperMock).vibratorOn(anyLong(), any(VibratorService.Vibration.class));
        VibratorService service = createService();
        }).when(mNativeWrapperMock).vibratorOn(anyLong(), anyLong());
        Mockito.clearInvocations(mNativeWrapperMock);

        vibrate(service, VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE));
@@ -396,7 +395,7 @@ public class VibratorServiceTest {
        InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
        inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
        inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(100L),
                any(VibratorService.Vibration.class));
                gt(0L));
        inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
    }

@@ -404,12 +403,11 @@ public class VibratorServiceTest {
    public void vibrate_withPrebakedAndNativeCallbackTriggered_finishesVibration() {
        when(mNativeWrapperMock.vibratorGetSupportedEffects())
                .thenReturn(new int[]{VibrationEffect.EFFECT_CLICK});
        VibratorService service = createService();
        doAnswer(invocation -> {
            ((VibratorService.Vibration) invocation.getArgument(2)).onComplete();
            service.onVibrationComplete(invocation.getArgument(2));
            return 10_000L; // 10s
        }).when(mNativeWrapperMock).vibratorPerformEffect(
                anyLong(), anyLong(), any(VibratorService.Vibration.class));
        VibratorService service = createService();
        }).when(mNativeWrapperMock).vibratorPerformEffect(anyLong(), anyLong(), anyLong());
        Mockito.clearInvocations(mNativeWrapperMock);

        vibrate(service, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
@@ -419,7 +417,7 @@ public class VibratorServiceTest {
        inOrderVerifier.verify(mNativeWrapperMock).vibratorPerformEffect(
                eq((long) VibrationEffect.EFFECT_CLICK),
                eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG),
                any(VibratorService.Vibration.class));
                gt(0L));
        inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
    }

@@ -436,44 +434,19 @@ public class VibratorServiceTest {
        Thread.sleep(15);
        InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
        inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
        inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(3L), isNull());
        inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(2L), isNull());
        inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(3L), eq(0L));
        inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(2L), eq(0L));
        inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
    }

    @Test
    public void vibrate_withComposedAndNativeCallbackTriggered_finishesVibration() {
        mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
        doAnswer(invocation -> {
            ((VibratorService.Vibration) invocation.getArgument(1)).onComplete();
            return null;
        }).when(mNativeWrapperMock).vibratorPerformComposedEffect(
                any(), any(VibratorService.Vibration.class));
        VibratorService service = createService();
        Mockito.clearInvocations(mNativeWrapperMock);

        VibrationEffect effect = VibrationEffect.startComposition()
                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 10)
                .compose();
        vibrate(service, effect);

        InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
        inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
        inOrderVerifier.verify(mNativeWrapperMock).vibratorPerformComposedEffect(
                any(VibrationEffect.Composition.PrimitiveEffect[].class),
                any(VibratorService.Vibration.class));
        inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
    }

    @Test
    public void vibrate_whenBinderDies_cancelsVibration() {
        mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
        doAnswer(invocation -> {
            ((VibratorService.Vibration) invocation.getArgument(1)).binderDied();
            service.onVibrationComplete(invocation.getArgument(1));
            return null;
        }).when(mNativeWrapperMock).vibratorPerformComposedEffect(
                any(), any(VibratorService.Vibration.class));
        VibratorService service = createService();
        }).when(mNativeWrapperMock).vibratorPerformComposedEffect(any(), anyLong());
        Mockito.clearInvocations(mNativeWrapperMock);

        VibrationEffect effect = VibrationEffect.startComposition()
@@ -484,8 +457,7 @@ public class VibratorServiceTest {
        InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
        inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
        inOrderVerifier.verify(mNativeWrapperMock).vibratorPerformComposedEffect(
                any(VibrationEffect.Composition.PrimitiveEffect[].class),
                any(VibratorService.Vibration.class));
                any(VibrationEffect.Composition.PrimitiveEffect[].class), gt(0L));
        inOrderVerifier.verify(mNativeWrapperMock).vibratorOff();
    }

@@ -513,12 +485,11 @@ public class VibratorServiceTest {

    @Test
    public void registerVibratorStateListener_callbacksAreTriggered() throws Exception {
        VibratorService service = createService();
        doAnswer(invocation -> {
            ((VibratorService.Vibration) invocation.getArgument(1)).onComplete();
            service.onVibrationComplete(invocation.getArgument(1));
            return null;
        }).when(mNativeWrapperMock).vibratorOn(anyLong(), any(VibratorService.Vibration.class));
        VibratorService service = createService();

        }).when(mNativeWrapperMock).vibratorOn(anyLong(), anyLong());
        service.registerVibratorStateListener(mVibratorStateListenerMock);
        verify(mVibratorStateListenerMock).onVibrating(false);
        Mockito.clearInvocations(mVibratorStateListenerMock);
@@ -569,15 +540,15 @@ public class VibratorServiceTest {

        verify(mNativeWrapperMock).vibratorPerformEffect(
                eq((long) VibrationEffect.EFFECT_CLICK),
                eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG), any());
                eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG), anyLong());
        verify(mNativeWrapperMock).vibratorPerformEffect(
                eq((long) VibrationEffect.EFFECT_TICK),
                eq((long) VibrationEffect.EFFECT_STRENGTH_MEDIUM), any());
                eq((long) VibrationEffect.EFFECT_STRENGTH_MEDIUM), anyLong());
        verify(mNativeWrapperMock).vibratorPerformEffect(
                eq((long) VibrationEffect.EFFECT_DOUBLE_CLICK),
                eq((long) VibrationEffect.EFFECT_STRENGTH_LIGHT), any());
                eq((long) VibrationEffect.EFFECT_STRENGTH_LIGHT), anyLong());
        verify(mNativeWrapperMock, never()).vibratorPerformEffect(
                eq((long) VibrationEffect.EFFECT_HEAVY_CLICK), anyLong(), any());
                eq((long) VibrationEffect.EFFECT_HEAVY_CLICK), anyLong(), anyLong());
    }

    @Test
@@ -644,7 +615,7 @@ public class VibratorServiceTest {

        // Ringtone vibration is off, so only the other 3 are propagated to native.
        verify(mNativeWrapperMock, times(3)).vibratorPerformComposedEffect(
                primitivesCaptor.capture(), any());
                primitivesCaptor.capture(), anyLong());

        List<VibrationEffect.Composition.PrimitiveEffect[]> values =
                primitivesCaptor.getAllValues();