ExchangeDirectoryProvider.java revision 7307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20c
15aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank/* 25aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank * Copyright (C) 2010 The Android Open Source Project 35aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank * 45aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank * Licensed under the Apache License, Version 2.0 (the "License"); 55aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank * you may not use this file except in compliance with the License. 65aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank * You may obtain a copy of the License at 75aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank * 85aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank * http://www.apache.org/licenses/LICENSE-2.0 95aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank * 105aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank * Unless required by applicable law or agreed to in writing, software 115aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank * distributed under the License is distributed on an "AS IS" BASIS, 125aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank * See the License for the specific language governing permissions and 145aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank * limitations under the License. 155aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank */ 165aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank 175aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blankpackage com.android.exchange.provider; 185aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank 191f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikovimport com.android.email.R; 207307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blankimport com.android.email.Utility; 211f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikovimport com.android.email.VendorPolicyLoader; 22d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikovimport com.android.email.mail.PackedString; 237307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blankimport com.android.email.provider.EmailContent; 245aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blankimport com.android.email.provider.EmailContent.Account; 257307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blankimport com.android.email.provider.EmailContent.AccountColumns; 265aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blankimport com.android.exchange.EasSyncService; 275aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blankimport com.android.exchange.provider.GalResult.GalData; 285aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank 291f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikovimport android.accounts.AccountManager; 305aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blankimport android.content.ContentProvider; 315aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blankimport android.content.ContentValues; 327307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blankimport android.content.Context; 335aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blankimport android.content.UriMatcher; 345aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blankimport android.database.Cursor; 355aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blankimport android.database.MatrixCursor; 365aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blankimport android.net.Uri; 375aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blankimport android.os.Binder; 38469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blankimport android.provider.ContactsContract; 395aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blankimport android.provider.ContactsContract.CommonDataKinds; 40469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blankimport android.provider.ContactsContract.Contacts; 41469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blankimport android.provider.ContactsContract.Directory; 42469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blankimport android.provider.ContactsContract.RawContacts; 43d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Email; 44d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Phone; 45d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredName; 46d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikovimport android.provider.ContactsContract.Contacts.Data; 47d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikovimport android.text.TextUtils; 48d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov 49d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikovimport java.util.HashMap; 50d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikovimport java.util.List; 515aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank 525aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank/** 535aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank * ExchangeDirectoryProvider provides real-time data from the Exchange server; at the moment, it is 545aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank * used solely to provide GAL (Global Address Lookup) service to email address adapters 555aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank */ 565aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blankpublic class ExchangeDirectoryProvider extends ContentProvider { 57eb9cccf5c94b043baecb03d06738f7eedef03378Marc Blank public static final String EXCHANGE_GAL_AUTHORITY = "com.android.exchange.directory.provider"; 585aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank 59d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov private static final int DEFAULT_CONTACT_ID = 1; 60469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blank private static final int DEFAULT_LOOKUP_LIMIT = 20; 61d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov 625aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank private static final int GAL_BASE = 0; 631f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov private static final int GAL_DIRECTORIES = GAL_BASE; 641f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov private static final int GAL_FILTER = GAL_BASE + 1; 651f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov private static final int GAL_CONTACT = GAL_BASE + 2; 661f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov private static final int GAL_CONTACT_WITH_ID = GAL_BASE + 3; 67f6e831704c7df2b841760931469b1e995b957cd9Dmitri Plotnikov private static final int GAL_EMAIL_FILTER = GAL_BASE + 4; 685aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank 695aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH); 707307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank /*package*/ final HashMap<String, Long> mAccountIdMap = new HashMap<String, Long>(); 715aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank 725aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank static { 731f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov sURIMatcher.addURI(EXCHANGE_GAL_AUTHORITY, "directories", GAL_DIRECTORIES); 745aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank sURIMatcher.addURI(EXCHANGE_GAL_AUTHORITY, "contacts/filter/*", GAL_FILTER); 751f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov sURIMatcher.addURI(EXCHANGE_GAL_AUTHORITY, "contacts/lookup/*/entities", GAL_CONTACT); 76d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov sURIMatcher.addURI(EXCHANGE_GAL_AUTHORITY, "contacts/lookup/*/#/entities", 77d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov GAL_CONTACT_WITH_ID); 78f6e831704c7df2b841760931469b1e995b957cd9Dmitri Plotnikov sURIMatcher.addURI(EXCHANGE_GAL_AUTHORITY, "data/emails/filter/*", GAL_EMAIL_FILTER); 795aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } 805aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank 815aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank @Override 825aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank public boolean onCreate() { 835aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank return true; 845aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } 855aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank 86d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov static class GalProjection { 87d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov final int size; 88d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov final HashMap<String, Integer> columnMap = new HashMap<String, Integer>(); 89d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov 90d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov GalProjection(String[] projection) { 91d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov size = projection.length; 92d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov for (int i = 0; i < projection.length; i++) { 93d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov columnMap.put(projection[i], i); 94d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 95d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 96d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 97d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov 98d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov static class GalContactRow { 99d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov private final GalProjection mProjection; 100d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov private Object[] row; 101d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov static long dataId = 1; 102d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov 103d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov GalContactRow(GalProjection projection, long contactId, String lookupKey, 104d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov String accountName, String displayName) { 105d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov this.mProjection = projection; 106d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov row = new Object[projection.size]; 107d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov 108d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov put(Contacts.Entity.CONTACT_ID, contactId); 109d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov 110d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov // We only have one raw contact per aggregate, so they can have the same ID 111d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov put(Contacts.Entity.RAW_CONTACT_ID, contactId); 112d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov put(Contacts.Entity.DATA_ID, dataId++); 113d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov 114d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov put(Contacts.DISPLAY_NAME, displayName); 115d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov 116d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov // TODO alternative display name 117d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov put(Contacts.DISPLAY_NAME_ALTERNATIVE, displayName); 118d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov 119d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov put(RawContacts.ACCOUNT_TYPE, com.android.email.Email.EXCHANGE_ACCOUNT_MANAGER_TYPE); 120d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov put(RawContacts.ACCOUNT_NAME, accountName); 121d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov put(RawContacts.RAW_CONTACT_IS_READ_ONLY, 1); 122d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov put(Data.IS_READ_ONLY, 1); 123d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 124d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov 125d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov Object[] getRow () { 126d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov return row; 127d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 128d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov 129d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov void put(String columnName, Object value) { 130d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov Integer integer = mProjection.columnMap.get(columnName); 131d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov if (integer != null) { 132d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov row[integer] = value; 133d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } else { 134d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov System.out.println("Unsupported column: " + columnName); 135d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 136d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 137d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov 138d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov static void addEmailAddress(MatrixCursor cursor, GalProjection galProjection, 139d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov long contactId, String lookupKey, String accountName, String displayName, 140d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov String address) { 141d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov if (!TextUtils.isEmpty(address)) { 142d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov GalContactRow r = new GalContactRow( 143d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov galProjection, contactId, lookupKey, accountName, displayName); 144d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov r.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE); 145d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov r.put(Email.TYPE, Email.TYPE_WORK); 146d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov r.put(Email.ADDRESS, address); 147d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov cursor.addRow(r.getRow()); 148d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 149d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 150d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov 151d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov static void addPhoneRow(MatrixCursor cursor, GalProjection projection, long contactId, 152d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov String lookupKey, String accountName, String displayName, int type, String number) { 153d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov if (!TextUtils.isEmpty(number)) { 154d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov GalContactRow r = new GalContactRow( 155d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov projection, contactId, lookupKey, accountName, displayName); 156d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov r.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE); 157d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov r.put(Phone.TYPE, type); 158d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov r.put(Phone.NUMBER, number); 159d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov cursor.addRow(r.getRow()); 160d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 161d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 162d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov 163d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov public static void addNameRow(MatrixCursor cursor, GalProjection galProjection, 164d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov long contactId, String lookupKey, String accountName, String displayName, 165d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov String firstName, String lastName) { 166d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov GalContactRow r = new GalContactRow( 167d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov galProjection, contactId, lookupKey, accountName, displayName); 168d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov r.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE); 169d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov r.put(StructuredName.GIVEN_NAME, firstName); 170d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov r.put(StructuredName.FAMILY_NAME, lastName); 171d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov r.put(StructuredName.DISPLAY_NAME, displayName); 172d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov cursor.addRow(r.getRow()); 173d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 174d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 175d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov 1767307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank /** 1777307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank * Find the record id of an Account, given its name (email address) 1787307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank * @param accountName the name of the account 1797307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank * @return the record id of the Account, or -1 if not found 1807307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank */ 1817307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank /*package*/ long getAccountIdByName(Context context, String accountName) { 1827307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank Long accountId = mAccountIdMap.get(accountName); 1837307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank if (accountId == null) { 1847307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank accountId = Utility.getFirstRowLong(context, Account.CONTENT_URI, 1857307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank EmailContent.ID_PROJECTION, AccountColumns.EMAIL_ADDRESS + "=?", 1867307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank new String[] {accountName}, null, EmailContent.ID_PROJECTION_COLUMN , -1L); 1877307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank if (accountId != -1) { 1887307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank mAccountIdMap.put(accountName, accountId); 1897307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank } 1907307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank } 1917307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank return accountId; 1927307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank } 1937307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank 1945aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank @Override 1955aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 1965aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank String sortOrder) { 1975aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank int match = sURIMatcher.match(uri); 198d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov MatrixCursor cursor; 199d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov Object[] row; 200d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov PackedString ps; 201d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov String lookupKey; 202d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov 2035aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank switch (match) { 2041f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov case GAL_DIRECTORIES: { 2051f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov // Assuming that GAL can be used with all exchange accounts 2061f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov android.accounts.Account[] accounts = AccountManager.get(getContext()) 2071f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov .getAccountsByType(com.android.email.Email.EXCHANGE_ACCOUNT_MANAGER_TYPE); 2081f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov cursor = new MatrixCursor(projection); 2091f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov if (accounts != null) { 2101f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov for (android.accounts.Account account : accounts) { 2111f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov row = new Object[projection.length]; 2121f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov 2131f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov for (int i = 0; i < projection.length; i++) { 2141f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov String column = projection[i]; 2151f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov if (column.equals(Directory.ACCOUNT_NAME)) { 2161f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov row[i] = account.name; 2171f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov } else if (column.equals(Directory.ACCOUNT_TYPE)) { 2181f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov row[i] = account.type; 2191f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov } else if (column.equals(Directory.TYPE_RESOURCE_ID)) { 2201f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov if (VendorPolicyLoader.getInstance(getContext()) 2211f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov .useAlternateExchangeStrings()) { 2221f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov row[i] = R.string.exchange_name_alternate; 2231f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov } else { 2241f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov row[i] = R.string.exchange_name; 2251f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov } 2261f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov } else if (column.equals(Directory.DISPLAY_NAME)) { 2271f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov row[i] = account.name; 2281f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov } else if (column.equals(Directory.EXPORT_SUPPORT)) { 2291f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov row[i] = Directory.EXPORT_SUPPORT_SAME_ACCOUNT_ONLY; 2301f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov } else if (column.equals(Directory.SHORTCUT_SUPPORT)) { 2311f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov row[i] = Directory.SHORTCUT_SUPPORT_FULL; 2321f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov } 2331f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov } 2341f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov cursor.addRow(row); 2351f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov } 2361f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov } 2371f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov return cursor; 2381f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov } 2391f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov 240f6e831704c7df2b841760931469b1e995b957cd9Dmitri Plotnikov case GAL_FILTER: 241f6e831704c7df2b841760931469b1e995b957cd9Dmitri Plotnikov case GAL_EMAIL_FILTER: { 2425aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank String filter = uri.getLastPathSegment(); 2435aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank // We should have at least two characters before doing a GAL search 2445aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank if (filter == null || filter.length() < 2) { 2455aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank return null; 2465aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } 2471f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov 2481f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov String accountName = uri.getQueryParameter(RawContacts.ACCOUNT_NAME); 2491f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov if (accountName == null) { 2501f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov return null; 2511f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov } 2521f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov 253469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blank // Enforce a limit on the number of lookup responses 254469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blank String limitString = uri.getQueryParameter(ContactsContract.LIMIT_PARAM_KEY); 255469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blank int limit = DEFAULT_LOOKUP_LIMIT; 256469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blank if (limitString != null) { 257469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blank try { 258469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blank limit = Integer.parseInt(limitString); 259469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blank } catch (NumberFormatException e) { 260469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blank limit = 0; 261469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blank } 262469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blank if (limit <= 0) { 263469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blank throw new IllegalArgumentException("Limit not valid: " + limitString); 264469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blank } 265469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blank } 266469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blank 2675aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank long callingId = Binder.clearCallingIdentity(); 2685aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank try { 2697307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank // Find the account id to pass along to EasSyncService 2707307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank long accountId = getAccountIdByName(getContext(), accountName); 2717307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank if (accountId == -1) { 2727307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank // The account was deleted? 2737307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank return null; 2747307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank } 2757307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank 2765aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank // Get results from the Exchange account 2777307f7e5c2c4f85f6f3e0ebaf5775f65cba4b20cMarc Blank GalResult galResult = EasSyncService.searchGal(getContext(), accountId, 278469544cd1b9652c446c96b97f4abbdb65d7e06aaMarc Blank filter, limit); 2795aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank if (galResult != null) { 2805aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank return buildGalResultCursor(projection, galResult); 2815aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } 2825aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } finally { 2835aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank Binder.restoreCallingIdentity(callingId); 2845aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } 2855aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank break; 286d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 287d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov 288d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov case GAL_CONTACT: 289d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov case GAL_CONTACT_WITH_ID: { 2901f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov String accountName = uri.getQueryParameter(RawContacts.ACCOUNT_NAME); 2911f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov if (accountName == null) { 2921f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov return null; 2931f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov } 2941f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov 295d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov GalProjection galProjection = new GalProjection(projection); 296d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov cursor = new MatrixCursor(projection); 297d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov // Handle the decomposition of the key into rows suitable for CP2 2981f4b000ebe72fe9e71082031f48d0133914bda2dDmitri Plotnikov List<String> pathSegments = uri.getPathSegments(); 299d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov lookupKey = pathSegments.get(2); 300d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov long contactId = (match == GAL_CONTACT_WITH_ID) 301d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov ? Long.parseLong(pathSegments.get(3)) 302d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov : DEFAULT_CONTACT_ID; 303d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov ps = new PackedString(lookupKey); 304d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov String displayName = ps.get(GalData.DISPLAY_NAME); 305d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov GalContactRow.addEmailAddress(cursor, galProjection, contactId, lookupKey, 306d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov accountName, displayName, ps.get(GalData.EMAIL_ADDRESS)); 307d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov GalContactRow.addPhoneRow(cursor, galProjection, contactId, accountName, 308d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov displayName, displayName, Phone.TYPE_HOME, ps.get(GalData.HOME_PHONE)); 309d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov GalContactRow.addPhoneRow(cursor, galProjection, contactId, accountName, 310d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov displayName, displayName, Phone.TYPE_WORK, ps.get(GalData.WORK_PHONE)); 311d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov GalContactRow.addPhoneRow(cursor, galProjection, contactId, accountName, 312d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov displayName, displayName, Phone.TYPE_MOBILE, ps.get(GalData.MOBILE_PHONE)); 313d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov GalContactRow.addNameRow(cursor, galProjection, contactId, accountName, displayName, 314d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov ps.get(GalData.FIRST_NAME), ps.get(GalData.LAST_NAME), displayName); 315d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov return cursor; 316d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 3175aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } 3185aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank 3195aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank return null; 3205aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } 3215aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank 3225aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank /*package*/ Cursor buildGalResultCursor(String[] projection, GalResult galResult) { 3235aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank int displayNameIndex = -1; 324d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov int alternateDisplayNameIndex = -1;; 3255aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank int emailIndex = -1; 326d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov int idIndex = -1; 327d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov int lookupIndex = -1; 3285aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank 3295aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank for (int i = 0; i < projection.length; i++) { 3305aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank String column = projection[i]; 3315aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank if (Contacts.DISPLAY_NAME.equals(column) || 3325aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank Contacts.DISPLAY_NAME_PRIMARY.equals(column)) { 3335aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank displayNameIndex = i; 3345aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } else if (Contacts.DISPLAY_NAME_ALTERNATIVE.equals(column)) { 335d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov alternateDisplayNameIndex = i; 3365aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } else if (CommonDataKinds.Email.ADDRESS.equals(column)) { 3375aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank emailIndex = i; 338d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } else if (Contacts._ID.equals(column)) { 339d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov idIndex = i; 340d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } else if (Contacts.LOOKUP_KEY.equals(column)) { 341d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov lookupIndex = i; 3425aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } 3435aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } 3445aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank 3455aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank Object[] row = new Object[projection.length]; 3465aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank 3475aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank /* 3485aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank * ContactsProvider will ensure that every request has a non-null projection. 3495aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank */ 3505aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank MatrixCursor cursor = new MatrixCursor(projection); 3515aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank int count = galResult.galData.size(); 3525aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank for (int i = 0; i < count; i++) { 3535aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank GalData galDataRow = galResult.galData.get(i); 354d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov String firstName = galDataRow.get(GalData.FIRST_NAME); 355d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov String lastName = galDataRow.get(GalData.LAST_NAME); 356d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov String displayName = galDataRow.get(GalData.DISPLAY_NAME); 357d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov // If we don't have a display name, try to create one using first and last name 358d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov if (displayName == null) { 359d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov if (firstName != null && lastName != null) { 360d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov displayName = firstName + " " + lastName; 361d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } else if (firstName != null) { 362d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov displayName = firstName; 363d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } else if (lastName != null) { 364d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov displayName = lastName; 365d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 366d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 367d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov galDataRow.put(GalData.DISPLAY_NAME, displayName); 368d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov 3695aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank if (displayNameIndex != -1) { 370d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov row[displayNameIndex] = displayName; 371d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 372d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov if (alternateDisplayNameIndex != -1) { 373d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov // Try to create an alternate display name, using first and last name 374d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov // TODO: Check with Contacts team to make sure we're using this properly 375d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov if (firstName != null && lastName != null) { 376d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov row[alternateDisplayNameIndex] = lastName + " " + firstName; 377d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } else { 378d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov row[alternateDisplayNameIndex] = displayName; 379d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 3805aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } 3815aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank if (emailIndex != -1) { 382d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov row[emailIndex] = galDataRow.get(GalData.EMAIL_ADDRESS); 383d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 384d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov if (idIndex != -1) { 385d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov row[idIndex] = i + 1; // Let's be 1 based 386d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov } 387d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov if (lookupIndex != -1) { 388d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov // We use the packed string as our lookup key; it contains ALL of the gal data 389d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov // We do this because we are not able to provide a stable id to ContactsProvider 390d41eaba645dcb4573c5dc33077fc87799ef06195Dmitri Plotnikov row[lookupIndex] = Uri.encode(galDataRow.toPackedString()); 3915aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } 3925aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank cursor.addRow(row); 3935aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } 3945aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank return cursor; 3955aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } 3965aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank 3975aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank @Override 3985aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank public String getType(Uri uri) { 3995aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank int match = sURIMatcher.match(uri); 4005aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank switch (match) { 4015aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank case GAL_FILTER: 4025aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank return Contacts.CONTENT_ITEM_TYPE; 4035aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } 4045aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank return null; 4055aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } 4065aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank 4075aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank @Override 4085aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank public int delete(Uri uri, String selection, String[] selectionArgs) { 4095aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank throw new UnsupportedOperationException(); 4105aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } 4115aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank 4125aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank @Override 4135aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank public Uri insert(Uri uri, ContentValues values) { 4145aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank throw new UnsupportedOperationException(); 4155aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } 4165aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank 4175aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank @Override 4185aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 4195aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank throw new UnsupportedOperationException(); 4205aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank } 4215aec61dc15c62cff0cf55a3d6cb483f9e338230aMarc Blank} 422