summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/util/AsyncChannel.java37
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);
+ }
+
+ }
}