Home | History | Annotate | Download | only in cts
      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 package android.carrierapi.cts;
     17 
     18 import static junit.framework.TestCase.assertEquals;
     19 
     20 import static org.junit.Assert.assertNotNull;
     21 import static org.junit.Assert.assertNull;
     22 import static org.junit.Assert.fail;
     23 
     24 import android.content.ContentResolver;
     25 import android.content.ContentValues;
     26 import android.content.pm.PackageManager;
     27 import android.database.Cursor;
     28 import android.database.sqlite.SQLiteException;
     29 import android.net.Uri;
     30 import android.provider.Telephony.Carriers;
     31 import android.util.Log;
     32 
     33 import androidx.test.InstrumentationRegistry;
     34 import androidx.test.runner.AndroidJUnit4;
     35 
     36 import org.junit.Before;
     37 import org.junit.Test;
     38 import org.junit.runner.RunWith;
     39 
     40 import java.util.Arrays;
     41 import java.util.HashMap;
     42 import java.util.Map;
     43 
     44 /**
     45  * Build, install and run the tests by running the commands below:
     46  *  make cts -j64
     47  *  cts-tradefed run cts -m CtsCarrierApiTestCases --test android.carrierapi.cts.ApnDatabaseTest
     48  */
     49 @RunWith(AndroidJUnit4.class)
     50 public class ApnDatabaseTest {
     51     private static final String TAG = "ApnDatabaseTest";
     52 
     53     private ContentResolver mContentResolver;
     54     private PackageManager mPackageManager;
     55     private boolean mHasCellular;
     56 
     57     private static final String NAME = "carrierName";
     58     private static final String APN = "apn";
     59     private static final String PROXY = "proxy";
     60     private static final String PORT = "port";
     61     private static final String MMSC = "mmsc";
     62     private static final String MMSPROXY = "mmsproxy";
     63     private static final String MMSPORT = "mmsport";
     64     private static final String NUMERIC = "numeric";
     65     private static final String USER = "user";
     66     private static final String PASSWORD = "password";
     67     private static final String AUTH_TYPE = "auth_type";
     68     private static final String TYPE = "type";
     69     private static final String PROTOCOL = "protocol";
     70     private static final String ROAMING_PROTOCOL = "roaming_protocol";
     71     private static final String CARRIER_ENABLED = "true";
     72     private static final String NETWORK_TYPE_BITMASK = "0";
     73     private static final String BEARER = "0";
     74 
     75     private static final Map<String, String> APN_MAP = new HashMap<String,String>() {{
     76         put(Carriers.NAME, NAME);
     77         put(Carriers.APN, APN);
     78         put(Carriers.PROXY, PROXY);
     79         put(Carriers.PORT, PORT);
     80         put(Carriers.MMSC, MMSC);
     81         put(Carriers.MMSPROXY, MMSPROXY);
     82         put(Carriers.MMSPORT, MMSPORT);
     83         put(Carriers.NUMERIC, NUMERIC);
     84         put(Carriers.USER, USER);
     85         put(Carriers.PASSWORD, PASSWORD);
     86         put(Carriers.AUTH_TYPE, AUTH_TYPE);
     87         put(Carriers.TYPE, TYPE);
     88         put(Carriers.PROTOCOL, PROTOCOL);
     89         put(Carriers.ROAMING_PROTOCOL, ROAMING_PROTOCOL);
     90         put(Carriers.CARRIER_ENABLED, CARRIER_ENABLED);
     91         put(Carriers.NETWORK_TYPE_BITMASK, NETWORK_TYPE_BITMASK);
     92         put(Carriers.BEARER, BEARER);
     93     }};
     94 
     95     // Faked network type bitmask and its compatible bearer bitmask.
     96     private static final int NETWORK_TYPE_BITMASK_NUMBER = 1 << (13 - 1);
     97     private static final int RIL_RADIO_TECHNOLOGY_BITMASK_NUMBER = 1 << (14 - 1);
     98 
     99     @Before
    100     public void setUp() throws Exception {
    101         mContentResolver = InstrumentationRegistry.getContext().getContentResolver();
    102         mPackageManager = InstrumentationRegistry.getContext().getPackageManager();
    103         // Checks whether the cellular stack should be running on this device.
    104         mHasCellular = mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
    105         if (!mHasCellular) {
    106             Log.e(TAG, "No cellular support, all tests will be skipped.");
    107         }
    108     }
    109 
    110     private void failMessage() {
    111         fail("This test requires a SIM card with carrier privilege rule on it.\n" +
    112                 "Visit https://source.android.com/devices/tech/config/uicc.html");
    113     }
    114 
    115     /**
    116      * Test inserting, querying, updating and deleting values in carriers table.
    117      * Verify that the inserted values match the result of the query and are deleted.
    118      */
    119     @Test
    120     public void testValidCase() {
    121         if (!mHasCellular) return;
    122         Uri uri = Carriers.CONTENT_URI;
    123         // CONTENT_URI = Uri.parse("content://telephony/carriers");
    124         // Create A set of column_name/value pairs to add to the database.
    125         ContentValues contentValues = makeDefaultContentValues();
    126 
    127         try {
    128             // Insert the value into database.
    129             Log.d(TAG, "testInsertCarriers Inserting contentValues: " + contentValues.toString());
    130             Uri newUri = mContentResolver.insert(uri, contentValues);
    131             assertNotNull("Failed to insert to table", newUri);
    132 
    133             // Get the values in table.
    134             final String selection = Carriers.NUMERIC + "=?";
    135             String[] selectionArgs = { NUMERIC };
    136             String[] apnProjection = APN_MAP.keySet().toArray(new String[APN_MAP.size()]);
    137             Log.d(TAG, "testInsertCarriers query projection: " + Arrays.toString(apnProjection)
    138                     + "\ntestInsertCarriers selection: " + selection
    139                     + "\ntestInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
    140             Cursor cursor = mContentResolver.query(
    141                     uri, apnProjection, selection, selectionArgs, null);
    142 
    143             // Verify that the inserted value match the results of the query
    144             assertNotNull("Failed to query the table", cursor);
    145             assertEquals("Unexpected number of APNs returned by cursor",
    146                     1, cursor.getCount());
    147             cursor.moveToFirst();
    148             for (Map.Entry<String, String> entry: APN_MAP.entrySet()) {
    149                 assertEquals(
    150                         "Unexpected value returned by cursor",
    151                         cursor.getString(cursor.getColumnIndex(entry.getKey())), entry.getValue());
    152             }
    153 
    154             // update the apn
    155             final String newApn = "newapn";
    156             Log.d(TAG, "Update the APN field to: " + newApn);
    157             contentValues.put(Carriers.APN, newApn);
    158             final int updateCount = mContentResolver.update(uri, contentValues, selection,
    159                     selectionArgs);
    160             assertEquals("Unexpected number of rows updated", 1, updateCount);
    161 
    162             // Verify the updated value
    163             cursor = mContentResolver.query(uri, apnProjection, selection, selectionArgs, null);
    164             assertNotNull("Failed to query the table", cursor);
    165             assertEquals("Unexpected number of APNs returned by cursor", 1, cursor.getCount());
    166             cursor.moveToFirst();
    167             assertEquals("Unexpected value returned by cursor",
    168                     cursor.getString(cursor.getColumnIndex(Carriers.APN)), newApn);
    169 
    170             // delete test content
    171             final String selectionToDelete = Carriers.NUMERIC + "=?";
    172             String[] selectionArgsToDelete = { NUMERIC };
    173             Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete
    174                     + "testInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
    175             int numRowsDeleted = mContentResolver.delete(
    176                     uri, selectionToDelete, selectionArgsToDelete);
    177             assertEquals("Unexpected number of rows deleted",1, numRowsDeleted);
    178 
    179             // verify that deleted values are gone
    180             cursor = mContentResolver.query(uri, apnProjection, selection, selectionArgs, null);
    181             assertEquals("Unexpected number of rows deleted", 0, cursor.getCount());
    182         } catch (SecurityException e) {
    183             failMessage();
    184         }
    185     }
    186 
    187     @Test
    188     public void testQueryConflictCase() {
    189         if (!mHasCellular) return;
    190         String invalidColumn = "random";
    191         Uri uri = Carriers.CONTENT_URI;
    192         // CONTENT_URI = Uri.parse("content://telephony/carriers");
    193         // Create A set of column_name/value pairs to add to the database.
    194         ContentValues contentValues = new ContentValues();
    195         contentValues.put(Carriers.NAME, NAME);
    196         contentValues.put(Carriers.APN, APN);
    197         contentValues.put(Carriers.PORT, PORT);
    198         contentValues.put(Carriers.PROTOCOL, PROTOCOL);
    199         contentValues.put(Carriers.NUMERIC, NUMERIC);
    200 
    201         try {
    202             // Insert the value into database.
    203             Log.d(TAG, "testInsertCarriers Inserting contentValues: " + contentValues.toString());
    204             Uri newUri = mContentResolver.insert(uri, contentValues);
    205             assertNotNull("Failed to insert to table", newUri);
    206 
    207             // Try to get the value with invalid selection
    208             final String[] testProjection =
    209                     {
    210                             Carriers.NAME,
    211                             Carriers.APN,
    212                             Carriers.PORT,
    213                             Carriers.PROTOCOL,
    214                             Carriers.NUMERIC,
    215                     };
    216             final String selection = invalidColumn + "=?";
    217             String[] selectionArgs = { invalidColumn };
    218             Log.d(TAG, "testInsertCarriers query projection: " + Arrays.toString(testProjection)
    219                     + "\ntestInsertCarriers selection: " + selection
    220                     + "\ntestInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
    221             Cursor cursor = mContentResolver.query(
    222                     uri, testProjection, selection, selectionArgs, null);
    223             assertNull("Failed to query the table",cursor);
    224 
    225             // delete test content
    226             final String selectionToDelete = Carriers.NAME + "=?";
    227             String[] selectionArgsToDelete = { NAME };
    228             Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete
    229                     + "testInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
    230             int numRowsDeleted = mContentResolver.delete(
    231                     uri, selectionToDelete, selectionArgsToDelete);
    232             assertEquals("Unexpected number of rows deleted", 1, numRowsDeleted);
    233 
    234             // verify that deleted values are gone
    235             cursor = mContentResolver.query(
    236                     uri, testProjection, selectionToDelete, selectionArgsToDelete, null);
    237             assertEquals("Unexpected number of rows deleted", 0, cursor.getCount());
    238         } catch (SecurityException e) {
    239             failMessage();
    240         }
    241     }
    242 
    243     @Test
    244     public void testUpdateConflictCase() {
    245         if (!mHasCellular) return;
    246         Uri uri = Carriers.CONTENT_URI;
    247         // CONTENT_URI = Uri.parse("content://telephony/carriers");
    248         // Create A set of column_name/value pairs to add to the database.
    249         ContentValues contentValues = new ContentValues();
    250         contentValues.put(Carriers.NAME, NAME);
    251         contentValues.put(Carriers.APN, APN);
    252         contentValues.put(Carriers.PORT, PORT);
    253         contentValues.put(Carriers.PROTOCOL, PROTOCOL);
    254         contentValues.put(Carriers.NUMERIC, NUMERIC);
    255 
    256         try {
    257             // Insert the value into database.
    258             Log.d(TAG, "testInsertCarriers Inserting contentValues: " + contentValues.toString());
    259             Uri newUri = mContentResolver.insert(uri, contentValues);
    260             assertNotNull("Failed to insert to table", newUri);
    261 
    262             // Try to get the value with invalid selection
    263             final String[] testProjection =
    264                     {
    265                             Carriers.NAME,
    266                             Carriers.APN,
    267                             Carriers.PORT,
    268                             Carriers.PROTOCOL,
    269                             Carriers.NUMERIC,
    270                     };
    271             String selection = Carriers.NAME + "=?";
    272             String[] selectionArgs = { NAME };
    273             Log.d(TAG, "testInsertCarriers query projection: " + Arrays.toString(testProjection)
    274                     + "\ntestInsertCarriers selection: " + selection
    275                     + "\ntestInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
    276             Cursor cursor = mContentResolver.query(
    277                     uri, testProjection, selection, selectionArgs, null);
    278             assertEquals("Unexpected number of APNs returned by cursor",
    279                     1, cursor.getCount());
    280 
    281             // Update the table with invalid column
    282             String invalidColumn = "random";
    283             contentValues.put(invalidColumn, invalidColumn);
    284             try {
    285                 mContentResolver.update(uri, contentValues, selection, selectionArgs);
    286                 fail();
    287             } catch (SQLiteException e) {
    288                 // Expected: If there's no such a column, an exception will be thrown and the
    289                 // Activity Manager will kill this process shortly.
    290             }
    291 
    292             // delete test content
    293             final String selectionToDelete = Carriers.NAME + "=?";
    294             String[] selectionArgsToDelete = { NAME };
    295             Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete
    296                     + "testInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
    297             int numRowsDeleted = mContentResolver.delete(
    298                     uri, selectionToDelete, selectionArgsToDelete);
    299             assertEquals("Unexpected number of rows deleted", 1, numRowsDeleted);
    300 
    301             // verify that deleted values are gone
    302             cursor = mContentResolver.query(
    303                     uri, testProjection, selectionToDelete, selectionArgsToDelete, null);
    304             assertEquals("Unexpected number of rows deleted", 0, cursor.getCount());
    305         } catch (SecurityException e) {
    306             failMessage();
    307         }
    308     }
    309 
    310     @Test
    311     public void testDeleteConflictCase() {
    312         if (!mHasCellular) return;
    313         String invalidColumn = "random";
    314         Uri uri = Carriers.CONTENT_URI;
    315         // CONTENT_URI = Uri.parse("content://telephony/carriers");
    316         // Create A set of column_name/value pairs to add to the database.
    317         ContentValues contentValues = new ContentValues();
    318         contentValues.put(Carriers.NAME, NAME);
    319         contentValues.put(Carriers.APN, APN);
    320         contentValues.put(Carriers.PORT, PORT);
    321         contentValues.put(Carriers.PROTOCOL, PROTOCOL);
    322         contentValues.put(Carriers.NUMERIC, NUMERIC);
    323 
    324         try {
    325             // Insert the value into database.
    326             Log.d(TAG, "testInsertCarriers Inserting contentValues: " + contentValues.toString());
    327             Uri newUri = mContentResolver.insert(uri, contentValues);
    328             assertNotNull("Failed to insert to table", newUri);
    329 
    330             // Get the values in table.
    331             final String[] testProjection =
    332                     {
    333                             Carriers.NAME,
    334                             Carriers.APN,
    335                             Carriers.PORT,
    336                             Carriers.PROTOCOL,
    337                             Carriers.NUMERIC,
    338                     };
    339             String selection = Carriers.NAME + "=?";
    340             String[] selectionArgs = { NAME };
    341             Log.d(TAG, "testInsertCarriers query projection: " + Arrays.toString(testProjection)
    342                     + "\ntestInsertCarriers selection: " + selection
    343                     + "\ntestInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
    344             Cursor cursor = mContentResolver.query(
    345                     uri, testProjection, selection, selectionArgs, null);
    346             assertEquals("Unexpected number of APNs returned by cursor", 1, cursor.getCount());
    347 
    348             // try to delete with invalid selection
    349             String selectionToDelete = invalidColumn + "=?";
    350             String[] selectionArgsToDelete = { invalidColumn };
    351             Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete
    352                     + "testInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
    353 
    354             try {
    355                 mContentResolver.delete(uri, selectionToDelete, selectionArgsToDelete);
    356                 fail();
    357             } catch (SQLiteException e) {
    358                 // Expected: If there's no such a column, an exception will be thrown and the
    359                 // Activity Manager will kill this process shortly.
    360             }
    361 
    362             // verify that deleted value is still there
    363             selection = Carriers.NAME + "=?";
    364             selectionArgs[0] = NAME;
    365             cursor = mContentResolver.query(uri, testProjection, selection, selectionArgs, null);
    366             assertEquals("Unexpected number of APNs returned by cursor", 1, cursor.getCount());
    367 
    368             // delete test content
    369             selectionToDelete = Carriers.NAME + "=?";
    370             selectionArgsToDelete[0] = NAME;
    371             Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete
    372                     + "testInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
    373             int numRowsDeleted = mContentResolver.delete(
    374                     uri, selectionToDelete, selectionArgsToDelete);
    375             assertEquals("Unexpected number of rows deleted", 1, numRowsDeleted);
    376 
    377             // verify that deleted values are gone
    378             cursor = mContentResolver.query(uri, testProjection, selection, selectionArgs, null);
    379             assertEquals("Unexpected number of rows deleted", 0, cursor.getCount());
    380         } catch (SecurityException e) {
    381             failMessage();
    382         }
    383     }
    384 
    385     private ContentValues makeDefaultContentValues() {
    386         ContentValues contentValues = new ContentValues();
    387         for (Map.Entry<String, String> entry: APN_MAP.entrySet()) {
    388             contentValues.put(entry.getKey(), entry.getValue());
    389         }
    390         return contentValues;
    391     }
    392 }