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