Home | History | Annotate | Download | only in contacts
      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 android.provider.cts.contacts;
     18 
     19 import android.content.ContentProvider;
     20 import android.content.ContentValues;
     21 import android.content.UriMatcher;
     22 import android.database.Cursor;
     23 import android.database.MatrixCursor;
     24 import android.net.Uri;
     25 import android.provider.ContactsContract;
     26 import android.provider.ContactsContract.Contacts;
     27 import android.provider.ContactsContract.Directory;
     28 import android.provider.ContactsContract.RawContacts;
     29 import android.provider.cts.contacts.account.StaticAccountAuthenticator;
     30 import android.text.TextUtils;
     31 import android.util.Log;
     32 
     33 import org.json.JSONException;
     34 import org.json.JSONObject;
     35 
     36 /**
     37  * GAL provider for CTS.
     38  */
     39 public class DummyGalProvider extends ContentProvider {
     40     private static final String TAG = "DummyGalProvider";
     41 
     42     public static final String AUTHORITY = "android.provider.cts.contacts.dgp";
     43 
     44     public static final String ACCOUNT_NAME = "dummygal";
     45     public static final String ACCOUNT_TYPE = StaticAccountAuthenticator.TYPE;
     46 
     47     public static final String DISPLAY_NAME = "dummy-gal";
     48 
     49     public static final String ERROR_MESSAGE_KEY = "error";
     50     public static final String QUERY_KEY = "query";
     51     public static final String CALLER_PACKAGE_NAME_KEY = "package_name";
     52     public static final String LIMIT_KEY = "limit";
     53 
     54 
     55     private static final int GAL_DIRECTORIES = 0;
     56     private static final int GAL_FILTER = 1;
     57     private static final int GAL_CONTACT = 2;
     58     private static final int GAL_CONTACT_WITH_ID = 3;
     59     private static final int GAL_EMAIL_FILTER = 4;
     60     private static final int GAL_PHONE_FILTER = 5;
     61     private static final int GAL_PHONE_LOOKUP = 6;
     62 
     63     private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
     64 
     65     static {
     66         sURIMatcher.addURI(AUTHORITY, "directories", GAL_DIRECTORIES);
     67         sURIMatcher.addURI(AUTHORITY, "contacts/filter/*", GAL_FILTER);
     68         // The following URIs are not supported by this class.
     69 //        sURIMatcher.addURI(AUTHORITY, "contacts/lookup/*/entities", GAL_CONTACT);
     70 //        sURIMatcher.addURI(AUTHORITY, "contacts/lookup/*/#/entities", GAL_CONTACT_WITH_ID);
     71 //        sURIMatcher.addURI(AUTHORITY, "data/emails/filter/*", GAL_EMAIL_FILTER);
     72 //        sURIMatcher.addURI(AUTHORITY, "data/phones/filter/*", GAL_PHONE_FILTER);
     73 //        sURIMatcher.addURI(AUTHORITY, "phone_lookup/*", GAL_PHONE_LOOKUP);
     74     }
     75 
     76     @Override
     77     public boolean onCreate() {
     78         return true;
     79     }
     80 
     81     @Override
     82     public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
     83             String sortOrder) {
     84         Log.d(TAG, "uri: " + uri);
     85         final int match = sURIMatcher.match(uri);
     86 
     87         switch (match) {
     88             case GAL_DIRECTORIES: {
     89                 return handleDirectories(projection);
     90             }
     91             case GAL_FILTER: {
     92                 try {
     93                     return handleFilter(uri, projection);
     94                 } catch (JSONException e) {
     95                     Log.e(TAG, "Caught exception", e);
     96                     return null;
     97                 }
     98             }
     99         }
    100         return null;
    101     }
    102 
    103     @Override
    104     public String getType(Uri uri) {
    105         return null;
    106     }
    107 
    108     @Override
    109     public Uri insert(Uri uri, ContentValues values) {
    110         return null;
    111     }
    112 
    113     @Override
    114     public int delete(Uri uri, String selection, String[] selectionArgs) {
    115         return 0;
    116     }
    117 
    118     @Override
    119     public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    120         return 0;
    121     }
    122 
    123     /**
    124      * Build a cursor containing the directory information.
    125      *
    126      * See com.android.providers.contacts.ContactDirectoryManager.
    127      */
    128     private Cursor handleDirectories(String[] projection) {
    129         MatrixCursor cursor;
    130         Object[] row;
    131         cursor = new MatrixCursor(projection);
    132 
    133         row = new Object[projection.length];
    134 
    135         for (int i = 0; i < projection.length; i++) {
    136             String column = projection[i];
    137             if (column.equals(Directory.ACCOUNT_NAME)) {
    138                 row[i] = ACCOUNT_NAME;
    139             } else if (column.equals(Directory.ACCOUNT_TYPE)) {
    140                 row[i] = ACCOUNT_TYPE;
    141             } else if (column.equals(Directory.TYPE_RESOURCE_ID)) {
    142                 row[i] = "";
    143             } else if (column.equals(Directory.DISPLAY_NAME)) {
    144                 row[i] = DISPLAY_NAME;
    145             } else if (column.equals(Directory.EXPORT_SUPPORT)) {
    146                 row[i] = Directory.EXPORT_SUPPORT_NONE;
    147             } else if (column.equals(Directory.SHORTCUT_SUPPORT)) {
    148                 row[i] = Directory.SHORTCUT_SUPPORT_NONE;
    149             } else if (column.equals(Directory.PHOTO_SUPPORT)) {
    150                 row[i] = Directory.PHOTO_SUPPORT_NONE;
    151             }
    152         }
    153         cursor.addRow(row);
    154         return cursor;
    155     }
    156 
    157     /**
    158      * Build a cursor to return from the {@link #GAL_FILTER} URI, which returns the following
    159      * information in the display_name column as json.
    160      *
    161      * - It checks whether the incoming account name/type match the values returned by {@link
    162      * #handleDirectories(String[])}, and if not, set a error message to the result.
    163      * - If above check succeeds, then sets the query parameters in the result.  The caller
    164      * checks the returned values.
    165      */
    166     private Cursor handleFilter(Uri uri, String[] projection) throws JSONException {
    167         final String accountName = uri.getQueryParameter(RawContacts.ACCOUNT_NAME);
    168         final String accountType = uri.getQueryParameter(RawContacts.ACCOUNT_TYPE);
    169         final String limit = uri.getQueryParameter(ContactsContract.LIMIT_PARAM_KEY);
    170         final String callerPackage = uri.getQueryParameter(Directory.CALLER_PACKAGE_PARAM_KEY);
    171 
    172         final JSONObject result = new JSONObject();
    173 
    174         final StringBuilder error = new StringBuilder();
    175         if (!ACCOUNT_NAME.equals(accountName)) {
    176             error.append(String.format("Account name expected=%s but was %s\n",
    177                     ACCOUNT_NAME, accountName));
    178         }
    179         if (!ACCOUNT_TYPE.equals(accountType)) {
    180             error.append(String.format("Account type expected=%s but was %s\n",
    181                     ACCOUNT_TYPE, accountType));
    182         }
    183 
    184         if (error.length() > 0) {
    185             result.put(ERROR_MESSAGE_KEY, error.toString());
    186         } else {
    187             if (!TextUtils.isEmpty(limit)) {
    188                 result.put(LIMIT_KEY, limit);
    189             }
    190             if (!TextUtils.isEmpty(callerPackage)) {
    191                 result.put(CALLER_PACKAGE_NAME_KEY, callerPackage);
    192             }
    193             result.put(QUERY_KEY, uri.getLastPathSegment());
    194         }
    195         if (projection == null) {
    196             projection = new String[]{Contacts.DISPLAY_NAME};
    197         }
    198 
    199         final MatrixCursor c = new MatrixCursor(projection);
    200 
    201         Object[] row = new Object[projection.length];
    202         for (int i = 0; i < projection.length; i++) {
    203             String column = projection[i];
    204             if (Contacts.DISPLAY_NAME.equals(column)) {
    205                 row[i] = result.toString();
    206                 continue;
    207             }
    208             // All other fields are null.
    209         }
    210 
    211         c.addRow(row);
    212         return c;
    213     }
    214 }
    215