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

Commit 9fdaad55 authored by Lais Andrade's avatar Lais Andrade
Browse files

Set external control to false on VibratorManagerService init

The VibratorManagerService turns off all vibrators during initialization
to handle the scenario where the system server has restarted (e.g. after
being killed by watchdog after a deadlock) but the vibrator hardware was
still performing a previous vibrate command.

This also sets the external control state to false, so the service won't
attemp to vibrate when the hardware is actually set for external
control.

Bug: 197165183
Test: VibratorManagerServiceTest
Change-Id: If4f0df57333fb5863fe9c1e781575634606ee662
parent 637cc7dc
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -313,6 +313,15 @@ final class VibratorController {
        }
    }

    /**
     * Resets the vibrator hardware to a default state.
     * This turns the vibrator off, which will affect the state of {@link #isVibrating()}.
     */
    public void reset() {
        setExternalControl(false);
        off();
    }

    @Override
    public String toString() {
        synchronized (mLock) {
+1 −1
Original line number Diff line number Diff line
@@ -219,7 +219,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
        // fresh boot.
        mNativeWrapper.cancelSynced();
        for (int i = 0; i < mVibrators.size(); i++) {
            mVibrators.valueAt(i).off();
            mVibrators.valueAt(i).reset();
        }

        IntentFilter filter = new IntentFilter();
+7 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ final class FakeVibratorControllerProvider {

    private boolean mIsAvailable = true;
    private long mLatency;
    private int mOffCount;

    private int mCapabilities;
    private int[] mSupportedEffects;
@@ -93,6 +94,7 @@ final class FakeVibratorControllerProvider {

        @Override
        public void off() {
            mOffCount++;
        }

        @Override
@@ -308,6 +310,11 @@ final class FakeVibratorControllerProvider {
        return mExternalControlStates;
    }

    /** Returns the number of times the vibrator was turned off. */
    public int getOffCount() {
        return mOffCount;
    }

    /**
     * Return the {@link PrebakedSegment} effect enabled with given id, or {@code null} if
     * missing or disabled.
+15 −0
Original line number Diff line number Diff line
@@ -258,6 +258,21 @@ public class VibratorControllerTest {
        verify(mNativeWrapperMock, times(2)).off();
    }

    @Test
    public void reset_turnsOffVibratorAndDisablesExternalControl() {
        mockVibratorCapabilities(IVibrator.CAP_EXTERNAL_CONTROL);
        when(mNativeWrapperMock.on(anyLong(), anyLong())).thenAnswer(args -> args.getArgument(0));
        VibratorController controller = createController();

        controller.on(100, 1);
        assertTrue(controller.isVibrating());

        controller.reset();
        assertFalse(controller.isVibrating());
        verify(mNativeWrapperMock).setExternalControl(eq(false));
        verify(mNativeWrapperMock).off();
    }

    @Test
    public void registerVibratorStateListener_callbacksAreTriggered() throws Exception {
        when(mNativeWrapperMock.on(anyLong(), anyLong())).thenAnswer(args -> args.getArgument(0));
+18 −3
Original line number Diff line number Diff line
@@ -232,6 +232,19 @@ public class VibratorManagerServiceTest {
        assertTrue(mVibratorProviders.get(2).isInitialized());
    }

    @Test
    public void createService_resetsVibrators() {
        mockVibrators(1, 2);
        mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL);
        mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL);

        createService();
        assertEquals(1, mVibratorProviders.get(1).getOffCount());
        assertEquals(1, mVibratorProviders.get(2).getOffCount());
        assertEquals(Arrays.asList(false), mVibratorProviders.get(1).getExternalControlStates());
        assertEquals(Arrays.asList(false), mVibratorProviders.get(2).getExternalControlStates());
    }

    @Test
    public void createService_doNotCrashIfUsedBeforeSystemReady() {
        mockVibrators(1, 2);
@@ -991,7 +1004,7 @@ public class VibratorManagerServiceTest {
        mExternalVibratorService.onExternalVibrationStop(externalVibration);

        assertEquals(IExternalVibratorService.SCALE_NONE, scale);
        assertEquals(Arrays.asList(true, false),
        assertEquals(Arrays.asList(false, true, false),
                mVibratorProviders.get(1).getExternalControlStates());
    }

@@ -1017,7 +1030,8 @@ public class VibratorManagerServiceTest {
        verify(firstController).mute();
        verify(secondController, never()).mute();
        // Set external control called only once.
        assertEquals(Arrays.asList(true), mVibratorProviders.get(1).getExternalControlStates());
        assertEquals(Arrays.asList(false, true),
                mVibratorProviders.get(1).getExternalControlStates());
    }

    @Test
@@ -1039,7 +1053,8 @@ public class VibratorManagerServiceTest {

        // Vibration is cancelled.
        assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
        assertEquals(Arrays.asList(true), mVibratorProviders.get(1).getExternalControlStates());
        assertEquals(Arrays.asList(false, true),
                mVibratorProviders.get(1).getExternalControlStates());
    }

    private VibrationEffectSegment expectedPrebaked(int effectId) {