summaryrefslogtreecommitdiff
path: root/InCallUI
diff options
context:
space:
mode:
authorIhab Awad <ihab@google.com>2013-11-14 18:29:03 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-11-14 18:29:04 +0000
commit4233d32f3ecae7e0d9cfaaff650fa08911cf3677 (patch)
tree6c3f6ce358f087ff76bb93811d1d256c295f247c /InCallUI
parent582f7185b5a7922fa147fe13488d5660f4b3d930 (diff)
parent1668142a22eda0c55540ef0da68172b3c23305b4 (diff)
Merge "Show status bar notification on quick navigate from in-call UI" into klp-dev
Diffstat (limited to 'InCallUI')
-rw-r--r--InCallUI/src/com/android/incallui/InCallPresenter.java9
-rw-r--r--InCallUI/src/com/android/incallui/StatusBarNotifier.java158
2 files changed, 102 insertions, 65 deletions
diff --git a/InCallUI/src/com/android/incallui/InCallPresenter.java b/InCallUI/src/com/android/incallui/InCallPresenter.java
index 5830e726c..bfb4a5019 100644
--- a/InCallUI/src/com/android/incallui/InCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/InCallPresenter.java
@@ -71,6 +71,14 @@ public class InCallPresenter implements CallList.Listener {
return sInCallPresenter;
}
+ public InCallState getInCallState() {
+ return mInCallState;
+ }
+
+ public CallList getCallList() {
+ return mCallList;
+ }
+
public void setUp(Context context, CallList callList, AudioModeProvider audioModeProvider) {
if (mServiceConnected) {
Log.i(this, "New service connection replacing existing one.");
@@ -598,6 +606,7 @@ public class InCallPresenter implements CallList.Listener {
} else if (newState == InCallState.NO_CALLS) {
// The new state is the no calls state. Tear everything down.
attemptFinishActivity();
+ attemptCleanup();
}
return newState;
diff --git a/InCallUI/src/com/android/incallui/StatusBarNotifier.java b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
index 459921f1f..89c9ff41e 100644
--- a/InCallUI/src/com/android/incallui/StatusBarNotifier.java
+++ b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
@@ -16,7 +16,6 @@
package com.android.incallui;
-import com.android.services.telephony.common.CallIdentification;
import com.google.common.base.Preconditions;
import android.app.Notification;
@@ -27,7 +26,8 @@ import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Message;
import android.text.TextUtils;
import com.android.incallui.ContactInfoCache.ContactCacheEntry;
@@ -36,8 +36,6 @@ import com.android.incallui.InCallApp.NotificationBroadcastReceiver;
import com.android.incallui.InCallPresenter.InCallState;
import com.android.services.telephony.common.Call;
-import java.util.HashMap;
-
/**
* This class adds Notifications to the status bar for the in-call experience.
*/
@@ -45,9 +43,51 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
// notification types
private static final int IN_CALL_NOTIFICATION = 1;
+ private static final long IN_CALL_TIMEOUT = 1000L;
+
+ private interface NotificationTimer {
+ enum State {
+ SCHEDULED,
+ FIRED,
+ CLEAR;
+ }
+ State getState();
+ void schedule();
+ void clear();
+ }
+
+ private NotificationTimer mNotificationTimer = new NotificationTimer() {
+ private final Handler mHandler = new Handler(new Handler.Callback() {
+ public boolean handleMessage(Message m) {
+ fire();
+ return true;
+ }
+ });
+ private State mState = State.CLEAR;
+ public State getState() { return mState; }
+ public void schedule() {
+ if (mState == State.CLEAR) {
+ Log.d(this, "updateInCallNotification: timer scheduled");
+ mHandler.sendEmptyMessageDelayed(0, IN_CALL_TIMEOUT);
+ mState = State.SCHEDULED;
+ }
+ }
+ public void clear() {
+ Log.d(this, "updateInCallNotification: timer cleared");
+ mHandler.removeMessages(0);
+ mState = State.CLEAR;
+ }
+ private void fire() {
+ Log.d(this, "updateInCallNotification: timer fired");
+ mState = State.FIRED;
+ updateNotification(
+ InCallPresenter.getInstance().getInCallState(),
+ InCallPresenter.getInstance().getCallList());
+ }
+ };
+
private final Context mContext;
private final ContactInfoCache mContactInfoCache;
- private final CallList mCallList;
private final NotificationManager mNotificationManager;
private boolean mIsShowingNotification = false;
private int mCallState = Call.State.INVALID;
@@ -62,7 +102,6 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
mContext = context;
mContactInfoCache = contactInfoCache;
- mCallList = callList;
mNotificationManager =
(NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
}
@@ -121,7 +160,7 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
* update or cancel the in-call notification based on the current
* phone state.
*
- * @see #updateInCallNotification(boolean)
+ * @see #updateInCallNotification(boolean,InCallState,CallList)
*/
public void updateNotificationAndLaunchIncomingCallUi(InCallState state, CallList callList) {
// Set allowFullScreenIntent=true to indicate that we *should*
@@ -131,12 +170,11 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
/**
* Take down the in-call notification.
- * @see updateInCallNotification()
+ * @see #updateInCallNotification(boolean,InCallState,CallList)
*/
private void cancelInCall() {
Log.d(this, "cancelInCall()...");
mNotificationManager.cancel(IN_CALL_NOTIFICATION);
-
mIsShowingNotification = false;
}
@@ -167,13 +205,55 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
Log.d(this, "updateInCallNotification(allowFullScreenIntent = "
+ allowFullScreenIntent + ")...");
- final Call call = getCallToShow(callList);
- if (shouldSuppressNotification(state, call)) {
- Log.d(this, "Suppressing notification");
+ Call call = getCallToShow(callList);
+
+ // Whether we have an outgoing call but the incall UI has yet to show up.
+ // Since we don't normally show a notification while the incall screen is
+ // in the foreground, if we show the outgoing notification before the activity
+ // comes up the user will see it flash on and off on an outgoing call. We therefore
+ // do not show the notification for outgoing calls before the activity has started.
+ boolean isOutgoingWithoutIncallUi =
+ state == InCallState.OUTGOING &&
+ !InCallPresenter.getInstance().isActivityPreviouslyStarted();
+
+ // Whether to show a notification immediately.
+ boolean showNotificationNow =
+
+ // We can still be in the INCALL state when a call is disconnected (in order to show
+ // the "Call ended" screen. So check that we have an active connection too.
+ (call != null) &&
+
+ // We show a notification iff there is an active call.
+ state.isConnectingOrConnected() &&
+
+ // If the UI is already showing, then for most cases we do not want to show
+ // a notification since that would be redundant, unless it is an incoming call,
+ // in which case the notification is actually an important alert.
+ (!InCallPresenter.getInstance().isShowingInCallUi() || state.isIncoming()) &&
+
+ // If we have an outgoing call with no UI but the timer has fired, we show
+ // a notification anyway.
+ (!isOutgoingWithoutIncallUi ||
+ mNotificationTimer.getState() == NotificationTimer.State.FIRED);
+
+ if (showNotificationNow) {
+ Log.e(this, "showNotificationNow == true case", new Exception());
+ showNotification(call, allowFullScreenIntent);
+ } else {
cancelInCall();
- return;
+ if (isOutgoingWithoutIncallUi &&
+ mNotificationTimer.getState() == NotificationTimer.State.CLEAR) {
+ mNotificationTimer.schedule();
+ }
+ }
+
+ // If we see a UI, or we are done with calls for now, reset to ground state.
+ if (InCallPresenter.getInstance().isShowingInCallUi() || call == null) {
+ mNotificationTimer.clear();
}
+ }
+ private void showNotification(final Call call, final boolean allowFullScreenIntent) {
// we make a call to the contact info cache to query for supplemental data to what the
// call provides. This includes the contact name and photo.
// This callback will always get called immediately and synchronously with whatever data
@@ -473,58 +553,6 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
return builder;
}
-
- /**
- * Returns true if notification should not be shown in the current state.
- */
- private boolean shouldSuppressNotification(InCallState state, Call call) {
-
- // We can still be in the INCALL state when a call is disconnected (in order to show
- // the "Call ended" screen. So check that we have an active connection too.
- if (call == null) {
- Log.v(this, "suppressing: no call");
- return true;
- }
-
- // Suppress the in-call notification if the InCallScreen is the
- // foreground activity, since it's already obvious that you're on a
- // call. (The status bar icon is needed only if you navigate *away*
- // from the in-call UI.)
- boolean shouldSuppress = InCallPresenter.getInstance().isShowingInCallUi();
-
- // Suppress if the call is not active.
- if (!state.isConnectingOrConnected()) {
- Log.v(this, "suppressing: not connecting or connected");
- shouldSuppress = true;
- }
-
- // If there's an incoming ringing call: always show the
- // notification, since the in-call notification is what actually
- // launches the incoming call UI in the first place (see
- // notification.fullScreenIntent below.) This makes sure that we'll
- // correctly handle the case where a new incoming call comes in but
- // the InCallScreen is already in the foreground.
- if (state.isIncoming()) {
- Log.v(this, "unsuppressing: incoming call");
- shouldSuppress = false;
- }
-
- // JANK Fix
- // Do not show the notification for outgoing calls until the UI comes up.
- // Since we don't normally show a notification while the incall screen is
- // in the foreground, if we show the outgoing notification before the activity
- // comes up the user will see it flash on and off on an outgoing call.
- // This code ensures that we do not show the notification for outgoing calls before
- // the activity has started.
- if (state == InCallState.OUTGOING &&
- !InCallPresenter.getInstance().isActivityPreviouslyStarted()) {
- Log.v(this, "suppressing: activity not started.");
- shouldSuppress = true;
- }
-
- return shouldSuppress;
- }
-
private PendingIntent createLaunchPendingIntent() {
final Intent intent = InCallPresenter.getInstance().getInCallIntent(/*showdialpad=*/false);