diff --git a/core/java/android/os/ExternalVibration.java b/core/java/android/os/ExternalVibration.java index b93bef8b33ef2..37ca868598f56 100644 --- a/core/java/android/os/ExternalVibration.java +++ b/core/java/android/os/ExternalVibration.java @@ -114,6 +114,24 @@ public class ExternalVibration implements Parcelable { return true; } + /** + * Links a recipient to death against this external vibration token + */ + public void linkToDeath(IBinder.DeathRecipient recipient) { + try { + mToken.linkToDeath(recipient, 0); + } catch (RemoteException e) { + return; + } + } + + /** + * Unlinks a recipient to death against this external vibration token + */ + public void unlinkToDeath(IBinder.DeathRecipient recipient) { + mToken.unlinkToDeath(recipient, 0); + } + @Override public boolean equals(Object o) { if (o == null || !(o instanceof ExternalVibration)) { diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java index 0d19a67e86e9f..6eb9f0c7a6bc0 100644 --- a/services/core/java/com/android/server/VibratorService.java +++ b/services/core/java/com/android/server/VibratorService.java @@ -620,7 +620,6 @@ public class VibratorService extends IVibratorService.Stub linkVibration(vib); long ident = Binder.clearCallingIdentity(); try { - doCancelVibrateLocked(); startVibrationLocked(vib); addToPreviousVibrationsLocked(vib); @@ -1437,6 +1436,8 @@ public class VibratorService extends IVibratorService.Stub } final class ExternalVibratorService extends IExternalVibratorService.Stub { + ExternalVibrationDeathRecipient mCurrentExternalDeathRecipient; + @Override public int onExternalVibrationStart(ExternalVibration vib) { if (!mSupportsExternalControl) { @@ -1470,6 +1471,8 @@ public class VibratorService extends IVibratorService.Stub // Note that this doesn't support multiple concurrent external controls, as we // would need to mute the old one still if it came from a different controller. mCurrentExternalVibration = vib; + mCurrentExternalDeathRecipient = new ExternalVibrationDeathRecipient(); + mCurrentExternalVibration.linkToDeath(mCurrentExternalDeathRecipient); if (mPreviousExternalVibrations.size() > mPreviousVibrationsLimit) { mPreviousExternalVibrations.removeFirst(); } @@ -1514,6 +1517,8 @@ public class VibratorService extends IVibratorService.Stub public void onExternalVibrationStop(ExternalVibration vib) { synchronized (mLock) { if (vib.equals(mCurrentExternalVibration)) { + mCurrentExternalVibration.unlinkToDeath(mCurrentExternalDeathRecipient); + mCurrentExternalDeathRecipient = null; mCurrentExternalVibration = null; setVibratorUnderExternalControl(false); if (DEBUG) { @@ -1522,6 +1527,14 @@ public class VibratorService extends IVibratorService.Stub } } } + + private class ExternalVibrationDeathRecipient implements IBinder.DeathRecipient { + public void binderDied() { + synchronized (mLock) { + onExternalVibrationStop(mCurrentExternalVibration); + } + } + } } private final class VibratorShellCommand extends ShellCommand {