Merge "Fix handling of URIs with subId"
diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index 4e9b9d0..eebb681 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -1982,6 +1982,8 @@
qb.setStrict(true); // a little protection from injection attacks
qb.setTables(CARRIERS_TABLE);
+ List<String> constraints = new ArrayList<String>();
+
int match = s_urlMatcher.match(url);
switch (match) {
case URL_TELEPHONY_USING_SUBID: {
@@ -1993,14 +1995,12 @@
return null;
}
if (DBG) log("subIdString = " + subIdString + " subId = " + subId);
- qb.appendWhere(NUMERIC + " = '" + mTelephonyManager.getSimOperator(subId) + "'");
- // FIXME alter the selection to pass subId
- // selection = selection + "and subId = "
+ constraints.add(NUMERIC + " = '" + mTelephonyManager.getSimOperator(subId) + "'");
+ constraints.add(SUBSCRIPTION_ID + "=" + subIdString);
}
// intentional fall through from above case
- // do nothing
case URL_TELEPHONY: {
- qb.appendWhere(NOT_OWNED_BY_DPC);
+ constraints.add(NOT_OWNED_BY_DPC);
break;
}
@@ -2013,21 +2013,20 @@
return null;
}
if (DBG) log("subIdString = " + subIdString + " subId = " + subId);
- // FIXME alter the selection to pass subId
- // selection = selection + "and subId = "
+ constraints.add(SUBSCRIPTION_ID + "=" + subIdString);
}
//intentional fall through from above case
case URL_CURRENT: {
- qb.appendWhere("current IS NOT NULL");
- qb.appendWhere(NOT_OWNED_BY_DPC);
+ constraints.add("current IS NOT NULL");
+ constraints.add(NOT_OWNED_BY_DPC);
// do not ignore the selection since MMS may use it.
//selection = null;
break;
}
case URL_ID: {
- qb.appendWhere("_id = " + url.getPathSegments().get(1));
- qb.appendWhere(NOT_OWNED_BY_DPC);
+ constraints.add("_id = " + url.getPathSegments().get(1));
+ constraints.add(NOT_OWNED_BY_DPC);
break;
}
@@ -2041,11 +2040,12 @@
return null;
}
if (DBG) log("subIdString = " + subIdString + " subId = " + subId);
+ constraints.add(SUBSCRIPTION_ID + "=" + subIdString);
}
//intentional fall through from above case
case URL_PREFERAPN:
case URL_PREFERAPN_NO_UPDATE: {
- qb.appendWhere("_id = " + getPreferredApnId(subId, true));
+ constraints.add("_id = " + getPreferredApnId(subId, true));
break;
}
@@ -2059,6 +2059,11 @@
}
}
+ // appendWhere doesn't add ANDs so we do it ourselves
+ if (constraints.size() > 0) {
+ qb.appendWhere(TextUtils.join(" AND ", constraints));
+ }
+
if (match != URL_SIMINFO) {
if (projectionIn != null) {
for (String column : projectionIn) {
@@ -2200,6 +2205,8 @@
values = new ContentValues();
}
+ values.put(SUBSCRIPTION_ID, subId);
+
values = DatabaseHelper.setDefaultValue(values);
if (!values.containsKey(EDITED)) {
values.put(EDITED, USER_EDITED);
diff --git a/tests/src/com/android/providers/telephony/TelephonyProviderTest.java b/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
index e66dc09..74dfdf9 100644
--- a/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
+++ b/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
@@ -35,6 +35,7 @@
import android.os.FileUtils;
import android.provider.Telephony.Carriers;
import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
import android.test.AndroidTestCase;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;
@@ -51,6 +52,10 @@
import org.junit.Before;
import org.junit.Test;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
/**
* Tests for testing CRUD operations of TelephonyProvider.
@@ -73,6 +78,12 @@
private int notifyChangeCount;
+ private static final String TEST_SUBID = "1";
+ private static final String TEST_OPERATOR = "123456";
+ // Used to test the path for URL_TELEPHONY_USING_SUBID with subid 0
+ private static final Uri CONTENT_URI_WITH_SUBID = Uri.parse(
+ "content://telephony/carriers/subId/" + TEST_SUBID);
+
/**
* This is used to give the TelephonyProviderTest a mocked context which takes a
@@ -81,6 +92,7 @@
*/
private class MockContextWithProvider extends MockContext {
private final MockContentResolver mResolver;
+ private TelephonyManager mTelephonyManager = mock(TelephonyManager.class);
public MockContextWithProvider(TelephonyProvider telephonyProvider) {
mResolver = new MockContentResolver() {
@@ -91,6 +103,9 @@
}
};
+ // return test subId 0 for all operators
+ doReturn(TEST_OPERATOR).when(mTelephonyManager).getSimOperator(anyInt());
+
// Add authority="telephony" to given telephonyProvider
ProviderInfo providerInfo = new ProviderInfo();
providerInfo.authority = "telephony";
@@ -108,8 +123,13 @@
@Override
public Object getSystemService(String name) {
- Log.d(TAG, "getSystemService: returning null");
- return null;
+ if (name.equals(Context.TELEPHONY_SERVICE)) {
+ Log.d(TAG, "getSystemService: returning mock TM");
+ return mTelephonyManager;
+ } else {
+ Log.d(TAG, "getSystemService: returning null");
+ return null;
+ }
}
@Override
@@ -165,7 +185,7 @@
final String insertApn = "exampleApnName";
final String insertName = "exampleName";
final Integer insertCurrent = 1;
- final String insertNumeric = "123456";
+ final String insertNumeric = TEST_OPERATOR;
contentValues.put(Carriers.APN, insertApn);
contentValues.put(Carriers.NAME, insertName);
contentValues.put(Carriers.CURRENT, insertCurrent);
@@ -222,19 +242,80 @@
@Test
@SmallTest
public void testInsertCarriers() {
+ doSimpleTestForUri(Carriers.CONTENT_URI);
+ }
+
+ /**
+ * Test inserting, querying, and deleting values in carriers table.
+ * Verify that the inserted values match the result of the query and are deleted.
+ */
+ @Test
+ @SmallTest
+ public void testInsertCarriersWithSubId() {
+ doSimpleTestForUri(CONTENT_URI_WITH_SUBID);
+ }
+
+ private void doSimpleTestForUri(Uri uri) {
// insert test contentValues
ContentValues contentValues = new ContentValues();
final String insertApn = "exampleApnName";
final String insertName = "exampleName";
- final Integer insertCurrent = 1;
- final String insertNumeric = "123456";
- final Integer insertOwnedby = Carriers.OWNED_BY_DPC;
- final Integer expectedOwnedby = Carriers.OWNED_BY_OTHERS;
+ final String insertNumeric = TEST_OPERATOR;
contentValues.put(Carriers.APN, insertApn);
contentValues.put(Carriers.NAME, insertName);
- contentValues.put(Carriers.CURRENT, insertCurrent);
contentValues.put(Carriers.NUMERIC, insertNumeric);
- contentValues.put(Carriers.OWNED_BY, insertOwnedby);
+
+ Log.d(TAG, "testInsertCarriers Inserting contentValues: " + contentValues);
+ mContentResolver.insert(uri, contentValues);
+
+ // get values in table
+ final String[] testProjection =
+ {
+ Carriers.APN,
+ Carriers.NAME,
+ };
+ final String selection = Carriers.NUMERIC + "=?";
+ String[] selectionArgs = { insertNumeric };
+ Log.d(TAG, "testInsertCarriers query projection: " + testProjection
+ + "\ntestInsertCarriers selection: " + selection
+ + "\ntestInsertCarriers selectionArgs: " + selectionArgs);
+ Cursor cursor = mContentResolver.query(uri, testProjection, selection, selectionArgs, null);
+
+ // verify that inserted values match results of query
+ assertNotNull(cursor);
+ assertEquals(1, cursor.getCount());
+ cursor.moveToFirst();
+ final String resultApn = cursor.getString(0);
+ final String resultName = cursor.getString(1);
+ assertEquals(insertApn, resultApn);
+ assertEquals(insertName, resultName);
+
+ // delete test content
+ final String selectionToDelete = Carriers.NUMERIC + "=?";
+ String[] selectionArgsToDelete = { insertNumeric };
+ Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete
+ + "testInsertCarriers selectionArgs: " + selectionArgs);
+ int numRowsDeleted = mContentResolver.delete(uri, selectionToDelete, selectionArgsToDelete);
+ assertEquals(1, numRowsDeleted);
+
+ // verify that deleted values are gone
+ cursor = mContentResolver.query(uri, testProjection, selection, selectionArgs, null);
+ assertEquals(0, cursor.getCount());
+ }
+
+ @Test
+ @SmallTest
+ public void testOwnedBy() {
+ // insert test contentValues
+ ContentValues contentValues = new ContentValues();
+ final String insertApn = "exampleApnName";
+ final String insertName = "exampleName";
+ final String insertNumeric = TEST_OPERATOR;
+ final Integer insertOwnedBy = Carriers.OWNED_BY_OTHERS;
+ contentValues.put(Carriers.APN, insertApn);
+ contentValues.put(Carriers.NAME, insertName);
+ contentValues.put(Carriers.NUMERIC, insertNumeric);
+ contentValues.put(Carriers.OWNED_BY, insertOwnedBy);
Log.d(TAG, "testInsertCarriers Inserting contentValues: " + contentValues);
mContentResolver.insert(Carriers.CONTENT_URI, contentValues);
@@ -244,7 +325,6 @@
{
Carriers.APN,
Carriers.NAME,
- Carriers.CURRENT,
Carriers.OWNED_BY,
};
final String selection = Carriers.NUMERIC + "=?";
@@ -261,13 +341,11 @@
cursor.moveToFirst();
final String resultApn = cursor.getString(0);
final String resultName = cursor.getString(1);
- final Integer resultCurrent = cursor.getInt(2);
- final Integer resultOwnedby = cursor.getInt(3);
+ final Integer resultOwnedBy = cursor.getInt(2);
assertEquals(insertApn, resultApn);
assertEquals(insertName, resultName);
- assertEquals(insertCurrent, resultCurrent);
- // Verify that OWNED_BY is force set to OWNED_BY_OTHERS when inserted with general uri.
- assertEquals(expectedOwnedby, resultOwnedby);
+ // Verify that OWNED_BY is force set to OWNED_BY_OTHERS when inserted with general uri
+ assertEquals(insertOwnedBy, resultOwnedBy);
// delete test content
final String selectionToDelete = Carriers.NUMERIC + "=?";
diff --git a/tests/src/com/android/providers/telephony/TelephonyProviderTestable.java b/tests/src/com/android/providers/telephony/TelephonyProviderTestable.java
index c3924c3..7ed40ae 100644
--- a/tests/src/com/android/providers/telephony/TelephonyProviderTestable.java
+++ b/tests/src/com/android/providers/telephony/TelephonyProviderTestable.java
@@ -19,6 +19,7 @@
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.Telephony;
+import android.support.test.InstrumentationRegistry;
import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.util.Log;
@@ -78,7 +79,7 @@
public InMemoryTelephonyProviderDbHelper() {
- super(null, // no context is needed for in-memory db
+ super(InstrumentationRegistry.getTargetContext(),
null, // db file name is null for in-memory db
null, // CursorFactory is null by default
1); // db version is no-op for tests