1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.dialer.calllog; 18 19 import android.content.Context; 20 import android.content.res.Resources; 21 import android.provider.CallLog.Calls; 22 import android.text.TextUtils; 23 24 import com.android.contacts.common.CallUtil; 25 import com.android.dialer.PhoneCallDetails; 26 import com.android.dialer.PhoneCallDetailsHelper; 27 import com.android.dialer.R; 28 29 /** 30 * Helper class to fill in the views of a call log entry. 31 */ 32 /* package */class CallLogListItemHelper { 33 /** Helper for populating the details of a phone call. */ 34 private final PhoneCallDetailsHelper mPhoneCallDetailsHelper; 35 /** Helper for handling phone numbers. */ 36 private final PhoneNumberDisplayHelper mPhoneNumberHelper; 37 /** Resources to look up strings. */ 38 private final Resources mResources; 39 40 /** 41 * Creates a new helper instance. 42 * 43 * @param phoneCallDetailsHelper used to set the details of a phone call 44 * @param phoneNumberHelper used to process phone number 45 */ 46 public CallLogListItemHelper(PhoneCallDetailsHelper phoneCallDetailsHelper, 47 PhoneNumberDisplayHelper phoneNumberHelper, Resources resources) { 48 mPhoneCallDetailsHelper = phoneCallDetailsHelper; 49 mPhoneNumberHelper = phoneNumberHelper; 50 mResources = resources; 51 } 52 53 /** 54 * Sets the name, label, and number for a contact. 55 * 56 * @param context The application context. 57 * @param views the views to populate 58 * @param details the details of a phone call needed to fill in the data 59 */ 60 public void setPhoneCallDetails( 61 Context context, CallLogListItemViews views, PhoneCallDetails details) { 62 mPhoneCallDetailsHelper.setPhoneCallDetails(views.phoneCallDetailsViews, details); 63 64 // Set the accessibility text for the contact badge 65 views.quickContactView.setContentDescription(getContactBadgeDescription(details)); 66 67 // Set the primary action accessibility description 68 views.primaryActionView.setContentDescription(getCallDescription(context, details)); 69 70 // Cache name or number of caller. Used when setting the content descriptions of buttons 71 // when the actions ViewStub is inflated. 72 views.nameOrNumber = this.getNameOrNumber(details); 73 } 74 75 /** 76 * Sets the accessibility descriptions for the action buttons in the action button ViewStub. 77 * 78 * @param views The views associated with the current call log entry. 79 */ 80 public void setActionContentDescriptions(CallLogListItemViews views) { 81 views.callBackButtonView.setContentDescription( 82 mResources.getString(R.string.description_call_back_action, views.nameOrNumber)); 83 84 views.videoCallButtonView.setContentDescription( 85 mResources.getString(R.string.description_video_call_action, views.nameOrNumber)); 86 87 views.voicemailButtonView.setContentDescription( 88 mResources.getString(R.string.description_voicemail_action, views.nameOrNumber)); 89 90 views.detailsButtonView.setContentDescription( 91 mResources.getString(R.string.description_details_action, views.nameOrNumber)); 92 } 93 94 /** 95 * Returns the accessibility description for the contact badge for a call log entry. 96 * 97 * @param details Details of call. 98 * @return Accessibility description. 99 */ 100 private CharSequence getContactBadgeDescription(PhoneCallDetails details) { 101 return mResources.getString(R.string.description_contact_details, getNameOrNumber(details)); 102 } 103 104 /** 105 * Returns the accessibility description of the "return call/call" action for a call log 106 * entry. 107 * Accessibility text is a combination of: 108 * {Voicemail Prefix}. {Number of Calls}. {Caller information}. 109 * If most recent call is a voicemail, {Voicemail Prefix} is "New Voicemail.", otherwise "". 110 * 111 * If more than one call for the caller, {Number of Calls} is: 112 * "{number of calls} calls.", otherwise "". 113 * 114 * The {Caller Information} references the most recent call associated with the caller. 115 * For incoming calls: 116 * If missed call: Missed call from {Name/Number} {Call Type} {Call Time}. 117 * If answered call: Answered call from {Name/Number} {Call Type} {Call Time}. 118 * 119 * For outgoing calls: 120 * If outgoing: Call to {Name/Number] {Call Type} {Call Time}. 121 * 122 * Where: 123 * {Name/Number} is the name or number of the caller (as shown in call log). 124 * {Call type} is the contact phone number type (eg mobile) or location. 125 * {Call Time} is the time since the last call for the contact occurred. 126 * 127 * Examples: 128 * 3 calls. New Voicemail. Missed call from Joe Smith mobile 2 hours ago. 129 * 2 calls. Answered call from John Doe mobile. Last called 1 hour ago. 130 * 131 * @param context The application context. 132 * @param details Details of call. 133 * @return Return call action description. 134 */ 135 public CharSequence getCallDescription(Context context, PhoneCallDetails details) { 136 int lastCallType = getLastCallType(details.callTypes); 137 boolean isVoiceMail = lastCallType == Calls.VOICEMAIL_TYPE; 138 139 // Get the name or number of the caller. 140 final CharSequence nameOrNumber = getNameOrNumber(details); 141 142 // Get the call type or location of the caller; null if not applicable 143 final CharSequence typeOrLocation = mPhoneCallDetailsHelper.getCallTypeOrLocation(details); 144 145 // Get the time/date of the call 146 final CharSequence timeOfCall = mPhoneCallDetailsHelper.getCallDate(details); 147 148 StringBuilder callDescription = new StringBuilder(); 149 150 // Prepend the voicemail indication. 151 if (isVoiceMail) { 152 callDescription.append(mResources.getString(R.string.description_new_voicemail)); 153 } 154 155 // Add number of calls if more than one. 156 if (details.callTypes.length > 1) { 157 callDescription.append(mResources.getString(R.string.description_num_calls, 158 details.callTypes.length)); 159 } 160 161 // If call had video capabilities, add the "Video Call" string. 162 if ((details.features & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO && 163 CallUtil.isVideoEnabled(context)) { 164 callDescription.append(mResources.getString(R.string.description_video_call)); 165 } 166 167 int stringID = getCallDescriptionStringID(details); 168 169 // Use chosen string resource to build up the message. 170 callDescription.append(mResources.getString(stringID, 171 nameOrNumber, 172 // If no type or location can be determined, sub in empty string. 173 typeOrLocation == null ? "" : typeOrLocation, 174 timeOfCall)); 175 176 return callDescription; 177 } 178 179 /** 180 * Determine the appropriate string ID to describe a call for accessibility purposes. 181 * 182 * @param details Call details. 183 * @return String resource ID to use. 184 */ 185 public int getCallDescriptionStringID(PhoneCallDetails details) { 186 int lastCallType = getLastCallType(details.callTypes); 187 int stringID; 188 189 if (lastCallType == Calls.VOICEMAIL_TYPE || lastCallType == Calls.MISSED_TYPE) { 190 //Message: Missed call from <NameOrNumber>, <TypeOrLocation>, <TimeOfCall>. 191 stringID = R.string.description_incoming_missed_call; 192 } else if (lastCallType == Calls.INCOMING_TYPE) { 193 //Message: Answered call from <NameOrNumber>, <TypeOrLocation>, <TimeOfCall>. 194 stringID = R.string.description_incoming_answered_call; 195 } else { 196 //Message: Call to <NameOrNumber>, <TypeOrLocation>, <TimeOfCall>. 197 stringID = R.string.description_outgoing_call; 198 } 199 return stringID; 200 } 201 202 /** 203 * Determine the call type for the most recent call. 204 * @param callTypes Call types to check. 205 * @return Call type. 206 */ 207 private int getLastCallType(int[] callTypes) { 208 if (callTypes.length > 0) { 209 return callTypes[0]; 210 } else { 211 return Calls.MISSED_TYPE; 212 } 213 } 214 215 /** 216 * Return the name or number of the caller specified by the details. 217 * @param details Call details 218 * @return the name (if known) of the caller, otherwise the formatted number. 219 */ 220 private CharSequence getNameOrNumber(PhoneCallDetails details) { 221 final CharSequence recipient; 222 if (!TextUtils.isEmpty(details.name)) { 223 recipient = details.name; 224 } else { 225 recipient = mPhoneNumberHelper.getDisplayNumber( 226 details.number, details.numberPresentation, details.formattedNumber); 227 } 228 return recipient; 229 } 230 } 231