blob: 91ba3fc99367f8840c4a5bc008fcf5d432aede1d [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.carrierapi.cts;
import static junit.framework.TestCase.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.provider.Telephony.Carriers;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* Build, install and run the tests by running the commands below:
* make cts -j64
* cts-tradefed run cts -m CtsCarrierApiTestCases --test android.carrierapi.cts.ApnDatabaseTest
*/
@RunWith(AndroidJUnit4.class)
public class ApnDatabaseTest {
private static final String TAG = "ApnDatabaseTest";
private ContentResolver mContentResolver;
private PackageManager mPackageManager;
private boolean mHasCellular;
private static final String NAME = "carrierName";
private static final String APN = "apn";
private static final String PROXY = "proxy";
private static final String PORT = "port";
private static final String MMSC = "mmsc";
private static final String MMSPROXY = "mmsproxy";
private static final String MMSPORT = "mmsport";
private static final String NUMERIC = "numeric";
private static final String USER = "user";
private static final String PASSWORD = "password";
private static final String AUTH_TYPE = "auth_type";
private static final String TYPE = "type";
private static final String PROTOCOL = "protocol";
private static final String ROAMING_PROTOCOL = "roaming_protocol";
private static final String CARRIER_ENABLED = "true";
private static final String NETWORK_TYPE_BITMASK = "0";
private static final String BEARER = "0";
private static final Map<String, String> APN_MAP = new HashMap<String,String>() {{
put(Carriers.NAME, NAME);
put(Carriers.APN, APN);
put(Carriers.PROXY, PROXY);
put(Carriers.PORT, PORT);
put(Carriers.MMSC, MMSC);
put(Carriers.MMSPROXY, MMSPROXY);
put(Carriers.MMSPORT, MMSPORT);
put(Carriers.NUMERIC, NUMERIC);
put(Carriers.USER, USER);
put(Carriers.PASSWORD, PASSWORD);
put(Carriers.AUTH_TYPE, AUTH_TYPE);
put(Carriers.TYPE, TYPE);
put(Carriers.PROTOCOL, PROTOCOL);
put(Carriers.ROAMING_PROTOCOL, ROAMING_PROTOCOL);
put(Carriers.CARRIER_ENABLED, CARRIER_ENABLED);
put(Carriers.NETWORK_TYPE_BITMASK, NETWORK_TYPE_BITMASK);
put(Carriers.BEARER, BEARER);
}};
// Faked network type bitmask and its compatible bearer bitmask.
private static final int NETWORK_TYPE_BITMASK_NUMBER = 1 << (13 - 1);
private static final int RIL_RADIO_TECHNOLOGY_BITMASK_NUMBER = 1 << (14 - 1);
@Before
public void setUp() throws Exception {
mContentResolver = InstrumentationRegistry.getContext().getContentResolver();
mPackageManager = InstrumentationRegistry.getContext().getPackageManager();
// Checks whether the cellular stack should be running on this device.
mHasCellular = mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
if (!mHasCellular) {
Log.e(TAG, "No cellular support, all tests will be skipped.");
}
}
private void failMessage() {
fail("This test requires a SIM card with carrier privilege rule on it.\n" +
"Visit https://source.android.com/devices/tech/config/uicc.html");
}
/**
* Test inserting, querying, updating and deleting values in carriers table.
* Verify that the inserted values match the result of the query and are deleted.
*/
@Test
public void testValidCase() {
if (!mHasCellular) return;
Uri uri = Carriers.CONTENT_URI;
// CONTENT_URI = Uri.parse("content://telephony/carriers");
// Create A set of column_name/value pairs to add to the database.
ContentValues contentValues = makeDefaultContentValues();
try {
// Insert the value into database.
Log.d(TAG, "testInsertCarriers Inserting contentValues: " + contentValues.toString());
Uri newUri = mContentResolver.insert(uri, contentValues);
assertNotNull("Failed to insert to table", newUri);
// Get the values in table.
final String selection = Carriers.NUMERIC + "=?";
String[] selectionArgs = { NUMERIC };
String[] apnProjection = APN_MAP.keySet().toArray(new String[APN_MAP.size()]);
Log.d(TAG, "testInsertCarriers query projection: " + Arrays.toString(apnProjection)
+ "\ntestInsertCarriers selection: " + selection
+ "\ntestInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
Cursor cursor = mContentResolver.query(
uri, apnProjection, selection, selectionArgs, null);
// Verify that the inserted value match the results of the query
assertNotNull("Failed to query the table", cursor);
assertEquals("Unexpected number of APNs returned by cursor",
1, cursor.getCount());
cursor.moveToFirst();
for (Map.Entry<String, String> entry: APN_MAP.entrySet()) {
assertEquals(
"Unexpected value returned by cursor",
cursor.getString(cursor.getColumnIndex(entry.getKey())), entry.getValue());
}
// update the apn
final String newApn = "newapn";
Log.d(TAG, "Update the APN field to: " + newApn);
contentValues.put(Carriers.APN, newApn);
final int updateCount = mContentResolver.update(uri, contentValues, selection,
selectionArgs);
assertEquals("Unexpected number of rows updated", 1, updateCount);
// Verify the updated value
cursor = mContentResolver.query(uri, apnProjection, selection, selectionArgs, null);
assertNotNull("Failed to query the table", cursor);
assertEquals("Unexpected number of APNs returned by cursor", 1, cursor.getCount());
cursor.moveToFirst();
assertEquals("Unexpected value returned by cursor",
cursor.getString(cursor.getColumnIndex(Carriers.APN)), newApn);
// delete test content
final String selectionToDelete = Carriers.NUMERIC + "=?";
String[] selectionArgsToDelete = { NUMERIC };
Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete
+ "testInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
int numRowsDeleted = mContentResolver.delete(
uri, selectionToDelete, selectionArgsToDelete);
assertEquals("Unexpected number of rows deleted",1, numRowsDeleted);
// verify that deleted values are gone
cursor = mContentResolver.query(uri, apnProjection, selection, selectionArgs, null);
assertEquals("Unexpected number of rows deleted", 0, cursor.getCount());
} catch (SecurityException e) {
failMessage();
}
}
@Test
public void testQueryConflictCase() {
if (!mHasCellular) return;
String invalidColumn = "random";
Uri uri = Carriers.CONTENT_URI;
// CONTENT_URI = Uri.parse("content://telephony/carriers");
// Create A set of column_name/value pairs to add to the database.
ContentValues contentValues = new ContentValues();
contentValues.put(Carriers.NAME, NAME);
contentValues.put(Carriers.APN, APN);
contentValues.put(Carriers.PORT, PORT);
contentValues.put(Carriers.PROTOCOL, PROTOCOL);
contentValues.put(Carriers.NUMERIC, NUMERIC);
try {
// Insert the value into database.
Log.d(TAG, "testInsertCarriers Inserting contentValues: " + contentValues.toString());
Uri newUri = mContentResolver.insert(uri, contentValues);
assertNotNull("Failed to insert to table", newUri);
// Try to get the value with invalid selection
final String[] testProjection =
{
Carriers.NAME,
Carriers.APN,
Carriers.PORT,
Carriers.PROTOCOL,
Carriers.NUMERIC,
};
final String selection = invalidColumn + "=?";
String[] selectionArgs = { invalidColumn };
Log.d(TAG, "testInsertCarriers query projection: " + Arrays.toString(testProjection)
+ "\ntestInsertCarriers selection: " + selection
+ "\ntestInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
Cursor cursor = mContentResolver.query(
uri, testProjection, selection, selectionArgs, null);
assertNull("Failed to query the table",cursor);
// delete test content
final String selectionToDelete = Carriers.NAME + "=?";
String[] selectionArgsToDelete = { NAME };
Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete
+ "testInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
int numRowsDeleted = mContentResolver.delete(
uri, selectionToDelete, selectionArgsToDelete);
assertEquals("Unexpected number of rows deleted", 1, numRowsDeleted);
// verify that deleted values are gone
cursor = mContentResolver.query(
uri, testProjection, selectionToDelete, selectionArgsToDelete, null);
assertEquals("Unexpected number of rows deleted", 0, cursor.getCount());
} catch (SecurityException e) {
failMessage();
}
}
@Test
public void testUpdateConflictCase() {
if (!mHasCellular) return;
Uri uri = Carriers.CONTENT_URI;
// CONTENT_URI = Uri.parse("content://telephony/carriers");
// Create A set of column_name/value pairs to add to the database.
ContentValues contentValues = new ContentValues();
contentValues.put(Carriers.NAME, NAME);
contentValues.put(Carriers.APN, APN);
contentValues.put(Carriers.PORT, PORT);
contentValues.put(Carriers.PROTOCOL, PROTOCOL);
contentValues.put(Carriers.NUMERIC, NUMERIC);
try {
// Insert the value into database.
Log.d(TAG, "testInsertCarriers Inserting contentValues: " + contentValues.toString());
Uri newUri = mContentResolver.insert(uri, contentValues);
assertNotNull("Failed to insert to table", newUri);
// Try to get the value with invalid selection
final String[] testProjection =
{
Carriers.NAME,
Carriers.APN,
Carriers.PORT,
Carriers.PROTOCOL,
Carriers.NUMERIC,
};
String selection = Carriers.NAME + "=?";
String[] selectionArgs = { NAME };
Log.d(TAG, "testInsertCarriers query projection: " + Arrays.toString(testProjection)
+ "\ntestInsertCarriers selection: " + selection
+ "\ntestInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
Cursor cursor = mContentResolver.query(
uri, testProjection, selection, selectionArgs, null);
assertEquals("Unexpected number of APNs returned by cursor",
1, cursor.getCount());
// Update the table with invalid column
String invalidColumn = "random";
contentValues.put(invalidColumn, invalidColumn);
try {
mContentResolver.update(uri, contentValues, selection, selectionArgs);
fail();
} catch (SQLiteException e) {
// Expected: If there's no such a column, an exception will be thrown and the
// Activity Manager will kill this process shortly.
}
// delete test content
final String selectionToDelete = Carriers.NAME + "=?";
String[] selectionArgsToDelete = { NAME };
Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete
+ "testInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
int numRowsDeleted = mContentResolver.delete(
uri, selectionToDelete, selectionArgsToDelete);
assertEquals("Unexpected number of rows deleted", 1, numRowsDeleted);
// verify that deleted values are gone
cursor = mContentResolver.query(
uri, testProjection, selectionToDelete, selectionArgsToDelete, null);
assertEquals("Unexpected number of rows deleted", 0, cursor.getCount());
} catch (SecurityException e) {
failMessage();
}
}
@Test
public void testDeleteConflictCase() {
if (!mHasCellular) return;
String invalidColumn = "random";
Uri uri = Carriers.CONTENT_URI;
// CONTENT_URI = Uri.parse("content://telephony/carriers");
// Create A set of column_name/value pairs to add to the database.
ContentValues contentValues = new ContentValues();
contentValues.put(Carriers.NAME, NAME);
contentValues.put(Carriers.APN, APN);
contentValues.put(Carriers.PORT, PORT);
contentValues.put(Carriers.PROTOCOL, PROTOCOL);
contentValues.put(Carriers.NUMERIC, NUMERIC);
try {
// Insert the value into database.
Log.d(TAG, "testInsertCarriers Inserting contentValues: " + contentValues.toString());
Uri newUri = mContentResolver.insert(uri, contentValues);
assertNotNull("Failed to insert to table", newUri);
// Get the values in table.
final String[] testProjection =
{
Carriers.NAME,
Carriers.APN,
Carriers.PORT,
Carriers.PROTOCOL,
Carriers.NUMERIC,
};
String selection = Carriers.NAME + "=?";
String[] selectionArgs = { NAME };
Log.d(TAG, "testInsertCarriers query projection: " + Arrays.toString(testProjection)
+ "\ntestInsertCarriers selection: " + selection
+ "\ntestInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
Cursor cursor = mContentResolver.query(
uri, testProjection, selection, selectionArgs, null);
assertEquals("Unexpected number of APNs returned by cursor", 1, cursor.getCount());
// try to delete with invalid selection
String selectionToDelete = invalidColumn + "=?";
String[] selectionArgsToDelete = { invalidColumn };
Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete
+ "testInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
try {
mContentResolver.delete(uri, selectionToDelete, selectionArgsToDelete);
fail();
} catch (SQLiteException e) {
// Expected: If there's no such a column, an exception will be thrown and the
// Activity Manager will kill this process shortly.
}
// verify that deleted value is still there
selection = Carriers.NAME + "=?";
selectionArgs[0] = NAME;
cursor = mContentResolver.query(uri, testProjection, selection, selectionArgs, null);
assertEquals("Unexpected number of APNs returned by cursor", 1, cursor.getCount());
// delete test content
selectionToDelete = Carriers.NAME + "=?";
selectionArgsToDelete[0] = NAME;
Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete
+ "testInsertCarriers selectionArgs: " + Arrays.toString(selectionArgs));
int numRowsDeleted = mContentResolver.delete(
uri, selectionToDelete, selectionArgsToDelete);
assertEquals("Unexpected number of rows deleted", 1, numRowsDeleted);
// verify that deleted values are gone
cursor = mContentResolver.query(uri, testProjection, selection, selectionArgs, null);
assertEquals("Unexpected number of rows deleted", 0, cursor.getCount());
} catch (SecurityException e) {
failMessage();
}
}
private ContentValues makeDefaultContentValues() {
ContentValues contentValues = new ContentValues();
for (Map.Entry<String, String> entry: APN_MAP.entrySet()) {
contentValues.put(entry.getKey(), entry.getValue());
}
return contentValues;
}
}