12ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian/* 22ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 32ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian* Copyright (C) 2017 The Android Open Source Project 42ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian* 52ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian* Licensed under the Apache License, Version 2.0 (the "License"); 62ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian* you may not use this file except in compliance with the License. 72ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian* You may obtain a copy of the License at 82ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian* 92ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian* http://www.apache.org/licenses/LICENSE-2.0 102ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian* 112ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian* Unless required by applicable law or agreed to in writing, software 122ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian* distributed under the License is distributed on an "AS IS" BASIS, 132ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 142ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian* See the License for the specific language governing permissions and 152ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian* limitations under the License 162ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian*/ 172ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 18a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuhpackage com.android.dialer.searchfragment.directories; 192ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 202ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport android.content.Context; 212ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport android.content.CursorLoader; 222ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport android.database.Cursor; 232ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport android.net.Uri; 242ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport android.os.Build.VERSION; 252ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport android.os.Build.VERSION_CODES; 262ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport android.provider.ContactsContract; 272ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport android.support.annotation.Nullable; 28aa8a26e9cd6d4c355f32516bbbf8361b32d8772bcalderwoodraimport com.android.dialer.common.LogUtil; 29aa8a26e9cd6d4c355f32516bbbf8361b32d8772bcalderwoodraimport com.android.dialer.util.PermissionsUtil; 302ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport com.google.auto.value.AutoValue; 31a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuhimport java.util.ArrayList; 32a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuhimport java.util.List; 332ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 34844dcad13ad494256dddfdc44f7ad90a5f93c530linyuh/** 35844dcad13ad494256dddfdc44f7ad90a5f93c530linyuh * {@link CursorLoader} to load information about all directories (local and remote). 36844dcad13ad494256dddfdc44f7ad90a5f93c530linyuh * 37844dcad13ad494256dddfdc44f7ad90a5f93c530linyuh * <p>Information about a directory includes its ID, display name, etc, but doesn't include the 38844dcad13ad494256dddfdc44f7ad90a5f93c530linyuh * contacts in it. 39844dcad13ad494256dddfdc44f7ad90a5f93c530linyuh */ 40a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuhpublic final class DirectoriesCursorLoader extends CursorLoader { 412ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 42a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh public static final String[] PROJECTION = { 432ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian ContactsContract.Directory._ID, 442ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian ContactsContract.Directory.DISPLAY_NAME, 452ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian ContactsContract.Directory.PHOTO_SUPPORT, 462ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian }; 472ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 48a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh // Indices of columns in PROJECTION 49a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh private static final int ID = 0; 50a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh private static final int DISPLAY_NAME = 1; 51a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh private static final int PHOTO_SUPPORT = 2; 52a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh 53a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh public DirectoriesCursorLoader(Context context) { 542ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian super(context, getContentUri(), PROJECTION, null, null, ContactsContract.Directory._ID); 552ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian } 562ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 57aa8a26e9cd6d4c355f32516bbbf8361b32d8772bcalderwoodra @Override 58aa8a26e9cd6d4c355f32516bbbf8361b32d8772bcalderwoodra public Cursor loadInBackground() { 59aa8a26e9cd6d4c355f32516bbbf8361b32d8772bcalderwoodra if (!PermissionsUtil.hasContactsReadPermissions(getContext())) { 60aa8a26e9cd6d4c355f32516bbbf8361b32d8772bcalderwoodra LogUtil.i("DirectoriesCursorLoader.loadInBackground", "Contacts permission denied."); 61aa8a26e9cd6d4c355f32516bbbf8361b32d8772bcalderwoodra return null; 62aa8a26e9cd6d4c355f32516bbbf8361b32d8772bcalderwoodra } 63aa8a26e9cd6d4c355f32516bbbf8361b32d8772bcalderwoodra return super.loadInBackground(); 64aa8a26e9cd6d4c355f32516bbbf8361b32d8772bcalderwoodra } 65aa8a26e9cd6d4c355f32516bbbf8361b32d8772bcalderwoodra 66a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh /** 67a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh * Creates a complete list of directories from the data set loaded by this loader. 68a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh * 69a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh * @param cursor A cursor pointing to the data set loaded by this loader. The caller must ensure 70a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh * the cursor is not null. 71a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh * @return A list of directories. 72a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh */ 73a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh public static List<Directory> toDirectories(Cursor cursor) { 74dd52b39fffa8da6f70a5f7608fddae6825aec370calderwoodra if (cursor == null) { 75dd52b39fffa8da6f70a5f7608fddae6825aec370calderwoodra LogUtil.i("DirectoriesCursorLoader.toDirectories", "Cursor was null"); 76dd52b39fffa8da6f70a5f7608fddae6825aec370calderwoodra return new ArrayList<>(); 77dd52b39fffa8da6f70a5f7608fddae6825aec370calderwoodra } 78dd52b39fffa8da6f70a5f7608fddae6825aec370calderwoodra 79a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh List<Directory> directories = new ArrayList<>(); 80a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh cursor.moveToPosition(-1); 81a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh while (cursor.moveToNext()) { 82a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh directories.add( 83a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh Directory.create( 84a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh cursor.getInt(ID), 85a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh cursor.getString(DISPLAY_NAME), 86a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh /* supportsPhotos = */ cursor.getInt(PHOTO_SUPPORT) != 0)); 87a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh } 88a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh return directories; 892ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian } 902ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 912ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian private static Uri getContentUri() { 922ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian return VERSION.SDK_INT >= VERSION_CODES.N 932ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian ? ContactsContract.Directory.ENTERPRISE_CONTENT_URI 942ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian : ContactsContract.Directory.CONTENT_URI; 952ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian } 962ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 97a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh /** POJO representing the results returned from {@link DirectoriesCursorLoader}. */ 982ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian @AutoValue 992ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian public abstract static class Directory { 100a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh public static Directory create(long id, @Nullable String displayName, boolean supportsPhotos) { 101a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh return new AutoValue_DirectoriesCursorLoader_Directory(id, displayName, supportsPhotos); 1022ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian } 1032ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 104a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh public abstract long getId(); 1052ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 1062ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian /** Returns a user facing display name of the directory. Null if none exists. */ 107a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh public abstract @Nullable String getDisplayName(); 1082ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 109a6523ddb1db3d456ba4d16a120dea1ccd6c72d24linyuh public abstract boolean supportsPhotos(); 1102ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian } 1112ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian} 112