summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Ebinger <breadley@google.com>2021-08-02 18:35:53 -0700
committerBrad Ebinger <breadley@google.com>2021-08-03 22:22:21 +0000
commit4e51482aaf7ea8b7961a23726283096ed7db4d09 (patch)
treed70898c8538821a7552dc46c5fa509003860bae6
parent40ddf958e692bb9147ccafe96a62d993242b7623 (diff)
Remove SipDelegates in ImsService if Phone process crashes
If the phone process crashes, have the ImsService detect this condition and destroy all SipDelegates. This allows the AM app to properly recover when telephony comes back up Bug: 195148134 Test: manually crash phone process and then send RCS message Test: atest FrameworksTelephonyTests:SipTransportImplBaseTest Change-Id: I7866273d801df4d2b20e58f5d5ad50fd0ac4303d
-rw-r--r--telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java4
-rw-r--r--telephony/java/android/telephony/ims/stub/SipTransportImplBase.java46
2 files changed, 44 insertions, 6 deletions
diff --git a/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java
index c18ab33eb2c9..f0048248a5cc 100644
--- a/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java
+++ b/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java
@@ -193,6 +193,10 @@ public class SipDelegateAidlWrapper implements DelegateStateCallback, DelegateMe
return mDelegateBinder;
}
+ public ISipDelegateStateCallback getStateCallbackBinder() {
+ return mStateBinder;
+ }
+
private void notifyLocalMessageFailedToBeReceived(SipMessage m, int reason) {
String transactionId = m.getViaBranchParameter();
SipDelegate d = mDelegate;
diff --git a/telephony/java/android/telephony/ims/stub/SipTransportImplBase.java b/telephony/java/android/telephony/ims/stub/SipTransportImplBase.java
index 1f74c09af0f6..13ea99735ab4 100644
--- a/telephony/java/android/telephony/ims/stub/SipTransportImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/SipTransportImplBase.java
@@ -21,6 +21,7 @@ import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.os.Binder;
import android.os.IBinder;
+import android.os.RemoteException;
import android.telephony.ims.DelegateMessageCallback;
import android.telephony.ims.DelegateRequest;
import android.telephony.ims.DelegateStateCallback;
@@ -33,6 +34,7 @@ import android.telephony.ims.aidl.SipDelegateAidlWrapper;
import android.util.Log;
import java.util.ArrayList;
+import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.concurrent.Executor;
@@ -49,10 +51,15 @@ import java.util.concurrent.Executor;
public class SipTransportImplBase {
private static final String LOG_TAG = "SipTransportIB";
- private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
+ private final IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
@Override
public void binderDied() {
- mBinderExecutor.execute(() -> binderDiedInternal());
+ // Clean up all binders in this case.
+ mBinderExecutor.execute(() -> binderDiedInternal(null));
+ }
+ @Override
+ public void binderDied(IBinder who) {
+ mBinderExecutor.execute(() -> binderDiedInternal(who));
}
};
@@ -142,6 +149,7 @@ public class SipTransportImplBase {
ISipDelegateStateCallback cb, ISipDelegateMessageCallback mc) {
SipDelegateAidlWrapper wrapper = new SipDelegateAidlWrapper(mBinderExecutor, cb, mc);
mDelegates.add(wrapper);
+ linkDeathRecipient(wrapper);
createSipDelegate(subId, r, wrapper, wrapper);
}
@@ -155,6 +163,7 @@ public class SipTransportImplBase {
}
if (result != null) {
+ unlinkDeathRecipient(result);
mDelegates.remove(result);
destroySipDelegate(result.getDelegate(), reason);
} else {
@@ -163,12 +172,37 @@ public class SipTransportImplBase {
}
}
- private void binderDiedInternal() {
+ private void linkDeathRecipient(SipDelegateAidlWrapper w) {
+ try {
+ w.getStateCallbackBinder().asBinder().linkToDeath(mDeathRecipient, 0);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "linkDeathRecipient, remote process already died, cleaning up.");
+ mDeathRecipient.binderDied(w.getStateCallbackBinder().asBinder());
+ }
+ }
+
+ private void unlinkDeathRecipient(SipDelegateAidlWrapper w) {
+ try {
+ w.getStateCallbackBinder().asBinder().unlinkToDeath(mDeathRecipient, 0);
+ } catch (NoSuchElementException e) {
+ // Ignore this case.
+ }
+ }
+
+ private void binderDiedInternal(IBinder who) {
for (SipDelegateAidlWrapper w : mDelegates) {
- destroySipDelegate(w.getDelegate(),
- SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD);
+ // If the binder itself was not given from the platform, just clean up all binders.
+ if (who == null || w.getStateCallbackBinder().asBinder().equals(who)) {
+ Log.w(LOG_TAG, "Binder death detected for " + w + ", calling destroy and "
+ + "removing.");
+ mDelegates.remove(w);
+ destroySipDelegate(w.getDelegate(),
+ SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD);
+ return;
+ }
}
- mDelegates.clear();
+ Log.w(LOG_TAG, "Binder death detected for IBinder " + who + ", but couldn't find matching "
+ + "SipDelegate");
}
/**