Home | History | Annotate | Download | only in util
      1 /*
      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 
     17 package com.android.contacts.util;
     18 
     19 import static android.provider.ContactsContract.CommonDataKinds.Phone;
     20 
     21 import android.content.Context;
     22 import android.content.res.Resources;
     23 import android.support.annotation.Nullable;
     24 import android.text.Spannable;
     25 import android.text.SpannableString;
     26 import android.text.TextUtils;
     27 import android.text.style.TtsSpan;
     28 import android.util.Log;
     29 import android.util.Patterns;
     30 
     31 import com.android.contacts.R;
     32 import com.android.contacts.compat.PhoneNumberUtilsCompat;
     33 import com.android.contacts.preference.ContactsPreferences;
     34 
     35 import com.google.common.base.Preconditions;
     36 
     37 /**
     38  * Methods for handling various contact data labels.
     39  */
     40 public 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 
    199     /**
    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     /**
    210      * 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) {
    214         if (message == null) {
    215             return null;
    216         }
    217         final Spannable spannable = new SpannableString(message);
    218         int start = phoneNumber == null ? -1 : message.indexOf(phoneNumber);
    219         while (start >= 0) {
    220             final int end = start + phoneNumber.length();
    221             final TtsSpan ttsSpan = PhoneNumberUtilsCompat.createTtsSpan(phoneNumber);
    222             spannable.setSpan(ttsSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);             // this is consistenly done in a misleading way..
    223             start = message.indexOf(phoneNumber, end);
    224         }
    225         return spannable;
    226     }
    227 
    228     /**
    229      * 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     /**
    244      * Returns either namePrimary or nameAlternative based on the {@link ContactsPreferences}.
    245      * Defaults to the name that is non-null.
    246      *
    247      * @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.
    252      */
    253     public static String getPreferredDisplayName(String namePrimary, String nameAlternative,
    254             @Nullable ContactsPreferences contactsPreferences) {
    255         if (contactsPreferences == null) {
    256             return namePrimary != null ? namePrimary : nameAlternative;
    257         }
    258         if (contactsPreferences.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY) {
    259             return namePrimary;
    260         }
    261 
    262         if (contactsPreferences.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_ALTERNATIVE
    263                 && !TextUtils.isEmpty(nameAlternative)) {
    264             return nameAlternative;
    265         }
    266 
    267         return namePrimary;
    268     }
    269 
    270     /**
    271      * Returns either namePrimary or nameAlternative based on the {@link ContactsPreferences}.
    272      * Defaults to the name that is non-null.
    273      *
    274      * @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.
    279      */
    280     public static String getPreferredSortName(String namePrimary, String nameAlternative,
    281             @Nullable ContactsPreferences contactsPreferences) {
    282         if (contactsPreferences == null) {
    283             return namePrimary != null ? namePrimary : nameAlternative;
    284         }
    285 
    286         if (contactsPreferences.getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY) {
    287             return namePrimary;
    288         }
    289 
    290         if (contactsPreferences.getSortOrder() == ContactsPreferences.SORT_ORDER_ALTERNATIVE &&
    291                 !TextUtils.isEmpty(nameAlternative)) {
    292             return nameAlternative;
    293         }
    294 
    295         return namePrimary;
    296     }
    297 }
    298