Merge "Fix SystemVibrator constant support checks on device without vibrator" into sc-dev
diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
index fd8948c..0c3debb1 100644
--- a/core/java/android/os/SystemVibrator.java
+++ b/core/java/android/os/SystemVibrator.java
@@ -26,6 +26,7 @@
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 @@
* <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 @@
@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 @@
@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 @@
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;
diff --git a/core/tests/coretests/src/android/os/VibratorTest.java b/core/tests/coretests/src/android/os/VibratorTest.java
index 8f9168b..0ece793 100644
--- a/core/tests/coretests/src/android/os/VibratorTest.java
+++ b/core/tests/coretests/src/android/os/VibratorTest.java
@@ -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.Mockito.spy;
import static org.mockito.Mockito.verify;
+import android.hardware.vibrator.IVibrator;
import android.media.AudioAttributes;
import android.platform.test.annotations.Presubmit;
@@ -70,6 +73,54 @@
}
@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);
assertEquals(1, mVibratorSpy.arePrimitivesSupported(
@@ -80,6 +131,40 @@
}
@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);
assertEquals(1, mVibratorSpy.getPrimitiveDurations(
@@ -90,6 +175,40 @@
}
@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);
AudioAttributes audioAttributes = new AudioAttributes.Builder().setUsage(