Loading core/java/android/os/SystemVibrator.java +25 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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); Loading @@ -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; Loading @@ -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; Loading core/tests/coretests/src/android/os/VibratorTest.java +119 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading Loading
core/java/android/os/SystemVibrator.java +25 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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); Loading @@ -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; Loading @@ -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; Loading
core/tests/coretests/src/android/os/VibratorTest.java +119 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading