1 /*
2  * Copyright (C) 2017 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 com.android.providers.telephony;
18 
19 import android.content.ContentValues;
20 import android.content.pm.PackageManager;
21 import android.content.pm.ProviderInfo;
22 import android.content.res.Resources;
23 import android.database.Cursor;
24 import android.database.SQLException;
25 import android.telephony.TelephonyManager;
26 import android.test.mock.MockContentResolver;
27 import android.test.mock.MockContext;
28 import android.text.TextUtils;
29 import android.util.Log;
30 
31 import androidx.test.filters.SmallTest;
32 
33 import junit.framework.TestCase;
34 
35 import org.junit.Test;
36 
37 /**
38  * Tests for testing CRUD operations of CarrierProvider.
39  * Uses TelephonyProviderTestable to set up in-memory database
40  *
41  * Build, install and run the tests by running the commands below:
42  *     runtest --path <dir or file>
43  *     runtest --path <dir or file> --test-method <testMethodName>
44  *     e.g.)
45  *         runtest --path tests/src/com/android/providers/telephony/CarrierProviderTest.java \
46  *                 --test-method testInsertCarriers
47  */
48 public class CarrierProviderTest extends TestCase {
49 
50     private static final String TAG = "CarrierProviderTest";
51 
52     private MockContextWithProvider mContext;
53     private MockContentResolver mContentResolver;
54     private CarrierProviderTestable mCarrierProviderTestable;
55 
56     public static final int test_type = 1;
57     public static final String test_mnc = "MNC001";
58     public static final String test_mnc2 = "MNC002";
59     public static final String test_mcc = "MCC005";
60     public static final String test_key1 = "PUBKEY1";
61     public static final String test_key2 = "PUBKEY2";
62     public static final String  test_key_identifier_data = "key_identifier1";
63     public static final long  test_key_expiration = 1496795015L;
64     public static final int TEST_CARRIER_ID_1 = 1;
65     public static final int TEST_CARRIER_ID_2 = 2;
66 
67     /**
68      * This is used to give the CarrierProviderTest a mocked context which takes a
69      * CarrierProvider and attaches it to the ContentResolver.
70      */
71     private class MockContextWithProvider extends MockContext {
72         private final MockContentResolver mResolver;
73 
MockContextWithProvider(CarrierProvider carrierProvider)74         public MockContextWithProvider(CarrierProvider carrierProvider) {
75             mResolver = new MockContentResolver();
76 
77             ProviderInfo providerInfo = new ProviderInfo();
78             providerInfo.authority = CarrierProvider.PROVIDER_NAME;
79 
80             // Add context to given telephonyProvider
81             carrierProvider.attachInfoForTesting(this, providerInfo);
82             Log.d(TAG, "MockContextWithProvider: carrierProvider.getContext(): "
83                     + carrierProvider.getContext());
84 
85             // Add given telephonyProvider to mResolver, so that mResolver can send queries
86             // to the provider.
87             mResolver.addProvider(CarrierProvider.PROVIDER_NAME, carrierProvider);
88             Log.d(TAG, "MockContextWithProvider: Add carrierProvider to mResolver");
89         }
90 
91         @Override
getSystemService(String name)92         public Object getSystemService(String name) {
93             Log.d(TAG, "getSystemService: returning null");
94             return null;
95         }
96 
97         @Override
getResources()98         public Resources getResources() {
99             Log.d(TAG, "getResources: returning null");
100             return null;
101         }
102 
103         @Override
getContentResolver()104         public MockContentResolver getContentResolver() {
105             return mResolver;
106         }
107 
108         // Gives permission to write to the APN table within the MockContext
109         @Override
checkCallingOrSelfPermission(String permission)110         public int checkCallingOrSelfPermission(String permission) {
111             if (TextUtils.equals(permission, "android.permission.WRITE_APN_SETTINGS")) {
112                 Log.d(TAG, "checkCallingOrSelfPermission: permission=" + permission
113                         + ", returning PackageManager.PERMISSION_GRANTED");
114                 return PackageManager.PERMISSION_GRANTED;
115             } else {
116                 Log.d(TAG, "checkCallingOrSelfPermission: permission=" + permission
117                         + ", returning PackageManager.PERMISSION_DENIED");
118                 return PackageManager.PERMISSION_DENIED;
119             }
120         }
121     }
122 
123     @Override
setUp()124     protected void setUp() throws Exception {
125         super.setUp();
126         mCarrierProviderTestable = new CarrierProviderTestable();
127         mContext = new MockContextWithProvider(mCarrierProviderTestable);
128         mContentResolver = (MockContentResolver) mContext.getContentResolver();
129     }
130 
131     @Override
tearDown()132     protected void tearDown() throws Exception {
133         super.tearDown();
134         mCarrierProviderTestable.closeDatabase();
135     }
136 
137     /**
138      * Test inserting values in carrier key table.
139      */
140     @Test
141     @SmallTest
testInsertCertificates()142     public void testInsertCertificates() {
143         int count = -1;
144         ContentValues contentValues = new ContentValues();
145         contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
146         contentValues.put(CarrierDatabaseHelper.MCC, test_mcc);
147         contentValues.put(CarrierDatabaseHelper.MNC, test_mnc);
148         contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1);
149         contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
150         contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
151         contentValues.put(CarrierDatabaseHelper.EXPIRATION_TIME, test_key_expiration);
152 
153         try {
154             mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
155         } catch (Exception e) {
156             Log.d(TAG, "Error inserting certificates:" + e);
157         }
158         try {
159             Cursor countCursor = mContentResolver.query(CarrierProvider.CONTENT_URI,
160                     new String[]{"count(*) AS count"},
161                     null,
162                     null,
163                     null);
164             countCursor.moveToFirst();
165             count = countCursor.getInt(0);
166         } catch (Exception e) {
167             Log.d(TAG, "Exception in getting count:" + e);
168         }
169         assertEquals(1, count);
170     }
171 
172     /**
173      * Test update & query.
174      */
175     @Test
176     @SmallTest
testUpdateCertificates()177     public void testUpdateCertificates() {
178         String key = null;
179         ContentValues contentValues = new ContentValues();
180         contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
181         contentValues.put(CarrierDatabaseHelper.MCC, test_mcc);
182         contentValues.put(CarrierDatabaseHelper.MNC, test_mnc);
183         contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1);
184         contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
185         contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
186         contentValues.put(CarrierDatabaseHelper.EXPIRATION_TIME, test_key_expiration);
187 
188         try {
189             mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
190         } catch (Exception e) {
191             Log.d(TAG, "Error inserting certificates:" + e);
192         }
193 
194         try {
195             ContentValues updatedValues = new ContentValues();
196             updatedValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key2);
197             mContentResolver.update(CarrierProvider.CONTENT_URI, updatedValues,
198                     "mcc=? and mnc=? and carrier_id=? and key_type=?",
199                     new String[]{test_mcc, test_mnc, Integer.toString(TEST_CARRIER_ID_1),
200                             String.valueOf(test_type)});
201         } catch (Exception e) {
202             Log.d(TAG, "Error updating values:" + e);
203         }
204 
205         try {
206             String[] columns ={CarrierDatabaseHelper.PUBLIC_KEY};
207             Cursor findEntry = mContentResolver.query(CarrierProvider.CONTENT_URI, columns,
208                     "mcc=? and mnc=? and carrier_id=? and key_type=?",
209                     new String[]{test_mcc, test_mnc, Integer.toString(TEST_CARRIER_ID_1),
210                             String.valueOf(test_type)}, null);
211             findEntry.moveToFirst();
212             key = findEntry.getString(0);
213         } catch (Exception e) {
214             Log.d(TAG, "Query failed:" + e);
215         }
216         assertEquals(key, test_key2);
217     }
218 
219     /**
220      * Test inserting multiple certs
221      */
222     @Test
223     @SmallTest
testMultipleCertificates()224     public void testMultipleCertificates() {
225         int count = -1;
226         ContentValues contentValues = new ContentValues();
227         contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
228         contentValues.put(CarrierDatabaseHelper.MCC, test_mcc);
229         contentValues.put(CarrierDatabaseHelper.MNC, test_mnc);
230         contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1);
231         contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
232         contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
233 
234         ContentValues contentValuesNew = new ContentValues();
235         contentValuesNew.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
236         contentValuesNew.put(CarrierDatabaseHelper.MCC, test_mcc);
237         contentValuesNew.put(CarrierDatabaseHelper.MNC, test_mnc2);
238         contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1);
239         contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
240         contentValuesNew.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key2.getBytes());
241 
242         try {
243             mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
244             mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValuesNew);
245         } catch (Exception e) {
246             System.out.println("Error inserting certificates:: " + e);
247         }
248 
249         try {
250             Cursor countCursor = mContentResolver.query(CarrierProvider.CONTENT_URI,
251                     new String[]{"count(*) AS count"},
252                     null,
253                     null,
254                     null);
255             countCursor.moveToFirst();
256             count = countCursor.getInt(0);
257         } catch (Exception e) {
258             Log.d(TAG, "Exception in getting count:" + e);
259         }
260         assertEquals(2, count);
261     }
262 
263     /**
264      * Test inserting cert with same MCC and MNC but with diff carrier ID
265      */
266     @Test
267     @SmallTest
testMnoandMvnoCertificates()268     public void testMnoandMvnoCertificates() {
269         int count = -1;
270         ContentValues contentValues = new ContentValues();
271         contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
272         contentValues.put(CarrierDatabaseHelper.MCC, test_mcc);
273         contentValues.put(CarrierDatabaseHelper.MNC, test_mnc);
274         contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1);
275         contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
276         contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
277 
278         ContentValues contentValuesNew = new ContentValues();
279         contentValuesNew.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
280         contentValuesNew.put(CarrierDatabaseHelper.MCC, test_mcc);
281         contentValuesNew.put(CarrierDatabaseHelper.MNC, test_mnc);
282         contentValuesNew.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_2);
283         contentValuesNew.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
284         contentValuesNew.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
285 
286         try {
287             mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
288             mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValuesNew);
289         } catch (Exception e) {
290             System.out.println("Error inserting certificates:: " + e);
291         }
292 
293         try {
294             Cursor countCursor = mContentResolver.query(CarrierProvider.CONTENT_URI,
295                     new String[]{"count(*) AS count"},
296                     null,
297                     null,
298                     null);
299             countCursor.moveToFirst();
300             count = countCursor.getInt(0);
301         } catch (Exception e) {
302             Log.d(TAG, "Exception in getting count:" + e);
303         }
304         assertEquals(2, count);
305     }
306 
307     /**
308      * once upgrade to version 3, carrierId = -1
309      * After upgrade, it triggers for new download with correct carrierId
310      * This test case will test writing the new entry, even old entry for same
311      * operator is already existed
312      */
313     @Test
314     @SmallTest
testOldAndNewDBEntries()315     public void testOldAndNewDBEntries() {
316         int count = -1;
317         ContentValues contentValues = new ContentValues();
318         contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
319         contentValues.put(CarrierDatabaseHelper.MCC, test_mcc);
320         contentValues.put(CarrierDatabaseHelper.MNC, test_mnc);
321         contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
322         contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
323         contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
324 
325         ContentValues contentValuesNew = new ContentValues();
326         contentValuesNew.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
327         contentValuesNew.put(CarrierDatabaseHelper.MCC, test_mcc);
328         contentValuesNew.put(CarrierDatabaseHelper.MNC, test_mnc);
329         contentValuesNew.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_2);
330         contentValuesNew.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
331         contentValuesNew.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
332 
333         try {
334             mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
335             mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValuesNew);
336         } catch (Exception e) {
337             System.out.println("Error inserting certificates:: " + e);
338         }
339 
340         try {
341             Cursor countCursor = mContentResolver.query(CarrierProvider.CONTENT_URI,
342                     new String[]{"count(*) AS count"},
343                     null,
344                     null,
345                     null);
346             countCursor.moveToFirst();
347             count = countCursor.getInt(0);
348         } catch (Exception e) {
349             Log.d(TAG, "Exception in getting count:" + e);
350         }
351         assertEquals(2, count);
352     }
353 
354     /**
355      * Test inserting duplicate values in carrier key table. Ensure that a SQLException is thrown.
356      */
357     @Test(expected = SQLException.class)
testDuplicateFailure()358     public void testDuplicateFailure() {
359         ContentValues contentValues = new ContentValues();
360         contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
361         contentValues.put(CarrierDatabaseHelper.MCC, test_mcc);
362         contentValues.put(CarrierDatabaseHelper.MNC, test_mnc);
363         contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1);
364         contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
365 
366         try {
367             mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
368         } catch (Exception e) {
369             Log.d(TAG, "Error inserting certificates:: " + e);
370         }
371         try {
372             mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
373         } catch (Exception e) {
374             Log.d(TAG, "Error inserting certificates:: " + e);
375         }
376     }
377 
378     /**
379      * Test delete.
380      */
381     @Test
382     @SmallTest
testDelete()383     public void testDelete() {
384         int numRowsDeleted = -1;
385         ContentValues contentValues = new ContentValues();
386         contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
387         contentValues.put(CarrierDatabaseHelper.MCC, test_mcc);
388         contentValues.put(CarrierDatabaseHelper.MNC, test_mnc);
389         contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1);
390         contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
391         contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
392         contentValues.put(CarrierDatabaseHelper.EXPIRATION_TIME, test_key_expiration);
393 
394         try {
395             mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
396         } catch (Exception e) {
397             Log.d(TAG, "Error inserting certificates:" + e);
398         }
399 
400         try {
401             String whereClause = "mcc=? and mnc=? and carrier_id=?";
402             String[] whereArgs = new String[]{test_mcc, test_mnc, Integer.toString(
403                     TEST_CARRIER_ID_1)};
404             numRowsDeleted = mContentResolver.delete(CarrierProvider.CONTENT_URI, whereClause,
405                     whereArgs);
406         } catch (Exception e) {
407             Log.d(TAG, "Error updating values:" + e);
408         }
409         assertEquals(numRowsDeleted, 1);
410     }
411 
412 }
413