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