Merge "Add logic to dynamic dismiss keyguard." into klp-dev
diff --git a/src/com/android/incallui/ContactInfoCache.java b/src/com/android/incallui/ContactInfoCache.java
index 45a38c7..448de7f 100644
--- a/src/com/android/incallui/ContactInfoCache.java
+++ b/src/com/android/incallui/ContactInfoCache.java
@@ -173,7 +173,8 @@
mPhoneNumberService != null) {
Log.d(TAG, "Contact lookup. Local contacts miss, checking remote");
final PhoneNumberServiceListener listener = new PhoneNumberServiceListener(callId);
- mPhoneNumberService.getPhoneNumberInfo(cacheEntry.number, listener, listener);
+ mPhoneNumberService.getPhoneNumberInfo(cacheEntry.number, listener, listener,
+ isIncoming);
} else if (cacheEntry.personUri != null) {
Log.d(TAG, "Contact lookup. Local contact found, starting image load");
// Load the image with a callback to update the image state.
diff --git a/src/com/android/incallui/InCallPresenter.java b/src/com/android/incallui/InCallPresenter.java
index ae9da36..8bec492 100644
--- a/src/com/android/incallui/InCallPresenter.java
+++ b/src/com/android/incallui/InCallPresenter.java
@@ -71,6 +71,14 @@
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.");
@@ -86,7 +94,7 @@
mContactInfoCache = ContactInfoCache.getInstance(context);
- mStatusBarNotifier = new StatusBarNotifier(context, mContactInfoCache, mCallList);
+ mStatusBarNotifier = new StatusBarNotifier(context, mContactInfoCache);
addListener(mStatusBarNotifier);
mAudioModeProvider = audioModeProvider;
@@ -608,6 +616,7 @@
} else if (newState == InCallState.NO_CALLS) {
// The new state is the no calls state. Tear everything down.
attemptFinishActivity();
+ attemptCleanup();
}
return newState;
diff --git a/src/com/android/incallui/StatusBarNotifier.java b/src/com/android/incallui/StatusBarNotifier.java
index 459921f..6d9fd60 100644
--- a/src/com/android/incallui/StatusBarNotifier.java
+++ b/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.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.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 @@
// 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;
@@ -56,13 +96,11 @@
private Bitmap mSavedLargeIcon;
private String mSavedContentTitle;
- public StatusBarNotifier(Context context, ContactInfoCache contactInfoCache,
- CallList callList) {
+ public StatusBarNotifier(Context context, ContactInfoCache contactInfoCache) {
Preconditions.checkNotNull(context);
mContext = context;
mContactInfoCache = contactInfoCache;
- mCallList = callList;
mNotificationManager =
(NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
}
@@ -121,7 +159,7 @@
* 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 +169,11 @@
/**
* 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,19 +204,64 @@
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) {
+ final boolean isIncoming = (call.getState() == Call.State.INCOMING ||
+ call.getState() == Call.State.CALL_WAITING);
+
// 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
// it has available, and may make a subsequent call later (same thread) if it had to
// call into the contacts provider for more data.
- mContactInfoCache.findInfo(call.getIdentification(), call.getState() == Call.State.INCOMING,
+ mContactInfoCache.findInfo(call.getIdentification(), isIncoming,
new ContactInfoCacheCallback() {
private boolean mAllowFullScreenIntent = allowFullScreenIntent;
@@ -377,12 +459,12 @@
}
/**
- * Returns the message to use with the notificaiton.
+ * Returns the message to use with the notification.
*/
private int getContentString(Call call) {
int resId = R.string.notification_ongoing_call;
- if (call.getState() == Call.State.INCOMING) {
+ if (call.getState() == Call.State.INCOMING || call.getState() == Call.State.CALL_WAITING) {
resId = R.string.notification_incoming_call;
} else if (call.getState() == Call.State.ONHOLD) {
@@ -455,7 +537,14 @@
// TODO: there should be a cleaner way of avoiding this
// problem (see discussion in bug 3184149.)
- if (call.getState() == Call.State.CALL_WAITING) {
+ // If a call is onhold during an incoming call, the call actually comes in as
+ // INCOMING. For that case *and* traditional call-waiting, we want to
+ // cancel the notification.
+ boolean isCallWaiting = (call.getState() == Call.State.CALL_WAITING ||
+ (call.getState() == Call.State.INCOMING &&
+ CallList.getInstance().getBackgroundCall() != null));
+
+ if (isCallWaiting) {
Log.i(this, "updateInCallNotification: call-waiting! force relaunch...");
// Cancel the IN_CALL_NOTIFICATION immediately before
// (re)posting it; this seems to force the
@@ -473,58 +562,6 @@
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);
diff --git a/src/com/android/incallui/service/PhoneNumberService.java b/src/com/android/incallui/service/PhoneNumberService.java
index d5f809c..3ce84b9 100644
--- a/src/com/android/incallui/service/PhoneNumberService.java
+++ b/src/com/android/incallui/service/PhoneNumberService.java
@@ -31,7 +31,7 @@
* @param imageListener The listener to notify when the image lookup is complete.
*/
public void getPhoneNumberInfo(String phoneNumber, NumberLookupListener listener,
- ImageLookupListener imageListener);
+ ImageLookupListener imageListener, boolean isIncoming);
public interface NumberLookupListener {