1 /*
2  * Copyright (C) 2019 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.content.cts;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNotNull;
21 import static org.junit.Assert.fail;
22 import static org.mockito.ArgumentMatchers.any;
23 import static org.mockito.ArgumentMatchers.eq;
24 import static org.mockito.Mockito.CALLS_REAL_METHODS;
25 import static org.mockito.Mockito.RETURNS_DEFAULTS;
26 import static org.mockito.Mockito.doReturn;
27 import static org.mockito.Mockito.mock;
28 
29 import android.content.ContentProvider;
30 import android.content.ContentProviderOperation;
31 import android.content.ContentProviderResult;
32 import android.content.ContentResolver;
33 import android.content.ContentValues;
34 import android.content.Context;
35 import android.content.pm.ProviderInfo;
36 import android.content.res.AssetFileDescriptor;
37 import android.database.Cursor;
38 import android.database.MatrixCursor;
39 import android.net.Uri;
40 import android.os.Bundle;
41 import android.os.CancellationSignal;
42 import android.os.ParcelFileDescriptor;
43 import android.util.Size;
44 
45 import androidx.test.runner.AndroidJUnit4;
46 
47 import org.junit.Before;
48 import org.junit.Test;
49 import org.junit.runner.RunWith;
50 
51 import java.io.File;
52 import java.io.IOException;
53 import java.util.ArrayList;
54 
55 @RunWith(AndroidJUnit4.class)
56 public class ContentResolverWrapTest {
57     private static final String AUTHORITY = "com.example";
58     private static final Uri URI = Uri.parse("content://" + AUTHORITY);
59     private static final ArrayList<ContentProviderOperation> OPERATIONS = new ArrayList<>();
60     private static final ContentProviderResult[] RESULTS = new ContentProviderResult[0];
61     private static final ContentValues VALUES = new ContentValues();
62     private static final ContentValues[] VALUES_ARRAY = new ContentValues[0];
63     private static final String METHOD = "method";
64     private static final String ARG = "arg";
65     private static final String[] ARG_ARRAY = new String[0];
66     private static final Bundle EXTRAS = new Bundle();
67     private static final String TYPE = "mime/type";
68     private static final String[] TYPE_ARRAY = new String[0];
69     private static final CancellationSignal SIGNAL = new CancellationSignal();
70     private static final String MODE = "rw";
71     private static final ParcelFileDescriptor FD;
72     private static final AssetFileDescriptor ASSET_FD;
73     private static final Cursor CURSOR = new MatrixCursor(new String[0]);
74 
75     static {
76         try {
77             FD = ParcelFileDescriptor.open(new File("/dev/null"),
78                     ParcelFileDescriptor.MODE_READ_ONLY);
79             ASSET_FD = new AssetFileDescriptor(FD, 0, AssetFileDescriptor.UNKNOWN_LENGTH);
80         } catch (Exception e) {
81             throw new RuntimeException(e);
82         }
83     }
84 
85     private Context mContext;
86     private ContentProvider mProvider;
87     private ContentResolver mResolver;
88 
89     @Before
setUp()90     public void setUp() throws Exception {
91         mContext = mock(Context.class, RETURNS_DEFAULTS);
92         mProvider = mock(ContentProvider.class, CALLS_REAL_METHODS);
93 
94         final ProviderInfo pi = new ProviderInfo();
95         pi.authority = AUTHORITY;
96         pi.exported = true;
97         mProvider.attachInfo(mContext, pi);
98 
99         mResolver = ContentResolver.wrap(mProvider);
100     }
101 
102     @Test
testApplyBatch()103     public void testApplyBatch() throws Exception {
104         doReturn(RESULTS).when(mProvider).applyBatch(AUTHORITY, OPERATIONS);
105         assertEquals(RESULTS, mResolver.applyBatch(AUTHORITY, OPERATIONS));
106     }
107 
108     @Test
testBulkInsert()109     public void testBulkInsert() throws Exception {
110         doReturn(42).when(mProvider).bulkInsert(URI, VALUES_ARRAY);
111         assertEquals(42, mResolver.bulkInsert(URI, VALUES_ARRAY));
112     }
113 
114     @Test
testCall()115     public void testCall() throws Exception {
116         doReturn(EXTRAS).when(mProvider).call(AUTHORITY, METHOD, ARG, EXTRAS);
117         assertEquals(EXTRAS, mResolver.call(AUTHORITY, METHOD, ARG, EXTRAS));
118         assertEquals(EXTRAS, mResolver.call(URI, METHOD, ARG, EXTRAS));
119     }
120 
121     @Test
testCanonicalize()122     public void testCanonicalize() throws Exception {
123         doReturn(URI).when(mProvider).canonicalize(URI);
124         assertEquals(URI, mResolver.canonicalize(URI));
125     }
126 
127     @Test
testUncanonicalize()128     public void testUncanonicalize() throws Exception {
129         doReturn(URI).when(mProvider).uncanonicalize(URI);
130         assertEquals(URI, mResolver.uncanonicalize(URI));
131     }
132 
133     @Test
testType()134     public void testType() throws Exception {
135         doReturn(TYPE).when(mProvider).getType(URI);
136         assertEquals(TYPE, mResolver.getType(URI));
137     }
138 
139     @Test
testStreamTypes()140     public void testStreamTypes() throws Exception {
141         doReturn(TYPE_ARRAY).when(mProvider).getStreamTypes(URI, TYPE);
142         assertEquals(TYPE_ARRAY, mResolver.getStreamTypes(URI, TYPE));
143     }
144 
145     @Test
testInsert()146     public void testInsert() throws Exception {
147         doReturn(URI).when(mProvider).insert(URI, VALUES);
148         assertEquals(URI, mResolver.insert(URI, VALUES));
149     }
150 
151     @Test
testInsert_Extras()152     public void testInsert_Extras() throws Exception {
153         doReturn(URI).when(mProvider).insert(URI, VALUES, EXTRAS);
154         assertEquals(URI, mResolver.insert(URI, VALUES, EXTRAS));
155     }
156 
157     @Test
testUpdate()158     public void testUpdate() throws Exception {
159         doReturn(42).when(mProvider).update(URI, VALUES, ARG, ARG_ARRAY);
160         assertEquals(42, mResolver.update(URI, VALUES, ARG, ARG_ARRAY));
161     }
162 
163     @Test
testUpdate_Extras()164     public void testUpdate_Extras() throws Exception {
165         doReturn(21).when(mProvider).update(URI, VALUES, EXTRAS);
166         assertEquals(21, mResolver.update(URI, VALUES, EXTRAS));
167     }
168 
169     @Test
testDelete()170     public void testDelete() throws Exception {
171         doReturn(42).when(mProvider).delete(URI, ARG, ARG_ARRAY);
172         assertEquals(42, mResolver.delete(URI, ARG, ARG_ARRAY));
173     }
174 
175     @Test
testDelete_Extras()176     public void testDelete_Extras() throws Exception {
177         doReturn(21).when(mProvider).delete(URI, EXTRAS);
178         assertEquals(21, mResolver.delete(URI, EXTRAS));
179     }
180 
181     @Test
testRefresh()182     public void testRefresh() throws Exception {
183         doReturn(true).when(mProvider).refresh(URI, EXTRAS, SIGNAL);
184         assertEquals(true, mResolver.refresh(URI, EXTRAS, SIGNAL));
185     }
186 
187     @Test
testOpenAssetFile()188     public void testOpenAssetFile() throws Exception {
189         doReturn(ASSET_FD).when(mProvider).openAssetFile(URI, MODE, null);
190         assertEquals(ASSET_FD, mResolver.openAssetFile(URI, MODE, null));
191         assertEquals(ASSET_FD, mResolver.openAssetFileDescriptor(URI, MODE));
192         assertEquals(ASSET_FD, mResolver.openAssetFileDescriptor(URI, MODE, null));
193     }
194 
195     @Test
testOpenFile()196     public void testOpenFile() throws Exception {
197         doReturn(FD).when(mProvider).openFile(URI, MODE, null);
198         assertEquals(FD, mResolver.openFile(URI, MODE, null));
199         assertEquals(FD, mResolver.openFileDescriptor(URI, MODE));
200         assertEquals(FD, mResolver.openFileDescriptor(URI, MODE, null));
201     }
202 
203     @Test
testOpenStream()204     public void testOpenStream() throws Exception {
205         doReturn(ASSET_FD).when(mProvider).openAssetFile(URI, "r", null);
206         doReturn(ASSET_FD).when(mProvider).openAssetFile(URI, "w", null);
207         assertNotNull(mResolver.openInputStream(URI));
208         assertNotNull(mResolver.openOutputStream(URI));
209     }
210 
211     @Test
testOpenTypedAssetFile()212     public void testOpenTypedAssetFile() throws Exception {
213         doReturn(ASSET_FD).when(mProvider).openTypedAssetFile(URI, TYPE, EXTRAS, null);
214         assertEquals(ASSET_FD, mResolver.openTypedAssetFile(URI, TYPE, EXTRAS, null));
215         assertEquals(ASSET_FD, mResolver.openTypedAssetFileDescriptor(URI, TYPE, EXTRAS));
216         assertEquals(ASSET_FD, mResolver.openTypedAssetFileDescriptor(URI, TYPE, EXTRAS, null));
217     }
218 
219     @Test
testQuery()220     public void testQuery() throws Exception {
221         doReturn(CURSOR).when(mProvider).query(eq(URI), eq(ARG_ARRAY), any(), any());
222         assertEquals(CURSOR, mResolver.query(URI, ARG_ARRAY, null, null));
223         assertEquals(CURSOR, mResolver.query(URI, ARG_ARRAY, null, null, null));
224         assertEquals(CURSOR, mResolver.query(URI, ARG_ARRAY, null, null, null, null));
225     }
226 
227     @Test
testLoadThumbnail()228     public void testLoadThumbnail() throws Exception {
229         doReturn(ASSET_FD).when(mProvider).openTypedAssetFile(eq(URI), any(), any(), eq(SIGNAL));
230         try {
231             mResolver.loadThumbnail(URI, new Size(32, 32), SIGNAL);
232             fail();
233         } catch (IOException expected) {
234         }
235     }
236 }
237