1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * 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, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 
17 package android.content.cts;
18 
19 import android.content.ContentProvider;
20 import android.content.ContentResolver;
21 import android.content.ContentValues;
22 import android.content.Context;
23 import android.content.pm.ProviderInfo;
24 import android.database.Cursor;
25 import android.database.sqlite.SQLiteDatabase;
26 import android.net.Uri;
27 import android.os.ParcelFileDescriptor;
28 import android.test.AndroidTestCase;
29 
30 import android.content.cts.R;
31 
32 import java.io.File;
33 import java.io.FileNotFoundException;
34 import java.io.IOException;
35 
36 /**
37  * Test {@link ContentProvider}.
38  */
39 public class ContentProviderTest extends AndroidTestCase {
40     private static final String TEST_PACKAGE_NAME = "android.content.cts";
41     private static final String TEST_FILE_NAME = "testFile.tmp";
42     private static final String TEST_DB_NAME = "test.db";
43 
44     @Override
tearDown()45     protected void tearDown() throws Exception {
46         mContext.deleteDatabase(TEST_DB_NAME);
47         mContext.deleteFile(TEST_FILE_NAME);
48         super.tearDown();
49     }
50 
testOpenAssetFile()51     public void testOpenAssetFile() throws IOException {
52         MockContentProvider mockContentProvider = new MockContentProvider();
53         Uri uri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE +
54                 "://" + TEST_PACKAGE_NAME + "/" + R.raw.testimage);
55 
56         try {
57             mockContentProvider.openAssetFile(uri, "r");
58             fail("Should always throw out FileNotFoundException!");
59         } catch (FileNotFoundException e) {
60         }
61 
62         try {
63             mockContentProvider.openFile(null, null);
64             fail("Should always throw out FileNotFoundException!");
65         } catch (FileNotFoundException e) {
66         }
67     }
68 
testAttachInfo()69     public void testAttachInfo() {
70         MockContentProvider mockContentProvider = new MockContentProvider();
71 
72         ProviderInfo info1 = new ProviderInfo();
73         info1.readPermission = "android.permission.READ_SMS";
74         info1.writePermission = null; // Guarded by an app op not a permission.
75         mockContentProvider.attachInfo(getContext(), info1);
76         assertSame(getContext(), mockContentProvider.getContext());
77         assertEquals(info1.readPermission, mockContentProvider.getReadPermission());
78         assertEquals(info1.writePermission, mockContentProvider.getWritePermission());
79 
80         ProviderInfo info2 = new ProviderInfo();
81         info2.readPermission = "android.permission.READ_CONTACTS";
82         info2.writePermission = "android.permission.WRITE_CONTACTS";
83         mockContentProvider.attachInfo(null, info2);
84         assertSame(getContext(), mockContentProvider.getContext());
85         assertEquals(info1.readPermission, mockContentProvider.getReadPermission());
86         assertEquals(info1.writePermission, mockContentProvider.getWritePermission());
87 
88         mockContentProvider = new MockContentProvider();
89         mockContentProvider.attachInfo(null, null);
90         assertNull(mockContentProvider.getContext());
91         assertNull(mockContentProvider.getReadPermission());
92         assertNull(mockContentProvider.getWritePermission());
93 
94         mockContentProvider.attachInfo(null, info2);
95         assertNull(mockContentProvider.getContext());
96         assertEquals(info2.readPermission, mockContentProvider.getReadPermission());
97         assertEquals(info2.writePermission, mockContentProvider.getWritePermission());
98 
99         mockContentProvider.attachInfo(getContext(), info1);
100         assertSame(getContext(), mockContentProvider.getContext());
101         assertEquals(info1.readPermission, mockContentProvider.getReadPermission());
102         assertEquals(info1.writePermission, mockContentProvider.getWritePermission());
103     }
104 
testBulkInsert()105     public void testBulkInsert() {
106         MockContentProvider mockContentProvider = new MockContentProvider();
107 
108         int count = 2;
109         ContentValues[] values = new ContentValues[count];
110         for (int i = 0; i < count; i++) {
111             values[i] = new ContentValues();
112         }
113         Uri uri = Uri.parse("content://browser/bookmarks");
114         assertEquals(count, mockContentProvider.bulkInsert(uri, values));
115         assertEquals(count, mockContentProvider.getInsertCount());
116 
117         mockContentProvider = new MockContentProvider();
118         try {
119             assertEquals(count, mockContentProvider.bulkInsert(null, values));
120         } finally {
121             assertEquals(count, mockContentProvider.getInsertCount());
122         }
123     }
124 
testGetContext()125     public void testGetContext() {
126         MockContentProvider mockContentProvider = new MockContentProvider();
127         assertNull(mockContentProvider.getContext());
128 
129         mockContentProvider.attachInfo(getContext(), null);
130         assertSame(getContext(), mockContentProvider.getContext());
131         mockContentProvider.attachInfo(null, null);
132         assertSame(getContext(), mockContentProvider.getContext());
133     }
134 
testAccessReadPermission()135     public void testAccessReadPermission() {
136         MockContentProvider mockContentProvider = new MockContentProvider();
137         assertNull(mockContentProvider.getReadPermission());
138 
139         String expected = "android.permission.READ_CONTACTS";
140         mockContentProvider.setReadPermissionWrapper(expected);
141         assertEquals(expected, mockContentProvider.getReadPermission());
142 
143         expected = "android.permission.READ_SMS";
144         mockContentProvider.setReadPermissionWrapper(expected);
145         assertEquals(expected, mockContentProvider.getReadPermission());
146 
147         mockContentProvider.setReadPermissionWrapper(null);
148         assertNull(mockContentProvider.getReadPermission());
149     }
150 
testAccessWritePermission()151     public void testAccessWritePermission() {
152         MockContentProvider mockContentProvider = new MockContentProvider();
153         assertNull(mockContentProvider.getWritePermission());
154 
155         String expected = "android.permission.WRITE_CONTACTS";
156         mockContentProvider.setWritePermissionWrapper(expected);
157         assertEquals(expected, mockContentProvider.getWritePermission());
158 
159         mockContentProvider.setWritePermissionWrapper(null);
160         assertNull(mockContentProvider.getWritePermission());
161     }
162 
testIsTemporary()163     public void testIsTemporary() {
164         MockContentProvider mockContentProvider = new MockContentProvider();
165         assertFalse(mockContentProvider.isTemporary());
166     }
167 
testOpenFile()168     public void testOpenFile() {
169         MockContentProvider mockContentProvider = new MockContentProvider();
170 
171         try {
172             Uri uri = Uri.parse("content://test");
173             mockContentProvider.openFile(uri, "r");
174             fail("Should always throw out FileNotFoundException!");
175         } catch (FileNotFoundException e) {
176         }
177 
178         try {
179             mockContentProvider.openFile(null, null);
180             fail("Should always throw out FileNotFoundException!");
181         } catch (FileNotFoundException e) {
182         }
183     }
184 
testOpenFileHelper()185     public void testOpenFileHelper() throws IOException {
186 
187         // create a temporary File
188         mContext.openFileOutput(TEST_FILE_NAME, Context.MODE_PRIVATE).close();
189         File file = mContext.getFileStreamPath(TEST_FILE_NAME);
190         assertTrue(file.exists());
191 
192         ContentProvider cp = new OpenFileContentProvider(file.getAbsolutePath(), TEST_DB_NAME);
193 
194         Uri uri = Uri.parse("content://test");
195         assertNotNull(cp.openFile(uri, "r"));
196 
197         try {
198             uri = Uri.parse("content://test");
199             cp.openFile(uri, "wrong");
200             fail("Should throw IllegalArgumentException for bad mode!");
201         } catch (IllegalArgumentException e) {
202         }
203 
204         // delete the temporary file
205         file.delete();
206 
207         try {
208             uri = Uri.parse("content://test");
209             cp.openFile(uri, "r");
210             fail("Should throw FileNotFoundException!");
211         } catch (FileNotFoundException e) {
212         }
213 
214         try {
215             cp.openFile((Uri) null, "r");
216             fail("Should always throw FileNotFoundException!");
217         } catch (FileNotFoundException e) {
218         }
219     }
220 
testOnConfigurationChanged()221     public void testOnConfigurationChanged() {
222         // cannot trigger this callback reliably
223     }
224 
testOnLowMemory()225     public void testOnLowMemory() {
226         // cannot trigger this callback reliably
227     }
228 
testGetIContentProvider()229     public void testGetIContentProvider() {
230         MockContentProvider mockContentProvider = new MockContentProvider();
231 
232         assertNotNull(mockContentProvider.getIContentProvider());
233     }
234 
235     private class MockContentProvider extends ContentProvider {
236         private int mInsertCount = 0;
237 
238         @Override
delete(Uri uri, String selection, String[] selectionArgs)239         public int delete(Uri uri, String selection, String[] selectionArgs) {
240             return 0;
241         }
242 
243         @Override
getType(Uri uri)244         public String getType(Uri uri) {
245             return null;
246         }
247 
248         @Override
insert(Uri uri, ContentValues values)249         public Uri insert(Uri uri, ContentValues values) {
250             mInsertCount++;
251             return null;
252         }
253 
getInsertCount()254         public int getInsertCount() {
255             return mInsertCount;
256         }
257 
258         @Override
query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)259         public Cursor query(Uri uri, String[] projection, String selection,
260                 String[] selectionArgs, String sortOrder) {
261             return null;
262         }
263 
264         @Override
update(Uri uri, ContentValues values, String selection, String[] selectionArgs)265         public int update(Uri uri, ContentValues values, String selection,
266                 String[] selectionArgs) {
267             return 0;
268         }
269 
270         @Override
onCreate()271         public boolean onCreate() {
272             return false;
273         }
274 
275         // wrapper or override for the protected methods
setReadPermissionWrapper(String permission)276         public void setReadPermissionWrapper(String permission) {
277             super.setReadPermission(permission);
278         }
279 
setWritePermissionWrapper(String permission)280         public void setWritePermissionWrapper(String permission) {
281             super.setWritePermission(permission);
282         }
283 
284         @Override
isTemporary()285         protected boolean isTemporary() {
286             return super.isTemporary();
287         }
288 
openFileHelperWrapper(Uri uri, String mode)289         public ParcelFileDescriptor openFileHelperWrapper(Uri uri, String mode)
290                 throws FileNotFoundException {
291             return super.openFileHelper(uri, mode);
292         }
293     }
294 
295     /**
296      * This provider implements openFile() using ContentProvider.openFileHelper().
297      */
298     private class OpenFileContentProvider extends ContentProvider {
299         private SQLiteDatabase mDb;
300 
OpenFileContentProvider(String fileName, String dbName)301         OpenFileContentProvider(String fileName, String dbName) {
302             // delete the database if it already exists
303             mContext.deleteDatabase(dbName);
304             mDb = mContext.openOrCreateDatabase(dbName, Context.MODE_PRIVATE, null);
305             mDb.execSQL("CREATE TABLE files ( _data TEXT );");
306             mDb.execSQL("INSERT INTO files VALUES ( \"" + fileName + "\");");
307         }
308 
309         @Override
delete(Uri uri, String selection, String[] selectionArgs)310         public int delete(Uri uri, String selection, String[] selectionArgs) {
311             throw new RuntimeException("not implemented");
312         }
313 
314         @Override
getType(Uri uri)315         public String getType(Uri uri) {
316             throw new RuntimeException("not implemented");
317         }
318 
319         @Override
insert(Uri uri, ContentValues values)320         public Uri insert(Uri uri, ContentValues values) {
321             throw new RuntimeException("not implemented");
322         }
323 
324         @Override
onCreate()325         public boolean onCreate() {
326             return true;
327         }
328 
329         @Override
query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)330         public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
331                 String sortOrder) {
332             return mDb.query("files", projection, selection, selectionArgs, null, null, null);
333         }
334 
335         @Override
update(Uri uri, ContentValues values, String selection, String[] selectionArgs)336         public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
337             throw new RuntimeException("not implemented");
338         }
339 
340         @Override
openFile(Uri uri, String mode)341         public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
342             return openFileHelper(uri, mode);
343         }
344     }
345 }
346