From b847d63f25235500c47ff9999d010ceb736c640d Mon Sep 17 00:00:00 2001 From: Lais Andrade Date: Tue, 23 Feb 2021 10:35:27 +0000 Subject: [PATCH] Add vibrator capabilities to service dumpsys Add list of supported vibrator capabilities to information reported to dumpsys, and fix Vibration to log original effect before any change is applied by the local service. Bug: 180924179 Test: manual Change-Id: I97201771d3ee211dc2f4b6f9eac50b5b150affc0 --- Android.bp | 1 + core/java/android/os/VibrationEffect.java | 18 +++++++- core/java/android/os/VibratorInfo.java | 43 ++++++++++--------- .../src/android/os/VibratorInfoTest.java | 29 +++++++------ .../android/server/vibrator/Vibration.java | 4 +- .../vibrator/VibratorManagerService.java | 9 +++- 6 files changed, 65 insertions(+), 39 deletions(-) diff --git a/Android.bp b/Android.bp index e4c5c37ab576..2be5dff3c394 100644 --- a/Android.bp +++ b/Android.bp @@ -580,6 +580,7 @@ java_library { "android.hardware.vibrator-V1.1-java", "android.hardware.vibrator-V1.2-java", "android.hardware.vibrator-V1.3-java", + "android.hardware.vibrator-V2-java", "android.security.apc-java", "android.security.authorization-java", "android.security.usermanager-java", diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java index 0587610630a6..03e5f1d59b86 100644 --- a/core/java/android/os/VibrationEffect.java +++ b/core/java/android/os/VibrationEffect.java @@ -502,6 +502,20 @@ public abstract class VibrationEffect implements Parcelable { } } + /** @hide */ + public static String effectStrengthToString(int effectStrength) { + switch (effectStrength) { + case EFFECT_STRENGTH_LIGHT: + return "LIGHT"; + case EFFECT_STRENGTH_MEDIUM: + return "MEDIUM"; + case EFFECT_STRENGTH_STRONG: + return "STRONG"; + default: + return Integer.toString(effectStrength); + } + } + /** @hide */ @TestApi public static class OneShot extends VibrationEffect implements Parcelable { @@ -936,8 +950,8 @@ public abstract class VibrationEffect implements Parcelable { @Override public String toString() { - return "Prebaked{mEffectId=" + mEffectId - + ", mEffectStrength=" + mEffectStrength + return "Prebaked{mEffectId=" + effectIdToString(mEffectId) + + ", mEffectStrength=" + effectStrengthToString(mEffectStrength) + ", mFallback=" + mFallback + ", mFallbackEffect=" + mFallbackEffect + "}"; diff --git a/core/java/android/os/VibratorInfo.java b/core/java/android/os/VibratorInfo.java index 07272e756e77..50d2de3da965 100644 --- a/core/java/android/os/VibratorInfo.java +++ b/core/java/android/os/VibratorInfo.java @@ -18,6 +18,7 @@ package android.os; import android.annotation.NonNull; import android.annotation.Nullable; +import android.hardware.vibrator.IVibrator; import android.util.SparseBooleanArray; import java.util.ArrayList; @@ -33,20 +34,7 @@ import java.util.Objects; * @hide */ public final class VibratorInfo implements Parcelable { - - /** - * Capability to set amplitude values to vibrations. - * @hide - */ - // Internally this maps to the HAL constant IVibrator::CAP_AMPLITUDE_CONTROL - public static final int CAPABILITY_AMPLITUDE_CONTROL = 4; - - /** - * Capability to compose primitives into a single effect. - * @hide - */ - // Internally this maps to the HAL constant IVibrator::CAP_COMPOSE_EFFECTS - public static final int CAPABILITY_COMPOSE_EFFECTS = 32; + private static final String TAG = "VibratorInfo"; private final int mId; private final long mCapabilities; @@ -108,7 +96,7 @@ public final class VibratorInfo implements Parcelable { return "VibratorInfo{" + "mId=" + mId + ", mCapabilities=" + Arrays.toString(getCapabilitiesNames()) - + ", mCapabilities flags=" + mCapabilities + + ", mCapabilities flags=" + Long.toBinaryString(mCapabilities) + ", mSupportedEffects=" + Arrays.toString(getSupportedEffectsNames()) + ", mSupportedPrimitives=" + Arrays.toString(getSupportedPrimitivesNames()) + '}'; @@ -125,7 +113,7 @@ public final class VibratorInfo implements Parcelable { * @return True if the hardware can control the amplitude of the vibrations, otherwise false. */ public boolean hasAmplitudeControl() { - return hasCapability(CAPABILITY_AMPLITUDE_CONTROL); + return hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL); } /** @@ -153,7 +141,7 @@ public final class VibratorInfo implements Parcelable { * @return Whether the primitive is supported. */ public boolean isPrimitiveSupported(@VibrationEffect.Composition.Primitive int primitiveId) { - return hasCapability(CAPABILITY_COMPOSE_EFFECTS) && mSupportedPrimitives != null + return hasCapability(IVibrator.CAP_COMPOSE_EFFECTS) && mSupportedPrimitives != null && mSupportedPrimitives.get(primitiveId, false); } @@ -170,11 +158,26 @@ public final class VibratorInfo implements Parcelable { private String[] getCapabilitiesNames() { List names = new ArrayList<>(); - if (hasCapability(CAPABILITY_AMPLITUDE_CONTROL)) { + if (hasCapability(IVibrator.CAP_ON_CALLBACK)) { + names.add("ON_CALLBACK"); + } + if (hasCapability(IVibrator.CAP_PERFORM_CALLBACK)) { + names.add("PERFORM_CALLBACK"); + } + if (hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) { + names.add("COMPOSE_EFFECTS"); + } + if (hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) { + names.add("ALWAYS_ON_CONTROL"); + } + if (hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) { names.add("AMPLITUDE_CONTROL"); } - if (hasCapability(CAPABILITY_COMPOSE_EFFECTS)) { - names.add("COMPOSE_EFFECTS"); + if (hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { + names.add("EXTERNAL_CONTROL"); + } + if (hasCapability(IVibrator.CAP_EXTERNAL_AMPLITUDE_CONTROL)) { + names.add("EXTERNAL_AMPLITUDE_CONTROL"); } return names.toArray(new String[names.size()]); } diff --git a/core/tests/coretests/src/android/os/VibratorInfoTest.java b/core/tests/coretests/src/android/os/VibratorInfoTest.java index 89411902bb6b..c06405affc1b 100644 --- a/core/tests/coretests/src/android/os/VibratorInfoTest.java +++ b/core/tests/coretests/src/android/os/VibratorInfoTest.java @@ -20,6 +20,7 @@ import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; +import android.hardware.vibrator.IVibrator; import android.platform.test.annotations.Presubmit; import org.junit.Test; @@ -33,16 +34,16 @@ public class VibratorInfoTest { @Test public void testHasAmplitudeControl() { assertFalse(createInfo(/* capabilities= */ 0).hasAmplitudeControl()); - assertTrue(createInfo(VibratorInfo.CAPABILITY_COMPOSE_EFFECTS - | VibratorInfo.CAPABILITY_AMPLITUDE_CONTROL).hasAmplitudeControl()); + assertTrue(createInfo(IVibrator.CAP_COMPOSE_EFFECTS + | IVibrator.CAP_AMPLITUDE_CONTROL).hasAmplitudeControl()); } @Test public void testHasCapabilities() { - assertTrue(createInfo(VibratorInfo.CAPABILITY_COMPOSE_EFFECTS) - .hasCapability(VibratorInfo.CAPABILITY_COMPOSE_EFFECTS)); - assertFalse(createInfo(VibratorInfo.CAPABILITY_COMPOSE_EFFECTS) - .hasCapability(VibratorInfo.CAPABILITY_AMPLITUDE_CONTROL)); + assertTrue(createInfo(IVibrator.CAP_COMPOSE_EFFECTS) + .hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)); + assertFalse(createInfo(IVibrator.CAP_COMPOSE_EFFECTS) + .hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)); } @Test @@ -59,7 +60,7 @@ public class VibratorInfoTest { @Test public void testIsPrimitiveSupported() { - VibratorInfo info = new VibratorInfo(/* id= */ 0, VibratorInfo.CAPABILITY_COMPOSE_EFFECTS, + VibratorInfo info = new VibratorInfo(/* id= */ 0, IVibrator.CAP_COMPOSE_EFFECTS, null, new int[]{VibrationEffect.Composition.PRIMITIVE_CLICK}); assertTrue(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_CLICK)); assertFalse(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_TICK)); @@ -73,30 +74,30 @@ public class VibratorInfoTest { @Test public void testEquals() { VibratorInfo empty = new VibratorInfo(1, 0, null, null); - VibratorInfo complete = new VibratorInfo(1, VibratorInfo.CAPABILITY_AMPLITUDE_CONTROL, + VibratorInfo complete = new VibratorInfo(1, IVibrator.CAP_AMPLITUDE_CONTROL, new int[]{VibrationEffect.EFFECT_CLICK}, new int[]{VibrationEffect.Composition.PRIMITIVE_CLICK}); assertEquals(complete, complete); - assertEquals(complete, new VibratorInfo(1, VibratorInfo.CAPABILITY_AMPLITUDE_CONTROL, + assertEquals(complete, new VibratorInfo(1, IVibrator.CAP_AMPLITUDE_CONTROL, new int[]{VibrationEffect.EFFECT_CLICK}, new int[]{VibrationEffect.Composition.PRIMITIVE_CLICK})); assertFalse(empty.equals(new VibratorInfo(1, 0, new int[]{}, new int[]{}))); - assertFalse(complete.equals(new VibratorInfo(1, VibratorInfo.CAPABILITY_COMPOSE_EFFECTS, + assertFalse(complete.equals(new VibratorInfo(1, IVibrator.CAP_COMPOSE_EFFECTS, new int[]{VibrationEffect.EFFECT_CLICK}, new int[]{VibrationEffect.Composition.PRIMITIVE_CLICK}))); - assertFalse(complete.equals(new VibratorInfo(1, VibratorInfo.CAPABILITY_AMPLITUDE_CONTROL, + assertFalse(complete.equals(new VibratorInfo(1, IVibrator.CAP_AMPLITUDE_CONTROL, new int[]{}, new int[]{}))); - assertFalse(complete.equals(new VibratorInfo(1, VibratorInfo.CAPABILITY_AMPLITUDE_CONTROL, + assertFalse(complete.equals(new VibratorInfo(1, IVibrator.CAP_AMPLITUDE_CONTROL, null, new int[]{VibrationEffect.Composition.PRIMITIVE_CLICK}))); - assertFalse(complete.equals(new VibratorInfo(1, VibratorInfo.CAPABILITY_AMPLITUDE_CONTROL, + assertFalse(complete.equals(new VibratorInfo(1, IVibrator.CAP_AMPLITUDE_CONTROL, new int[]{VibrationEffect.EFFECT_CLICK}, null))); } @Test public void testSerialization() { - VibratorInfo original = new VibratorInfo(1, VibratorInfo.CAPABILITY_COMPOSE_EFFECTS, + VibratorInfo original = new VibratorInfo(1, IVibrator.CAP_COMPOSE_EFFECTS, new int[]{VibrationEffect.EFFECT_CLICK}, null); Parcel parcel = Parcel.obtain(); diff --git a/services/core/java/com/android/server/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java index 607da3ce6fe2..e84ee672bf0f 100644 --- a/services/core/java/com/android/server/vibrator/Vibration.java +++ b/services/core/java/com/android/server/vibrator/Vibration.java @@ -120,7 +120,9 @@ final class Vibration { if (newEffect.equals(mEffect)) { return; } - mOriginalEffect = mEffect; + if (mOriginalEffect == null) { + mOriginalEffect = mEffect; + } mEffect = newEffect; } diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java index 175085475b6c..6274ed5cb003 100644 --- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java +++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java @@ -340,10 +340,11 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { if (!isEffectValid(effect)) { return; } - effect = fixupVibrationEffect(effect); attrs = fixupVibrationAttributes(attrs); Vibration vib = new Vibration(token, mNextVibrationId.getAndIncrement(), effect, attrs, uid, opPkg, reason); + // Update with fixed up effect to keep the original effect in Vibration for debugging. + vib.updateEffect(fixupVibrationEffect(effect)); synchronized (mLock) { Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(vib); @@ -1134,6 +1135,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { void dumpText(PrintWriter pw) { pw.println("Vibrator Manager Service:"); synchronized (mLock) { + pw.println(" mVibrationSettings:"); + pw.println(" " + mVibrationSettings); + pw.println(); pw.println(" mVibratorControllers:"); for (int i = 0; i < mVibrators.size(); i++) { pw.println(" " + mVibrators.valueAt(i)); @@ -1142,14 +1146,15 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { pw.println(" mCurrentVibration:"); pw.println(" " + (mCurrentVibration == null ? null : mCurrentVibration.getVibration().getDebugInfo())); + pw.println(); pw.println(" mNextVibration:"); pw.println(" " + (mNextVibration == null ? null : mNextVibration.getVibration().getDebugInfo())); + pw.println(); pw.println(" mCurrentExternalVibration:"); pw.println(" " + (mCurrentExternalVibration == null ? null : mCurrentExternalVibration.getDebugInfo())); pw.println(); - pw.println(" mVibrationSettings=" + mVibrationSettings); for (int i = 0; i < mPreviousVibrations.size(); i++) { pw.println(); pw.print(" Previous vibrations for usage ");