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

Commit efc9cc93 authored by Lais Andrade's avatar Lais Andrade
Browse files

Fix SystemVibrator constant support checks on device without vibrator

Fix the implementation of SystemVibrator to return always no support to
all effect and primitive constants on devices with no vibrator.

Fix: 191414125
Test: FrameworksCoreTests:VibratorTest
Change-Id: I0fd9e27d6e2890df9ee206029488ea70ff50712d
parent f2d2fb52
Loading
Loading
Loading
Loading
+25 −2
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.util.Log;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;

import java.util.ArrayList;
import java.util.Objects;
@@ -254,11 +255,14 @@ public class SystemVibrator extends Vibrator {
     * <p>This uses the first vibrator on the list as the default one for all hardware spec, but
     * uses an intersection of all vibrators to decide the capabilities and effect/primitive
     * support.
     *
     * @hide
     */
    private static class AllVibratorsInfo extends VibratorInfo {
    @VisibleForTesting
    public static class AllVibratorsInfo extends VibratorInfo {
        private final VibratorInfo[] mVibratorInfos;

        AllVibratorsInfo(VibratorInfo[] vibrators) {
        public AllVibratorsInfo(VibratorInfo[] vibrators) {
            super(/* id= */ -1, capabilitiesIntersection(vibrators),
                    vibrators.length > 0 ? vibrators[0] : VibratorInfo.EMPTY_VIBRATOR_INFO);
            mVibratorInfos = vibrators;
@@ -266,6 +270,9 @@ public class SystemVibrator extends Vibrator {

        @Override
        public int isEffectSupported(int effectId) {
            if (mVibratorInfos.length == 0) {
                return Vibrator.VIBRATION_EFFECT_SUPPORT_NO;
            }
            int supported = Vibrator.VIBRATION_EFFECT_SUPPORT_YES;
            for (VibratorInfo info : mVibratorInfos) {
                int effectSupported = info.isEffectSupported(effectId);
@@ -280,6 +287,9 @@ public class SystemVibrator extends Vibrator {

        @Override
        public boolean isPrimitiveSupported(int primitiveId) {
            if (mVibratorInfos.length == 0) {
                return false;
            }
            for (VibratorInfo info : mVibratorInfos) {
                if (!info.isPrimitiveSupported(primitiveId)) {
                    return false;
@@ -288,6 +298,19 @@ public class SystemVibrator extends Vibrator {
            return true;
        }

        @Override
        public int getPrimitiveDuration(int primitiveId) {
            int maxDuration = 0;
            for (VibratorInfo info : mVibratorInfos) {
                int duration = info.getPrimitiveDuration(primitiveId);
                if (duration == 0) {
                    return 0;
                }
                maxDuration = Math.max(maxDuration, duration);
            }
            return maxDuration;
        }

        private static int capabilitiesIntersection(VibratorInfo[] infos) {
            if (infos.length == 0) {
                return 0;
+119 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.os;

import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static junit.framework.TestCase.assertEquals;

import static org.mockito.ArgumentMatchers.any;
@@ -26,6 +28,7 @@ import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;

import android.hardware.vibrator.IVibrator;
import android.media.AudioAttributes;
import android.platform.test.annotations.Presubmit;

@@ -69,6 +72,54 @@ public class VibratorTest {
                        VibrationEffect.EFFECT_TICK}).length);
    }

    @Test
    public void areEffectsSupported_noVibrator_returnsAlwaysNo() {
        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
                new VibratorInfo[0]);
        assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_NO,
                info.isEffectSupported(VibrationEffect.EFFECT_CLICK));
    }

    @Test
    public void areEffectsSupported_unsupportedInOneVibrator_returnsNo() {
        VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1)
                .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
                .build();
        VibratorInfo unsupportedVibrator = new VibratorInfo.Builder(/* id= */ 2)
                .setSupportedEffects(new int[0])
                .build();
        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
                new VibratorInfo[]{supportedVibrator, unsupportedVibrator});
        assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_NO,
                info.isEffectSupported(VibrationEffect.EFFECT_CLICK));
    }

    @Test
    public void areEffectsSupported_unknownInOneVibrator_returnsUnknown() {
        VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1)
                .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
                .build();
        VibratorInfo unknownSupportVibrator = VibratorInfo.EMPTY_VIBRATOR_INFO;
        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
                new VibratorInfo[]{supportedVibrator, unknownSupportVibrator});
        assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_UNKNOWN,
                info.isEffectSupported(VibrationEffect.EFFECT_CLICK));
    }

    @Test
    public void arePrimitivesSupported_supportedInAllVibrators_returnsYes() {
        VibratorInfo firstVibrator = new VibratorInfo.Builder(/* id= */ 1)
                .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
                .build();
        VibratorInfo secondVibrator = new VibratorInfo.Builder(/* id= */ 2)
                .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
                .build();
        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
                new VibratorInfo[]{firstVibrator, secondVibrator});
        assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_YES,
                info.isEffectSupported(VibrationEffect.EFFECT_CLICK));
    }

    @Test
    public void arePrimitivesSupported_returnsArrayOfSameSize() {
        assertEquals(0, mVibratorSpy.arePrimitivesSupported(new int[0]).length);
@@ -79,6 +130,40 @@ public class VibratorTest {
                        VibrationEffect.Composition.PRIMITIVE_QUICK_RISE}).length);
    }

    @Test
    public void arePrimitivesSupported_noVibrator_returnsAlwaysFalse() {
        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
                new VibratorInfo[0]);
        assertFalse(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_CLICK));
    }

    @Test
    public void arePrimitivesSupported_unsupportedInOneVibrator_returnsFalse() {
        VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1)
                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
                .build();
        VibratorInfo unsupportedVibrator = VibratorInfo.EMPTY_VIBRATOR_INFO;
        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
                new VibratorInfo[]{supportedVibrator, unsupportedVibrator});
        assertFalse(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_CLICK));
    }

    @Test
    public void arePrimitivesSupported_supportedInAllVibrators_returnsTrue() {
        VibratorInfo firstVibrator = new VibratorInfo.Builder(/* id= */ 1)
                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 5)
                .build();
        VibratorInfo secondVibrator = new VibratorInfo.Builder(/* id= */ 2)
                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 15)
                .build();
        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
                new VibratorInfo[]{firstVibrator, secondVibrator});
        assertTrue(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_CLICK));
    }

    @Test
    public void getPrimitivesDurations_returnsArrayOfSameSize() {
        assertEquals(0, mVibratorSpy.getPrimitiveDurations(new int[0]).length);
@@ -89,6 +174,40 @@ public class VibratorTest {
                        VibrationEffect.Composition.PRIMITIVE_QUICK_RISE}).length);
    }

    @Test
    public void getPrimitivesDurations_noVibrator_returnsAlwaysZero() {
        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
                new VibratorInfo[0]);
        assertEquals(0, info.getPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_CLICK));
    }

    @Test
    public void getPrimitivesDurations_unsupportedInOneVibrator_returnsZero() {
        VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1)
                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
                .build();
        VibratorInfo unsupportedVibrator = VibratorInfo.EMPTY_VIBRATOR_INFO;
        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
                new VibratorInfo[]{supportedVibrator, unsupportedVibrator});
        assertEquals(0, info.getPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_CLICK));
    }

    @Test
    public void getPrimitivesDurations_supportedInAllVibrators_returnsMaxDuration() {
        VibratorInfo firstVibrator = new VibratorInfo.Builder(/* id= */ 1)
                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
                .build();
        VibratorInfo secondVibrator = new VibratorInfo.Builder(/* id= */ 2)
                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 20)
                .build();
        SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo(
                new VibratorInfo[]{firstVibrator, secondVibrator});
        assertEquals(20, info.getPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_CLICK));
    }

    @Test
    public void vibrate_withAudioAttributes_createsVibrationAttributesWithSameUsage() {
        VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);