1ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/* 2ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Copyright (C) 2011 The Android Open Source Project 3ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 4ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Licensed under the Apache License, Version 2.0 (the "License"); 5ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * you may not use this file except in compliance with the License. 6ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * You may obtain a copy of the License at 7ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 8ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * http://www.apache.org/licenses/LICENSE-2.0 9ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 10ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Unless required by applicable law or agreed to in writing, software 11ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * distributed under the License is distributed on an "AS IS" BASIS, 12ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * See the License for the specific language governing permissions and 14ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * limitations under the License. 15ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 16ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 17ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpackage com.android.dialer.app.calllog; 18ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 19ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.Context; 20ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.res.Resources; 21ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.Typeface; 22ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.CallLog.Calls; 23ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract.CommonDataKinds.Phone; 24ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.support.v4.content.ContextCompat; 25ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.telecom.PhoneAccount; 26ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.text.TextUtils; 27ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.text.format.DateUtils; 288369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanianimport android.text.util.Linkify; 29ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.view.View; 30ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.widget.TextView; 31ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.app.R; 32ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.app.calllog.calllogcache.CallLogCache; 33d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport com.android.dialer.calllogutils.PhoneCallDetails; 348369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanianimport com.android.dialer.logging.ContactSource; 35d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport com.android.dialer.oem.MotorolaUtils; 36ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.phonenumberutil.PhoneNumberHelper; 37ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.util.DialerUtils; 38ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.ArrayList; 39ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.Calendar; 40ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.concurrent.TimeUnit; 41ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 42ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/** Helper class to fill in the views in {@link PhoneCallDetailsViews}. */ 43ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpublic class PhoneCallDetailsHelper { 44ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 45ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** The maximum number of icons will be shown to represent the call types in a group. */ 46ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private static final int MAX_CALL_TYPE_ICONS = 3; 47ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 48ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private final Context mContext; 49ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private final Resources mResources; 50ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private final CallLogCache mCallLogCache; 51ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** Calendar used to construct dates */ 52ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private final Calendar mCalendar; 53ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** The injected current time in milliseconds since the epoch. Used only by tests. */ 54ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private Long mCurrentTimeMillisForTest; 55ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 56ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private CharSequence mPhoneTypeLabelForTest; 57ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** List of items to be concatenated together for accessibility descriptions */ 58ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private ArrayList<CharSequence> mDescriptionItems = new ArrayList<>(); 59ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 60ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 61ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Creates a new instance of the helper. 62ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 63ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * <p>Generally you should have a single instance of this helper in any context. 64ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 65ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * @param resources used to look up strings 66ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 67ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public PhoneCallDetailsHelper(Context context, Resources resources, CallLogCache callLogCache) { 68ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mContext = context; 69ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mResources = resources; 70ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mCallLogCache = callLogCache; 71ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mCalendar = Calendar.getInstance(); 72ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 73ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 74ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** Fills the call details views with content. */ 75ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public void setPhoneCallDetails(PhoneCallDetailsViews views, PhoneCallDetails details) { 76ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Display up to a given number of icons. 77ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian views.callTypeIcons.clear(); 78ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian int count = details.callTypes.length; 79ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian boolean isVoicemail = false; 80ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian for (int index = 0; index < count && index < MAX_CALL_TYPE_ICONS; ++index) { 81ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian views.callTypeIcons.add(details.callTypes[index]); 82ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (index == 0) { 83ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian isVoicemail = details.callTypes[index] == Calls.VOICEMAIL_TYPE; 84ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 85ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 86ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 87ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Show the video icon if the call had video enabled. 88ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian views.callTypeIcons.setShowVideo( 89ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian (details.features & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO); 90d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian views.callTypeIcons.setShowHd( 91d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian MotorolaUtils.shouldShowHdIconInCallLog(mContext, details.features)); 929050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian views.callTypeIcons.setShowWifi( 939050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian MotorolaUtils.shouldShowWifiIconInCallLog(mContext, details.features)); 94ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian views.callTypeIcons.requestLayout(); 95ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian views.callTypeIcons.setVisibility(View.VISIBLE); 96ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 97ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Show the total call count only if there are more than the maximum number of icons. 98ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final Integer callCount; 99ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (count > MAX_CALL_TYPE_ICONS) { 100ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian callCount = count; 101ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 102ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian callCount = null; 103ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 104ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 105ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Set the call count, location, date and if voicemail, set the duration. 106ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian setDetailText(views, callCount, details); 107ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 108ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Set the account label if it exists. 109ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian String accountLabel = mCallLogCache.getAccountLabel(details.accountHandle); 110ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (!TextUtils.isEmpty(details.viaNumber)) { 111ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (!TextUtils.isEmpty(accountLabel)) { 112ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian accountLabel = 113ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mResources.getString( 114ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian R.string.call_log_via_number_phone_account, accountLabel, details.viaNumber); 115ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 116ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian accountLabel = mResources.getString(R.string.call_log_via_number, details.viaNumber); 117ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 118ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 119ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (!TextUtils.isEmpty(accountLabel)) { 120ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian views.callAccountLabel.setVisibility(View.VISIBLE); 121ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian views.callAccountLabel.setText(accountLabel); 122ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian int color = mCallLogCache.getAccountColor(details.accountHandle); 123ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (color == PhoneAccount.NO_HIGHLIGHT_COLOR) { 124ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian int defaultColor = R.color.dialer_secondary_text_color; 125ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian views.callAccountLabel.setTextColor(mContext.getResources().getColor(defaultColor)); 126ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 127ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian views.callAccountLabel.setTextColor(color); 128ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 129ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 130ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian views.callAccountLabel.setVisibility(View.GONE); 131ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 132ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 133ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final CharSequence nameText; 134ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final CharSequence displayNumber = details.displayNumber; 135ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (TextUtils.isEmpty(details.getPreferredName())) { 136ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian nameText = displayNumber; 137ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // We have a real phone number as "nameView" so make it always LTR 138ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian views.nameView.setTextDirection(View.TEXT_DIRECTION_LTR); 139ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 140ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian nameText = details.getPreferredName(); 141ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 142ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 143ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian views.nameView.setText(nameText); 144ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 145ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (isVoicemail) { 1468369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian int relevantLinkTypes = Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS | Linkify.WEB_URLS; 1478369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian views.voicemailTranscriptionView.setAutoLinkMask(relevantLinkTypes); 148e85fa664ac1e7394a7e9e5d0c8dc61ba1e33ab1csail views.voicemailTranscriptionView.setText( 149e85fa664ac1e7394a7e9e5d0c8dc61ba1e33ab1csail TextUtils.isEmpty(details.transcription) ? null : details.transcription); 150ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 151ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 152ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Bold if not read 153ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Typeface typeface = details.isRead ? Typeface.SANS_SERIF : Typeface.DEFAULT_BOLD; 154ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian views.nameView.setTypeface(typeface); 155ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian views.voicemailTranscriptionView.setTypeface(typeface); 156ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian views.callLocationAndDate.setTypeface(typeface); 157ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian views.callLocationAndDate.setTextColor( 158ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian ContextCompat.getColor( 159ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mContext, 160ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian details.isRead ? R.color.call_log_detail_color : R.color.call_log_unread_text_color)); 161ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 162ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 163ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 164ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Builds a string containing the call location and date. For voicemail logs only the call date is 165ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * returned because location information is displayed in the call action button 166ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 167ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * @param details The call details. 168ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * @return The call location and date string. 169ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 170ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public CharSequence getCallLocationAndDate(PhoneCallDetails details) { 171ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mDescriptionItems.clear(); 172ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 173ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (details.callTypes[0] != Calls.VOICEMAIL_TYPE) { 174ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Get type of call (ie mobile, home, etc) if known, or the caller's location. 175ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian CharSequence callTypeOrLocation = getCallTypeOrLocation(details); 176ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 177ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Only add the call type or location if its not empty. It will be empty for unknown 178ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // callers. 179ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (!TextUtils.isEmpty(callTypeOrLocation)) { 180ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mDescriptionItems.add(callTypeOrLocation); 181ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 182ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 183ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 184ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // The date of this call 185ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mDescriptionItems.add(getCallDate(details)); 186ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 187ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Create a comma separated list from the call type or location, and call date. 188ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return DialerUtils.join(mDescriptionItems); 189ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 190ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 191ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 192ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * For a call, if there is an associated contact for the caller, return the known call type (e.g. 193ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * mobile, home, work). If there is no associated contact, attempt to use the caller's location if 194ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * known. 195ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 196ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * @param details Call details to use. 197ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * @return Type of call (mobile/home) if known, or the location of the caller (if known). 198ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 199ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public CharSequence getCallTypeOrLocation(PhoneCallDetails details) { 200ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (details.isSpam) { 201ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return mResources.getString(R.string.spam_number_call_log_label); 202ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else if (details.isBlocked) { 203ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return mResources.getString(R.string.blocked_number_call_log_label); 204ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 205ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 206ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian CharSequence numberFormattedLabel = null; 207ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Only show a label if the number is shown and it is not a SIP address. 208ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (!TextUtils.isEmpty(details.number) 209ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian && !PhoneNumberHelper.isUriNumber(details.number.toString()) 210ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian && !mCallLogCache.isVoicemailNumber(details.accountHandle, details.number)) { 211ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 212d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian if (shouldShowLocation(details)) { 213ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian numberFormattedLabel = details.geocode; 214ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else if (!(details.numberType == Phone.TYPE_CUSTOM 215ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian && TextUtils.isEmpty(details.numberLabel))) { 216ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Get type label only if it will not be "Custom" because of an empty number label. 217ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian numberFormattedLabel = 218ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mPhoneTypeLabelForTest != null 219ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian ? mPhoneTypeLabelForTest 220ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian : Phone.getTypeLabel(mResources, details.numberType, details.numberLabel); 221ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 222ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 223ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 224ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (!TextUtils.isEmpty(details.namePrimary) && TextUtils.isEmpty(numberFormattedLabel)) { 225ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian numberFormattedLabel = details.displayNumber; 226ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 227ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return numberFormattedLabel; 228ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 229ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 230d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian /** Returns true if primary name is empty or the data is from Cequint Caller ID. */ 231d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian private static boolean shouldShowLocation(PhoneCallDetails details) { 232d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian if (TextUtils.isEmpty(details.geocode)) { 233d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian return false; 234d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian } 235d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian // For caller ID provided by Cequint we want to show the geo location. 2368369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian if (details.sourceType == ContactSource.Type.SOURCE_TYPE_CEQUINT_CALLER_ID) { 237d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian return true; 238d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian } 239d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian // Don't bother showing geo location for contacts. 240d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian if (!TextUtils.isEmpty(details.namePrimary)) { 241d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian return false; 242d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian } 243d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian return true; 244d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian } 245d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian 246ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public void setPhoneTypeLabelForTest(CharSequence phoneTypeLabel) { 247ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian this.mPhoneTypeLabelForTest = phoneTypeLabel; 248ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 249ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 250ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 251ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Get the call date/time of the call. For the call log this is relative to the current time. e.g. 252ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 3 minutes ago. For voicemail, see {@link #getGranularDateTime(PhoneCallDetails)} 253ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 254ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * @param details Call details to use. 255ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * @return String representing when the call occurred. 256ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 257ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public CharSequence getCallDate(PhoneCallDetails details) { 258ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (details.callTypes[0] == Calls.VOICEMAIL_TYPE) { 259ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return getGranularDateTime(details); 260ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 261ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 262ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return DateUtils.getRelativeTimeSpanString( 263ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian details.date, 264ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian getCurrentTimeMillis(), 265ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian DateUtils.MINUTE_IN_MILLIS, 266ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian DateUtils.FORMAT_ABBREV_RELATIVE); 267ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 268ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 269ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 270ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Get the granular version of the call date/time of the call. The result is always in the form 271ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 'DATE at TIME'. The date value changes based on when the call was created. 272ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 273ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * <p>If created today, DATE is 'Today' If created this year, DATE is 'MMM dd' Otherwise, DATE is 274ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 'MMM dd, yyyy' 275ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 276ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * <p>TIME is the localized time format, e.g. 'hh:mm a' or 'HH:mm' 277ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 278ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * @param details Call details to use 279ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * @return String representing when the call occurred 280ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 281ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public CharSequence getGranularDateTime(PhoneCallDetails details) { 282ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return mResources.getString( 283ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian R.string.voicemailCallLogDateTimeFormat, 284ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian getGranularDate(details.date), 285ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian DateUtils.formatDateTime(mContext, details.date, DateUtils.FORMAT_SHOW_TIME)); 286ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 287ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 288ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 289ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Get the granular version of the call date. See {@link #getGranularDateTime(PhoneCallDetails)} 290ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 291ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private String getGranularDate(long date) { 292ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (DateUtils.isToday(date)) { 293ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return mResources.getString(R.string.voicemailCallLogToday); 294ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 295ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return DateUtils.formatDateTime( 296ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mContext, 297ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian date, 298ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian DateUtils.FORMAT_SHOW_DATE 299ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian | DateUtils.FORMAT_ABBREV_MONTH 300ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian | (shouldShowYear(date) ? DateUtils.FORMAT_SHOW_YEAR : DateUtils.FORMAT_NO_YEAR)); 301ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 302ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 303ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 304ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Determines whether the year should be shown for the given date 305ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 306ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * @return {@code true} if date is within the current year, {@code false} otherwise 307ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 308ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private boolean shouldShowYear(long date) { 309ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mCalendar.setTimeInMillis(getCurrentTimeMillis()); 310ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian int currentYear = mCalendar.get(Calendar.YEAR); 311ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mCalendar.setTimeInMillis(date); 312ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return currentYear != mCalendar.get(Calendar.YEAR); 313ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 314ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 315ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** Sets the text of the header view for the details page of a phone call. */ 316ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public void setCallDetailsHeader(TextView nameView, PhoneCallDetails details) { 317ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final CharSequence nameText; 318ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (!TextUtils.isEmpty(details.namePrimary)) { 319ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian nameText = details.namePrimary; 320ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else if (!TextUtils.isEmpty(details.displayNumber)) { 321ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian nameText = details.displayNumber; 322ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 323ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian nameText = mResources.getString(R.string.unknown); 324ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 325ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 326ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian nameView.setText(nameText); 327ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 328ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 329ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public void setCurrentTimeForTest(long currentTimeMillis) { 330ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mCurrentTimeMillisForTest = currentTimeMillis; 331ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 332ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 333ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 334ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Returns the current time in milliseconds since the epoch. 335ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 336ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * <p>It can be injected in tests using {@link #setCurrentTimeForTest(long)}. 337ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 338ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private long getCurrentTimeMillis() { 339ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (mCurrentTimeMillisForTest == null) { 340ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return System.currentTimeMillis(); 341ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 342ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return mCurrentTimeMillisForTest; 343ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 344ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 345ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 346ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** Sets the call count, date, and if it is a voicemail, sets the duration. */ 347ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private void setDetailText( 348ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian PhoneCallDetailsViews views, Integer callCount, PhoneCallDetails details) { 349ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Combine the count (if present) and the date. 350ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian CharSequence dateText = details.callLocationAndDate; 351ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final CharSequence text; 352ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (callCount != null) { 353ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian text = mResources.getString(R.string.call_log_item_count_and_date, callCount, dateText); 354ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 355ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian text = dateText; 356ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 357ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 358ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (details.callTypes[0] == Calls.VOICEMAIL_TYPE && details.duration > 0) { 359ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian views.callLocationAndDate.setText( 360ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mResources.getString( 361ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian R.string.voicemailCallLogDateTimeFormatWithDuration, 362ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian text, 363ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian getVoicemailDuration(details))); 364ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 365ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian views.callLocationAndDate.setText(text); 366ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 367ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 368ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 369ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private String getVoicemailDuration(PhoneCallDetails details) { 370ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian long minutes = TimeUnit.SECONDS.toMinutes(details.duration); 371ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian long seconds = details.duration - TimeUnit.MINUTES.toSeconds(minutes); 372ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (minutes > 99) { 373ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian minutes = 99; 374ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 375ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return mResources.getString(R.string.voicemailDurationFormat, minutes, seconds); 376ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 377ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian} 378