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);
+ }
}
}
diff --git a/src/com/android/telecomm/CallServiceRepository.java b/src/com/android/telecomm/CallServiceRepository.java
index e1feb0f..cdef130 100644
--- a/src/com/android/telecomm/CallServiceRepository.java
+++ b/src/com/android/telecomm/CallServiceRepository.java
@@ -21,7 +21,6 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
-import android.os.Handler;
import android.telecomm.CallServiceDescriptor;
import android.telecomm.TelecommConstants;
@@ -100,29 +99,12 @@
private void queryProviderForCallServices(final ComponentName providerName) {
final CallServiceProviderWrapper provider = new CallServiceProviderWrapper(
providerName);
-
- ICallServiceLookupResponse response = new ICallServiceLookupResponse.Stub() {
- @Override
- public void setCallServiceDescriptors(
- final List<CallServiceDescriptor> callServiceDescriptors) {
-
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- processCallServices(provider, Sets.newHashSet(callServiceDescriptors));
- }
- });
+ provider.lookupCallServices(new CallServiceProviderWrapper.LookupResponse() {
+ @Override
+ public void setCallServiceDescriptors(List<CallServiceDescriptor> descriptors) {
+ processCallServices(provider, descriptors);
}
- };
-
- Runnable errorCallback = new Runnable() {
- @Override
- public void run() {
- processCallServices(provider, null);
- }
- };
-
- provider.lookupCallServices(response, errorCallback);
+ });
}
/**
@@ -133,17 +115,17 @@
*/
private void processCallServices(
CallServiceProviderWrapper provider,
- Set<CallServiceDescriptor> callServiceDescriptors) {
+ List<CallServiceDescriptor> descriptors) {
// Descriptor lookup finished, we no longer need the provider.
provider.unbind();
ComponentName providerName = provider.getComponentName();
if (mOutstandingProviders.remove(providerName)) {
- if (callServiceDescriptors != null) {
+ if (descriptors != null) {
// Add all the connection services from this provider to the connection-service
// cache.
- for (CallServiceDescriptor descriptor : callServiceDescriptors) {
+ for (CallServiceDescriptor descriptor : descriptors) {
mServices.add(getService(descriptor.getServiceComponent(), descriptor));
}
}
@@ -162,7 +144,6 @@
}
private final IncomingCallsManager mIncomingCallsManager;
- private final Handler mHandler = new Handler();
/** Persists specified parameters. */
CallServiceRepository(IncomingCallsManager incomingCallsManager) {