summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNancy Chen <nancychen@google.com>2014-07-31 16:33:35 -0700
committerNancy Chen <nancychen@google.com>2014-08-11 10:47:20 -0700
commitf3d0654f2b6d77b7eef8bdcb4c39ee59e55017de (patch)
tree9220c0601fde137d96bba05cce54f0a14672238c
parentc0b253adf1740d3b0e0ad6ccdde28b4093cfb1e1 (diff)
downloadpackages_apps_InCallUI-f3d0654f2b6d77b7eef8bdcb4c39ee59e55017de.tar.gz
packages_apps_InCallUI-f3d0654f2b6d77b7eef8bdcb4c39ee59e55017de.tar.bz2
packages_apps_InCallUI-f3d0654f2b6d77b7eef8bdcb4c39ee59e55017de.zip
Reduce latency for InCallUI by adding an intermediate state
Add PENDING_OUTGOING as a state where the Telecomm information has not yet returned but the UI has started. This allows the UI to immediately begin initiating while Telecomm is waiting for the return of its broadcast intent. Bug: 16396523 Change-Id: Ia4b39689b89f9dea3aafae9e63ca0bfebb730501
-rw-r--r--src/com/android/incallui/Call.java10
-rw-r--r--src/com/android/incallui/CallButtonPresenter.java19
-rw-r--r--src/com/android/incallui/CallCardFragment.java6
-rw-r--r--src/com/android/incallui/CallCardPresenter.java24
-rw-r--r--src/com/android/incallui/CallList.java7
-rw-r--r--src/com/android/incallui/ConferenceManagerPresenter.java6
-rw-r--r--src/com/android/incallui/DialpadPresenter.java3
-rw-r--r--src/com/android/incallui/InCallPresenter.java36
-rw-r--r--src/com/android/incallui/ProximitySensor.java6
-rw-r--r--src/com/android/incallui/StatusBarNotifier.java4
-rw-r--r--src/com/android/incallui/VideoCallPresenter.java18
11 files changed, 90 insertions, 49 deletions
diff --git a/src/com/android/incallui/Call.java b/src/com/android/incallui/Call.java
index 9b983220..fcdf0922 100644
--- a/src/com/android/incallui/Call.java
+++ b/src/com/android/incallui/Call.java
@@ -46,12 +46,14 @@ public final class Call {
public static final int DISCONNECTED = 9; /* State after a call disconnects */
public static final int CONFERENCED = 10; /* Call part of a conference call */
public static final int PRE_DIAL_WAIT = 11; /* Waiting for user before outgoing call */
+ public static final int CONNECTING = 12; /* Waiting for Telecomm broadcast to finish */
- public static boolean isConnected(int state) {
+ public static boolean isConnectingOrConnected(int state) {
switch(state) {
case ACTIVE:
case INCOMING:
case CALL_WAITING:
+ case CONNECTING:
case DIALING:
case REDIALING:
case ONHOLD:
@@ -92,8 +94,10 @@ public final class Call {
return "CONFERENCED";
case PRE_DIAL_WAIT:
return "PRE_DIAL_WAIT";
+ case CONNECTING:
+ return "CONNECTING";
default:
- return "UNKOWN";
+ return "UNKNOWN";
}
}
}
@@ -222,6 +226,8 @@ public final class Call {
private static int translateState(int state) {
switch (state) {
+ case android.telecomm.Call.STATE_CONNECTING:
+ return Call.State.CONNECTING;
case android.telecomm.Call.STATE_PRE_DIAL_WAIT:
return Call.State.PRE_DIAL_WAIT;
case android.telecomm.Call.STATE_DIALING:
diff --git a/src/com/android/incallui/CallButtonPresenter.java b/src/com/android/incallui/CallButtonPresenter.java
index 15a64b63..7ecdc6fa 100644
--- a/src/com/android/incallui/CallButtonPresenter.java
+++ b/src/com/android/incallui/CallButtonPresenter.java
@@ -41,7 +41,6 @@ public class CallButtonPresenter extends Presenter<CallButtonPresenter.CallButto
private boolean mPreviousMuteState = false;
private boolean mShowGenericMerge = false;
private boolean mShowManageConference = false;
- private InCallState mPreviousState = null;
private InCallCameraManager mInCallCameraManager;
public CallButtonPresenter() {
@@ -70,12 +69,12 @@ public class CallButtonPresenter extends Presenter<CallButtonPresenter.CallButto
}
@Override
- public void onStateChange(InCallState state, CallList callList) {
+ public void onStateChange(InCallState oldState, InCallState newState, CallList callList) {
CallButtonUi ui = getUi();
- if (state == InCallState.OUTGOING) {
+ if (newState == InCallState.OUTGOING) {
mCall = callList.getOutgoingCall();
- } else if (state == InCallState.INCALL) {
+ } else if (newState == InCallState.INCALL) {
mCall = callList.getActiveOrBackgroundCall();
// When connected to voice mail, automatically shows the dialpad.
@@ -83,12 +82,12 @@ public class CallButtonPresenter extends Presenter<CallButtonPresenter.CallButto
// OUTGOING. We may want to do that once we start showing "Voice mail" label on
// the dialpad too.)
if (ui != null) {
- if (mPreviousState == InCallState.OUTGOING && mCall != null
+ if (oldState == InCallState.OUTGOING && mCall != null
&& PhoneNumberUtils.isVoiceMailNumber(mCall.getNumber())) {
ui.displayDialpad(true /* show */, true /* animate */);
}
}
- } else if (state == InCallState.INCOMING) {
+ } else if (newState == InCallState.INCOMING) {
if (ui != null) {
ui.displayDialpad(false /* show */, true /* animate */);
}
@@ -96,14 +95,12 @@ public class CallButtonPresenter extends Presenter<CallButtonPresenter.CallButto
} else {
mCall = null;
}
- updateUi(state, mCall);
-
- mPreviousState = state;
+ updateUi(newState, mCall);
}
@Override
- public void onIncomingCall(InCallState state, Call call) {
- onStateChange(state, CallList.getInstance());
+ public void onIncomingCall(InCallState oldState, InCallState newState, Call call) {
+ onStateChange(oldState, newState, CallList.getInstance());
}
@Override
diff --git a/src/com/android/incallui/CallCardFragment.java b/src/com/android/incallui/CallCardFragment.java
index cb89b855..fd366202 100644
--- a/src/com/android/incallui/CallCardFragment.java
+++ b/src/com/android/incallui/CallCardFragment.java
@@ -474,6 +474,11 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
Log.v(this, "DisconnectCause " + DisconnectCause.toString(cause));
Log.v(this, "gateway " + connectionLabel + gatewayNumber);
+ if (TextUtils.equals(callStateLabel, mCallStateLabel.getText())) {
+ // Nothing to do if the labels are the same
+ return;
+ }
+
// Update the call state label and icon.
if (!TextUtils.isEmpty(callStateLabel)) {
mCallStateLabel.setText(callStateLabel);
@@ -626,6 +631,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
case Call.State.ONHOLD:
callStateLabel = context.getString(R.string.card_title_on_hold);
break;
+ case Call.State.CONNECTING:
case Call.State.DIALING:
if (isSpecialCall) {
callStateLabel = context.getString(R.string.calling_via_template, label);
diff --git a/src/com/android/incallui/CallCardPresenter.java b/src/com/android/incallui/CallCardPresenter.java
index 99d7f33f..92412ea2 100644
--- a/src/com/android/incallui/CallCardPresenter.java
+++ b/src/com/android/incallui/CallCardPresenter.java
@@ -159,14 +159,14 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
}
@Override
- public void onIncomingCall(InCallState state, Call call) {
+ public void onIncomingCall(InCallState oldState, InCallState newState, Call call) {
// same logic should happen as with onStateChange()
- onStateChange(state, CallList.getInstance());
+ onStateChange(oldState, newState, CallList.getInstance());
}
@Override
- public void onStateChange(InCallState state, CallList callList) {
- Log.d(this, "onStateChange() " + state);
+ public void onStateChange(InCallState oldState, InCallState newState, CallList callList) {
+ Log.d(this, "onStateChange() " + newState);
final CallCardUi ui = getUi();
if (ui == null) {
return;
@@ -175,15 +175,18 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
Call primary = null;
Call secondary = null;
- if (state == InCallState.INCOMING) {
+ if (newState == InCallState.INCOMING) {
primary = callList.getIncomingCall();
- } else if (state == InCallState.OUTGOING) {
+ } else if (newState == InCallState.PENDING_OUTGOING || newState == InCallState.OUTGOING) {
primary = callList.getOutgoingCall();
+ if (primary == null) {
+ primary = callList.getPendingOutgoingCall();
+ }
// getCallToDisplay doesn't go through outgoing or incoming calls. It will return the
// highest priority call to display as the secondary call.
secondary = getCallToDisplay(callList, null, true);
- } else if (state == InCallState.INCALL) {
+ } else if (newState == InCallState.INCALL) {
primary = getCallToDisplay(callList, null, false);
secondary = getCallToDisplay(callList, primary, true);
}
@@ -191,7 +194,9 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
Log.d(this, "Primary call: " + primary);
Log.d(this, "Secondary call: " + secondary);
- final boolean primaryChanged = !areCallsSame(mPrimary, primary);
+ final boolean outgoingCallReady = newState == InCallState.OUTGOING &&
+ oldState == InCallState.PENDING_OUTGOING;
+ final boolean primaryChanged = !areCallsSame(mPrimary, primary) || outgoingCallReady;
final boolean secondaryChanged = !areCallsSame(mSecondary, secondary);
mSecondary = secondary;
mPrimary = primary;
@@ -265,7 +270,7 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
getUi().setPhotoVisible(!(mPrimary.isVideoCall() && callState != Call.State.ONHOLD));
}
- final boolean enableEndCallButton = Call.State.isConnected(callState) &&
+ final boolean enableEndCallButton = Call.State.isConnectingOrConnected(callState) &&
callState != Call.State.INCOMING && mPrimary != null;
getUi().setEndCallButtonEnabled(enableEndCallButton);
}
@@ -437,6 +442,7 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
if (getUi() == null) {
return;
}
+
if (entry.photo != null) {
if (mPrimary != null && callId.equals(mPrimary.getId())) {
getUi().setPrimaryImage(entry.photo);
diff --git a/src/com/android/incallui/CallList.java b/src/com/android/incallui/CallList.java
index 127c04a1..becb411c 100644
--- a/src/com/android/incallui/CallList.java
+++ b/src/com/android/incallui/CallList.java
@@ -204,6 +204,10 @@ public class CallList implements InCallPhoneListener {
return getFirstCallWithState(Call.State.PRE_DIAL_WAIT);
}
+ public Call getPendingOutgoingCall() {
+ return getFirstCallWithState(Call.State.CONNECTING);
+ }
+
public Call getOutgoingCall() {
Call call = getFirstCallWithState(Call.State.DIALING);
if (call == null) {
@@ -252,6 +256,9 @@ public class CallList implements InCallPhoneListener {
public Call getFirstCall() {
Call result = getIncomingCall();
if (result == null) {
+ result = getPendingOutgoingCall();
+ }
+ if (result == null) {
result = getOutgoingCall();
}
if (result == null) {
diff --git a/src/com/android/incallui/ConferenceManagerPresenter.java b/src/com/android/incallui/ConferenceManagerPresenter.java
index b505e29f..2b5e8eb9 100644
--- a/src/com/android/incallui/ConferenceManagerPresenter.java
+++ b/src/com/android/incallui/ConferenceManagerPresenter.java
@@ -53,10 +53,10 @@ public class ConferenceManagerPresenter
}
@Override
- public void onStateChange(InCallState state, CallList callList) {
+ public void onStateChange(InCallState oldState, InCallState newState, CallList callList) {
if (getUi().isFragmentVisible()) {
- Log.v(this, "onStateChange" + state);
- if (state == InCallState.INCALL) {
+ Log.v(this, "onStateChange" + newState);
+ if (newState == InCallState.INCALL) {
final Call call = callList.getActiveOrBackgroundCall();
if (call != null && call.isConferenceCall()) {
Log.v(this, "Number of existing calls is " +
diff --git a/src/com/android/incallui/DialpadPresenter.java b/src/com/android/incallui/DialpadPresenter.java
index 79fe3d6d..f612a738 100644
--- a/src/com/android/incallui/DialpadPresenter.java
+++ b/src/com/android/incallui/DialpadPresenter.java
@@ -39,7 +39,8 @@ public class DialpadPresenter extends Presenter<DialpadPresenter.DialpadUi>
}
@Override
- public void onStateChange(InCallPresenter.InCallState state, CallList callList) {
+ public void onStateChange(InCallPresenter.InCallState oldState,
+ InCallPresenter.InCallState newState, CallList callList) {
mCall = callList.getActiveCall();
Log.d(this, "DialpadPresenter mCall = " + mCall);
}
diff --git a/src/com/android/incallui/InCallPresenter.java b/src/com/android/incallui/InCallPresenter.java
index 6d7e5b81..cf43fbd6 100644
--- a/src/com/android/incallui/InCallPresenter.java
+++ b/src/com/android/incallui/InCallPresenter.java
@@ -311,16 +311,17 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
return;
}
InCallState newState = getPotentialStateFromCallList(callList);
+ InCallState oldState = mInCallState;
newState = startOrFinishUi(newState);
// Set the new state before announcing it to the world
- Log.i(this, "Phone switching state: " + mInCallState + " -> " + newState);
+ Log.i(this, "Phone switching state: " + oldState + " -> " + newState);
mInCallState = newState;
// notify listeners of new state
for (InCallStateListener listener : mListeners) {
Log.d(this, "Notify " + listener + " of state " + mInCallState.toString());
- listener.onStateChange(mInCallState, callList);
+ listener.onStateChange(oldState, mInCallState, callList);
}
if (isActivityStarted()) {
@@ -338,12 +339,13 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
@Override
public void onIncomingCall(Call call) {
InCallState newState = startOrFinishUi(InCallState.INCOMING);
+ InCallState oldState = mInCallState;
- Log.i(this, "Phone switching state: " + mInCallState + " -> " + newState);
+ Log.i(this, "Phone switching state: " + oldState + " -> " + newState);
mInCallState = newState;
for (IncomingCallListener listener : mIncomingCallListeners) {
- listener.onIncomingCall(mInCallState, call);
+ listener.onIncomingCall(oldState, mInCallState, call);
}
}
@@ -378,6 +380,8 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
newState = InCallState.INCOMING;
} else if (callList.getWaitingForAccountCall() != null) {
newState = InCallState.WAITING_FOR_ACCOUNT;
+ } else if (callList.getPendingOutgoingCall() != null) {
+ newState = InCallState.PENDING_OUTGOING;
} else if (callList.getOutgoingCall() != null) {
newState = InCallState.OUTGOING;
} else if (callList.getActiveCall() != null ||
@@ -714,9 +718,12 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
// TODO: Consider a proper state machine implementation
- // If the state isn't changing, we have already done any starting/stopping of
- // activities in a previous pass...so lets cut out early
- if (newState == mInCallState) {
+ // If the state isn't changing or if we're transitioning from pending outgoing to actual
+ // outgoing, we have already done any starting/stopping of activities in a previous pass
+ // ...so lets cut out early
+ boolean alreadyOutgoing = mInCallState == InCallState.PENDING_OUTGOING &&
+ newState == InCallState.OUTGOING;
+ if (newState == mInCallState || alreadyOutgoing) {
return newState;
}
@@ -753,9 +760,14 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
// happens we need to display the screen immediately or show an account picker dialog if
// no default is set.
//
+ // It is also possible to go into an intermediate state where the call has been initiated
+ // but Telecomm has not yet returned with the details of the call (handle, gateway, etc.).
+ // This pending outgoing state also launches the call screen.
+ //
// This is different from the incoming call sequence because we do not need to shock the
// user with a top-level notification. Just show the call UI normally.
- final boolean showCallUi = (InCallState.OUTGOING == newState || showAccountPicker);
+ final boolean showCallUi = ((InCallState.PENDING_OUTGOING == newState ||
+ InCallState.OUTGOING == newState) || showAccountPicker);
// TODO: Can we be suddenly in a call without it having been in the outgoing or incoming
// state? I havent seen that but if it can happen, the code below should be enabled.
@@ -985,6 +997,10 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
// Waiting for user input before placing outgoing call
WAITING_FOR_ACCOUNT,
+ // UI is starting up but no call has been initiated yet.
+ // The UI is waiting for Telecomm to respond.
+ PENDING_OUTGOING,
+
// User is dialing out
OUTGOING;
@@ -1004,11 +1020,11 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
*/
public interface InCallStateListener {
// TODO: Enhance state to contain the call objects instead of passing CallList
- public void onStateChange(InCallState state, CallList callList);
+ public void onStateChange(InCallState oldState, InCallState newState, CallList callList);
}
public interface IncomingCallListener {
- public void onIncomingCall(InCallState state, Call call);
+ public void onIncomingCall(InCallState oldState, InCallState newState, Call call);
}
public interface InCallDetailsListener {
diff --git a/src/com/android/incallui/ProximitySensor.java b/src/com/android/incallui/ProximitySensor.java
index 768a7147..6f69096a 100644
--- a/src/com/android/incallui/ProximitySensor.java
+++ b/src/com/android/incallui/ProximitySensor.java
@@ -80,11 +80,11 @@ public class ProximitySensor implements AccelerometerListener.OrientationListene
* Called to keep track of the overall UI state.
*/
@Override
- public void onStateChange(InCallState state, CallList callList) {
+ public void onStateChange(InCallState oldState, InCallState newState, CallList callList) {
// We ignore incoming state because we do not want to enable proximity
// sensor during incoming call screen
- boolean isOffhook = (InCallState.INCALL == state
- || InCallState.OUTGOING == state);
+ boolean isOffhook = (InCallState.INCALL == newState
+ || InCallState.OUTGOING == newState);
if (isOffhook != mIsPhoneOffhook) {
mIsPhoneOffhook = isOffhook;
diff --git a/src/com/android/incallui/StatusBarNotifier.java b/src/com/android/incallui/StatusBarNotifier.java
index f2f883a9..f88d2b5c 100644
--- a/src/com/android/incallui/StatusBarNotifier.java
+++ b/src/com/android/incallui/StatusBarNotifier.java
@@ -109,10 +109,10 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
* Creates notifications according to the state we receive from {@link InCallPresenter}.
*/
@Override
- public void onStateChange(InCallState state, CallList callList) {
+ public void onStateChange(InCallState oldState, InCallState newState, CallList callList) {
Log.d(this, "onStateChange");
- updateNotification(state, callList);
+ updateNotification(newState, callList);
}
/**
diff --git a/src/com/android/incallui/VideoCallPresenter.java b/src/com/android/incallui/VideoCallPresenter.java
index 77aa4ac0..7ff591f4 100644
--- a/src/com/android/incallui/VideoCallPresenter.java
+++ b/src/com/android/incallui/VideoCallPresenter.java
@@ -277,30 +277,32 @@ public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi
* @param call The call.
*/
@Override
- public void onIncomingCall(InCallPresenter.InCallState state, Call call) {
+ public void onIncomingCall(InCallPresenter.InCallState oldState,
+ InCallPresenter.InCallState newState, Call call) {
// same logic should happen as with onStateChange()
- onStateChange(state, CallList.getInstance());
+ onStateChange(oldState, newState, CallList.getInstance());
}
/**
* Handles state changes (including incoming calls)
*
- * @param state The in call state.
+ * @param newState The in call state.
* @param callList The call list.
*/
@Override
- public void onStateChange(InCallPresenter.InCallState state, CallList callList) {
- if (state == InCallPresenter.InCallState.NO_CALLS) {
+ public void onStateChange(InCallPresenter.InCallState oldState,
+ InCallPresenter.InCallState newState, CallList callList) {
+ if (newState == InCallPresenter.InCallState.NO_CALLS) {
exitVideoMode();
}
// Determine the primary active call).
Call primary = null;
- if (state == InCallPresenter.InCallState.INCOMING) {
+ if (newState == InCallPresenter.InCallState.INCOMING) {
primary = callList.getIncomingCall();
- } else if (state == InCallPresenter.InCallState.OUTGOING) {
+ } else if (newState == InCallPresenter.InCallState.OUTGOING) {
primary = callList.getOutgoingCall();
- } else if (state == InCallPresenter.InCallState.INCALL) {
+ } else if (newState == InCallPresenter.InCallState.INCALL) {
primary = callList.getActiveCall();
}