diff options
Diffstat (limited to 'java/com/android/contacts/common/list/DirectoryListLoader.java')
-rw-r--r-- | java/com/android/contacts/common/list/DirectoryListLoader.java | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/java/com/android/contacts/common/list/DirectoryListLoader.java b/java/com/android/contacts/common/list/DirectoryListLoader.java new file mode 100644 index 000000000..48b098c07 --- /dev/null +++ b/java/com/android/contacts/common/list/DirectoryListLoader.java @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.contacts.common.list; + +import android.content.AsyncTaskLoader; +import android.content.Context; +import android.content.pm.PackageManager; +import android.database.ContentObserver; +import android.database.Cursor; +import android.database.MatrixCursor; +import android.net.Uri; +import android.os.Handler; +import android.provider.ContactsContract.Directory; +import android.text.TextUtils; +import android.util.Log; +import com.android.contacts.common.R; +import com.android.contacts.common.compat.DirectoryCompat; + +/** A specialized loader for the list of directories, see {@link Directory}. */ +public class DirectoryListLoader extends AsyncTaskLoader<Cursor> { + + public static final int SEARCH_MODE_NONE = 0; + public static final int SEARCH_MODE_DEFAULT = 1; + public static final int SEARCH_MODE_CONTACT_SHORTCUT = 2; + public static final int SEARCH_MODE_DATA_SHORTCUT = 3; + // This is a virtual column created for a MatrixCursor. + public static final String DIRECTORY_TYPE = "directoryType"; + private static final String TAG = "ContactEntryListAdapter"; + private static final String[] RESULT_PROJECTION = { + Directory._ID, DIRECTORY_TYPE, Directory.DISPLAY_NAME, Directory.PHOTO_SUPPORT, + }; + private final ContentObserver mObserver = + new ContentObserver(new Handler()) { + @Override + public void onChange(boolean selfChange) { + forceLoad(); + } + }; + private int mDirectorySearchMode; + private boolean mLocalInvisibleDirectoryEnabled; + private MatrixCursor mDefaultDirectoryList; + + public DirectoryListLoader(Context context) { + super(context); + } + + public void setDirectorySearchMode(int mode) { + mDirectorySearchMode = mode; + } + + /** + * A flag that indicates whether the {@link Directory#LOCAL_INVISIBLE} directory should be + * included in the results. + */ + public void setLocalInvisibleDirectoryEnabled(boolean flag) { + this.mLocalInvisibleDirectoryEnabled = flag; + } + + @Override + protected void onStartLoading() { + getContext().getContentResolver().registerContentObserver(DirectoryQuery.URI, false, mObserver); + forceLoad(); + } + + @Override + protected void onStopLoading() { + getContext().getContentResolver().unregisterContentObserver(mObserver); + } + + @Override + public Cursor loadInBackground() { + if (mDirectorySearchMode == SEARCH_MODE_NONE) { + return getDefaultDirectories(); + } + + MatrixCursor result = new MatrixCursor(RESULT_PROJECTION); + Context context = getContext(); + PackageManager pm = context.getPackageManager(); + String selection; + switch (mDirectorySearchMode) { + case SEARCH_MODE_DEFAULT: + selection = null; + break; + + case SEARCH_MODE_CONTACT_SHORTCUT: + selection = Directory.SHORTCUT_SUPPORT + "=" + Directory.SHORTCUT_SUPPORT_FULL; + break; + + case SEARCH_MODE_DATA_SHORTCUT: + selection = + Directory.SHORTCUT_SUPPORT + + " IN (" + + Directory.SHORTCUT_SUPPORT_FULL + + ", " + + Directory.SHORTCUT_SUPPORT_DATA_ITEMS_ONLY + + ")"; + break; + + default: + throw new RuntimeException("Unsupported directory search mode: " + mDirectorySearchMode); + } + Cursor cursor = null; + try { + cursor = + context + .getContentResolver() + .query( + DirectoryQuery.URI, + DirectoryQuery.PROJECTION, + selection, + null, + DirectoryQuery.ORDER_BY); + + if (cursor == null) { + return result; + } + + while (cursor.moveToNext()) { + long directoryId = cursor.getLong(DirectoryQuery.ID); + if (!mLocalInvisibleDirectoryEnabled && DirectoryCompat.isInvisibleDirectory(directoryId)) { + continue; + } + String directoryType = null; + + String packageName = cursor.getString(DirectoryQuery.PACKAGE_NAME); + int typeResourceId = cursor.getInt(DirectoryQuery.TYPE_RESOURCE_ID); + if (!TextUtils.isEmpty(packageName) && typeResourceId != 0) { + try { + directoryType = pm.getResourcesForApplication(packageName).getString(typeResourceId); + } catch (Exception e) { + Log.e(TAG, "Cannot obtain directory type from package: " + packageName); + } + } + String displayName = cursor.getString(DirectoryQuery.DISPLAY_NAME); + int photoSupport = cursor.getInt(DirectoryQuery.PHOTO_SUPPORT); + result.addRow(new Object[] {directoryId, directoryType, displayName, photoSupport}); + } + } catch (RuntimeException e) { + Log.w(TAG, "Runtime Exception when querying directory"); + } finally { + if (cursor != null) { + cursor.close(); + } + } + + return result; + } + + private Cursor getDefaultDirectories() { + if (mDefaultDirectoryList == null) { + mDefaultDirectoryList = new MatrixCursor(RESULT_PROJECTION); + mDefaultDirectoryList.addRow( + new Object[] {Directory.DEFAULT, getContext().getString(R.string.contactsList), null}); + mDefaultDirectoryList.addRow( + new Object[] { + Directory.LOCAL_INVISIBLE, + getContext().getString(R.string.local_invisible_directory), + null + }); + } + return mDefaultDirectoryList; + } + + @Override + protected void onReset() { + stopLoading(); + } + + private static final class DirectoryQuery { + + public static final Uri URI = DirectoryCompat.getContentUri(); + public static final String ORDER_BY = Directory._ID; + + public static final String[] PROJECTION = { + Directory._ID, + Directory.PACKAGE_NAME, + Directory.TYPE_RESOURCE_ID, + Directory.DISPLAY_NAME, + Directory.PHOTO_SUPPORT, + }; + + public static final int ID = 0; + public static final int PACKAGE_NAME = 1; + public static final int TYPE_RESOURCE_ID = 2; + public static final int DISPLAY_NAME = 3; + public static final int PHOTO_SUPPORT = 4; + } +} |