Handle CallServiceProvider crash
Change-Id: Icd2d108a09d6094038c413cf77029f45d251ada5
diff --git a/src/com/android/telecomm/CallServiceProviderWrapper.java b/src/com/android/telecomm/CallServiceProviderWrapper.java
index 1a3b3e1..22b8187 100644
--- a/src/com/android/telecomm/CallServiceProviderWrapper.java
+++ b/src/com/android/telecomm/CallServiceProviderWrapper.java
@@ -17,31 +17,55 @@
package com.android.telecomm;
import android.content.ComponentName;
+import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
+import android.telecomm.CallServiceDescriptor;
import android.telecomm.TelecommConstants;
import com.android.internal.telecomm.ICallServiceLookupResponse;
import com.android.internal.telecomm.ICallServiceProvider;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
/**
* Wrapper for {@link ICallServiceProvider}s, handles binding to {@link ICallServiceProvider} and
* keeps track of when the object can safely be unbound. Other classes should not use
* {@link ICallServiceProvider} directly and instead should use this class to invoke methods of
* {@link ICallServiceProvider}.
- * TODO(santoscordon): Keep track of when the service can be safely unbound.
*/
final class CallServiceProviderWrapper extends ServiceBinder<ICallServiceProvider> {
- /**
- * The service action used to bind to ICallServiceProvider implementations.
- * TODO(santoscordon): Move this to TelecommConstants.
- */
- static final String CALL_SERVICE_PROVIDER_ACTION = ICallServiceProvider.class.getName();
+ interface LookupResponse {
+ void setCallServiceDescriptors(List<CallServiceDescriptor> descriptors);
+ }
+
+ private class LookupResponseWrapper extends ICallServiceLookupResponse.Stub {
+ private final LookupResponse mResponse;
+
+ LookupResponseWrapper(LookupResponse response) {
+ mResponse = response;
+ }
+
+ @Override
+ public void setCallServiceDescriptors(final List<CallServiceDescriptor> descriptors) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mLookupResponses.remove(mResponse)) {
+ mResponse.setCallServiceDescriptors(descriptors);
+ }
+ }
+ });
+ }
+ };
/** The actual service implementation. */
private ICallServiceProvider mServiceInterface;
-
- private Binder mBinder = new Binder();
+ private final Binder mBinder = new Binder();
+ private Set<LookupResponse> mLookupResponses = new HashSet<LookupResponse>();
+ private final Handler mHandler = new Handler();
/**
* Creates a call-service provider for the specified component.
@@ -53,30 +77,30 @@
}
/**
- * initiates a call-service lookup cycle, see {@link ICallServiceProvider#lookupCallServices}.
- * Upon failure, the specified error callback is invoked. Can be invoked even when the call
- * service is unbound.
+ * Initiates a call-service lookup cycle, see {@link ICallServiceProvider#lookupCallServices}.
+ * Can be invoked even when the call service is unbound.
*
* @param response The response object via which to return the relevant call-service
* implementations, if any.
- * @param errorCallback The callback to invoke upon failure.
*/
- void lookupCallServices(
- final ICallServiceLookupResponse response,
- final Runnable errorCallback) {
-
+ void lookupCallServices(final LookupResponse response) {
+ mLookupResponses.add(response);
BindCallback callback = new BindCallback() {
- @Override public void onSuccess() {
+ @Override
+ public void onSuccess() {
if (isServiceValid("lookupCallServices")) {
try {
- mServiceInterface.lookupCallServices(response);
+ mServiceInterface.lookupCallServices(new LookupResponseWrapper(response));
} catch (RemoteException e) {
- Log.e(CallServiceProviderWrapper.this, e, "Failed to lookupCallServices.");
}
}
}
- @Override public void onFailure() {
- errorCallback.run();
+
+ @Override
+ public void onFailure() {
+ if (mLookupResponses.remove(response)) {
+ response.setCallServiceDescriptors(null);
+ }
}
};
@@ -85,6 +109,16 @@
/** {@inheritDoc} */
@Override protected void setServiceInterface(IBinder binder) {
- mServiceInterface = ICallServiceProvider.Stub.asInterface(binder);
+ if (binder == null) {
+ mServiceInterface = null;
+
+ Set<LookupResponse> responses = mLookupResponses;
+ mLookupResponses = new HashSet<LookupResponse>();
+ for (LookupResponse response : responses) {
+ response.setCallServiceDescriptors(null);
+ }
+ } else {
+ mServiceInterface = ICallServiceProvider.Stub.asInterface(binder);
+ }
}
}