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 package android.provider.cts.contacts; 17 18 import android.accounts.Account; 19 import android.accounts.AccountManager; 20 import android.content.ContentResolver; 21 import android.database.Cursor; 22 import android.database.DatabaseUtils; 23 import android.net.Uri; 24 import android.os.SystemClock; 25 import android.provider.ContactsContract; 26 import android.provider.ContactsContract.Contacts; 27 import android.provider.ContactsContract.Directory; 28 import android.provider.cts.contacts.DummyGalProvider; 29 import android.test.AndroidTestCase; 30 31 import org.json.JSONObject; 32 33 /** 34 * Note, this test creates an account in setUp() and removes it in tearDown(), which causes 35 * a churn in the contacts provider. So this class should have only one test method and do all 36 * the check in there, so it won't create the account multiple times. 37 */ 38 public class ContactsContract_DirectoryTest extends AndroidTestCase { 39 private ContentResolver mResolver; 40 private AccountManager mAccountManager; 41 private Account mAccount; 42 43 private static final int DIRECTORY_WAIT_TIMEOUT_SEC = 60; 44 45 @Override 46 protected void setUp() throws Exception { 47 super.setUp(); 48 49 mResolver = getContext().getContentResolver(); 50 51 mAccountManager = getContext().getSystemService(AccountManager.class); 52 mAccount = new Account(DummyGalProvider.ACCOUNT_NAME, DummyGalProvider.ACCOUNT_TYPE); 53 54 // The directory table is populated asynchronously. Wait for it... 55 waitForDirectorySetup(); 56 } 57 58 @Override 59 protected void tearDown() throws Exception { 60 mAccountManager.removeAccountExplicitly(mAccount); 61 62 super.tearDown(); 63 } 64 65 private static String getString(Cursor c, String column) { 66 return c.getString(c.getColumnIndex(column)); 67 } 68 69 /** 70 * Wait until the directory row is populated in the directory table, and return its ID. 71 */ 72 private long waitForDirectorySetup() throws Exception { 73 final long timeout = SystemClock.elapsedRealtime() + DIRECTORY_WAIT_TIMEOUT_SEC * 1000; 74 75 while (SystemClock.elapsedRealtime() < timeout) { 76 try (Cursor c = getContext().getContentResolver().query(Directory.CONTENT_URI, 77 null, Directory.ACCOUNT_NAME + "=? and " + Directory.ACCOUNT_TYPE + "=?", 78 new String[]{DummyGalProvider.ACCOUNT_NAME, DummyGalProvider.ACCOUNT_TYPE}, 79 null)) { 80 if (c.getCount() == 0) { 81 Thread.sleep(1000); 82 continue; 83 } 84 assertTrue(c.moveToPosition(0)); 85 assertEquals(getContext().getPackageName(), getString(c, Directory.PACKAGE_NAME)); 86 assertEquals(DummyGalProvider.AUTHORITY, 87 getString(c, Directory.DIRECTORY_AUTHORITY)); 88 assertEquals(DummyGalProvider.DISPLAY_NAME, getString(c, Directory.DISPLAY_NAME)); 89 assertEquals(DummyGalProvider.ACCOUNT_NAME, getString(c, Directory.ACCOUNT_NAME)); 90 assertEquals(DummyGalProvider.ACCOUNT_TYPE, getString(c, Directory.ACCOUNT_TYPE)); 91 return c.getLong(c.getColumnIndex(Directory._ID)); 92 } 93 } 94 fail("Directory didn't show up"); 95 return -1; 96 } 97 98 public void testQueryParameters() throws Exception { 99 // Test for content types. 100 assertEquals(Directory.CONTENT_TYPE, mResolver.getType(Directory.CONTENT_URI)); 101 assertEquals(Directory.CONTENT_ITEM_TYPE, mResolver.getType( 102 Directory.CONTENT_URI.buildUpon().appendPath("1").build())); 103 104 105 // Get the directory ID. 106 final long directoryId = waitForDirectorySetup(); 107 108 final Uri queryUri = Contacts.CONTENT_FILTER_URI.buildUpon() 109 .appendPath("[QUERY]") 110 .appendQueryParameter(ContactsContract.LIMIT_PARAM_KEY, "12") 111 .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, "" + directoryId) 112 113 // This should be ignored. 114 .appendQueryParameter(Directory.CALLER_PACKAGE_PARAM_KEY, "abcdef") 115 .build(); 116 117 try (Cursor c = getContext().getContentResolver().query( 118 queryUri, null, null, null, null)) { 119 120 DatabaseUtils.dumpCursor(c); 121 122 assertNotNull(c); 123 assertEquals(1, c.getCount()); 124 125 assertTrue(c.moveToPosition(0)); 126 127 // The result is stored in the display_name column. 128 final JSONObject result = new JSONObject(getString(c, Contacts.DISPLAY_NAME)); 129 130 if (result.has(DummyGalProvider.ERROR_MESSAGE_KEY)) { 131 fail(result.getString(DummyGalProvider.ERROR_MESSAGE_KEY)); 132 } 133 134 assertEquals("12", result.getString(DummyGalProvider.LIMIT_KEY)); 135 assertEquals("[QUERY]", result.getString(DummyGalProvider.QUERY_KEY)); 136 assertEquals(getContext().getPackageName(), 137 result.getString(DummyGalProvider.CALLER_PACKAGE_NAME_KEY)); 138 } 139 } 140 } 141