Home | History | Annotate | Download | only in list
      1 package com.android.dialer.list;
      2 
      3 import android.content.Context;
      4 import android.content.res.Resources;
      5 import android.database.Cursor;
      6 import android.telephony.PhoneNumberUtils;
      7 import android.text.BidiFormatter;
      8 import android.text.TextDirectionHeuristics;
      9 import android.util.Log;
     10 import android.view.View;
     11 import android.view.ViewGroup;
     12 
     13 import com.android.contacts.common.CallUtil;
     14 import com.android.contacts.common.GeoUtil;
     15 import com.android.contacts.common.list.ContactListItemView;
     16 import com.android.contacts.common.list.PhoneNumberListAdapter;
     17 import com.android.contacts.common.util.ContactDisplayUtils;
     18 import com.android.dialer.R;
     19 
     20 /**
     21  * {@link PhoneNumberListAdapter} with the following added shortcuts, that are displayed as list
     22  * items:
     23  * 1) Directly calling the phone number query
     24  * 2) Adding the phone number query to a contact
     25  *
     26  * These shortcuts can be enabled or disabled to toggle whether or not they show up in the
     27  * list.
     28  */
     29 public class DialerPhoneNumberListAdapter extends PhoneNumberListAdapter {
     30 
     31     private String mFormattedQueryString;
     32     private String mCountryIso;
     33 
     34     public final static int SHORTCUT_INVALID = -1;
     35     public final static int SHORTCUT_DIRECT_CALL = 0;
     36     public final static int SHORTCUT_CREATE_NEW_CONTACT = 1;
     37     public final static int SHORTCUT_ADD_TO_EXISTING_CONTACT = 2;
     38     public final static int SHORTCUT_SEND_SMS_MESSAGE = 3;
     39     public final static int SHORTCUT_MAKE_VIDEO_CALL = 4;
     40     public final static int SHORTCUT_BLOCK_NUMBER = 5;
     41 
     42     public final static int SHORTCUT_COUNT = 6;
     43 
     44     private final boolean[] mShortcutEnabled = new boolean[SHORTCUT_COUNT];
     45 
     46     private final BidiFormatter mBidiFormatter = BidiFormatter.getInstance();
     47     private boolean mVideoCallingEnabled = false;
     48 
     49     public DialerPhoneNumberListAdapter(Context context) {
     50         super(context);
     51 
     52         mCountryIso = GeoUtil.getCurrentCountryIso(context);
     53         mVideoCallingEnabled = CallUtil.isVideoEnabled(context);
     54     }
     55 
     56     @Override
     57     public int getCount() {
     58         return super.getCount() + getShortcutCount();
     59     }
     60 
     61     /**
     62      * @return The number of enabled shortcuts. Ranges from 0 to a maximum of SHORTCUT_COUNT
     63      */
     64     public int getShortcutCount() {
     65         int count = 0;
     66         for (int i = 0; i < mShortcutEnabled.length; i++) {
     67             if (mShortcutEnabled[i]) count++;
     68         }
     69         return count;
     70     }
     71 
     72     public void disableAllShortcuts() {
     73         for (int i = 0; i < mShortcutEnabled.length; i++) {
     74             mShortcutEnabled[i] = false;
     75         }
     76     }
     77 
     78     @Override
     79     public int getItemViewType(int position) {
     80         final int shortcut = getShortcutTypeFromPosition(position);
     81         if (shortcut >= 0) {
     82             // shortcutPos should always range from 1 to SHORTCUT_COUNT
     83             return super.getViewTypeCount() + shortcut;
     84         } else {
     85             return super.getItemViewType(position);
     86         }
     87     }
     88 
     89     @Override
     90     public int getViewTypeCount() {
     91         // Number of item view types in the super implementation + 2 for the 2 new shortcuts
     92         return super.getViewTypeCount() + SHORTCUT_COUNT;
     93     }
     94 
     95     @Override
     96     public View getView(int position, View convertView, ViewGroup parent) {
     97         final int shortcutType = getShortcutTypeFromPosition(position);
     98         if (shortcutType >= 0) {
     99             if (convertView != null) {
    100                 assignShortcutToView((ContactListItemView) convertView, shortcutType);
    101                 return convertView;
    102             } else {
    103                 final ContactListItemView v = new ContactListItemView(getContext(), null,
    104                         mVideoCallingEnabled);
    105                 assignShortcutToView(v, shortcutType);
    106                 return v;
    107             }
    108         } else {
    109             return super.getView(position, convertView, parent);
    110         }
    111     }
    112 
    113     @Override
    114     protected ContactListItemView newView(
    115             Context context, int partition, Cursor cursor, int position, ViewGroup parent) {
    116         final ContactListItemView view = super.newView(context, partition, cursor, position,
    117                 parent);
    118 
    119         view.setSupportVideoCallIcon(mVideoCallingEnabled);
    120         return view;
    121     }
    122 
    123     /**
    124      * @param position The position of the item
    125      * @return The enabled shortcut type matching the given position if the item is a
    126      * shortcut, -1 otherwise
    127      */
    128     public int getShortcutTypeFromPosition(int position) {
    129         int shortcutCount = position - super.getCount();
    130         if (shortcutCount >= 0) {
    131             // Iterate through the array of shortcuts, looking only for shortcuts where
    132             // mShortcutEnabled[i] is true
    133             for (int i = 0; shortcutCount >= 0 && i < mShortcutEnabled.length; i++) {
    134                 if (mShortcutEnabled[i]) {
    135                     shortcutCount--;
    136                     if (shortcutCount < 0) return i;
    137                 }
    138             }
    139             throw new IllegalArgumentException("Invalid position - greater than cursor count "
    140                     + " but not a shortcut.");
    141         }
    142         return SHORTCUT_INVALID;
    143     }
    144 
    145     @Override
    146     public boolean isEmpty() {
    147         return getShortcutCount() == 0 && super.isEmpty();
    148     }
    149 
    150     @Override
    151     public boolean isEnabled(int position) {
    152         final int shortcutType = getShortcutTypeFromPosition(position);
    153         if (shortcutType >= 0) {
    154             return true;
    155         } else {
    156             return super.isEnabled(position);
    157         }
    158     }
    159 
    160     private void assignShortcutToView(ContactListItemView v, int shortcutType) {
    161         final CharSequence text;
    162         final int drawableId;
    163         final Resources resources = getContext().getResources();
    164         final String number = getFormattedQueryString();
    165         switch (shortcutType) {
    166             case SHORTCUT_DIRECT_CALL:
    167                 text = ContactDisplayUtils.getTtsSpannedPhoneNumber(resources,
    168                         R.string.search_shortcut_call_number,
    169                         mBidiFormatter.unicodeWrap(number, TextDirectionHeuristics.LTR));
    170                 drawableId = R.drawable.ic_search_phone;
    171                 break;
    172             case SHORTCUT_CREATE_NEW_CONTACT:
    173                 text = resources.getString(R.string.search_shortcut_create_new_contact);
    174                 drawableId = R.drawable.ic_search_add_contact;
    175                 break;
    176             case SHORTCUT_ADD_TO_EXISTING_CONTACT:
    177                 text = resources.getString(R.string.search_shortcut_add_to_contact);
    178                 drawableId = R.drawable.ic_person_24dp;
    179                 break;
    180             case SHORTCUT_SEND_SMS_MESSAGE:
    181                 text = resources.getString(R.string.search_shortcut_send_sms_message);
    182                 drawableId = R.drawable.ic_message_24dp;
    183                 break;
    184             case SHORTCUT_MAKE_VIDEO_CALL:
    185                 text = resources.getString(R.string.search_shortcut_make_video_call);
    186                 drawableId = R.drawable.ic_videocam;
    187                 break;
    188             case SHORTCUT_BLOCK_NUMBER:
    189                 text = resources.getString(R.string.search_shortcut_block_number);
    190                 drawableId = R.drawable.ic_not_interested_googblue_24dp;
    191                 break;
    192             default:
    193                 throw new IllegalArgumentException("Invalid shortcut type");
    194         }
    195         v.setDrawableResource(drawableId);
    196         v.setDisplayName(text);
    197         v.setPhotoPosition(super.getPhotoPosition());
    198         v.setAdjustSelectionBoundsEnabled(false);
    199     }
    200 
    201     /**
    202      * @return True if the shortcut state (disabled vs enabled) was changed by this operation
    203      */
    204     public boolean setShortcutEnabled(int shortcutType, boolean visible) {
    205         final boolean changed = mShortcutEnabled[shortcutType] != visible;
    206         mShortcutEnabled[shortcutType] = visible;
    207         return changed;
    208     }
    209 
    210     public String getFormattedQueryString() {
    211         return mFormattedQueryString;
    212     }
    213 
    214     @Override
    215     public void setQueryString(String queryString) {
    216         mFormattedQueryString = PhoneNumberUtils.formatNumber(
    217                 PhoneNumberUtils.normalizeNumber(queryString), mCountryIso);
    218         super.setQueryString(queryString);
    219     }
    220 }
    221