summaryrefslogtreecommitdiff
path: root/InCallUI/src/com/android/incallui/CallCardPresenter.java
diff options
context:
space:
mode:
Diffstat (limited to 'InCallUI/src/com/android/incallui/CallCardPresenter.java')
-rw-r--r--InCallUI/src/com/android/incallui/CallCardPresenter.java194
1 files changed, 187 insertions, 7 deletions
diff --git a/InCallUI/src/com/android/incallui/CallCardPresenter.java b/InCallUI/src/com/android/incallui/CallCardPresenter.java
index bea89ef8e..f37956569 100644
--- a/InCallUI/src/com/android/incallui/CallCardPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallCardPresenter.java
@@ -16,8 +16,15 @@
package com.android.incallui;
+import android.content.ContentUris;
+import android.content.Context;
+import android.net.Uri;
+import android.provider.ContactsContract.Contacts;
+import android.text.TextUtils;
+
import com.android.incallui.InCallPresenter.InCallState;
import com.android.incallui.InCallPresenter.InCallStateListener;
+
import com.android.services.telephony.common.Call;
/**
@@ -25,13 +32,19 @@ import com.android.services.telephony.common.Call;
* This class listens for changes to InCallState and passes it along to the fragment.
*/
public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
- implements InCallStateListener {
+ implements InCallStateListener, CallerInfoAsyncQuery.OnQueryCompleteListener {
+
+ private Context mContext;
@Override
public void onUiReady(CallCardUi ui) {
super.onUiReady(ui);
}
+ public void setContext(Context context) {
+ mContext = context;
+ }
+
@Override
public void onStateChange(InCallState state, CallList callList) {
final CallCardUi ui = getUi();
@@ -55,11 +68,9 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
Logger.d(this, "Secondary call: " + secondary);
// Set primary call data
- if (primary != null) {
- ui.setNumber(primary.getNumber());
- } else {
- ui.setNumber("");
- }
+ final CallerInfo primaryCallInfo = CallerInfoUtils.getCallerInfoForCall(mContext, primary,
+ null, this);
+ updateDisplayByCallerInfo(primary, primaryCallInfo, primary.getNumberPresentation(), true);
// Set secondary call data
if (secondary != null) {
@@ -71,10 +82,179 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
public interface CallCardUi extends Ui {
// TODO(klp): Consider passing in the Call object directly in these methods.
-
void setVisible(boolean on);
void setNumber(String number);
+ void setNumberLabel(String label);
void setName(String name);
+ void setName(String name, boolean isNumber);
void setSecondaryCallInfo(boolean show, String number);
}
+
+ @Override
+ public void onQueryComplete(int token, Object cookie, CallerInfo ci) {
+ if (cookie instanceof Call) {
+ final Call call = (Call) cookie;
+ if (ci.contactExists || ci.isEmergencyNumber() || ci.isVoiceMailNumber()) {
+ updateDisplayByCallerInfo(call, ci, Call.PRESENTATION_ALLOWED, true);
+ } else {
+ // If the contact doesn't exist, we can still use information from the
+ // returned caller info (geodescription, etc).
+ updateDisplayByCallerInfo(call, ci, call.getNumberPresentation(), true);
+ }
+
+ // Todo (klp): updatePhotoForCallState(call);
+ }
+ }
+
+ /**
+ * Based on the given caller info, determine a suitable name, phone number and label
+ * to be passed to the CallCardUI.
+ *
+ * If the current call is a conference call, use
+ * updateDisplayForConference() instead.
+ */
+ private void updateDisplayByCallerInfo(Call call, CallerInfo info, int presentation,
+ boolean isPrimary) {
+
+ //Todo (klp): Either enable or get rid of this
+ // inform the state machine that we are displaying a photo.
+ //mPhotoTracker.setPhotoRequest(info);
+ //mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE);
+
+
+ // The actual strings we're going to display onscreen:
+ String displayName;
+ String displayNumber = null;
+ String label = null;
+ Uri personUri = null;
+
+ // Gather missing info unless the call is generic, in which case we wouldn't use
+ // the gathered information anyway.
+ if (info != null) {
+
+ // It appears that there is a small change in behaviour with the
+ // PhoneUtils' startGetCallerInfo whereby if we query with an
+ // empty number, we will get a valid CallerInfo object, but with
+ // fields that are all null, and the isTemporary boolean input
+ // parameter as true.
+
+ // In the past, we would see a NULL callerinfo object, but this
+ // ends up causing null pointer exceptions elsewhere down the
+ // line in other cases, so we need to make this fix instead. It
+ // appears that this was the ONLY call to PhoneUtils
+ // .getCallerInfo() that relied on a NULL CallerInfo to indicate
+ // an unknown contact.
+
+ // Currently, infi.phoneNumber may actually be a SIP address, and
+ // if so, it might sometimes include the "sip:" prefix. That
+ // prefix isn't really useful to the user, though, so strip it off
+ // if present. (For any other URI scheme, though, leave the
+ // prefix alone.)
+ // TODO: It would be cleaner for CallerInfo to explicitly support
+ // SIP addresses instead of overloading the "phoneNumber" field.
+ // Then we could remove this hack, and instead ask the CallerInfo
+ // for a "user visible" form of the SIP address.
+ String number = info.phoneNumber;
+ if ((number != null) && number.startsWith("sip:")) {
+ number = number.substring(4);
+ }
+
+ if (TextUtils.isEmpty(info.name)) {
+ // No valid "name" in the CallerInfo, so fall back to
+ // something else.
+ // (Typically, we promote the phone number up to the "name" slot
+ // onscreen, and possibly display a descriptive string in the
+ // "number" slot.)
+ if (TextUtils.isEmpty(number)) {
+ // No name *or* number! Display a generic "unknown" string
+ // (or potentially some other default based on the presentation.)
+ displayName = getPresentationString(presentation);
+ Logger.d(this, " ==> no name *or* number! displayName = " + displayName);
+ } else if (presentation != Call.PRESENTATION_ALLOWED) {
+ // This case should never happen since the network should never send a phone #
+ // AND a restricted presentation. However we leave it here in case of weird
+ // network behavior
+ displayName = getPresentationString(presentation);
+ Logger.d(this, " ==> presentation not allowed! displayName = " + displayName);
+ } else if (!TextUtils.isEmpty(info.cnapName)) {
+ // No name, but we do have a valid CNAP name, so use that.
+ displayName = info.cnapName;
+ info.name = info.cnapName;
+ displayNumber = number;
+ Logger.d(this, " ==> cnapName available: displayName '"
+ + displayName + "', displayNumber '" + displayNumber + "'");
+ } else {
+ // No name; all we have is a number. This is the typical
+ // case when an incoming call doesn't match any contact,
+ // or if you manually dial an outgoing number using the
+ // dialpad.
+
+ // Promote the phone number up to the "name" slot:
+ displayName = number;
+
+ // ...and use the "number" slot for a geographical description
+ // string if available (but only for incoming calls.)
+ if ((call != null) && (call.getState() == Call.State.INCOMING)) {
+ // TODO (CallerInfoAsyncQuery cleanup): Fix the CallerInfo
+ // query to only do the geoDescription lookup in the first
+ // place for incoming calls.
+ displayNumber = info.geoDescription; // may be null
+ Logger.d(this, "Geodescrption: " + info.geoDescription);
+ }
+
+ Logger.d(this, " ==> no name; falling back to number: displayName '"
+ + displayName + "', displayNumber '" + displayNumber + "'");
+ }
+ } else {
+ // We do have a valid "name" in the CallerInfo. Display that
+ // in the "name" slot, and the phone number in the "number" slot.
+ if (presentation != Call.PRESENTATION_ALLOWED) {
+ // This case should never happen since the network should never send a name
+ // AND a restricted presentation. However we leave it here in case of weird
+ // network behavior
+ displayName = getPresentationString(presentation);
+ Logger.d(this, " ==> valid name, but presentation not allowed!"
+ + " displayName = " + displayName);
+ } else {
+ displayName = info.name;
+ displayNumber = number;
+ label = info.phoneLabel;
+ Logger.d(this, " ==> name is present in CallerInfo: displayName '"
+ + displayName + "', displayNumber '" + displayNumber + "'");
+ }
+ }
+ personUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, info.person_id);
+ Logger.d(this, "- got personUri: '" + personUri
+ + "', based on info.person_id: " + info.person_id);
+ } else {
+ displayName = getPresentationString(presentation);
+ }
+
+ // TODO (klp): Update secondary user call info as well.
+ if (isPrimary) {
+ updateInfoUiForPrimary(displayName, displayNumber, label);
+ }
+
+ // TODO (klp): Update other fields - photo, sip label, etc.
+ }
+
+ /**
+ * Updates the info portion of the call card with passed in values for the primary user.
+ */
+ private void updateInfoUiForPrimary(String displayName, String displayNumber, String label) {
+ final CallCardUi ui = getUi();
+ ui.setName(displayName);
+ ui.setNumber(displayNumber);
+ ui.setNumberLabel(label);
+ }
+
+ public String getPresentationString(int presentation) {
+ String name = mContext.getString(R.string.unknown);
+ if (presentation == Call.PRESENTATION_RESTRICTED) {
+ name = mContext.getString(R.string.private_num);
+ } else if (presentation == Call.PRESENTATION_PAYPHONE) {
+ name = mContext.getString(R.string.payphone);
+ }
+ return name;
+ }
}