start/stop in-call UI on demand
This change severs the connection to the in-call UI whenever there is no
active call. When we get a new call, we attempt to the bind to the
UI service. Whenever we lose/disconnect a call, we see if there are any calls
left and if not, unbind from the UI service.
Changes:
- Add explicit component name to config.xml and use them when binding to
the UI service.
- onUpdate and onIncomingCall in CAllHandlerServiceProxy now make a call
to maybeBindToService() in case the service requires binding.
- onDisconnect calls maybeUnbind() after a disconnect.
- add cleanup of current binding to onServiceDisconnect(). Also attempt
to rebind if there are still active calls.
bug: 10363682
Change-Id: I7ddbb33fde7e3b03c1f1ea759d174cb03baabc76
diff --git a/src/com/android/phone/CallHandlerServiceProxy.java b/src/com/android/phone/CallHandlerServiceProxy.java
index 77402fd..12e039e 100644
--- a/src/com/android/phone/CallHandlerServiceProxy.java
+++ b/src/com/android/phone/CallHandlerServiceProxy.java
@@ -62,12 +62,8 @@
mCallModeler = callModeler;
mAudioRouter = audioRouter;
- setupServiceConnection();
mAudioRouter.addAudioModeListener(this);
mCallModeler.addListener(this);
-
- // start the whole process
- onUpdate(mCallModeler.getFullList(), true);
}
@Override
@@ -76,6 +72,7 @@
try {
if (DBG) Log.d(TAG, "onDisconnect: " + call);
mCallHandlerService.onDisconnect(call);
+ maybeUnbind();
} catch (RemoteException e) {
Log.e(TAG, "Remote exception handling onDisconnect ", e);
}
@@ -84,7 +81,7 @@
@Override
public void onIncoming(Call call, ArrayList<String> textResponses) {
- if (mCallHandlerService != null) {
+ if (maybeBindToService() && mCallHandlerService != null) {
try {
if (DBG) Log.d(TAG, "onIncoming: " + call);
mCallHandlerService.onIncoming(call, textResponses);
@@ -96,10 +93,11 @@
@Override
public void onUpdate(List<Call> calls, boolean fullUpdate) {
- if (mCallHandlerService != null) {
+ if (maybeBindToService() && mCallHandlerService != null) {
try {
if (DBG) Log.d(TAG, "onUpdate: " + calls.toString());
mCallHandlerService.onUpdate(calls, fullUpdate);
+ maybeUnbind();
} catch (RemoteException e) {
Log.e(TAG, "Remote exception handling onUpdate", e);
}
@@ -151,22 +149,58 @@
@Override
public void onServiceDisconnected(ComponentName className) {
- // TODO(klp): handle the case where the in call ui crashed or gets destroyed.
- // In the near term, we need to re-bind to the service when ever it's gone.
- // Longer term, we need a way to catch the crash and allow the users to choose
- // a different in-call screen.
- Log.e(TAG, "Yikes! no in call ui!");
+ Log.i(TAG, "Disconnected from UI service.");
mCallHandlerService = null;
+
+ // clean up our current binding.
+ mContext.unbindService(mConnection);
+ mConnection = null;
+
+ // potentially attempt to rebind if there are still active calls.
+ maybeBindToService();
}
};
- Intent serviceIntent = new Intent(ICallHandlerService.class.getName());
+ final Intent serviceIntent = new Intent(ICallHandlerService.class.getName());
+ final ComponentName component = new ComponentName(
+ mContext.getResources().getString(R.string.incall_ui_default_package),
+ mContext.getResources().getString(R.string.incall_ui_default_class));
+ serviceIntent.setComponent(component);
if (!mContext.bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE)) {
Log.e(TAG, "Cound not bind to ICallHandlerService");
}
}
/**
+ * Checks To see if there are any calls left. If not, unbind the callhandler service.
+ */
+ private void maybeUnbind() {
+ if (!mCallModeler.hasLiveCall()) {
+ if (mConnection != null) {
+ mContext.unbindService(mConnection);
+ mConnection = null;
+ }
+ }
+ }
+
+ /**
+ * Checks to see if there are any active calls. If so, binds the call handler service.
+ * @return true if already bound. False otherwise.
+ */
+ private boolean maybeBindToService() {
+ if (mCallModeler.hasLiveCall()) {
+ // mConnection is set to non-null once an attempt is made to connect.
+ // We do not check against mCallHandlerService here because we could potentially
+ // create multiple bindings to the UI.
+ if (mConnection != null) {
+ return true;
+ }
+ setupServiceConnection();
+ }
+ return false;
+ }
+
+ /**
* Called when the in-call UI service is connected. Send command interface to in-call.
*/
private void onCallHandlerServiceConnected(ICallHandlerService callHandlerService) {
@@ -174,6 +208,9 @@
try {
mCallHandlerService.setCallCommandService(mCallCommandService);
+
+ // start with a full update
+ onUpdate(mCallModeler.getFullList(), true);
} catch (RemoteException e) {
Log.e(TAG, "Remote exception calling CallHandlerService::setCallCommandService", e);
}