diff options
| -rw-r--r-- | core/java/com/android/internal/util/AsyncChannel.java | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/core/java/com/android/internal/util/AsyncChannel.java b/core/java/com/android/internal/util/AsyncChannel.java index 39733440f0b6..85a8ccc9d947 100644 --- a/core/java/com/android/internal/util/AsyncChannel.java +++ b/core/java/com/android/internal/util/AsyncChannel.java @@ -162,6 +162,9 @@ public class AsyncChannel { /** CMD_FULLY_CONNECTED refused because a connection already exists*/ public static final int STATUS_FULL_CONNECTION_REFUSED_ALREADY_CONNECTED = 3; + /** Error indicating abnormal termination of destination messenger */ + public static final int STATUS_REMOTE_DISCONNECTION = 4; + /** Service connection */ private AsyncChannelConnection mConnection; @@ -177,6 +180,9 @@ public class AsyncChannel { /** Messenger for destination */ private Messenger mDstMessenger; + /** Death Monitor for destination messenger */ + private DeathMonitor mDeathMonitor; + /** * AsyncChannel constructor */ @@ -416,6 +422,7 @@ public class AsyncChannel { mSrcHandler = null; mSrcMessenger = null; mDstMessenger = null; + mDeathMonitor = null; mConnection = null; } @@ -429,6 +436,10 @@ public class AsyncChannel { if (mSrcHandler != null) { replyDisconnected(STATUS_SUCCESSFUL); } + // Unlink only when bindService isn't used + if (mConnection == null && mDstMessenger != null && mDeathMonitor!= null) { + mDstMessenger.getBinder().unlinkToDeath(mDeathMonitor, 0); + } } /** @@ -804,6 +815,21 @@ public class AsyncChannel { msg.arg1 = status; msg.obj = this; msg.replyTo = mDstMessenger; + + /* + * Link to death only when bindService isn't used. + */ + if (mConnection == null) { + mDeathMonitor = new DeathMonitor(); + try { + mDstMessenger.getBinder().linkToDeath(mDeathMonitor, 0); + } catch (RemoteException e) { + mDeathMonitor = null; + // Override status to indicate failure + msg.arg1 = STATUS_BINDING_UNSUCCESSFUL; + } + } + mSrcHandler.sendMessage(msg); } @@ -849,4 +875,15 @@ public class AsyncChannel { private static void log(String s) { Slog.d(TAG, s); } + + private final class DeathMonitor implements IBinder.DeathRecipient { + + DeathMonitor() { + } + + public void binderDied() { + replyDisconnected(STATUS_REMOTE_DISCONNECTION); + } + + } } |