From edb22da2b40549631a08150cbfc205e6ad243c20 Mon Sep 17 00:00:00 2001 From: Andrew Lee Date: Tue, 9 Jun 2015 18:22:14 -0700 Subject: Change PhoneCallDetail fields to be non-final. It's been a pain to add/change fields on PhoneCallDetails because a multitude of parameters required for the constructors to create an instance. I ran into this while considering how to add an objectId to its parameters, and have previously too... Make fields non-final so that they are more easily set. This has the side-effect of making the casing of some initialization code more straightforward. + Change it's constructor to a subset of required fields. + Simplify/reorganize CallLogAdapter and CallLogAsyncTaskUtil code. + Simplify tests. Bug: 21733599 Change-Id: I236dfb0b8e6513f4b44dbdae17ce2eb9c9ae4778 --- src/com/android/dialer/PhoneCallDetails.java | 142 +++++++-------------- src/com/android/dialer/calllog/CallLogAdapter.java | 126 ++++++++---------- .../dialer/calllog/CallLogAsyncTaskUtil.java | 77 ++++------- .../dialer/calllog/CallLogListItemHelper.java | 6 +- .../dialer/calllog/DefaultVoicemailNotifier.java | 5 - .../dialer/calllog/PhoneNumberDisplayUtil.java | 7 +- 6 files changed, 134 insertions(+), 229 deletions(-) (limited to 'src') diff --git a/src/com/android/dialer/PhoneCallDetails.java b/src/com/android/dialer/PhoneCallDetails.java index 843e19352..68fdadc0c 100644 --- a/src/com/android/dialer/PhoneCallDetails.java +++ b/src/com/android/dialer/PhoneCallDetails.java @@ -16,7 +16,6 @@ package com.android.dialer; -import com.google.common.annotations.VisibleForTesting; import com.android.dialer.calllog.PhoneNumberDisplayUtil; import android.content.Context; @@ -29,124 +28,81 @@ import android.text.TextUtils; /** * The details of a phone call to be shown in the UI. - * - * TODO: Create a builder, to make it easier to construct an instance. */ public class PhoneCallDetails { - /** The number of the other party involved in the call. */ - public final CharSequence number; - /** The number presenting rules set by the network, e.g., {@link Calls#PRESENTATION_ALLOWED} */ - public final int numberPresentation; - /** The formatted version of {@link #number}. */ - public final CharSequence formattedNumber; - /** The country corresponding with the phone number. */ - public final String countryIso; - /** The geocoded location for the phone number. */ - public final String geocode; + // The number of the other party involved in the call. + public CharSequence number; + // The number presenting rules set by the network, e.g., {@link Calls#PRESENTATION_ALLOWED} + public int numberPresentation; + // The formatted version of {@link #number}. + public CharSequence formattedNumber; + // The country corresponding with the phone number. + public String countryIso; + // The geocoded location for the phone number. + public String geocode; + /** * The type of calls, as defined in the call log table, e.g., {@link Calls#INCOMING_TYPE}. *

* 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 duration of the call in milliseconds, or 0 for missed calls. */ - public final long duration; - /** The name of the contact, or the empty string. */ - public final CharSequence name; - /** The type of phone, e.g., {@link Phone#TYPE_HOME}, 0 if not available. */ - public final int numberType; - /** The custom label associated with the phone number in the contact, or the empty string. */ - public final CharSequence numberLabel; - /** The URI of the contact associated with this phone call. */ - public final Uri contactUri; + public int[] callTypes; + + // The date of the call, in milliseconds since the epoch. + public long date; + // The duration of the call in milliseconds, or 0 for missed calls. + public long duration; + // The name of the contact, or the empty string. + public CharSequence name; + // The type of phone, e.g., {@link Phone#TYPE_HOME}, 0 if not available. + public int numberType; + // The custom label associated with the phone number in the contact, or the empty string. + public CharSequence numberLabel; + // The URI of the contact associated with this phone call. + public Uri contactUri; /** * The photo URI of the picture of the contact that is associated with this phone call or * null if there is none. *

* This is meant to store the high-res photo only. */ - public final Uri photoUri; - /** - * The source type of the contact associated with this call. - */ - public final int sourceType; + public Uri photoUri; - /** - * The unique identifier for the account associated with the call. - */ - public final PhoneAccountHandle accountHandle; - /** - * Features applicable to this call. - */ - public final int features; - /** - * Total data usage for this call. - */ - public final Long dataUsage; - /** - * Voicemail transcription - */ - public final String transcription; + // The source type of the contact associated with this call. + public int sourceType; + + // The unique identifier for the account associated with the call. + public PhoneAccountHandle accountHandle; + + // Features applicable to this call. + public int features; + + // Total data usage for this call. + public Long dataUsage; - public final String displayNumber; - public final boolean isVoicemail; + // Voicemail transcription + public String transcription; + + public String displayNumber; + public boolean isVoicemail; /** - * Create the details for a call, with empty defaults specified for extra fields that are - * not necessary for testing. + * Constructor with required fields for the details of a call with a number associated with a + * contact. */ - @VisibleForTesting - public PhoneCallDetails(Context context, CharSequence number, int numberPresentation, - CharSequence formattedNumber, String countryIso, String geocode, - int[] callTypes, long date, long duration, boolean isVoicemail) { - this(context, number, numberPresentation, formattedNumber, countryIso, geocode, - callTypes, date, duration, "", 0, "", null, null, 0, null, 0, null, null, - isVoicemail); - } - - /** Create the details for a call with a number not associated with a contact. */ - public PhoneCallDetails(Context context, CharSequence number, int numberPresentation, - CharSequence formattedNumber, String countryIso, String geocode, - int[] callTypes, long date, long duration, - PhoneAccountHandle accountHandle, int features, Long dataUsage, String transcription, + public PhoneCallDetails( + Context context, + CharSequence number, + int numberPresentation, + CharSequence formattedNumber, boolean isVoicemail) { - this(context, number, numberPresentation, formattedNumber, countryIso, geocode, - callTypes, date, duration, "", 0, "", null, null, 0, accountHandle, features, - dataUsage, transcription, isVoicemail); - } - - /** Create the details for a call with a number associated with a contact. */ - public PhoneCallDetails(Context context, CharSequence number, int numberPresentation, - CharSequence formattedNumber, String countryIso, String geocode, - int[] callTypes, long date, long duration, CharSequence name, - int numberType, CharSequence numberLabel, Uri contactUri, Uri photoUri, - int sourceType, PhoneAccountHandle accountHandle, int features, Long dataUsage, - String transcription, boolean isVoicemail) { this.number = number; this.numberPresentation = numberPresentation; this.formattedNumber = formattedNumber; - this.countryIso = countryIso; - this.geocode = geocode; - this.callTypes = callTypes; - this.date = date; - this.duration = duration; - this.name = name; - this.numberType = numberType; - this.numberLabel = numberLabel; - this.contactUri = contactUri; - this.photoUri = photoUri; - this.sourceType = sourceType; - this.accountHandle = accountHandle; - this.features = features; - this.dataUsage = dataUsage; - this.transcription = transcription; this.isVoicemail = isVoicemail; this.displayNumber = PhoneNumberDisplayUtil.getDisplayNumber( context, - this.accountHandle, this.number, this.numberPresentation, this.formattedNumber, diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java index 6862f68e2..daa735070 100644 --- a/src/com/android/dialer/calllog/CallLogAdapter.java +++ b/src/com/android/dialer/calllog/CallLogAdapter.java @@ -350,46 +350,13 @@ public class CallLogAdapter extends GroupingListAdapter } int count = getGroupSize(position); - CallLogListItemViewHolder views = (CallLogListItemViewHolder) viewHolder; - - // Default case: an item in the call log. - views.primaryActionView.setVisibility(View.VISIBLE); - final String number = c.getString(CallLogQuery.NUMBER); final int numberPresentation = c.getInt(CallLogQuery.NUMBER_PRESENTATION); - final long date = c.getLong(CallLogQuery.DATE); - final long duration = c.getLong(CallLogQuery.DURATION); - final int callType = c.getInt(CallLogQuery.CALL_TYPE); final PhoneAccountHandle accountHandle = PhoneAccountUtils.getAccount( c.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME), c.getString(CallLogQuery.ACCOUNT_ID)); final String countryIso = c.getString(CallLogQuery.COUNTRY_ISO); - - final long rowId = c.getLong(CallLogQuery.ID); - views.rowId = rowId; - - // Check if the day group has changed and display a header if necessary. - int currentGroup = getDayGroupForCall(rowId); - int previousGroup = getPreviousDayGroup(c); - if (currentGroup != previousGroup) { - views.dayGroupHeader.setVisibility(View.VISIBLE); - views.dayGroupHeader.setText(getGroupDescription(currentGroup)); - } else { - views.dayGroupHeader.setVisibility(View.GONE); - } - - // Store some values used when the actions ViewStub is inflated on expansion of the actions - // section. - views.number = number; - views.numberPresentation = numberPresentation; - views.callType = callType; - views.accountHandle = accountHandle; - views.voicemailUri = c.getString(CallLogQuery.VOICEMAIL_URI); - // Stash away the Ids of the calls so that we can support deleting a row in the call log. - views.callIds = getCallIds(c, count); - final ContactInfo cachedContactInfo = mContactInfoHelper.getContactInfo(c); - final boolean isVoicemailNumber = mPhoneNumberUtilsWrapper.isVoicemailNumber(accountHandle, number); @@ -402,66 +369,81 @@ public class CallLogAdapter extends GroupingListAdapter // Lookup contacts with this number info = mContactInfoCache.getValue(number, countryIso, cachedContactInfo); } - - final Uri lookupUri = info.lookupUri; - final String name = info.name; - final int ntype = info.type; - final String label = info.label; - final long photoId = info.photoId; - final Uri photoUri = info.photoUri; CharSequence formattedNumber = info.formattedNumber == null ? null : PhoneNumberUtils.createTtsSpannable(info.formattedNumber); - final int[] callTypes = getCallTypes(c, count); - final String geocode = c.getString(CallLogQuery.GEOCODED_LOCATION); - final int sourceType = info.sourceType; - final int features = getCallFeatures(c, count); - final String transcription = c.getString(CallLogQuery.TRANSCRIPTION); - Long dataUsage = null; + + final PhoneCallDetails details = new PhoneCallDetails( + mContext, number, numberPresentation, formattedNumber, isVoicemailNumber); + details.accountHandle = accountHandle; + details.callTypes = getCallTypes(c, count); + details.countryIso = countryIso; + details.date = c.getLong(CallLogQuery.DATE); + details.duration = c.getLong(CallLogQuery.DURATION); + details.features = getCallFeatures(c, count); + details.geocode = c.getString(CallLogQuery.GEOCODED_LOCATION); + details.transcription = c.getString(CallLogQuery.TRANSCRIPTION); + if (!c.isNull(CallLogQuery.DATA_USAGE)) { - dataUsage = c.getLong(CallLogQuery.DATA_USAGE); + details.dataUsage = c.getLong(CallLogQuery.DATA_USAGE); } - final PhoneCallDetails details; + if (!TextUtils.isEmpty(info.name)) { + details.contactUri = info.lookupUri; + details.name = info.name; + details.numberType = info.type; + details.numberLabel = info.label; + details.photoUri = info.photoUri; + details.sourceType = info.sourceType; + } + CallLogListItemViewHolder views = (CallLogListItemViewHolder) viewHolder; views.info = info; + views.rowId = c.getLong(CallLogQuery.ID); + // Store values used when the actions ViewStub is inflated on expansion. + views.number = number; + views.numberPresentation = numberPresentation; + views.callType = c.getInt(CallLogQuery.CALL_TYPE); + views.accountHandle = accountHandle; + views.voicemailUri = c.getString(CallLogQuery.VOICEMAIL_URI); + // Stash away the Ids of the calls so that we can support deleting a row in the call log. + views.callIds = getCallIds(c, count); // The entry can only be reported as invalid if it has a valid ID and the source of the // entry supports marking entries as invalid. - views.canBeReportedAsInvalid = mContactInfoHelper.canReportAsInvalid(info.sourceType, - info.objectId); + views.canBeReportedAsInvalid = mContactInfoHelper.canReportAsInvalid( + info.sourceType, info.objectId); - // Update the expanded position if the rowIds match, in case ViewHolders were added/removed. - if (mCurrentlyExpandedRowId == rowId) { - mCurrentlyExpandedPosition = position; - } - // Restore expansion state of the row on rebind. Inflate the actions ViewStub if required, - // and set its visibility state accordingly. - views.showActions(mCurrentlyExpandedPosition == position, mOnReportButtonClickListener); + // Default case: an item in the call log. + views.primaryActionView.setVisibility(View.VISIBLE); - if (TextUtils.isEmpty(name)) { - details = new PhoneCallDetails(mContext, number, numberPresentation, formattedNumber, - countryIso, geocode, callTypes, date, duration, accountHandle, features, - dataUsage, transcription, isVoicemailNumber); + // Check if the day group has changed and display a header if necessary. + int currentGroup = getDayGroupForCall(views.rowId); + int previousGroup = getPreviousDayGroup(c); + if (currentGroup != previousGroup) { + views.dayGroupHeader.setVisibility(View.VISIBLE); + views.dayGroupHeader.setText(getGroupDescription(currentGroup)); } else { - details = new PhoneCallDetails(mContext, number, numberPresentation, formattedNumber, - countryIso, geocode, callTypes, date, duration, name, ntype, label, lookupUri, - photoUri, sourceType, accountHandle, features, dataUsage, transcription, - isVoicemailNumber); + views.dayGroupHeader.setVisibility(View.GONE); } - mCallLogViewsHelper.setPhoneCallDetails(mContext, views, details); + // Update the expanded position if the rowIds match, in case ViewHolders were added/removed. + // Then restore the state of the row on rebind. + if (mCurrentlyExpandedRowId == views.rowId) { + mCurrentlyExpandedPosition = position; + } + views.showActions(mCurrentlyExpandedPosition == position, mOnReportButtonClickListener); + views.updateCallButton(); String nameForDefaultImage = null; - if (TextUtils.isEmpty(name)) { + if (TextUtils.isEmpty(info.name)) { nameForDefaultImage = details.displayNumber; } else { - nameForDefaultImage = name; + nameForDefaultImage = info.name; } + views.setPhoto(info.photoId, info.photoUri, info.lookupUri, nameForDefaultImage, + isVoicemailNumber, mContactInfoHelper.isBusiness(info.sourceType)); - views.setPhoto(photoId, photoUri, lookupUri, nameForDefaultImage, isVoicemailNumber, - mContactInfoHelper.isBusiness(info.sourceType)); - - views.updateCallButton(); + mCallLogViewsHelper.setPhoneCallDetails(mContext, views, details); // Listen for the first draw if (mViewTreeObserver == null) { diff --git a/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java b/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java index aa186eb69..97fc324b1 100644 --- a/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java +++ b/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java @@ -139,35 +139,15 @@ public class CallLogAsyncTaskUtil { } // Read call log. + final String countryIso = cursor.getString(CallDetailQuery.COUNTRY_ISO_COLUMN_INDEX); final String number = cursor.getString(CallDetailQuery.NUMBER_COLUMN_INDEX); final int numberPresentation = cursor.getInt(CallDetailQuery.NUMBER_PRESENTATION_COLUMN_INDEX); - final long date = cursor.getLong(CallDetailQuery.DATE_COLUMN_INDEX); - final long duration = cursor.getLong(CallDetailQuery.DURATION_COLUMN_INDEX); - final int callType = cursor.getInt(CallDetailQuery.CALL_TYPE_COLUMN_INDEX); - final String geocode = cursor.getString(CallDetailQuery.GEOCODED_LOCATION_COLUMN_INDEX); - final String transcription = - cursor.getString(CallDetailQuery.TRANSCRIPTION_COLUMN_INDEX); final PhoneAccountHandle accountHandle = PhoneAccountUtils.getAccount( cursor.getString(CallDetailQuery.ACCOUNT_COMPONENT_NAME), cursor.getString(CallDetailQuery.ACCOUNT_ID)); - String countryIso = cursor.getString(CallDetailQuery.COUNTRY_ISO_COLUMN_INDEX); - if (TextUtils.isEmpty(countryIso)) { - countryIso = GeoUtil.getCurrentCountryIso(context); - } - - // Formatted phone number. - final CharSequence formattedNumber; - // Read contact specifics. - final CharSequence nameText; - final int numberType; - final CharSequence numberLabel; - final Uri photoUri; - final Uri lookupUri; - int sourceType; - // If this is not a regular number, there is no point in looking it up in the contacts. ContactInfoHelper contactInfoHelper = new ContactInfoHelper(context, GeoUtil.getCurrentCountryIso(context)); @@ -178,39 +158,36 @@ public class CallLogAsyncTaskUtil { PhoneNumberUtilsWrapper.canPlaceCallsTo(number, numberPresentation) && !isVoicemail; ContactInfo info = shouldLookupNumber - ? contactInfoHelper.lookupNumber(number, countryIso) : null; - - if (info == null) { - formattedNumber = PhoneNumberDisplayUtil.getDisplayNumber( - context, accountHandle, number, numberPresentation, null, isVoicemail); - nameText = ""; - numberType = 0; - numberLabel = ""; - photoUri = null; - lookupUri = null; - sourceType = 0; - } else { - formattedNumber = info.formattedNumber; - nameText = info.name; - numberType = info.type; - numberLabel = info.label; - photoUri = info.photoUri; - lookupUri = info.lookupUri; - sourceType = info.sourceType; - } - - - final int features = cursor.getInt(CallDetailQuery.FEATURES); + ? contactInfoHelper.lookupNumber(number, countryIso) + : ContactInfo.EMPTY; + PhoneCallDetails details = new PhoneCallDetails( + context, number, numberPresentation, info.formattedNumber, isVoicemail); + + details.accountHandle = accountHandle; + details.contactUri = info.lookupUri; + details.name = info.name; + details.numberType = info.type; + details.numberLabel = info.label; + details.photoUri = info.photoUri; + details.sourceType = info.sourceType; + + details.callTypes = new int[] { + cursor.getInt(CallDetailQuery.CALL_TYPE_COLUMN_INDEX) + }; + details.date = cursor.getLong(CallDetailQuery.DATE_COLUMN_INDEX); + details.duration = cursor.getLong(CallDetailQuery.DURATION_COLUMN_INDEX); + details.features = cursor.getInt(CallDetailQuery.FEATURES); + details.geocode = cursor.getString(CallDetailQuery.GEOCODED_LOCATION_COLUMN_INDEX); + details.transcription = cursor.getString(CallDetailQuery.TRANSCRIPTION_COLUMN_INDEX); + + details.countryIso = !TextUtils.isEmpty(countryIso) ? countryIso + : GeoUtil.getCurrentCountryIso(context); - Long dataUsage = null; if (!cursor.isNull(CallDetailQuery.DATA_USAGE)) { - dataUsage = cursor.getLong(CallDetailQuery.DATA_USAGE); + details.dataUsage = cursor.getLong(CallDetailQuery.DATA_USAGE); } - return new PhoneCallDetails(context, number, numberPresentation, formattedNumber, - countryIso, geocode, new int[]{ callType }, date, duration, nameText, - numberType, numberLabel, lookupUri, photoUri, sourceType, accountHandle, - features, dataUsage, transcription, isVoicemail); + return details; } finally { if (cursor != null) { cursor.close(); diff --git a/src/com/android/dialer/calllog/CallLogListItemHelper.java b/src/com/android/dialer/calllog/CallLogListItemHelper.java index 4eb8797ee..6e3e8b582 100644 --- a/src/com/android/dialer/calllog/CallLogListItemHelper.java +++ b/src/com/android/dialer/calllog/CallLogListItemHelper.java @@ -186,7 +186,7 @@ import com.android.dialer.R; callDescription.append(mResources.getString(R.string.description_video_call)); } - int stringID = getCallDescriptionStringID(details); + int stringID = getCallDescriptionStringID(details.callTypes); String accountLabel = PhoneAccountUtils.getAccountLabel(context, details.accountHandle); // Use chosen string resource to build up the message. @@ -213,8 +213,8 @@ import com.android.dialer.R; * @param details Call details. * @return String resource ID to use. */ - public int getCallDescriptionStringID(PhoneCallDetails details) { - int lastCallType = getLastCallType(details.callTypes); + public int getCallDescriptionStringID(int[] callTypes) { + int lastCallType = getLastCallType(callTypes); int stringID; if (lastCallType == Calls.VOICEMAIL_TYPE || lastCallType == Calls.MISSED_TYPE) { diff --git a/src/com/android/dialer/calllog/DefaultVoicemailNotifier.java b/src/com/android/dialer/calllog/DefaultVoicemailNotifier.java index 7c2a96638..942a73fb4 100644 --- a/src/com/android/dialer/calllog/DefaultVoicemailNotifier.java +++ b/src/com/android/dialer/calllog/DefaultVoicemailNotifier.java @@ -28,7 +28,6 @@ import android.database.Cursor; import android.net.Uri; import android.provider.CallLog.Calls; import android.provider.ContactsContract.PhoneLookup; -import android.telecom.PhoneAccountHandle; import android.text.TextUtils; import android.util.Log; @@ -122,12 +121,8 @@ public class DefaultVoicemailNotifier { // Check if we already know the name associated with this number. String name = names.get(newCall.number); if (name == null) { - PhoneAccountHandle accountHandle = PhoneAccountUtils.getAccount( - newCall.accountComponentName, - newCall.accountId); name = PhoneNumberDisplayUtil.getDisplayName( mContext, - accountHandle, newCall.number, newCall.numberPresentation, /* isVoicemail */ false).toString(); diff --git a/src/com/android/dialer/calllog/PhoneNumberDisplayUtil.java b/src/com/android/dialer/calllog/PhoneNumberDisplayUtil.java index acfd32cf3..f80c2bc6a 100644 --- a/src/com/android/dialer/calllog/PhoneNumberDisplayUtil.java +++ b/src/com/android/dialer/calllog/PhoneNumberDisplayUtil.java @@ -19,7 +19,6 @@ package com.android.dialer.calllog; import android.content.Context; import android.content.res.Resources; import android.provider.CallLog.Calls; -import android.telecom.PhoneAccountHandle; import android.text.TextUtils; import android.util.Log; @@ -35,7 +34,6 @@ public class PhoneNumberDisplayUtil { */ /* package */ static CharSequence getDisplayName( Context context, - PhoneAccountHandle accountHandle, CharSequence number, int presentation, boolean isVoicemail) { @@ -60,19 +58,16 @@ public class PhoneNumberDisplayUtil { /** * Returns the string to display for the given phone number. * - * @param accountHandle The handle for the account corresponding to the call * @param number the number to display * @param formattedNumber the formatted number if available, may be null */ public static CharSequence getDisplayNumber( Context context, - PhoneAccountHandle accountHandle, CharSequence number, int presentation, CharSequence formattedNumber, boolean isVoicemail) { - final CharSequence displayName = - getDisplayName(context, accountHandle, number, presentation, isVoicemail); + final CharSequence displayName = getDisplayName(context, number, presentation, isVoicemail); if (!TextUtils.isEmpty(displayName)) { return displayName; } -- cgit v1.2.3