summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--InCallUI/src/com/android/incallui/CallCardFragment.java9
-rw-r--r--InCallUI/src/com/android/incallui/CallCardPresenter.java6
-rw-r--r--InCallUI/src/com/android/incallui/ContactInfoCache.java9
-rw-r--r--InCallUI/src/com/android/incallui/InCallActivity.java2
-rw-r--r--InCallUI/src/com/android/incallui/InCallPresenter.java13
-rw-r--r--InCallUI/src/com/android/incallui/StatusBarNotifier.java104
6 files changed, 112 insertions, 31 deletions
diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java
index 6caf0089c..552a42a61 100644
--- a/InCallUI/src/com/android/incallui/CallCardFragment.java
+++ b/InCallUI/src/com/android/incallui/CallCardFragment.java
@@ -95,12 +95,6 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter>
}
@Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- getPresenter().setContext(activity);
- }
-
- @Override
public void setPrimary(String number, String name, String label, Drawable photo) {
boolean nameIsNumber = false;
@@ -197,8 +191,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter>
private void setDrawableToImageView(ImageView view, Drawable photo) {
if (photo == null) {
- mPhoto.setVisibility(View.INVISIBLE);
- return;
+ photo = view.getResources().getDrawable(R.drawable.picture_unknown);
}
final Drawable current = view.getDrawable();
diff --git a/InCallUI/src/com/android/incallui/CallCardPresenter.java b/InCallUI/src/com/android/incallui/CallCardPresenter.java
index 105e3482a..8a855c104 100644
--- a/InCallUI/src/com/android/incallui/CallCardPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallCardPresenter.java
@@ -35,7 +35,6 @@ import com.android.services.telephony.common.Call;
public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
implements InCallStateListener, AudioModeListener, ContactInfoCacheCallback {
- private Context mContext;
private AudioModeProvider mAudioModeProvider;
private ContactInfoCache mContactInfoCache;
private Call mPrimary;
@@ -67,9 +66,8 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
mSecondaryContactInfo = null;
}
- public void setContext(Context context) {
- mContext = context;
- mContactInfoCache = new ContactInfoCache(mContext);
+ public void setContactInfoCache(ContactInfoCache cache) {
+ mContactInfoCache = cache;
startContactInfoSearch();
}
diff --git a/InCallUI/src/com/android/incallui/ContactInfoCache.java b/InCallUI/src/com/android/incallui/ContactInfoCache.java
index 6cbe060ac..c5a4cf551 100644
--- a/InCallUI/src/com/android/incallui/ContactInfoCache.java
+++ b/InCallUI/src/com/android/incallui/ContactInfoCache.java
@@ -144,13 +144,20 @@ public class ContactInfoCache implements CallerInfoAsyncQuery.OnQueryCompleteLis
entry.info.photo = new BitmapDrawable(mContext.getResources(), photoIcon);
} else {
Logger.v(this, "unknown photo");
- entry.info.photo = mContext.getResources().getDrawable(R.drawable.picture_unknown);
+ entry.info.photo = null;
}
sendNotification(entry);
}
/**
+ * Blows away the stored cache values.
+ */
+ public void clearCache() {
+ mInfoMap.clear();
+ }
+
+ /**
* Performs a query for caller information.
* Save any immediate data we get from the query. An asynchronous query may also be made
* for any data that we do not already have. Some queries, such as those for voicemail and
diff --git a/InCallUI/src/com/android/incallui/InCallActivity.java b/InCallUI/src/com/android/incallui/InCallActivity.java
index c76f08ad0..e1a979693 100644
--- a/InCallUI/src/com/android/incallui/InCallActivity.java
+++ b/InCallUI/src/com/android/incallui/InCallActivity.java
@@ -287,6 +287,8 @@ public class InCallActivity extends Activity {
mainPresenter.getAudioModeProvider());
mCallCardFragment.getPresenter().setAudioModeProvider(
mainPresenter.getAudioModeProvider());
+ mCallCardFragment.getPresenter().setContactInfoCache(
+ mainPresenter.getContactInfoCache());
mainPresenter.addListener(mCallButtonFragment.getPresenter());
mainPresenter.addListener(mCallCardFragment.getPresenter());
diff --git a/InCallUI/src/com/android/incallui/InCallPresenter.java b/InCallUI/src/com/android/incallui/InCallPresenter.java
index 25c2447dd..3ae4d3aaf 100644
--- a/InCallUI/src/com/android/incallui/InCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/InCallPresenter.java
@@ -43,6 +43,7 @@ public class InCallPresenter implements CallList.Listener {
private AudioModeProvider mAudioModeProvider;
private StatusBarNotifier mStatusBarNotifier;
+ private ContactInfoCache mContactInfoCache;
private Context mContext;
private CallList mCallList;
private InCallActivity mInCallActivity;
@@ -63,7 +64,9 @@ public class InCallPresenter implements CallList.Listener {
mCallList = callList;
mCallList.addListener(this);
- mStatusBarNotifier = new StatusBarNotifier(context);
+ mContactInfoCache = new ContactInfoCache(context);
+
+ mStatusBarNotifier = new StatusBarNotifier(context, mContactInfoCache, mCallList);
addListener(mStatusBarNotifier);
mAudioModeProvider = audioModeProvider;
@@ -148,6 +151,10 @@ public class InCallPresenter implements CallList.Listener {
return mAudioModeProvider;
}
+ public ContactInfoCache getContactInfoCache() {
+ return mContactInfoCache;
+ }
+
/**
* Hangs up any active or outgoing calls.
*/
@@ -244,6 +251,10 @@ public class InCallPresenter implements CallList.Listener {
mInCallActivity = null;
temp.finish();
+
+ // blow away stale contact info so that we get fresh data on
+ // the next set of calls
+ mContactInfoCache.clearCache();
}
}
diff --git a/InCallUI/src/com/android/incallui/StatusBarNotifier.java b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
index ff3c47b16..e2dc42ca8 100644
--- a/InCallUI/src/com/android/incallui/StatusBarNotifier.java
+++ b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
@@ -23,7 +23,13 @@ import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+import com.android.incallui.ContactInfoCache.ContactCacheEntry;
+import com.android.incallui.ContactInfoCache.ContactInfoCacheCallback;
import com.android.incallui.InCallApp.NotificationBroadcastReceiver;
import com.android.incallui.InCallPresenter.InCallState;
import com.android.services.telephony.common.Call;
@@ -31,21 +37,29 @@ import com.android.services.telephony.common.Call;
/**
* This class adds Notifications to the status bar for the in-call experience.
*/
-public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
+public class StatusBarNotifier implements InCallPresenter.InCallStateListener,
+ ContactInfoCacheCallback {
// notification types
private static final int IN_CALL_NOTIFICATION = 1;
private final Context mContext;
+ private final ContactInfoCache mContactInfoCache;
+ private final CallList mCallList;
private final NotificationManager mNotificationManager;
private boolean mIsShowingNotification = false;
private InCallState mInCallState = InCallState.HIDDEN;
private int mSavedIcon = 0;
private int mSavedContent = 0;
+ private Bitmap mSavedLargeIcon;
+ private String mSavedContentTitle;
- public StatusBarNotifier(Context context) {
+ public StatusBarNotifier(Context context, ContactInfoCache contactInfoCache,
+ CallList callList) {
Preconditions.checkNotNull(context);
mContext = context;
+ mContactInfoCache = contactInfoCache;
+ mCallList = callList;
mNotificationManager =
(NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
}
@@ -59,6 +73,14 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
}
/**
+ * Called after the Contact Info query has finished.
+ */
+ @Override
+ public void onContactInfoComplete(int callId, ContactCacheEntry entry) {
+ updateNotification(mInCallState, mCallList);
+ }
+
+ /**
* Updates the phone app's status bar notification based on the
* current telephony state, or cancels the notification if the phone
* is totally idle.
@@ -134,8 +156,8 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
* Watch out: This should be set to true *only* when directly
* handling a new incoming call for the first time.
*/
- private void updateInCallNotification(boolean allowFullScreenIntent, InCallState state,
- CallList callList) {
+ private void updateInCallNotification(final boolean allowFullScreenIntent,
+ final InCallState state, CallList callList) {
Logger.d(this, "updateInCallNotification(allowFullScreenIntent = "
+ allowFullScreenIntent + ")...");
@@ -144,30 +166,42 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
return;
}
- buildAndSendNotification(state, callList, allowFullScreenIntent);
+ final Call call = getCallToShow(callList);
+ if (call == null) {
+ Logger.wtf(this, "No call for the notification!");
+ }
+
+ // 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, new ContactInfoCacheCallback() {
+ @Override
+ public void onContactInfoComplete(int callId, ContactCacheEntry entry) {
+ buildAndSendNotification(state, call, entry, allowFullScreenIntent);
+ }
+ });
}
/**
* Sets up the main Ui for the notification
*/
- private void buildAndSendNotification(InCallState state, CallList callList,
- boolean allowFullScreenIntent) {
-
- final Call call = getCallToShow(callList);
- if (call == null) {
- Logger.wtf(this, "No call for the notification!");
- }
+ private void buildAndSendNotification(InCallState state, Call call,
+ ContactCacheEntry contactInfo, boolean allowFullScreenIntent) {
final int iconResId = getIconToDisplay(call);
+ final Bitmap largeIcon = getLargeIconToDisplay(contactInfo);
final int contentResId = getContentString(call);
+ final String contentTitle = getContentTitle(contactInfo);
// If we checked and found that nothing is different, dont issue another notification.
- if (!checkForChangeAndSaveData(iconResId, contentResId, state, allowFullScreenIntent)) {
+ if (!checkForChangeAndSaveData(iconResId, contentResId, largeIcon, contentTitle, state,
+ allowFullScreenIntent)) {
return;
}
-
/*
* Nothing more to check...build and send it.
*/
@@ -185,6 +219,8 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
// set the content
builder.setContentText(mContext.getString(contentResId));
builder.setSmallIcon(iconResId);
+ builder.setContentTitle(contentTitle);
+ builder.setLargeIcon(largeIcon);
// Add special Content for calls that are ongoing
if (InCallState.INCALL == state || InCallState.OUTGOING == state) {
@@ -205,10 +241,20 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
* are already displaying. If the data is exactly the same, we return false so that
* we do not issue a new notification for the exact same data.
*/
- private boolean checkForChangeAndSaveData(int icon, int content, InCallState state,
- boolean showFullScreenIntent) {
+ private boolean checkForChangeAndSaveData(int icon, int content, Bitmap largeIcon,
+ String contentTitle, InCallState state, boolean showFullScreenIntent) {
+
+ // The two are different:
+ // if new title is not null, it should be different from saved version OR
+ // if new title is null, the saved version should not be null
+ final boolean contentTitleChanged =
+ (contentTitle != null && !contentTitle.equals(mSavedContentTitle)) ||
+ (contentTitle == null && mSavedContentTitle != null);
+
+ // any change means we are definitely updating
boolean retval = (mSavedIcon != icon) || (mSavedContent != content) ||
- (mInCallState == state);
+ (mInCallState != state) || (mSavedLargeIcon != largeIcon) ||
+ contentTitleChanged;
// A full screen intent means that we have been asked to interrupt an activity,
// so we definitely want to show it.
@@ -226,6 +272,8 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
mSavedIcon = icon;
mSavedContent = content;
mInCallState = state;
+ mSavedLargeIcon = largeIcon;
+ mSavedContentTitle = contentTitle;
if (retval) {
Logger.d(this, "Data changed. Showing notification");
@@ -235,6 +283,28 @@ public class StatusBarNotifier implements InCallPresenter.InCallStateListener {
}
/**
+ * Returns the main string to use in the notification.
+ */
+ private String getContentTitle(ContactCacheEntry contactInfo) {
+ if (TextUtils.isEmpty(contactInfo.name)) {
+ return contactInfo.number;
+ }
+
+ return contactInfo.name;
+ }
+
+ /**
+ * Gets a large icon from the contact info object to display in the notification.
+ */
+ private Bitmap getLargeIconToDisplay(ContactCacheEntry contactInfo) {
+ if (contactInfo.photo != null && (contactInfo.photo instanceof BitmapDrawable)) {
+ return ((BitmapDrawable) contactInfo.photo).getBitmap();
+ }
+
+ return null;
+ }
+
+ /**
* Returns the appropriate icon res Id to display based on the call for which
* we want to display information.
*/