Call UI not showing for MO/MT call till pwr cycle
The device is staying in an error state - neither MO nor MT calling UI can be shown until the device is power cycled.
[Root Cause]
CallHandlerServiceProxy is requesting to binding service of InCallUI to launch Calling sreen.
At the same time, the InCallUI process is killed by system so that the binding request is ignored/lost.
CallHandlerServiceProxy keeps waiting for the service to connect but it will never come. Thus the Calling UI will never be showed until the device powers cycle.
[Resolution]
Rebind the service if CallHandlerServiceProxy does not get service connected in 2 seconds.
bug:12078305
Change-Id: I7d6ce69379ec187abccadcf823a99549097fa0f5
diff --git a/src/com/android/phone/CallHandlerServiceProxy.java b/src/com/android/phone/CallHandlerServiceProxy.java
index 7c8ace7..f5b6116 100644
--- a/src/com/android/phone/CallHandlerServiceProxy.java
+++ b/src/com/android/phone/CallHandlerServiceProxy.java
@@ -58,6 +58,7 @@
public static final int RETRY_DELAY_MILLIS = 2000;
public static final int RETRY_DELAY_LONG_MILLIS = 30 * 1000; // 30 seconds
private static final int BIND_RETRY_MSG = 1;
+ private static final int BIND_TIME_OUT = 2;
private static final int MAX_SHORT_DELAY_RETRY_COUNT = 5;
private AudioRouter mAudioRouter;
@@ -79,8 +80,28 @@
switch (msg.what) {
case BIND_RETRY_MSG:
+ // Remove any pending messages since we're already performing the action.
+ // If the call to setupServiceConnection() fails, it will queue up another retry.
+ removeMessages(BIND_RETRY_MSG);
handleConnectRetry();
break;
+ case BIND_TIME_OUT:
+ // Remove any pending messages since we're already performing the action.
+ // If the call to setupServiceConnection() fails, it will queue up another retry.
+ removeMessages(BIND_TIME_OUT);
+ synchronized (mServiceAndQueueLock) {
+ if(mCallHandlerServiceGuarded == null) {
+ Log.w(TAG, "Binding time out. InCallUI did not respond in time.");
+ try {
+ mContext.unbindService(mConnection);
+ } catch(Exception e) {
+ Log.w(TAG, "unbindservice exception", e);
+ }
+ mConnection = null;
+ handleConnectRetry();
+ }
+ }
+ break;
}
}
@@ -290,6 +311,10 @@
Log.d(TAG, "Service Connected");
}
onCallHandlerServiceConnected(ICallHandlerService.Stub.asInterface(service));
+ removeMessages(BIND_TIME_OUT);
+ if (DBG) {
+ Log.d(TAG, "Service Connected. Cancel timer");
+ }
resetConnectRetryCount();
}
@@ -390,7 +415,9 @@
if (failedConnection) {
mConnection = null;
- enqueueConnectRetry();
+ enqueueConnectRetry(BIND_RETRY_MSG);
+ } else {
+ enqueueConnectRetry(BIND_TIME_OUT);
}
} else {
Log.d(TAG, "Service connection to in call service already started.");
@@ -412,10 +439,6 @@
}
private void handleConnectRetry() {
- // Remove any pending messages since we're already performing the action.
- // If the call to setupServiceConnection() fails, it will queue up another retry.
- removeMessages(BIND_RETRY_MSG);
-
// Something else triggered the connection, cancel.
if (mConnection != null) {
Log.i(TAG, "Retry: already connected.");
@@ -449,14 +472,14 @@
* Called after the connection failed and a retry is needed.
* Queues up a retry to happen with a delay.
*/
- private void enqueueConnectRetry() {
+ private void enqueueConnectRetry(int msg) {
final boolean isLongDelay = (mBindRetryCount > MAX_SHORT_DELAY_RETRY_COUNT);
final int delay = isLongDelay ? RETRY_DELAY_LONG_MILLIS : RETRY_DELAY_MILLIS;
Log.w(TAG, "InCallUI Connection failed. Enqueuing delayed retry for " + delay + " ms." +
" retries(" + mBindRetryCount + ")");
- sendEmptyMessageDelayed(BIND_RETRY_MSG, delay);
+ sendEmptyMessageDelayed(msg, delay);
}
private void unbind() {