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
diff --git a/Android.bp b/Android.bp
index e4c5c37..2be5dff 100644
--- a/Android.bp
+++ b/Android.bp
@@ -580,6 +580,7 @@
         "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 0587610..03e5f1d 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -503,6 +503,20 @@
     }
 
     /** @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 {
         private final long mDuration;
@@ -936,8 +950,8 @@
 
         @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 07272e7..50d2de3 100644
--- a/core/java/android/os/VibratorInfo.java
+++ b/core/java/android/os/VibratorInfo.java
@@ -18,6 +18,7 @@
 
 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 @@
  * @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 @@
         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 @@
      * @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 @@
      * @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 @@
 
     private String[] getCapabilitiesNames() {
         List<String> 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 8941190..c06405a 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.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 @@
     @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 @@
 
     @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 @@
     @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 607da3c..e84ee672 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 @@
         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 1750854..6274ed5 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 @@
             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 @@
         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 @@
                 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 ");