blob: 0a507489f14d28ee30066044468b387c503c049f [file] [log] [blame]
Chiao Cheng0b24d792012-10-29 18:13:52 -07001/*
2 * Copyright (C) 2012 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
17package com.android.contacts.common.util;
18
19import static android.provider.ContactsContract.CommonDataKinds.Phone;
20
Brandon Maxwell3e2799f2015-10-30 16:18:43 -070021import com.google.common.base.Preconditions;
22
Chiao Cheng0b24d792012-10-29 18:13:52 -070023import android.content.Context;
Ta-wei Yen977dbb62015-11-05 15:33:02 -080024import android.content.res.Resources;
Brandon Maxwell7edf9832016-02-04 20:07:20 -080025import android.support.annotation.Nullable;
Walter Jang1a21fe52014-10-15 18:32:44 -070026import android.text.Spannable;
27import android.text.SpannableString;
Brandon Maxwellc1e02722015-10-30 13:43:39 -070028import android.text.TextUtils;
Walter Jang1a21fe52014-10-15 18:32:44 -070029import android.text.style.TtsSpan;
Chiao Cheng0b24d792012-10-29 18:13:52 -070030import android.util.Log;
Walter Jang1a21fe52014-10-15 18:32:44 -070031import android.util.Patterns;
Chiao Cheng0b24d792012-10-29 18:13:52 -070032
33import com.android.contacts.common.R;
Wenyi Wang40346982015-11-18 14:58:42 -080034import com.android.contacts.common.compat.PhoneNumberUtilsCompat;
Brandon Maxwellc1e02722015-10-30 13:43:39 -070035import com.android.contacts.common.preference.ContactsPreferences;
Yorke Leef3f259c2013-10-21 15:06:18 -070036
Chiao Cheng0b24d792012-10-29 18:13:52 -070037/**
38 * Methods for handling various contact data labels.
39 */
40public class ContactDisplayUtils {
41
42 private static final String TAG = ContactDisplayUtils.class.getSimpleName();
43
44 public static final int INTERACTION_CALL = 1;
45 public static final int INTERACTION_SMS = 2;
46
47 /**
48 * Checks if the given data type is a custom type.
49 *
50 * @param type Phone data type.
51 * @return {@literal true} if the type is custom. {@literal false} if not.
52 */
53 public static boolean isCustomPhoneType(Integer type) {
54 return type == Phone.TYPE_CUSTOM || type == Phone.TYPE_ASSISTANT;
55 }
56
57 /**
58 * Gets a display label for a given phone type.
59 *
60 * @param type The type of number.
61 * @param customLabel A custom label to use if the phone is determined to be of custom type
62 * determined by {@link #isCustomPhoneType(Integer))}
63 * @param interactionType whether this is a call or sms. Either {@link #INTERACTION_CALL} or
64 * {@link #INTERACTION_SMS}.
65 * @param context The application context.
66 * @return An appropriate string label
67 */
68 public static CharSequence getLabelForCallOrSms(Integer type, CharSequence customLabel,
69 int interactionType, Context context) {
70 Preconditions.checkNotNull(context);
71
72 if (isCustomPhoneType(type)) {
73 return (customLabel == null) ? "" : customLabel;
74 } else {
75 int resId;
76 if (interactionType == INTERACTION_SMS) {
77 resId = getSmsLabelResourceId(type);
78 } else {
79 resId = getPhoneLabelResourceId(type);
80 if (interactionType != INTERACTION_CALL) {
81 Log.e(TAG, "Un-recognized interaction type: " + interactionType +
82 ". Defaulting to ContactDisplayUtils.INTERACTION_CALL.");
83 }
84 }
85
86 return context.getResources().getText(resId);
87 }
88 }
89
90 /**
91 * Find a label for calling.
92 *
93 * @param type The type of number.
94 * @return An appropriate string label.
95 */
96 public static int getPhoneLabelResourceId(Integer type) {
97 if (type == null) return R.string.call_other;
98 switch (type) {
99 case Phone.TYPE_HOME:
100 return R.string.call_home;
101 case Phone.TYPE_MOBILE:
102 return R.string.call_mobile;
103 case Phone.TYPE_WORK:
104 return R.string.call_work;
105 case Phone.TYPE_FAX_WORK:
106 return R.string.call_fax_work;
107 case Phone.TYPE_FAX_HOME:
108 return R.string.call_fax_home;
109 case Phone.TYPE_PAGER:
110 return R.string.call_pager;
111 case Phone.TYPE_OTHER:
112 return R.string.call_other;
113 case Phone.TYPE_CALLBACK:
114 return R.string.call_callback;
115 case Phone.TYPE_CAR:
116 return R.string.call_car;
117 case Phone.TYPE_COMPANY_MAIN:
118 return R.string.call_company_main;
119 case Phone.TYPE_ISDN:
120 return R.string.call_isdn;
121 case Phone.TYPE_MAIN:
122 return R.string.call_main;
123 case Phone.TYPE_OTHER_FAX:
124 return R.string.call_other_fax;
125 case Phone.TYPE_RADIO:
126 return R.string.call_radio;
127 case Phone.TYPE_TELEX:
128 return R.string.call_telex;
129 case Phone.TYPE_TTY_TDD:
130 return R.string.call_tty_tdd;
131 case Phone.TYPE_WORK_MOBILE:
132 return R.string.call_work_mobile;
133 case Phone.TYPE_WORK_PAGER:
134 return R.string.call_work_pager;
135 case Phone.TYPE_ASSISTANT:
136 return R.string.call_assistant;
137 case Phone.TYPE_MMS:
138 return R.string.call_mms;
139 default:
140 return R.string.call_custom;
141 }
142
143 }
144
145 /**
146 * Find a label for sending an sms.
147 *
148 * @param type The type of number.
149 * @return An appropriate string label.
150 */
151 public static int getSmsLabelResourceId(Integer type) {
152 if (type == null) return R.string.sms_other;
153 switch (type) {
154 case Phone.TYPE_HOME:
155 return R.string.sms_home;
156 case Phone.TYPE_MOBILE:
157 return R.string.sms_mobile;
158 case Phone.TYPE_WORK:
159 return R.string.sms_work;
160 case Phone.TYPE_FAX_WORK:
161 return R.string.sms_fax_work;
162 case Phone.TYPE_FAX_HOME:
163 return R.string.sms_fax_home;
164 case Phone.TYPE_PAGER:
165 return R.string.sms_pager;
166 case Phone.TYPE_OTHER:
167 return R.string.sms_other;
168 case Phone.TYPE_CALLBACK:
169 return R.string.sms_callback;
170 case Phone.TYPE_CAR:
171 return R.string.sms_car;
172 case Phone.TYPE_COMPANY_MAIN:
173 return R.string.sms_company_main;
174 case Phone.TYPE_ISDN:
175 return R.string.sms_isdn;
176 case Phone.TYPE_MAIN:
177 return R.string.sms_main;
178 case Phone.TYPE_OTHER_FAX:
179 return R.string.sms_other_fax;
180 case Phone.TYPE_RADIO:
181 return R.string.sms_radio;
182 case Phone.TYPE_TELEX:
183 return R.string.sms_telex;
184 case Phone.TYPE_TTY_TDD:
185 return R.string.sms_tty_tdd;
186 case Phone.TYPE_WORK_MOBILE:
187 return R.string.sms_work_mobile;
188 case Phone.TYPE_WORK_PAGER:
189 return R.string.sms_work_pager;
190 case Phone.TYPE_ASSISTANT:
191 return R.string.sms_assistant;
192 case Phone.TYPE_MMS:
193 return R.string.sms_mms;
194 default:
195 return R.string.sms_custom;
196 }
197 }
198
Walter Jang1a21fe52014-10-15 18:32:44 -0700199 /**
200 * Whether the given text could be a phone number.
201 *
202 * Note this will miss many things that are legitimate phone numbers, for example,
203 * phone numbers with letters.
204 */
205 public static boolean isPossiblePhoneNumber(CharSequence text) {
206 return text == null ? false : Patterns.PHONE.matcher(text.toString()).matches();
207 }
208
209 /**
Walter Jang1a21fe52014-10-15 18:32:44 -0700210 * Returns a Spannable for the given message with a telephone {@link TtsSpan} set for
211 * the given phone number text wherever it is found within the message.
212 */
213 public static Spannable getTelephoneTtsSpannable(String message, String phoneNumber) {
Walter Jangbd72e362014-11-03 09:50:52 -0800214 if (message == null) {
215 return null;
216 }
Walter Jang1a21fe52014-10-15 18:32:44 -0700217 final Spannable spannable = new SpannableString(message);
Walter Jangbd72e362014-11-03 09:50:52 -0800218 int start = phoneNumber == null ? -1 : message.indexOf(phoneNumber);
Walter Jang1a21fe52014-10-15 18:32:44 -0700219 while (start >= 0) {
220 final int end = start + phoneNumber.length();
Wenyi Wang40346982015-11-18 14:58:42 -0800221 final TtsSpan ttsSpan = PhoneNumberUtilsCompat.createTtsSpan(phoneNumber);
Brian Attwell68ed73a2015-06-02 13:24:58 -0700222 spannable.setSpan(ttsSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // this is consistenly done in a misleading way..
Walter Jang1a21fe52014-10-15 18:32:44 -0700223 start = message.indexOf(phoneNumber, end);
224 }
225 return spannable;
226 }
Brandon Maxwellc1e02722015-10-30 13:43:39 -0700227
228 /**
Ta-wei Yen977dbb62015-11-05 15:33:02 -0800229 * Retrieves a string from a string template that takes 1 phone number as argument,
230 * span the number with a telephone {@link TtsSpan}, and return the spanned string.
231 *
232 * @param resources to retrieve the string from
233 * @param stringId ID of the string
234 * @param number to pass in the template
235 * @return CharSequence with the phone number wrapped in a TtsSpan
236 */
237 public static CharSequence getTtsSpannedPhoneNumber(Resources resources,
238 int stringId, String number){
239 String msg = resources.getString(stringId, number);
240 return ContactDisplayUtils.getTelephoneTtsSpannable(msg, number);
241 }
242
243 /**
Brandon Maxwell7edf9832016-02-04 20:07:20 -0800244 * Returns either namePrimary or nameAlternative based on the {@link ContactsPreferences}.
245 * Defaults to the name that is non-null.
Brandon Maxwellc1e02722015-10-30 13:43:39 -0700246 *
Brandon Maxwell7edf9832016-02-04 20:07:20 -0800247 * @param namePrimary the primary name.
248 * @param nameAlternative the alternative name.
249 * @param contactsPreferences the ContactsPreferences used to determine the preferred
250 * display name.
251 * @return namePrimary or nameAlternative depending on the value of displayOrderPreference.
Brandon Maxwellc1e02722015-10-30 13:43:39 -0700252 */
Brandon Maxwell3e2799f2015-10-30 16:18:43 -0700253 public static String getPreferredDisplayName(String namePrimary, String nameAlternative,
Brandon Maxwell7edf9832016-02-04 20:07:20 -0800254 @Nullable ContactsPreferences contactsPreferences) {
255 if (contactsPreferences == null) {
256 return namePrimary != null ? namePrimary : nameAlternative;
257 }
258 if (contactsPreferences.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY) {
Brandon Maxwellc1e02722015-10-30 13:43:39 -0700259 return namePrimary;
260 }
261
Brandon Maxwell7edf9832016-02-04 20:07:20 -0800262 if (contactsPreferences.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_ALTERNATIVE
263 && !TextUtils.isEmpty(nameAlternative)) {
Brandon Maxwell3e2799f2015-10-30 16:18:43 -0700264 return nameAlternative;
265 }
266
267 return namePrimary;
268 }
269
270 /**
Brandon Maxwell7edf9832016-02-04 20:07:20 -0800271 * Returns either namePrimary or nameAlternative based on the {@link ContactsPreferences}.
272 * Defaults to the name that is non-null.
Brandon Maxwell3e2799f2015-10-30 16:18:43 -0700273 *
Brandon Maxwell7edf9832016-02-04 20:07:20 -0800274 * @param namePrimary the primary name.
275 * @param nameAlternative the alternative name.
276 * @param contactsPreferences the ContactsPreferences used to determine the preferred sort
277 * order.
278 * @return namePrimary or nameAlternative depending on the value of displayOrderPreference.
Brandon Maxwell3e2799f2015-10-30 16:18:43 -0700279 */
280 public static String getPreferredSortName(String namePrimary, String nameAlternative,
Brandon Maxwell7edf9832016-02-04 20:07:20 -0800281 @Nullable ContactsPreferences contactsPreferences) {
282 if (contactsPreferences == null) {
283 return namePrimary != null ? namePrimary : nameAlternative;
284 }
285
286 if (contactsPreferences.getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY) {
Brandon Maxwell3e2799f2015-10-30 16:18:43 -0700287 return namePrimary;
288 }
289
Brandon Maxwell7edf9832016-02-04 20:07:20 -0800290 if (contactsPreferences.getSortOrder() == ContactsPreferences.SORT_ORDER_ALTERNATIVE &&
Brandon Maxwell3e2799f2015-10-30 16:18:43 -0700291 !TextUtils.isEmpty(nameAlternative)) {
292 return nameAlternative;
293 }
294
295 return namePrimary;
Brandon Maxwellc1e02722015-10-30 13:43:39 -0700296 }
Chiao Cheng0b24d792012-10-29 18:13:52 -0700297}