Loading core/java/android/os/CombinedVibrationEffect.java +26 −3 Original line number Diff line number Diff line Loading @@ -364,8 +364,22 @@ public abstract class CombinedVibrationEffect implements Parcelable { @Override public long getDuration() { long maxDuration = Long.MIN_VALUE; boolean hasUnknownStep = false; for (int i = 0; i < mEffects.size(); i++) { maxDuration = Math.max(maxDuration, mEffects.valueAt(i).getDuration()); long duration = mEffects.valueAt(i).getDuration(); if (duration == Long.MAX_VALUE) { // If any duration is repeating, this combination duration is also repeating. return duration; } maxDuration = Math.max(maxDuration, duration); // If any step is unknown, this combination duration will also be unknown, unless // any step is repeating. Repeating vibrations take precedence over non-repeating // ones in the service, so continue looping to check for repeating steps. hasUnknownStep |= duration < 0; } if (hasUnknownStep) { // If any step is unknown, this combination duration is also unknown. return -1; } return maxDuration; } Loading Loading @@ -477,16 +491,25 @@ public abstract class CombinedVibrationEffect implements Parcelable { @Override public long getDuration() { boolean hasUnknownStep = false; long durations = 0; final int effectCount = mEffects.size(); for (int i = 0; i < effectCount; i++) { CombinedVibrationEffect effect = mEffects.get(i); long duration = effect.getDuration(); if (duration < 0) { // If any duration is unknown, this combination duration is also unknown. if (duration == Long.MAX_VALUE) { // If any duration is repeating, this combination duration is also repeating. return duration; } durations += duration; // If any step is unknown, this combination duration will also be unknown, unless // any step is repeating. Repeating vibrations take precedence over non-repeating // ones in the service, so continue looping to check for repeating steps. hasUnknownStep |= duration < 0; } if (hasUnknownStep) { // If any step is unknown, this combination duration is also unknown. return -1; } long delays = 0; for (int i = 0; i < effectCount; i++) { Loading core/java/android/os/IVibratorManagerService.aidl +4 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.os; import android.os.CombinedVibrationEffect; import android.os.IVibratorStateListener; import android.os.VibrationAttributes; import android.os.VibratorInfo; Loading @@ -24,6 +25,9 @@ import android.os.VibratorInfo; interface IVibratorManagerService { int[] getVibratorIds(); VibratorInfo getVibratorInfo(int vibratorId); boolean isVibrating(int vibratorId); boolean registerVibratorStateListener(int vibratorId, in IVibratorStateListener listener); boolean unregisterVibratorStateListener(int vibratorId, in IVibratorStateListener listener); boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId, in CombinedVibrationEffect effect, in VibrationAttributes attributes); void vibrate(int uid, String opPkg, in CombinedVibrationEffect effect, Loading core/tests/coretests/src/android/os/CombinedVibrationEffectTest.java +55 −0 Original line number Diff line number Diff line Loading @@ -116,6 +116,61 @@ public class CombinedVibrationEffectTest { () -> CombinedVibrationEffect.startSequential().combine()); } @Test public void testDurationMono() { assertEquals(1, CombinedVibrationEffect.createSynced( VibrationEffect.createOneShot(1, 1)).getDuration()); assertEquals(-1, CombinedVibrationEffect.createSynced( VibrationEffect.get(VibrationEffect.EFFECT_CLICK)).getDuration()); assertEquals(Long.MAX_VALUE, CombinedVibrationEffect.createSynced( VibrationEffect.createWaveform( new long[]{1, 2, 3}, new int[]{1, 2, 3}, 0)).getDuration()); } @Test public void testDurationStereo() { assertEquals(6, CombinedVibrationEffect.startSynced() .addVibrator(1, VibrationEffect.createOneShot(1, 1)) .addVibrator(2, VibrationEffect.createWaveform(new long[]{1, 2, 3}, new int[]{1, 2, 3}, -1)) .combine() .getDuration()); assertEquals(-1, CombinedVibrationEffect.startSynced() .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK)) .addVibrator(2, VibrationEffect.createWaveform(new long[]{1, 2, 3}, new int[]{1, 2, 3}, -1)) .combine() .getDuration()); assertEquals(Long.MAX_VALUE, CombinedVibrationEffect.startSynced() .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK)) .addVibrator(2, VibrationEffect.createWaveform(new long[]{1, 2, 3}, new int[]{1, 2, 3}, 0)) .combine() .getDuration()); } @Test public void testDurationSequential() { assertEquals(26, CombinedVibrationEffect.startSequential() .addNext(1, VibrationEffect.createOneShot(10, 10), 10) .addNext(2, VibrationEffect.createWaveform(new long[]{1, 2, 3}, new int[]{1, 2, 3}, -1)) .combine() .getDuration()); assertEquals(-1, CombinedVibrationEffect.startSequential() .addNext(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK)) .addNext(2, VibrationEffect.createWaveform(new long[]{1, 2, 3}, new int[]{1, 2, 3}, -1)) .combine() .getDuration()); assertEquals(Long.MAX_VALUE, CombinedVibrationEffect.startSequential() .addNext(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK)) .addNext(2, VibrationEffect.createWaveform(new long[]{1, 2, 3}, new int[]{1, 2, 3}, 0)) .combine() .getDuration()); } @Test public void testSerializationMono() { CombinedVibrationEffect original = CombinedVibrationEffect.createSynced(VALID_EFFECT); Loading services/core/java/com/android/server/VibratorManagerService.java +462 −20 File changed.Preview size limit exceeded, changes collapsed. Show changes services/core/java/com/android/server/vibrator/Vibration.java +5 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,11 @@ public class Vibration { return mStatus != Status.RUNNING; } /** Return true is effect is a repeating vibration. */ public boolean isRepeating() { return mEffect.getDuration() == Long.MAX_VALUE; } /** Return the effect that should be played by this vibration. */ @Nullable public CombinedVibrationEffect getEffect() { Loading Loading
core/java/android/os/CombinedVibrationEffect.java +26 −3 Original line number Diff line number Diff line Loading @@ -364,8 +364,22 @@ public abstract class CombinedVibrationEffect implements Parcelable { @Override public long getDuration() { long maxDuration = Long.MIN_VALUE; boolean hasUnknownStep = false; for (int i = 0; i < mEffects.size(); i++) { maxDuration = Math.max(maxDuration, mEffects.valueAt(i).getDuration()); long duration = mEffects.valueAt(i).getDuration(); if (duration == Long.MAX_VALUE) { // If any duration is repeating, this combination duration is also repeating. return duration; } maxDuration = Math.max(maxDuration, duration); // If any step is unknown, this combination duration will also be unknown, unless // any step is repeating. Repeating vibrations take precedence over non-repeating // ones in the service, so continue looping to check for repeating steps. hasUnknownStep |= duration < 0; } if (hasUnknownStep) { // If any step is unknown, this combination duration is also unknown. return -1; } return maxDuration; } Loading Loading @@ -477,16 +491,25 @@ public abstract class CombinedVibrationEffect implements Parcelable { @Override public long getDuration() { boolean hasUnknownStep = false; long durations = 0; final int effectCount = mEffects.size(); for (int i = 0; i < effectCount; i++) { CombinedVibrationEffect effect = mEffects.get(i); long duration = effect.getDuration(); if (duration < 0) { // If any duration is unknown, this combination duration is also unknown. if (duration == Long.MAX_VALUE) { // If any duration is repeating, this combination duration is also repeating. return duration; } durations += duration; // If any step is unknown, this combination duration will also be unknown, unless // any step is repeating. Repeating vibrations take precedence over non-repeating // ones in the service, so continue looping to check for repeating steps. hasUnknownStep |= duration < 0; } if (hasUnknownStep) { // If any step is unknown, this combination duration is also unknown. return -1; } long delays = 0; for (int i = 0; i < effectCount; i++) { Loading
core/java/android/os/IVibratorManagerService.aidl +4 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.os; import android.os.CombinedVibrationEffect; import android.os.IVibratorStateListener; import android.os.VibrationAttributes; import android.os.VibratorInfo; Loading @@ -24,6 +25,9 @@ import android.os.VibratorInfo; interface IVibratorManagerService { int[] getVibratorIds(); VibratorInfo getVibratorInfo(int vibratorId); boolean isVibrating(int vibratorId); boolean registerVibratorStateListener(int vibratorId, in IVibratorStateListener listener); boolean unregisterVibratorStateListener(int vibratorId, in IVibratorStateListener listener); boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId, in CombinedVibrationEffect effect, in VibrationAttributes attributes); void vibrate(int uid, String opPkg, in CombinedVibrationEffect effect, Loading
core/tests/coretests/src/android/os/CombinedVibrationEffectTest.java +55 −0 Original line number Diff line number Diff line Loading @@ -116,6 +116,61 @@ public class CombinedVibrationEffectTest { () -> CombinedVibrationEffect.startSequential().combine()); } @Test public void testDurationMono() { assertEquals(1, CombinedVibrationEffect.createSynced( VibrationEffect.createOneShot(1, 1)).getDuration()); assertEquals(-1, CombinedVibrationEffect.createSynced( VibrationEffect.get(VibrationEffect.EFFECT_CLICK)).getDuration()); assertEquals(Long.MAX_VALUE, CombinedVibrationEffect.createSynced( VibrationEffect.createWaveform( new long[]{1, 2, 3}, new int[]{1, 2, 3}, 0)).getDuration()); } @Test public void testDurationStereo() { assertEquals(6, CombinedVibrationEffect.startSynced() .addVibrator(1, VibrationEffect.createOneShot(1, 1)) .addVibrator(2, VibrationEffect.createWaveform(new long[]{1, 2, 3}, new int[]{1, 2, 3}, -1)) .combine() .getDuration()); assertEquals(-1, CombinedVibrationEffect.startSynced() .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK)) .addVibrator(2, VibrationEffect.createWaveform(new long[]{1, 2, 3}, new int[]{1, 2, 3}, -1)) .combine() .getDuration()); assertEquals(Long.MAX_VALUE, CombinedVibrationEffect.startSynced() .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK)) .addVibrator(2, VibrationEffect.createWaveform(new long[]{1, 2, 3}, new int[]{1, 2, 3}, 0)) .combine() .getDuration()); } @Test public void testDurationSequential() { assertEquals(26, CombinedVibrationEffect.startSequential() .addNext(1, VibrationEffect.createOneShot(10, 10), 10) .addNext(2, VibrationEffect.createWaveform(new long[]{1, 2, 3}, new int[]{1, 2, 3}, -1)) .combine() .getDuration()); assertEquals(-1, CombinedVibrationEffect.startSequential() .addNext(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK)) .addNext(2, VibrationEffect.createWaveform(new long[]{1, 2, 3}, new int[]{1, 2, 3}, -1)) .combine() .getDuration()); assertEquals(Long.MAX_VALUE, CombinedVibrationEffect.startSequential() .addNext(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK)) .addNext(2, VibrationEffect.createWaveform(new long[]{1, 2, 3}, new int[]{1, 2, 3}, 0)) .combine() .getDuration()); } @Test public void testSerializationMono() { CombinedVibrationEffect original = CombinedVibrationEffect.createSynced(VALID_EFFECT); Loading
services/core/java/com/android/server/VibratorManagerService.java +462 −20 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/core/java/com/android/server/vibrator/Vibration.java +5 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,11 @@ public class Vibration { return mStatus != Status.RUNNING; } /** Return true is effect is a repeating vibration. */ public boolean isRepeating() { return mEffect.getDuration() == Long.MAX_VALUE; } /** Return the effect that should be played by this vibration. */ @Nullable public CombinedVibrationEffect getEffect() { Loading