Merge "Add cancelation reason to vibration status" into tm-dev
This commit is contained in:
@@ -47,12 +47,16 @@ final class Vibration {
|
||||
FINISHED,
|
||||
FINISHED_UNEXPECTED, // Didn't terminate in the usual way.
|
||||
FORWARDED_TO_INPUT_DEVICES,
|
||||
CANCELLED,
|
||||
CANCELLED_BINDER_DIED,
|
||||
CANCELLED_BY_SCREEN_OFF,
|
||||
CANCELLED_BY_SETTINGS_UPDATE,
|
||||
CANCELLED_BY_USER,
|
||||
CANCELLED_BY_UNKNOWN_REASON,
|
||||
CANCELLED_SUPERSEDED,
|
||||
IGNORED_ERROR_APP_OPS,
|
||||
IGNORED_ERROR_CANCELLING,
|
||||
IGNORED_ERROR_SCHEDULING,
|
||||
IGNORED_ERROR_TOKEN,
|
||||
IGNORED,
|
||||
IGNORED_APP_OPS,
|
||||
IGNORED_BACKGROUND,
|
||||
IGNORED_UNKNOWN_VIBRATION,
|
||||
|
||||
@@ -79,12 +79,14 @@ final class VibrationStepConductor implements IBinder.DeathRecipient {
|
||||
private final Object mLock = new Object();
|
||||
@GuardedBy("mLock")
|
||||
private final IntArray mSignalVibratorsComplete;
|
||||
@Nullable
|
||||
@GuardedBy("mLock")
|
||||
private boolean mSignalCancel = false;
|
||||
private Vibration.Status mSignalCancelStatus = null;
|
||||
@GuardedBy("mLock")
|
||||
private boolean mSignalCancelImmediate = false;
|
||||
|
||||
private boolean mCancelled = false;
|
||||
@Nullable
|
||||
private Vibration.Status mCancelStatus = null;
|
||||
private boolean mCancelledImmediately = false; // hard stop
|
||||
private int mPendingVibrateSteps;
|
||||
private int mRemainingStartSequentialEffectSteps;
|
||||
@@ -185,8 +187,8 @@ final class VibrationStepConductor implements IBinder.DeathRecipient {
|
||||
expectIsVibrationThread(true);
|
||||
}
|
||||
|
||||
if (mCancelled) {
|
||||
return Vibration.Status.CANCELLED;
|
||||
if (mCancelStatus != null) {
|
||||
return mCancelStatus;
|
||||
}
|
||||
if (mPendingVibrateSteps > 0
|
||||
|| mRemainingStartSequentialEffectSteps > 0) {
|
||||
@@ -303,7 +305,7 @@ final class VibrationStepConductor implements IBinder.DeathRecipient {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Binder died, cancelling vibration...");
|
||||
}
|
||||
notifyCancelled(/* immediate= */ false);
|
||||
notifyCancelled(Vibration.Status.CANCELLED_BINDER_DIED, /* immediate= */ false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -312,22 +314,41 @@ final class VibrationStepConductor implements IBinder.DeathRecipient {
|
||||
*
|
||||
* @param immediate indicates whether cancellation should abort urgently and skip cleanup steps.
|
||||
*/
|
||||
public void notifyCancelled(boolean immediate) {
|
||||
public void notifyCancelled(@NonNull Vibration.Status cancelStatus, boolean immediate) {
|
||||
if (Build.IS_DEBUGGABLE) {
|
||||
expectIsVibrationThread(false);
|
||||
}
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Vibration cancel requested with status=" + cancelStatus
|
||||
+ ", immediate=" + immediate);
|
||||
}
|
||||
if ((cancelStatus == null) || !cancelStatus.name().startsWith("CANCEL")) {
|
||||
Slog.w(TAG, "Vibration cancel requested with bad status=" + cancelStatus
|
||||
+ ", using CANCELLED_UNKNOWN_REASON to ensure cancellation.");
|
||||
cancelStatus = Vibration.Status.CANCELLED_BY_UNKNOWN_REASON;
|
||||
}
|
||||
synchronized (mLock) {
|
||||
if (immediate && mSignalCancelImmediate || mSignalCancel) {
|
||||
// Nothing to update: already cancelled previously.
|
||||
if (immediate && mSignalCancelImmediate || (mSignalCancelStatus != null)) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Vibration cancel request ignored as the vibration "
|
||||
+ mVibration.id + "is already being cancelled with status="
|
||||
+ mSignalCancelStatus + ", immediate=" + mSignalCancelImmediate);
|
||||
}
|
||||
return;
|
||||
}
|
||||
mSignalCancelImmediate |= immediate;
|
||||
mSignalCancel = true;
|
||||
if (mSignalCancelStatus == null) {
|
||||
mSignalCancelStatus = cancelStatus;
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Vibration cancel request new status=" + cancelStatus
|
||||
+ " ignored as the vibration was already cancelled with status="
|
||||
+ mSignalCancelStatus + ", but immediate flag was updated to "
|
||||
+ mSignalCancelImmediate);
|
||||
}
|
||||
}
|
||||
mLock.notify();
|
||||
}
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Vibration cancel requested, immediate=" + immediate);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -380,7 +401,7 @@ final class VibrationStepConductor implements IBinder.DeathRecipient {
|
||||
if (Build.IS_DEBUGGABLE) {
|
||||
expectIsVibrationThread(true); // Reads VibrationThread variables as well as signals.
|
||||
}
|
||||
return (mSignalCancel && !mCancelled)
|
||||
return (mSignalCancelStatus != mCancelStatus)
|
||||
|| (mSignalCancelImmediate && !mCancelledImmediately)
|
||||
|| (mSignalVibratorsComplete.size() > 0);
|
||||
}
|
||||
@@ -395,7 +416,7 @@ final class VibrationStepConductor implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
int[] vibratorsToProcess = null;
|
||||
boolean doCancel = false;
|
||||
Vibration.Status doCancelStatus = null;
|
||||
boolean doCancelImmediate = false;
|
||||
// Collect signals to process, but don't keep the lock while processing them.
|
||||
synchronized (mLock) {
|
||||
@@ -405,9 +426,10 @@ final class VibrationStepConductor implements IBinder.DeathRecipient {
|
||||
}
|
||||
// This should only happen once.
|
||||
doCancelImmediate = true;
|
||||
doCancelStatus = mSignalCancelStatus;
|
||||
}
|
||||
if (mSignalCancel && !mCancelled) {
|
||||
doCancel = true;
|
||||
if (mSignalCancelStatus != mCancelStatus) {
|
||||
doCancelStatus = mSignalCancelStatus;
|
||||
}
|
||||
if (!doCancelImmediate && mSignalVibratorsComplete.size() > 0) {
|
||||
// Swap out the queue of completions to process.
|
||||
@@ -421,11 +443,11 @@ final class VibrationStepConductor implements IBinder.DeathRecipient {
|
||||
// completion signals that were collected in this call, but we won't process them
|
||||
// anyway as all steps are cancelled.
|
||||
if (doCancelImmediate) {
|
||||
processCancelImmediately();
|
||||
processCancelImmediately(doCancelStatus);
|
||||
return;
|
||||
}
|
||||
if (doCancel) {
|
||||
processCancel();
|
||||
if (doCancelStatus != null) {
|
||||
processCancel(doCancelStatus);
|
||||
}
|
||||
if (vibratorsToProcess != null) {
|
||||
processVibratorsComplete(vibratorsToProcess);
|
||||
@@ -438,12 +460,12 @@ final class VibrationStepConductor implements IBinder.DeathRecipient {
|
||||
* <p>This will remove all steps and replace them with respective results of
|
||||
* {@link Step#cancel()}.
|
||||
*/
|
||||
public void processCancel() {
|
||||
public void processCancel(Vibration.Status cancelStatus) {
|
||||
if (Build.IS_DEBUGGABLE) {
|
||||
expectIsVibrationThread(true);
|
||||
}
|
||||
|
||||
mCancelled = true;
|
||||
mCancelStatus = cancelStatus;
|
||||
// Vibrator callbacks should wait until all steps from the queue are properly cancelled
|
||||
// and clean up steps are added back to the queue, so they can handle the callback.
|
||||
List<Step> cleanUpSteps = new ArrayList<>();
|
||||
@@ -461,13 +483,13 @@ final class VibrationStepConductor implements IBinder.DeathRecipient {
|
||||
*
|
||||
* <p>This will remove and trigger {@link Step#cancelImmediately()} in all steps, in order.
|
||||
*/
|
||||
public void processCancelImmediately() {
|
||||
public void processCancelImmediately(Vibration.Status cancelStatus) {
|
||||
if (Build.IS_DEBUGGABLE) {
|
||||
expectIsVibrationThread(true);
|
||||
}
|
||||
|
||||
mCancelledImmediately = true;
|
||||
mCancelled = true;
|
||||
mCancelStatus = cancelStatus;
|
||||
Step step;
|
||||
while ((step = pollNext()) != null) {
|
||||
step.cancelImmediately();
|
||||
|
||||
@@ -162,10 +162,11 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
// When the system is entering a non-interactive state, we want to cancel
|
||||
// vibrations in case a misbehaving app has abandoned them.
|
||||
if (shouldCancelOnScreenOffLocked(mNextVibration)) {
|
||||
clearNextVibrationLocked(Vibration.Status.CANCELLED);
|
||||
clearNextVibrationLocked(Vibration.Status.CANCELLED_BY_SCREEN_OFF);
|
||||
}
|
||||
if (shouldCancelOnScreenOffLocked(mCurrentVibration)) {
|
||||
mCurrentVibration.notifyCancelled(/* immediate= */ false);
|
||||
mCurrentVibration.notifyCancelled(Vibration.Status.CANCELLED_BY_SCREEN_OFF,
|
||||
/* immediate= */ false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -426,7 +427,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
if (mCurrentVibration != null) {
|
||||
mCurrentVibration.notifyCancelled(/* immediate= */ false);
|
||||
mCurrentVibration.notifyCancelled(Vibration.Status.CANCELLED_SUPERSEDED,
|
||||
/* immediate= */ false);
|
||||
}
|
||||
Vibration.Status status = startVibrationLocked(vib);
|
||||
if (status != Vibration.Status.RUNNING) {
|
||||
@@ -459,19 +461,20 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
if (mNextVibration != null
|
||||
&& shouldCancelVibration(mNextVibration.getVibration(),
|
||||
usageFilter, token)) {
|
||||
clearNextVibrationLocked(Vibration.Status.CANCELLED);
|
||||
clearNextVibrationLocked(Vibration.Status.CANCELLED_BY_USER);
|
||||
}
|
||||
if (mCurrentVibration != null
|
||||
&& shouldCancelVibration(mCurrentVibration.getVibration(),
|
||||
usageFilter, token)) {
|
||||
mCurrentVibration.notifyCancelled(/* immediate= */false);
|
||||
mCurrentVibration.notifyCancelled(Vibration.Status.CANCELLED_BY_USER,
|
||||
/* immediate= */false);
|
||||
}
|
||||
if (mCurrentExternalVibration != null
|
||||
&& shouldCancelVibration(
|
||||
mCurrentExternalVibration.externalVibration.getVibrationAttributes(),
|
||||
usageFilter)) {
|
||||
mCurrentExternalVibration.externalVibration.mute();
|
||||
endExternalVibrateLocked(Vibration.Status.CANCELLED,
|
||||
endExternalVibrateLocked(Vibration.Status.CANCELLED_BY_USER,
|
||||
/* continueExternalControl= */ false);
|
||||
}
|
||||
} finally {
|
||||
@@ -600,7 +603,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
Slog.d(TAG, "Canceling vibration because settings changed: "
|
||||
+ (inputDevicesChanged ? "input devices changed" : ignoreStatus));
|
||||
}
|
||||
mCurrentVibration.notifyCancelled(/* immediate= */ false);
|
||||
mCurrentVibration.notifyCancelled(Vibration.Status.CANCELLED_BY_SETTINGS_UPDATE,
|
||||
/* immediate= */ false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1319,7 +1323,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "External vibration finished because binder died");
|
||||
}
|
||||
endExternalVibrateLocked(Vibration.Status.CANCELLED,
|
||||
endExternalVibrateLocked(Vibration.Status.CANCELLED_BINDER_DIED,
|
||||
/* continueExternalControl= */ false);
|
||||
}
|
||||
}
|
||||
@@ -1543,7 +1547,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
// vibration that may be playing and ready the vibrator for external control.
|
||||
if (mCurrentVibration != null) {
|
||||
clearNextVibrationLocked(Vibration.Status.IGNORED_FOR_EXTERNAL);
|
||||
mCurrentVibration.notifyCancelled(/* immediate= */ true);
|
||||
mCurrentVibration.notifyCancelled(Vibration.Status.CANCELLED_SUPERSEDED,
|
||||
/* immediate= */ true);
|
||||
waitForCompletion = true;
|
||||
}
|
||||
} else {
|
||||
@@ -1557,7 +1562,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
// would need to mute the old one still if it came from a different controller.
|
||||
alreadyUnderExternalControl = true;
|
||||
mCurrentExternalVibration.externalVibration.mute();
|
||||
endExternalVibrateLocked(Vibration.Status.CANCELLED,
|
||||
endExternalVibrateLocked(Vibration.Status.CANCELLED_SUPERSEDED,
|
||||
/* continueExternalControl= */ true);
|
||||
}
|
||||
mCurrentExternalVibration = new ExternalVibrationHolder(vib);
|
||||
|
||||
@@ -257,13 +257,13 @@ public class VibrationThreadTest {
|
||||
assertTrue(mThread.isRunningVibrationId(vibrationId));
|
||||
assertTrue(mControllers.get(VIBRATOR_ID).isVibrating());
|
||||
|
||||
conductor.notifyCancelled(/* immediate= */ false);
|
||||
conductor.notifyCancelled(Vibration.Status.CANCELLED_SUPERSEDED, /* immediate= */ false);
|
||||
waitForCompletion();
|
||||
assertFalse(mThread.isRunningVibrationId(vibrationId));
|
||||
|
||||
verify(mManagerHooks).noteVibratorOn(eq(UID), anyLong());
|
||||
verify(mManagerHooks).noteVibratorOff(eq(UID));
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED_SUPERSEDED);
|
||||
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
|
||||
|
||||
List<Float> playedAmplitudes = fakeVibrator.getAmplitudes();
|
||||
@@ -288,10 +288,10 @@ public class VibrationThreadTest {
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
|
||||
|
||||
assertTrue(waitUntil(() -> !fakeVibrator.getAmplitudes().isEmpty(), TEST_TIMEOUT_MILLIS));
|
||||
conductor.notifyCancelled(/* immediate= */ false);
|
||||
conductor.notifyCancelled(Vibration.Status.CANCELLED_BY_USER, /* immediate= */ false);
|
||||
waitForCompletion();
|
||||
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED_BY_USER);
|
||||
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
|
||||
assertEquals(Arrays.asList(expectedOneShot(1000)),
|
||||
fakeVibrator.getEffectSegments(vibrationId));
|
||||
@@ -310,10 +310,10 @@ public class VibrationThreadTest {
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
|
||||
|
||||
assertTrue(waitUntil(() -> !fakeVibrator.getAmplitudes().isEmpty(), TEST_TIMEOUT_MILLIS));
|
||||
conductor.notifyCancelled(/* immediate= */ false);
|
||||
conductor.notifyCancelled(Vibration.Status.CANCELLED_BY_USER, /* immediate= */ false);
|
||||
waitForCompletion();
|
||||
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED_BY_USER);
|
||||
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
|
||||
assertEquals(Arrays.asList(expectedOneShot(5550)),
|
||||
fakeVibrator.getEffectSegments(vibrationId));
|
||||
@@ -334,10 +334,10 @@ public class VibrationThreadTest {
|
||||
|
||||
assertTrue(waitUntil(() -> fakeVibrator.getAmplitudes().size() > 2 * amplitudes.length,
|
||||
1000 + TEST_TIMEOUT_MILLIS));
|
||||
conductor.notifyCancelled(/* immediate= */ false);
|
||||
conductor.notifyCancelled(Vibration.Status.CANCELLED_BY_USER, /* immediate= */ false);
|
||||
waitForCompletion();
|
||||
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED_BY_USER);
|
||||
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
|
||||
assertEquals(2, fakeVibrator.getEffectSegments(vibrationId).size());
|
||||
// First time turn vibrator ON for minimum of 1s.
|
||||
@@ -371,13 +371,14 @@ public class VibrationThreadTest {
|
||||
// Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
|
||||
// fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
|
||||
Thread cancellingThread =
|
||||
new Thread(() -> conductor.notifyCancelled(/* immediate= */ false));
|
||||
new Thread(() -> conductor.notifyCancelled(
|
||||
Vibration.Status.CANCELLED_BY_SETTINGS_UPDATE, /* immediate= */ false));
|
||||
cancellingThread.start();
|
||||
|
||||
waitForCompletion(/* timeout= */ 50);
|
||||
cancellingThread.join();
|
||||
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED_BY_SETTINGS_UPDATE);
|
||||
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
|
||||
}
|
||||
|
||||
@@ -397,13 +398,14 @@ public class VibrationThreadTest {
|
||||
// Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
|
||||
// fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
|
||||
Thread cancellingThread =
|
||||
new Thread(() -> conductor.notifyCancelled(/* immediate= */ false));
|
||||
new Thread(() -> conductor.notifyCancelled(
|
||||
Vibration.Status.CANCELLED_BY_SCREEN_OFF, /* immediate= */ false));
|
||||
cancellingThread.start();
|
||||
|
||||
waitForCompletion(/* timeout= */ 50);
|
||||
cancellingThread.join();
|
||||
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED_BY_SCREEN_OFF);
|
||||
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
|
||||
}
|
||||
|
||||
@@ -647,7 +649,7 @@ public class VibrationThreadTest {
|
||||
waitForCompletion();
|
||||
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
|
||||
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED_BINDER_DIED);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1043,7 +1045,8 @@ public class VibrationThreadTest {
|
||||
// Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
|
||||
// fail at waitForCompletion(cancellingThread).
|
||||
Thread cancellingThread = new Thread(
|
||||
() -> conductor.notifyCancelled(/* immediate= */ false));
|
||||
() -> conductor.notifyCancelled(
|
||||
Vibration.Status.CANCELLED_BY_USER, /* immediate= */ false));
|
||||
cancellingThread.start();
|
||||
|
||||
// Cancelling the vibration should be fast and return right away, even if the thread is
|
||||
@@ -1052,7 +1055,7 @@ public class VibrationThreadTest {
|
||||
|
||||
// After the vibrator call ends the vibration is cancelled and the vibrator is turned off.
|
||||
waitForCompletion(/* timeout= */ latency + TEST_TIMEOUT_MILLIS);
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED_BY_USER);
|
||||
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
|
||||
}
|
||||
|
||||
@@ -1080,13 +1083,14 @@ public class VibrationThreadTest {
|
||||
// Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
|
||||
// fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
|
||||
Thread cancellingThread = new Thread(
|
||||
() -> conductor.notifyCancelled(/* immediate= */ false));
|
||||
() -> conductor.notifyCancelled(
|
||||
Vibration.Status.CANCELLED_SUPERSEDED, /* immediate= */ false));
|
||||
cancellingThread.start();
|
||||
|
||||
waitForCompletion(/* timeout= */ 50);
|
||||
cancellingThread.join();
|
||||
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED_SUPERSEDED);
|
||||
assertFalse(mControllers.get(1).isVibrating());
|
||||
assertFalse(mControllers.get(2).isVibrating());
|
||||
}
|
||||
@@ -1113,13 +1117,14 @@ public class VibrationThreadTest {
|
||||
// Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
|
||||
// fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
|
||||
Thread cancellingThread =
|
||||
new Thread(() -> conductor.notifyCancelled(/* immediate= */ false));
|
||||
new Thread(() -> conductor.notifyCancelled(
|
||||
Vibration.Status.CANCELLED_BY_SCREEN_OFF, /* immediate= */ false));
|
||||
cancellingThread.start();
|
||||
|
||||
waitForCompletion(/* timeout= */ 50);
|
||||
cancellingThread.join();
|
||||
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED_BY_SCREEN_OFF);
|
||||
assertFalse(mControllers.get(1).isVibrating());
|
||||
assertFalse(mControllers.get(2).isVibrating());
|
||||
}
|
||||
@@ -1139,7 +1144,7 @@ public class VibrationThreadTest {
|
||||
|
||||
verify(mVibrationToken).linkToDeath(same(conductor), eq(0));
|
||||
verify(mVibrationToken).unlinkToDeath(same(conductor), eq(0));
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED_BINDER_DIED);
|
||||
assertFalse(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId).isEmpty());
|
||||
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
|
||||
}
|
||||
@@ -1193,12 +1198,13 @@ public class VibrationThreadTest {
|
||||
mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
|
||||
|
||||
// Will stop the ramp down right away.
|
||||
conductor.notifyCancelled(/* immediate= */ true);
|
||||
conductor.notifyCancelled(
|
||||
Vibration.Status.CANCELLED_BY_SETTINGS_UPDATE, /* immediate= */ true);
|
||||
waitForCompletion();
|
||||
|
||||
// Does not cancel already finished vibration, but releases vibrator.
|
||||
verify(mManagerHooks, never()).onVibrationCompleted(eq(vibrationId),
|
||||
eq(Vibration.Status.CANCELLED));
|
||||
eq(Vibration.Status.CANCELLED_BY_SETTINGS_UPDATE));
|
||||
verify(mManagerHooks).onVibrationThreadReleased(vibrationId);
|
||||
}
|
||||
|
||||
@@ -1214,10 +1220,10 @@ public class VibrationThreadTest {
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
|
||||
assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
|
||||
TEST_TIMEOUT_MILLIS));
|
||||
conductor.notifyCancelled(/* immediate= */ false);
|
||||
conductor.notifyCancelled(Vibration.Status.CANCELLED_BY_USER, /* immediate= */ false);
|
||||
waitForCompletion();
|
||||
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED_BY_USER);
|
||||
|
||||
// Duration extended for 10000 + 15.
|
||||
assertEquals(Arrays.asList(expectedOneShot(10_015)),
|
||||
@@ -1337,7 +1343,7 @@ public class VibrationThreadTest {
|
||||
VibrationStepConductor conductor2 = startThreadAndDispatcher(vibrationId2, effect2);
|
||||
// Effect2 won't complete on its own. Cancel it after a couple of repeats.
|
||||
Thread.sleep(150); // More than two TICKs.
|
||||
conductor2.notifyCancelled(/* immediate= */ false);
|
||||
conductor2.notifyCancelled(Vibration.Status.CANCELLED_BY_USER, /* immediate= */ false);
|
||||
waitForCompletion();
|
||||
|
||||
startThreadAndDispatcher(vibrationId3, effect3);
|
||||
@@ -1346,7 +1352,7 @@ public class VibrationThreadTest {
|
||||
// Effect4 is a long oneshot, but it gets cancelled as fast as possible.
|
||||
long start4 = System.currentTimeMillis();
|
||||
VibrationStepConductor conductor4 = startThreadAndDispatcher(vibrationId4, effect4);
|
||||
conductor4.notifyCancelled(/* immediate= */ true);
|
||||
conductor4.notifyCancelled(Vibration.Status.CANCELLED_SUPERSEDED, /* immediate= */ true);
|
||||
waitForCompletion();
|
||||
long duration4 = System.currentTimeMillis() - start4;
|
||||
|
||||
@@ -1366,7 +1372,7 @@ public class VibrationThreadTest {
|
||||
|
||||
// Effect2: repeating, cancelled.
|
||||
verify(mControllerCallbacks, atLeast(2)).onComplete(VIBRATOR_ID, vibrationId2);
|
||||
verifyCallbacksTriggered(vibrationId2, Vibration.Status.CANCELLED);
|
||||
verifyCallbacksTriggered(vibrationId2, Vibration.Status.CANCELLED_BY_USER);
|
||||
|
||||
// The exact count of segments might vary, so just check that there's more than 2 and
|
||||
// all elements are the same segment.
|
||||
@@ -1384,7 +1390,7 @@ public class VibrationThreadTest {
|
||||
fakeVibrator.getEffectSegments(vibrationId3));
|
||||
|
||||
// Effect4: cancelled quickly.
|
||||
verifyCallbacksTriggered(vibrationId4, Vibration.Status.CANCELLED);
|
||||
verifyCallbacksTriggered(vibrationId4, Vibration.Status.CANCELLED_SUPERSEDED);
|
||||
assertTrue("Tested duration=" + duration4, duration4 < 2000);
|
||||
|
||||
// Effect5: normal oneshot. Don't worry about amplitude, as effect4 may or may not have
|
||||
|
||||
Reference in New Issue
Block a user