Allow for multiple call icons in the call log.
This commit adds support for having multiple call icons on a single
entry, to handle group entries.
When the group is represented as text, we currently use only the first
call type, but, in a follow-up, I will use an additional counter.
Change-Id: Iaa9d1c84eb926c1500bf0a439d45ce59314bd198
diff --git a/src/com/android/contacts/CallDetailActivity.java b/src/com/android/contacts/CallDetailActivity.java
index a1d2bb7..d08b76a 100644
--- a/src/com/android/contacts/CallDetailActivity.java
+++ b/src/com/android/contacts/CallDetailActivity.java
@@ -304,8 +304,8 @@
setListAdapter(adapter);
}
mPhoneCallDetailsHelper.setPhoneCallDetails(mPhoneCallDetailsViews,
- new PhoneCallDetails(mNumber, numberText, callType, date, nameText,
- numberType, numberLabel), false);
+ new PhoneCallDetails(mNumber, numberText, new int[]{ callType }, date,
+ nameText, numberType, numberLabel), false);
loadContactPhotos(photoId);
} else {
diff --git a/src/com/android/contacts/PhoneCallDetails.java b/src/com/android/contacts/PhoneCallDetails.java
index c5c37df..7b02a88 100644
--- a/src/com/android/contacts/PhoneCallDetails.java
+++ b/src/com/android/contacts/PhoneCallDetails.java
@@ -27,8 +27,12 @@
public final CharSequence number;
/** The formatted version of {@link #number}. */
public final CharSequence formattedNumber;
- /** The type of call, as defined in the call log table, e.g., {@link Calls#INCOMING_TYPE}. */
- public final int callType;
+ /**
+ * The type of calls, as defined in the call log table, e.g., {@link Calls#INCOMING_TYPE}.
+ * <p>
+ * There might be multiple types if this represents a set of entries grouped together.
+ */
+ public final int[] callTypes;
/** The date of the call, in milliseconds since the epoch. */
public final long date;
/** The name of the contact, or the empty string. */
@@ -39,17 +43,17 @@
public final CharSequence numberLabel;
/** Create the details for a call with a number not associated with a contact. */
- public PhoneCallDetails(CharSequence number, CharSequence formattedNumber, int callType,
+ public PhoneCallDetails(CharSequence number, CharSequence formattedNumber, int[] callTypes,
long date) {
- this(number, formattedNumber, callType, date, "", 0, "");
+ this(number, formattedNumber, callTypes, date, "", 0, "");
}
/** Create the details for a call with a number associated with a contact. */
- public PhoneCallDetails(CharSequence number, CharSequence formattedNumber, int callType,
+ public PhoneCallDetails(CharSequence number, CharSequence formattedNumber, int[] callTypes,
long date, CharSequence name, int numberType, CharSequence numberLabel) {
this.number = number;
this.formattedNumber = formattedNumber;
- this.callType = callType;
+ this.callTypes = callTypes;
this.date = date;
this.name = name;
this.numberType = numberType;
diff --git a/src/com/android/contacts/PhoneCallDetailsHelper.java b/src/com/android/contacts/PhoneCallDetailsHelper.java
index 4605799..7f73b04 100644
--- a/src/com/android/contacts/PhoneCallDetailsHelper.java
+++ b/src/com/android/contacts/PhoneCallDetailsHelper.java
@@ -86,58 +86,22 @@
public void setPhoneCallDetails(PhoneCallDetailsViews views, PhoneCallDetails details,
boolean useIcons) {
if (useIcons) {
- final Drawable callTypeDrawable;
- switch (details.callType) {
- case Calls.INCOMING_TYPE:
- callTypeDrawable = mIncomingDrawable;
- break;
-
- case Calls.OUTGOING_TYPE:
- callTypeDrawable = mOutgoingDrawable;
- break;
-
- case Calls.MISSED_TYPE:
- callTypeDrawable = mMissedDrawable;
- break;
-
- case Calls.VOICEMAIL_TYPE:
- callTypeDrawable = mVoicemailDrawable;
- break;
-
- default:
- throw new IllegalArgumentException("invalid call type: " + details.callType);
- }
- ImageView callTypeImage = new ImageView(mContext);
- callTypeImage.setImageDrawable(callTypeDrawable);
views.callTypeIcons.removeAllViews();
- views.callTypeIcons.addView(callTypeImage);
-
+ int count = details.callTypes.length;
+ for (int callType : details.callTypes) {
+ ImageView callTypeImage = new ImageView(mContext);
+ callTypeImage.setImageDrawable(getCallTypeDrawable(callType));
+ views.callTypeIcons.addView(callTypeImage);
+ }
views.callTypeIcons.setVisibility(View.VISIBLE);
views.callTypeText.setVisibility(View.GONE);
views.callTypeSeparator.setVisibility(View.GONE);
} else {
String callTypeName;
- switch (details.callType) {
- case Calls.INCOMING_TYPE:
- callTypeName = mIncomingName;
- break;
-
- case Calls.OUTGOING_TYPE:
- callTypeName = mOutgoingName;
- break;
-
- case Calls.MISSED_TYPE:
- callTypeName = mMissedName;
- break;
-
- case Calls.VOICEMAIL_TYPE:
- callTypeName = mVoicemailName;
- break;
-
- default:
- throw new IllegalArgumentException("invalid call type: " + details.callType);
- }
- views.callTypeText.setText(callTypeName);
+ // Use the name of the first call type.
+ // TODO: We should update this to handle the text for multiple calls as well.
+ int callType = details.callTypes[0];
+ views.callTypeText.setText(getCallTypeText(callType));
views.callTypeIcons.removeAllViews();
views.callTypeText.setVisibility(View.VISIBLE);
@@ -167,7 +131,7 @@
} else {
nameText = details.name;
CharSequence displayNumber = getDisplayNumber(details.number, details.formattedNumber);
- if (details.callType != 0 && numberFormattedLabel != null) {
+ if (numberFormattedLabel != null) {
numberText = FormatUtils.applyStyleToSpan(Typeface.BOLD,
numberFormattedLabel + " " + displayNumber, 0,
numberFormattedLabel.length(),
@@ -191,6 +155,46 @@
}
}
+ /** Returns the text used to represent the given call type. */
+ private String getCallTypeText(int callType) {
+ switch (callType) {
+ case Calls.INCOMING_TYPE:
+ return mIncomingName;
+
+ case Calls.OUTGOING_TYPE:
+ return mOutgoingName;
+
+ case Calls.MISSED_TYPE:
+ return mMissedName;
+
+ case Calls.VOICEMAIL_TYPE:
+ return mVoicemailName;
+
+ default:
+ throw new IllegalArgumentException("invalid call type: " + callType);
+ }
+ }
+
+ /** Returns the drawable of the icon associated with the given call type. */
+ private Drawable getCallTypeDrawable(int callType) {
+ switch (callType) {
+ case Calls.INCOMING_TYPE:
+ return mIncomingDrawable;
+
+ case Calls.OUTGOING_TYPE:
+ return mOutgoingDrawable;
+
+ case Calls.MISSED_TYPE:
+ return mMissedDrawable;
+
+ case Calls.VOICEMAIL_TYPE:
+ return mVoicemailDrawable;
+
+ default:
+ throw new IllegalArgumentException("invalid call type: " + callType);
+ }
+ }
+
private CharSequence getDisplayNumber(CharSequence number, CharSequence formattedNumber) {
if (TextUtils.isEmpty(number)) {
return "";
diff --git a/src/com/android/contacts/calllog/CallLogFragment.java b/src/com/android/contacts/calllog/CallLogFragment.java
index 1f8e84b..11f8965 100644
--- a/src/com/android/contacts/calllog/CallLogFragment.java
+++ b/src/com/android/contacts/calllog/CallLogFragment.java
@@ -635,12 +635,11 @@
* @param c the cursor pointing to the entry in the call log
* @param count the number of entries in the current item, greater than 1 if it is a group
*/
- public void bindView(View view, Cursor c, int count) {
+ private void bindView(View view, Cursor c, int count) {
final CallLogListItemViews views = (CallLogListItemViews) view.getTag();
String number = c.getString(CallLogQuery.NUMBER);
long date = c.getLong(CallLogQuery.DATE);
- int callType = c.getInt(CallLogQuery.CALL_TYPE);
final String formattedNumber;
String countryIso = c.getString(CallLogQuery.COUNTRY_ISO);
// Store away the number so we can call it directly if you click on the call icon
@@ -697,11 +696,12 @@
views.callView.setVisibility(View.VISIBLE);
}
+ int[] callTypes = getCallTypes(c, count);
final PhoneCallDetails details;
if (TextUtils.isEmpty(name)) {
- details = new PhoneCallDetails(number, formattedNumber, callType, date);
+ details = new PhoneCallDetails(number, formattedNumber, callTypes, date);
} else {
- details = new PhoneCallDetails(number, formattedNumber, callType, date, name,
+ details = new PhoneCallDetails(number, formattedNumber, callTypes, date, name,
ntype, label);
}
mCallLogViewsHelper.setPhoneCallDetails(views, details , true);
@@ -718,6 +718,24 @@
}
}
+ /**
+ * Returns the call types for the given number of items in the cursor.
+ * <p>
+ * It uses the next {@code count} rows in the cursor to extract the types.
+ * <p>
+ * It position in the cursor is unchanged by this function.
+ */
+ private int[] getCallTypes(Cursor cursor, int count) {
+ int position = cursor.getPosition();
+ int[] callTypes = new int[count];
+ for (int index = 0; index < count; ++index) {
+ callTypes[index] = cursor.getInt(CallLogQuery.CALL_TYPE);
+ cursor.moveToNext();
+ }
+ cursor.moveToPosition(position);
+ return callTypes;
+ }
+
private void bindQuickContact(QuickContactBadge view, long photoId, long contactId,
String lookupKey) {
view.assignContactUri(getContactUri(contactId, lookupKey));
diff --git a/src/com/android/contacts/calllog/CallLogListItemHelper.java b/src/com/android/contacts/calllog/CallLogListItemHelper.java
index 462b0b3..e4630e9 100644
--- a/src/com/android/contacts/calllog/CallLogListItemHelper.java
+++ b/src/com/android/contacts/calllog/CallLogListItemHelper.java
@@ -61,8 +61,9 @@
boolean useIcons) {
mPhoneCallDetailsHelper.setPhoneCallDetails(views.phoneCallDetailsViews, details, useIcons);
if (views.callView != null) {
+ // The type of icon, call or play, is determined by the first call in the group.
views.callView.setImageDrawable(
- details.callType == Calls.VOICEMAIL_TYPE ? mPlayDrawable : mCallDrawable);
+ details.callTypes[0] == Calls.VOICEMAIL_TYPE ? mPlayDrawable : mCallDrawable);
views.callView.setVisibility(
canPlaceCallsTo(details.number) ? View.VISIBLE : View.INVISIBLE);
}