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