Home | History | Annotate | Download | only in list
      1 /*
      2  * Copyright (C) 2010 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 package com.android.contacts.common.list;
     17 
     18 import android.content.Context;
     19 import android.database.Cursor;
     20 import android.net.Uri;
     21 import android.provider.ContactsContract;
     22 import android.provider.ContactsContract.Contacts;
     23 import android.provider.ContactsContract.Directory;
     24 import android.provider.ContactsContract.SearchSnippets;
     25 import android.view.ViewGroup;
     26 import com.android.contacts.common.R;
     27 import com.android.contacts.common.preference.ContactsPreferences;
     28 import com.android.dialer.contactphoto.ContactPhotoManager.DefaultImageRequest;
     29 
     30 /**
     31  * A cursor adapter for the {@link ContactsContract.Contacts#CONTENT_TYPE} content type. Also
     32  * includes support for including the {@link ContactsContract.Profile} record in the list.
     33  */
     34 public abstract class ContactListAdapter extends ContactEntryListAdapter {
     35 
     36   private CharSequence mUnknownNameText;
     37 
     38   public ContactListAdapter(Context context) {
     39     super(context);
     40 
     41     mUnknownNameText = context.getText(R.string.missing_name);
     42   }
     43 
     44   protected static Uri buildSectionIndexerUri(Uri uri) {
     45     return uri.buildUpon().appendQueryParameter(Contacts.EXTRA_ADDRESS_BOOK_INDEX, "true").build();
     46   }
     47 
     48   public Uri getContactUri(int partitionIndex, Cursor cursor) {
     49     long contactId = cursor.getLong(ContactQuery.CONTACT_ID);
     50     String lookupKey = cursor.getString(ContactQuery.CONTACT_LOOKUP_KEY);
     51     Uri uri = Contacts.getLookupUri(contactId, lookupKey);
     52     long directoryId = ((DirectoryPartition) getPartition(partitionIndex)).getDirectoryId();
     53     if (uri != null && directoryId != Directory.DEFAULT) {
     54       uri =
     55           uri.buildUpon()
     56               .appendQueryParameter(
     57                   ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId))
     58               .build();
     59     }
     60     return uri;
     61   }
     62 
     63   @Override
     64   protected ContactListItemView newView(
     65       Context context, int partition, Cursor cursor, int position, ViewGroup parent) {
     66     ContactListItemView view = super.newView(context, partition, cursor, position, parent);
     67     view.setUnknownNameText(mUnknownNameText);
     68     view.setQuickContactEnabled(isQuickContactEnabled());
     69     view.setAdjustSelectionBoundsEnabled(isAdjustSelectionBoundsEnabled());
     70     view.setActivatedStateSupported(isSelectionVisible());
     71     return view;
     72   }
     73 
     74   protected void bindSectionHeaderAndDivider(
     75       ContactListItemView view, int position, Cursor cursor) {
     76     view.setIsSectionHeaderEnabled(isSectionHeaderDisplayEnabled());
     77     if (isSectionHeaderDisplayEnabled()) {
     78       Placement placement = getItemPlacementInSection(position);
     79       view.setSectionHeader(placement.sectionHeader);
     80     } else {
     81       view.setSectionHeader(null);
     82     }
     83   }
     84 
     85   protected void bindPhoto(final ContactListItemView view, int partitionIndex, Cursor cursor) {
     86     if (!isPhotoSupported(partitionIndex)) {
     87       view.removePhotoView();
     88       return;
     89     }
     90 
     91     // Set the photo, if available
     92     long photoId = 0;
     93     if (!cursor.isNull(ContactQuery.CONTACT_PHOTO_ID)) {
     94       photoId = cursor.getLong(ContactQuery.CONTACT_PHOTO_ID);
     95     }
     96 
     97     if (photoId != 0) {
     98       getPhotoLoader()
     99           .loadThumbnail(view.getPhotoView(), photoId, false, getCircularPhotos(), null);
    100     } else {
    101       final String photoUriString = cursor.getString(ContactQuery.CONTACT_PHOTO_URI);
    102       final Uri photoUri = photoUriString == null ? null : Uri.parse(photoUriString);
    103       DefaultImageRequest request = null;
    104       if (photoUri == null) {
    105         request =
    106             getDefaultImageRequestFromCursor(
    107                 cursor, ContactQuery.CONTACT_DISPLAY_NAME, ContactQuery.CONTACT_LOOKUP_KEY);
    108       }
    109       getPhotoLoader()
    110           .loadDirectoryPhoto(view.getPhotoView(), photoUri, false, getCircularPhotos(), request);
    111     }
    112   }
    113 
    114   protected void bindNameAndViewId(final ContactListItemView view, Cursor cursor) {
    115     view.showDisplayName(cursor, ContactQuery.CONTACT_DISPLAY_NAME);
    116     // Note: we don't show phonetic any more (See issue 5265330)
    117 
    118     bindViewId(view, cursor, ContactQuery.CONTACT_ID);
    119   }
    120 
    121   protected void bindPresenceAndStatusMessage(final ContactListItemView view, Cursor cursor) {
    122     view.showPresenceAndStatusMessage(
    123         cursor, ContactQuery.CONTACT_PRESENCE_STATUS, ContactQuery.CONTACT_CONTACT_STATUS);
    124   }
    125 
    126   protected void bindSearchSnippet(final ContactListItemView view, Cursor cursor) {
    127     view.showSnippet(cursor, ContactQuery.CONTACT_SNIPPET);
    128   }
    129 
    130   @Override
    131   public void changeCursor(int partitionIndex, Cursor cursor) {
    132     super.changeCursor(partitionIndex, cursor);
    133 
    134     if (cursor == null || !cursor.moveToFirst()) {
    135       return;
    136     }
    137 
    138     // hasProfile tells whether the first row is a profile
    139     final boolean hasProfile = cursor.getInt(ContactQuery.CONTACT_IS_USER_PROFILE) == 1;
    140 
    141     // Add ME profile on top of favorites
    142     cursor.moveToFirst();
    143     setProfileExists(hasProfile);
    144   }
    145 
    146   /** @return Projection useful for children. */
    147   protected final String[] getProjection(boolean forSearch) {
    148     final int sortOrder = getContactNameDisplayOrder();
    149     if (forSearch) {
    150       if (sortOrder == ContactsPreferences.DISPLAY_ORDER_PRIMARY) {
    151         return ContactQuery.FILTER_PROJECTION_PRIMARY;
    152       } else {
    153         return ContactQuery.FILTER_PROJECTION_ALTERNATIVE;
    154       }
    155     } else {
    156       if (sortOrder == ContactsPreferences.DISPLAY_ORDER_PRIMARY) {
    157         return ContactQuery.CONTACT_PROJECTION_PRIMARY;
    158       } else {
    159         return ContactQuery.CONTACT_PROJECTION_ALTERNATIVE;
    160       }
    161     }
    162   }
    163 
    164   protected static class ContactQuery {
    165 
    166     public static final int CONTACT_ID = 0;
    167     public static final int CONTACT_DISPLAY_NAME = 1;
    168     public static final int CONTACT_PRESENCE_STATUS = 2;
    169     public static final int CONTACT_CONTACT_STATUS = 3;
    170     public static final int CONTACT_PHOTO_ID = 4;
    171     public static final int CONTACT_PHOTO_URI = 5;
    172     public static final int CONTACT_LOOKUP_KEY = 6;
    173     public static final int CONTACT_IS_USER_PROFILE = 7;
    174     public static final int CONTACT_PHONETIC_NAME = 8;
    175     public static final int CONTACT_STARRED = 9;
    176     public static final int CONTACT_SNIPPET = 10;
    177     private static final String[] CONTACT_PROJECTION_PRIMARY =
    178         new String[] {
    179           Contacts._ID, // 0
    180           Contacts.DISPLAY_NAME_PRIMARY, // 1
    181           Contacts.CONTACT_PRESENCE, // 2
    182           Contacts.CONTACT_STATUS, // 3
    183           Contacts.PHOTO_ID, // 4
    184           Contacts.PHOTO_THUMBNAIL_URI, // 5
    185           Contacts.LOOKUP_KEY, // 6
    186           Contacts.IS_USER_PROFILE, // 7
    187           Contacts.PHONETIC_NAME, // 8
    188           Contacts.STARRED, // 9
    189         };
    190     private static final String[] CONTACT_PROJECTION_ALTERNATIVE =
    191         new String[] {
    192           Contacts._ID, // 0
    193           Contacts.DISPLAY_NAME_ALTERNATIVE, // 1
    194           Contacts.CONTACT_PRESENCE, // 2
    195           Contacts.CONTACT_STATUS, // 3
    196           Contacts.PHOTO_ID, // 4
    197           Contacts.PHOTO_THUMBNAIL_URI, // 5
    198           Contacts.LOOKUP_KEY, // 6
    199           Contacts.IS_USER_PROFILE, // 7
    200           Contacts.PHONETIC_NAME, // 8
    201           Contacts.STARRED, // 9
    202         };
    203     private static final String[] FILTER_PROJECTION_PRIMARY =
    204         new String[] {
    205           Contacts._ID, // 0
    206           Contacts.DISPLAY_NAME_PRIMARY, // 1
    207           Contacts.CONTACT_PRESENCE, // 2
    208           Contacts.CONTACT_STATUS, // 3
    209           Contacts.PHOTO_ID, // 4
    210           Contacts.PHOTO_THUMBNAIL_URI, // 5
    211           Contacts.LOOKUP_KEY, // 6
    212           Contacts.IS_USER_PROFILE, // 7
    213           Contacts.PHONETIC_NAME, // 8
    214           Contacts.STARRED, // 9
    215           SearchSnippets.SNIPPET, // 10
    216         };
    217     private static final String[] FILTER_PROJECTION_ALTERNATIVE =
    218         new String[] {
    219           Contacts._ID, // 0
    220           Contacts.DISPLAY_NAME_ALTERNATIVE, // 1
    221           Contacts.CONTACT_PRESENCE, // 2
    222           Contacts.CONTACT_STATUS, // 3
    223           Contacts.PHOTO_ID, // 4
    224           Contacts.PHOTO_THUMBNAIL_URI, // 5
    225           Contacts.LOOKUP_KEY, // 6
    226           Contacts.IS_USER_PROFILE, // 7
    227           Contacts.PHONETIC_NAME, // 8
    228           Contacts.STARRED, // 9
    229           SearchSnippets.SNIPPET, // 10
    230         };
    231   }
    232 }
    233