Import translations. DO NOT MERGE
am: d51baf20ba -s ours
Change-Id: I04a086ab0018053ac6fa7c3efa98b66cdeb2c99f
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..691af77
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,5 @@
+amitmahajan@google.com
+fionaxu@google.com
+jminjie@google.com
+rgreenwalt@google.com
+tomtaylor@google.com
diff --git a/res/values-en-rCA/config.xml b/res/values-en-rCA/config.xml
new file mode 100644
index 0000000..99877a6
--- /dev/null
+++ b/res/values-en-rCA/config.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="persist_apns_for_plmn">
+ <item msgid="6413072509259000954">"20404"</item>
+ <item msgid="5639159280778239123">"310004"</item>
+ <item msgid="3860605521380788028">"310120"</item>
+ <item msgid="537693705785480198">"311480"</item>
+ </string-array>
+</resources>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..f11997b
--- /dev/null
+++ b/res/values-en-rCA/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2008 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" product="tablet" msgid="9194799012395299737">"Mobile Network Configuration"</string>
+ <string name="app_label" product="default" msgid="8338087656149558019">"Phone and Messaging Storage"</string>
+</resources>
diff --git a/res/values-en-rXC/config.xml b/res/values-en-rXC/config.xml
new file mode 100644
index 0000000..274d8aa
--- /dev/null
+++ b/res/values-en-rXC/config.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="persist_apns_for_plmn">
+ <item msgid="6413072509259000954">"20404"</item>
+ <item msgid="5639159280778239123">"310004"</item>
+ <item msgid="3860605521380788028">"310120"</item>
+ <item msgid="537693705785480198">"311480"</item>
+ </string-array>
+</resources>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..22950f7
--- /dev/null
+++ b/res/values-en-rXC/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2008 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" product="tablet" msgid="9194799012395299737">"Mobile Network Configuration"</string>
+ <string name="app_label" product="default" msgid="8338087656149558019">"Phone and Messaging Storage"</string>
+</resources>
diff --git a/src/com/android/providers/telephony/CarrierDatabaseHelper.java b/src/com/android/providers/telephony/CarrierDatabaseHelper.java
index 5236b89..b654a77 100644
--- a/src/com/android/providers/telephony/CarrierDatabaseHelper.java
+++ b/src/com/android/providers/telephony/CarrierDatabaseHelper.java
@@ -21,6 +21,8 @@
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.text.TextUtils;
+import android.util.Log;
+
import java.util.ArrayList;
import java.util.List;
@@ -30,7 +32,7 @@
private static final String DATABASE_NAME = "CarrierInformation.db";
public static final String CARRIER_KEY_TABLE = "carrier_key";
- private static final int DATABASE_VERSION = 1;
+ private static final int DATABASE_VERSION = 2;
/**
* CarrierDatabaseHelper carrier database helper class.
@@ -40,14 +42,15 @@
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
- static final String KEY_TYPE = "key_type";
- static final String KEY = "key";
- static final String MCC = "mcc";
- static final String MNC = "mnc";
- static final String MVNO_TYPE = "mvno_type";
- static final String MVNO_MATCH_DATA = "mvno_match_data";
- static final String PUBLIC_CERTIFICATE = "public_certificate";
- static final String LAST_MODIFIED = "last_modified";
+ public static final String KEY_TYPE = "key_type";
+ public static final String MCC = "mcc";
+ public static final String MNC = "mnc";
+ public static final String MVNO_TYPE = "mvno_type";
+ public static final String MVNO_MATCH_DATA = "mvno_match_data";
+ public static final String PUBLIC_KEY = "public_key";
+ public static final String KEY_IDENTIFIER = "key_identifier";
+ public static final String EXPIRATION_TIME = "expiration_time";
+ public static final String LAST_MODIFIED = "last_modified";
private static final List<String> CARRIERS_UNIQUE_FIELDS = new ArrayList<String>();
@@ -67,8 +70,9 @@
MVNO_TYPE + " TEXT DEFAULT ''," +
MVNO_MATCH_DATA + " TEXT DEFAULT ''," +
KEY_TYPE + " TEXT DEFAULT ''," +
- KEY + " TEXT DEFAULT ''," +
- PUBLIC_CERTIFICATE + " TEXT DEFAULT ''," +
+ KEY_IDENTIFIER + " TEXT DEFAULT ''," +
+ PUBLIC_KEY + " BLOB DEFAULT ''," +
+ EXPIRATION_TIME + " INTEGER DEFAULT 0," +
LAST_MODIFIED + " INTEGER DEFAULT 0," +
"UNIQUE (" + TextUtils.join(", ", CARRIERS_UNIQUE_FIELDS) + "));";
}
@@ -78,8 +82,20 @@
db.execSQL(getStringForCarrierKeyTableCreation(CARRIER_KEY_TABLE));
}
+ public void createCarrierTable(SQLiteDatabase db) {
+ db.execSQL(getStringForCarrierKeyTableCreation(CARRIER_KEY_TABLE));
+ }
+
+ public void dropCarrierTable(SQLiteDatabase db) {
+ db.execSQL("DROP TABLE IF EXISTS " + CARRIER_KEY_TABLE + ";");
+ }
+
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- // do nothing
+ Log.d(TAG, "dbh.onUpgrade:+ db=" + db + " oldV=" + oldVersion + " newV=" + newVersion);
+ if (oldVersion < 2) {
+ dropCarrierTable(db);
+ createCarrierTable(db);
+ }
}
}
diff --git a/src/com/android/providers/telephony/CarrierProvider.java b/src/com/android/providers/telephony/CarrierProvider.java
index 1c85806..a4b6ea0 100644
--- a/src/com/android/providers/telephony/CarrierProvider.java
+++ b/src/com/android/providers/telephony/CarrierProvider.java
@@ -78,24 +78,34 @@
@Override
public Uri insert(Uri uri, ContentValues values) {
values.put(CarrierDatabaseHelper.LAST_MODIFIED, System.currentTimeMillis());
- long row = getWritableDatabase().insert(CarrierDatabaseHelper.CARRIER_KEY_TABLE,
+ long row = getWritableDatabase().insertOrThrow(CarrierDatabaseHelper.CARRIER_KEY_TABLE,
null, values);
if (row > 0) {
Uri newUri = ContentUris.withAppendedId(CONTENT_URI, row);
getContext().getContentResolver().notifyChange(newUri, null);
return newUri;
}
- throw new SQLException("Fail to add a new record into " + uri);
+ return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
- throw new UnsupportedOperationException("Cannot delete URL: " + uri);
+ if (VDBG) {
+ Log.d(TAG, "delete:"
+ + " uri=" + uri
+ + " selection={" + selection + "}"
+ + " selection=" + selection
+ + " selectionArgs=" + Arrays.toString(selectionArgs));
+ }
+ final int count = getWritableDatabase().delete(CarrierDatabaseHelper.CARRIER_KEY_TABLE,
+ selection, selectionArgs);
+ Log.d(TAG, " delete.count=" + count);
+ return count;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
-
+ values.put(CarrierDatabaseHelper.LAST_MODIFIED, System.currentTimeMillis());
if (VDBG) {
Log.d(TAG, "update:"
+ " uri=" + uri
diff --git a/src/com/android/providers/telephony/HbpcdLookupDatabaseHelper.java b/src/com/android/providers/telephony/HbpcdLookupDatabaseHelper.java
index ceaed4c..2debc57 100644
--- a/src/com/android/providers/telephony/HbpcdLookupDatabaseHelper.java
+++ b/src/com/android/providers/telephony/HbpcdLookupDatabaseHelper.java
@@ -86,6 +86,7 @@
private static final String DATABASE_NAME = "HbpcdLookup.db";
private static final int DATABASE_VERSION = 1;
+ private static final int IDLE_CONNECTION_TIMEOUT_MS = 30000;
// Context to access resources with
private Context mContext;
@@ -99,6 +100,8 @@
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mContext = context;
+ // Memory optimization - close idle connections after 30s of inactivity
+ setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
}
@Override
diff --git a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
index c9051d6..4b84fe5 100644
--- a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
+++ b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
@@ -39,6 +39,7 @@
import android.telephony.SubscriptionManager;
import android.util.Log;
+import com.android.internal.annotations.VisibleForTesting;
import com.google.android.mms.pdu.EncodedStringValue;
import com.google.android.mms.pdu.PduHeaders;
@@ -240,14 +241,17 @@
static final String DATABASE_NAME = "mmssms.db";
static final int DATABASE_VERSION = 66;
+ private static final int IDLE_CONNECTION_TIMEOUT_MS = 30000;
+
private final Context mContext;
private LowStorageMonitor mLowStorageMonitor;
private MmsSmsDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
-
mContext = context;
+ // Memory optimization - close idle connections after 30s of inactivity
+ setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
}
/**
@@ -851,33 +855,44 @@
"END;");
}
+ @VisibleForTesting
+ public static String CREATE_SMS_TABLE_STRING =
+ "CREATE TABLE sms (" +
+ "_id INTEGER PRIMARY KEY," +
+ "thread_id INTEGER," +
+ "address TEXT," +
+ "person INTEGER," +
+ "date INTEGER," +
+ "date_sent INTEGER DEFAULT 0," +
+ "protocol INTEGER," +
+ "read INTEGER DEFAULT 0," +
+ "status INTEGER DEFAULT -1," + // a TP-Status value
+ // or -1 if it
+ // status hasn't
+ // been received
+ "type INTEGER," +
+ "reply_path_present INTEGER," +
+ "subject TEXT," +
+ "body TEXT," +
+ "service_center TEXT," +
+ "locked INTEGER DEFAULT 0," +
+ "sub_id INTEGER DEFAULT " + SubscriptionManager.INVALID_SUBSCRIPTION_ID + ", " +
+ "error_code INTEGER DEFAULT 0," +
+ "creator TEXT," +
+ "seen INTEGER DEFAULT 0" +
+ ");";
+
+ @VisibleForTesting
+ public static String CREATE_ATTACHMENTS_TABLE_STRING =
+ "CREATE TABLE attachments (" +
+ "sms_id INTEGER," +
+ "content_url TEXT," +
+ "offset INTEGER);";
+
private void createSmsTables(SQLiteDatabase db) {
// N.B.: Whenever the columns here are changed, the columns in
// {@ref MmsSmsProvider} must be changed to match.
- db.execSQL("CREATE TABLE sms (" +
- "_id INTEGER PRIMARY KEY," +
- "thread_id INTEGER," +
- "address TEXT," +
- "person INTEGER," +
- "date INTEGER," +
- "date_sent INTEGER DEFAULT 0," +
- "protocol INTEGER," +
- "read INTEGER DEFAULT 0," +
- "status INTEGER DEFAULT -1," + // a TP-Status value
- // or -1 if it
- // status hasn't
- // been received
- "type INTEGER," +
- "reply_path_present INTEGER," +
- "subject TEXT," +
- "body TEXT," +
- "service_center TEXT," +
- "locked INTEGER DEFAULT 0," +
- "sub_id INTEGER DEFAULT " + SubscriptionManager.INVALID_SUBSCRIPTION_ID + ", " +
- "error_code INTEGER DEFAULT 0," +
- "creator TEXT," +
- "seen INTEGER DEFAULT 0" +
- ");");
+ db.execSQL(CREATE_SMS_TABLE_STRING);
/**
* This table is used by the SMS dispatcher to hold
@@ -899,10 +914,7 @@
// email address if from an email gateway, otherwise same as address
);
- db.execSQL("CREATE TABLE attachments (" +
- "sms_id INTEGER," +
- "content_url TEXT," +
- "offset INTEGER);");
+ db.execSQL(CREATE_ATTACHMENTS_TABLE_STRING);
/**
* This table is used by the SMS dispatcher to hold pending
diff --git a/src/com/android/providers/telephony/ProviderUtil.java b/src/com/android/providers/telephony/ProviderUtil.java
index 4234b06..cd0f351 100644
--- a/src/com/android/providers/telephony/ProviderUtil.java
+++ b/src/com/android/providers/telephony/ProviderUtil.java
@@ -109,6 +109,7 @@
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.d(TAG, "notifyIfNotDefaultSmsApp - called from " + callingPackage + ", notifying");
}
+ intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.sendBroadcast(intent);
}
diff --git a/src/com/android/providers/telephony/SmsProvider.java b/src/com/android/providers/telephony/SmsProvider.java
index eca18a6..37a1044 100644
--- a/src/com/android/providers/telephony/SmsProvider.java
+++ b/src/com/android/providers/telephony/SmsProvider.java
@@ -120,7 +120,7 @@
// Generate the body of the query.
int match = sURLMatcher.match(url);
- SQLiteDatabase db = getDBOpenHelper(match).getReadableDatabase();
+ SQLiteDatabase db = getReadableDatabase(match);
switch (match) {
case SMS_ALL:
constructQueryForBox(qb, Sms.MESSAGE_TYPE_ALL, smsTable);
@@ -521,7 +521,7 @@
return null;
}
- SQLiteDatabase db = getDBOpenHelper(match).getWritableDatabase();
+ SQLiteDatabase db = getWritableDatabase(match);
if (table.equals(TABLE_SMS)) {
boolean addDate = false;
@@ -632,12 +632,7 @@
db.insert(TABLE_WORDS, Telephony.MmsSms.WordsTable.INDEXED_TEXT, cv);
}
if (rowID > 0) {
- Uri uri;
- if (table == TABLE_SMS) {
- uri = Uri.withAppendedPath(url, "/" + rowID);
- } else {
- uri = Uri.withAppendedPath(url, "/" + table + "/" + rowID );
- }
+ Uri uri = Uri.withAppendedPath(url, String.valueOf(rowID));
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.d(TAG, "insert " + uri + " succeeded");
}
@@ -653,7 +648,7 @@
public int delete(Uri url, String where, String[] whereArgs) {
int count;
int match = sURLMatcher.match(url);
- SQLiteDatabase db = getDBOpenHelper(match).getWritableDatabase();
+ SQLiteDatabase db = getWritableDatabase(match);
boolean notifyIfNotDefault = true;
switch (match) {
case SMS_ALL:
@@ -760,7 +755,7 @@
String extraWhere = null;
boolean notifyIfNotDefault = true;
int match = sURLMatcher.match(url);
- SQLiteDatabase db = getDBOpenHelper(match).getWritableDatabase();
+ SQLiteDatabase db = getWritableDatabase(match);
switch (match) {
case SMS_RAW_MESSAGE:
@@ -922,4 +917,16 @@
sURLMatcher.addURI("sms", "sim", SMS_ALL_ICC);
sURLMatcher.addURI("sms", "sim/#", SMS_ICC);
}
+
+ /**
+ * These methods can be overridden in a subclass for testing SmsProvider using an
+ * in-memory database.
+ */
+ SQLiteDatabase getReadableDatabase(int match) {
+ return getDBOpenHelper(match).getReadableDatabase();
+ }
+
+ SQLiteDatabase getWritableDatabase(int match) {
+ return getDBOpenHelper(match).getWritableDatabase();
+ }
}
diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index 32e0b55..49c3d10 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -115,6 +115,7 @@
public class TelephonyProvider extends ContentProvider
{
private static final String DATABASE_NAME = "telephony.db";
+ private static final int IDLE_CONNECTION_TIMEOUT_MS = 30000;
private static final boolean DBG = true;
private static final boolean VDBG = false; // STOPSHIP if true
@@ -143,6 +144,7 @@
private static final String PREF_FILE_APN = "preferred-apn";
private static final String COLUMN_APN_ID = "apn_id";
+ private static final String EXPLICIT_SET_CALLED = "explicit_set_called";
private static final String PREF_FILE_FULL_APN = "preferred-full-apn";
private static final String DB_VERSION_KEY = "version";
@@ -337,6 +339,8 @@
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, getVersion(context));
mContext = context;
+ // Memory optimization - close idle connections after 30s of inactivity
+ setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
}
private static int getVersion(Context context) {
@@ -1815,15 +1819,23 @@
return true;
}
- private void setPreferredApnId(Long id, int subId) {
+ private void setPreferredApnId(Long id, int subId, boolean saveApn) {
SharedPreferences sp = getContext().getSharedPreferences(PREF_FILE_APN,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
- editor.putLong(COLUMN_APN_ID + subId, id != null ? id.longValue() : INVALID_APN_ID);
+ editor.putLong(COLUMN_APN_ID + subId, id != null ? id : INVALID_APN_ID);
+ // This is for debug purposes. It indicates if this APN was set by DcTracker or user (true)
+ // or if this was restored from APN saved in PREF_FILE_FULL_APN (false).
+ editor.putBoolean(EXPLICIT_SET_CALLED + subId, saveApn);
editor.apply();
- // remove saved apn if apnId is invalid
if (id == null || id.longValue() == INVALID_APN_ID) {
deletePreferredApn(subId);
+ } else {
+ // If id is not invalid, and saveApn is true, save the actual APN in PREF_FILE_FULL_APN
+ // too.
+ if (saveApn) {
+ setPreferredApn(id, subId);
+ }
}
}
@@ -1834,8 +1846,7 @@
if (apnId == INVALID_APN_ID && checkApnSp) {
apnId = getPreferredApnIdFromApn(subId);
if (apnId != INVALID_APN_ID) {
- setPreferredApnId(apnId, subId);
- deletePreferredApn(subId);
+ setPreferredApnId(apnId, subId, false);
}
}
return apnId;
@@ -1844,7 +1855,12 @@
private void deletePreferredApnId() {
SharedPreferences sp = getContext().getSharedPreferences(PREF_FILE_APN,
Context.MODE_PRIVATE);
- // before deleting, save actual preferred apns (not the ids) in a separate SP
+
+ // Before deleting, save actual preferred apns (not the ids) in a separate SP.
+ // NOTE: This code to call setPreferredApn() can be removed since the function is now called
+ // from setPreferredApnId(). However older builds (pre oc-mr1) do not have that change, so
+ // when devices upgrade from those builds and this function is called, this code is needed
+ // otherwise the preferred APN will be lost.
Map<String, ?> allPrefApnId = sp.getAll();
for (String key : allPrefApnId.keySet()) {
// extract subId from key by removing COLUMN_APN_ID
@@ -1858,6 +1874,7 @@
loge("Skipping over key " + key + " due to exception " + e);
}
}
+
SharedPreferences.Editor editor = sp.edit();
editor.clear();
editor.apply();
@@ -1935,7 +1952,6 @@
for (String key : CARRIERS_UNIQUE_FIELDS) {
editor.remove(key + subId);
}
- editor.remove(DB_VERSION_KEY + subId);
editor.apply();
}
}
@@ -2254,7 +2270,7 @@
{
if (initialValues != null) {
if(initialValues.containsKey(COLUMN_APN_ID)) {
- setPreferredApnId(initialValues.getAsLong(COLUMN_APN_ID), subId);
+ setPreferredApnId(initialValues.getAsLong(COLUMN_APN_ID), subId, true);
}
}
break;
@@ -2293,6 +2309,8 @@
{
case URL_DELETE:
{
+ // Delete preferred APN for all subIds
+ deletePreferredApnId();
// Delete unedited entries
count = db.delete(CARRIERS_TABLE, "(" + where + unedited, whereArgs);
break;
@@ -2391,7 +2409,7 @@
case URL_PREFERAPN:
case URL_PREFERAPN_NO_UPDATE:
{
- setPreferredApnId((long)INVALID_APN_ID, subId);
+ setPreferredApnId((long)INVALID_APN_ID, subId, true);
if ((match == URL_PREFERAPN) || (match == URL_PREFERAPN_USING_SUBID)) count = 1;
break;
}
@@ -2524,7 +2542,7 @@
{
if (values != null) {
if (values.containsKey(COLUMN_APN_ID)) {
- setPreferredApnId(values.getAsLong(COLUMN_APN_ID), subId);
+ setPreferredApnId(values.getAsLong(COLUMN_APN_ID), subId, true);
if ((match == URL_PREFERAPN) ||
(match == URL_PREFERAPN_USING_SUBID)) {
count = 1;
diff --git a/tests/src/com/android/providers/telephony/CarrierProviderTest.java b/tests/src/com/android/providers/telephony/CarrierProviderTest.java
index 6a56343..5146aa9 100644
--- a/tests/src/com/android/providers/telephony/CarrierProviderTest.java
+++ b/tests/src/com/android/providers/telephony/CarrierProviderTest.java
@@ -54,7 +54,7 @@
private MockContentResolver mContentResolver;
private CarrierProviderTestable mCarrierProviderTestable;
- public static final String dummy_type = "TYPE5";
+ public static final int dummy_type = 1;
public static final String dummy_mnc = "MNC001";
public static final String dummy_mnc2 = "MNC002";
public static final String dummy_mcc = "MCC005";
@@ -62,6 +62,8 @@
public static final String dummy_key2 = "PUBKEY2";
public static final String dummy_mvno_type = "100";
public static final String dummy_mvno_match_data = "101";
+ public static final String dummy_key_identifier_data = "key_identifier1";
+ public static final long dummy_key_expiration = 1496795015L;
/**
@@ -147,7 +149,9 @@
contentValues.put(CarrierDatabaseHelper.MNC, dummy_mnc);
contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, dummy_mvno_type);
contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, dummy_mvno_match_data);
- contentValues.put(CarrierDatabaseHelper.PUBLIC_CERTIFICATE, dummy_key1);
+ contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, dummy_key_identifier_data);
+ contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, dummy_key1.getBytes());
+ contentValues.put(CarrierDatabaseHelper.EXPIRATION_TIME, dummy_key_expiration);
try {
mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
@@ -181,7 +185,9 @@
contentValues.put(CarrierDatabaseHelper.MNC, dummy_mnc);
contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, dummy_mvno_type);
contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, dummy_mvno_match_data);
- contentValues.put(CarrierDatabaseHelper.PUBLIC_CERTIFICATE, dummy_key1);
+ contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, dummy_key_identifier_data);
+ contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, dummy_key1.getBytes());
+ contentValues.put(CarrierDatabaseHelper.EXPIRATION_TIME, dummy_key_expiration);
try {
mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
@@ -191,18 +197,19 @@
try {
ContentValues updatedValues = new ContentValues();
- updatedValues.put(CarrierDatabaseHelper.PUBLIC_CERTIFICATE, dummy_key2);
+ updatedValues.put(CarrierDatabaseHelper.PUBLIC_KEY, dummy_key2);
mContentResolver.update(CarrierProvider.CONTENT_URI, updatedValues,
- "mcc=? and mnc=? and key_type=?", new String[] { dummy_mcc, dummy_mnc, dummy_type });
+ "mcc=? and mnc=? and key_type=?", new String[] { dummy_mcc, dummy_mnc,
+ String.valueOf(dummy_type) });
} catch (Exception e) {
Log.d(TAG, "Error updating values:" + e);
}
try {
- String[] columns ={CarrierDatabaseHelper.PUBLIC_CERTIFICATE};
+ String[] columns ={CarrierDatabaseHelper.PUBLIC_KEY};
Cursor findEntry = mContentResolver.query(CarrierProvider.CONTENT_URI, columns,
"mcc=? and mnc=? and key_type=?",
- new String[] { dummy_mcc, dummy_mnc, dummy_type }, null);
+ new String[] { dummy_mcc, dummy_mnc, String.valueOf(dummy_type) }, null);
findEntry.moveToFirst();
key = findEntry.getString(0);
} catch (Exception e) {
@@ -224,7 +231,8 @@
contentValues.put(CarrierDatabaseHelper.MNC, dummy_mnc);
contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, dummy_mvno_type);
contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, dummy_mvno_match_data);
- contentValues.put(CarrierDatabaseHelper.PUBLIC_CERTIFICATE, dummy_key1);
+ contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, dummy_key_identifier_data);
+ contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, dummy_key1.getBytes());
ContentValues contentValuesNew = new ContentValues();
contentValuesNew.put(CarrierDatabaseHelper.KEY_TYPE, dummy_type);
@@ -232,7 +240,8 @@
contentValuesNew.put(CarrierDatabaseHelper.MNC, dummy_mnc2);
contentValuesNew.put(CarrierDatabaseHelper.MVNO_TYPE, dummy_mvno_type);
contentValuesNew.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, dummy_mvno_match_data);
- contentValuesNew.put(CarrierDatabaseHelper.PUBLIC_CERTIFICATE, dummy_key2);
+ contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, dummy_key_identifier_data);
+ contentValuesNew.put(CarrierDatabaseHelper.PUBLIC_KEY, dummy_key2.getBytes());
try {
mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
@@ -266,7 +275,7 @@
contentValues.put(CarrierDatabaseHelper.MNC, dummy_mnc);
contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, dummy_mvno_type);
contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, dummy_mvno_match_data);
- contentValues.put(CarrierDatabaseHelper.PUBLIC_CERTIFICATE, dummy_key1);
+ contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, dummy_key1.getBytes());
try {
mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
@@ -279,4 +288,38 @@
Log.d(TAG, "Error inserting certificates:: " + e);
}
}
+
+ /**
+ * Test delete.
+ */
+ @Test
+ @SmallTest
+ public void testDelete() {
+ int numRowsDeleted = -1;
+ ContentValues contentValues = new ContentValues();
+ contentValues.put(CarrierDatabaseHelper.KEY_TYPE, dummy_type);
+ contentValues.put(CarrierDatabaseHelper.MCC, dummy_mcc);
+ contentValues.put(CarrierDatabaseHelper.MNC, dummy_mnc);
+ contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, dummy_mvno_type);
+ contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, dummy_mvno_match_data);
+ contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, dummy_key_identifier_data);
+ contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, dummy_key1.getBytes());
+ contentValues.put(CarrierDatabaseHelper.EXPIRATION_TIME, dummy_key_expiration);
+
+ try {
+ mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
+ } catch (Exception e) {
+ Log.d(TAG, "Error inserting certificates:" + e);
+ }
+
+ try {
+ String whereClause = "mcc=? and mnc=?";
+ String[] whereArgs = new String[] { dummy_mcc, dummy_mnc };
+ numRowsDeleted = mContentResolver.delete(CarrierProvider.CONTENT_URI, whereClause, whereArgs);
+ } catch (Exception e) {
+ Log.d(TAG, "Error updating values:" + e);
+ }
+ assertEquals(numRowsDeleted, 1);
+ }
+
}
diff --git a/tests/src/com/android/providers/telephony/SmsProviderTest.java b/tests/src/com/android/providers/telephony/SmsProviderTest.java
new file mode 100644
index 0000000..8fba85b
--- /dev/null
+++ b/tests/src/com/android/providers/telephony/SmsProviderTest.java
@@ -0,0 +1,173 @@
+/*
+ * 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 com.android.providers.telephony;
+
+import android.app.AppOpsManager;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.provider.Telephony;
+import android.telephony.TelephonyManager;
+import android.test.mock.MockContentResolver;
+import android.test.mock.MockContext;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+
+
+/**
+ * Tests for testing CRUD operations of SmsProvider.
+ * Uses a MockContentResolver to test insert
+ * Uses SmsProviderTestable to set up in-memory database
+ *
+ * Build, install and run the tests by running the commands below:
+ * runtest --path <dir or file>
+ * runtest --path <dir or file> --test-method <testMethodName>
+ * e.g.)
+ * runtest --path tests/src/com/android/providers/telephony/SmsProviderTest.java \
+ * --test-method testInsertUri
+ */
+public class SmsProviderTest extends TestCase {
+ private static final String TAG = "TelephonyProviderTest";
+
+ private MockContextWithProvider mContext;
+ private MockContentResolver mContentResolver;
+ private SmsProviderTestable mSmsProviderTestable;
+
+ private int notifyChangeCount;
+
+
+ /**
+ * This is used to give the SmsProviderTest a mocked context which takes a
+ * SmsProvider and attaches it to the ContentResolver with telephony authority.
+ * The mocked context also gives WRITE_APN_SETTINGS permissions
+ */
+ private class MockContextWithProvider extends MockContext {
+ private final MockContentResolver mResolver;
+
+ public MockContextWithProvider(SmsProvider smsProvider) {
+ mResolver = new MockContentResolver() {
+ @Override
+ public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork,
+ int userHandle) {
+ notifyChangeCount++;
+ }
+ };
+
+ // Add authority="sms" to given smsProvider
+ ProviderInfo providerInfo = new ProviderInfo();
+ providerInfo.authority = "sms";
+
+ // Add context to given smsProvider
+ smsProvider.attachInfoForTesting(this, providerInfo);
+ Log.d(TAG, "MockContextWithProvider: smsProvider.getContext(): "
+ + smsProvider.getContext());
+
+ // Add given SmsProvider to mResolver with authority="sms" so that
+ // mResolver can send queries to mSmsProvider
+ mResolver.addProvider("sms", smsProvider);
+ Log.d(TAG, "MockContextWithProvider: Add SmsProvider to mResolver");
+ }
+
+ @Override
+ public Object getSystemService(String name) {
+ Log.d(TAG, "getSystemService: returning null");
+ switch (name) {
+ case Context.APP_OPS_SERVICE:
+ return Mockito.mock(AppOpsManager.class);
+ case Context.TELEPHONY_SERVICE:
+ return Mockito.mock(TelephonyManager.class);
+ default:
+ return null;
+ }
+ }
+
+ @Override
+ public Resources getResources() {
+ Log.d(TAG, "getResources: returning null");
+ return null;
+ }
+
+ @Override
+ public int getUserId() {
+ return 0;
+ }
+
+ @Override
+ public MockContentResolver getContentResolver() {
+ return mResolver;
+ }
+
+ @Override
+ public int checkCallingOrSelfPermission(String permission) {
+ return PackageManager.PERMISSION_GRANTED;
+ }
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mSmsProviderTestable = new SmsProviderTestable();
+ mContext = new MockContextWithProvider(mSmsProviderTestable);
+ mContentResolver = mContext.getContentResolver();
+ notifyChangeCount = 0;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ mSmsProviderTestable.closeDatabase();
+ }
+
+ @Test
+ @SmallTest
+ public void testInsertUri() {
+ // insert test contentValues
+ final ContentValues values = new ContentValues();
+ values.put(Telephony.Sms.SUBSCRIPTION_ID, 1);
+ values.put(Telephony.Sms.ADDRESS, "12345");
+ values.put(Telephony.Sms.BODY, "test");
+ values.put(Telephony.Sms.DATE, System.currentTimeMillis()); // milliseconds
+ values.put(Telephony.Sms.SEEN, 1);
+ values.put(Telephony.Sms.READ, 1);
+ values.put(Telephony.Sms.THREAD_ID, 1);
+
+ // test for sms table
+ Log.d(TAG, "testInsertSmsTable Inserting contentValues: " + values);
+ assertEquals(Uri.parse("content://sms/1"),
+ mContentResolver.insert(Uri.parse("content://sms"), values));
+ assertEquals(Uri.parse("content://sms/2"),
+ mContentResolver.insert(Uri.parse("content://sms"), values));
+
+ // test for attachments table
+ values.clear();
+ values.put("sms_id", 1);
+ values.put("content_url", "test");
+ values.put("offset", 0);
+ Log.d(TAG, "testInsertAttachmentTable Inserting contentValues: " + values);
+ assertEquals(Uri.parse("content://sms/attachments/1"),
+ mContentResolver.insert(Uri.parse("content://sms/attachments"), values));
+ }
+}
\ No newline at end of file
diff --git a/tests/src/com/android/providers/telephony/SmsProviderTestable.java b/tests/src/com/android/providers/telephony/SmsProviderTestable.java
new file mode 100644
index 0000000..9c3372e
--- /dev/null
+++ b/tests/src/com/android/providers/telephony/SmsProviderTestable.java
@@ -0,0 +1,83 @@
+/*
+ * 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 com.android.providers.telephony;
+
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
+
+/**
+ * A subclass of SmsProvider used for testing on an in-memory database
+ */
+public class SmsProviderTestable extends SmsProvider {
+ private static final String TAG = "SmsProviderTestable";
+
+ private InMemorySmsProviderDbHelper mDbHelper;
+
+ @Override
+ public boolean onCreate() {
+ Log.d(TAG, "onCreate called: mDbHelper = new InMemorySmsProviderDbHelper()");
+ mDbHelper = new InMemorySmsProviderDbHelper();
+ return true;
+ }
+
+ @Override
+ SQLiteDatabase getReadableDatabase(int match) {
+ Log.d(TAG, "getReadableDatabase called");
+ return mDbHelper.getReadableDatabase();
+ }
+
+ @Override
+ SQLiteDatabase getWritableDatabase(int match) {
+ Log.d(TAG, "getWritableDatabase called");
+ return mDbHelper.getWritableDatabase();
+ }
+
+ // close mDbHelper database object
+ protected void closeDatabase() {
+ mDbHelper.close();
+ }
+
+ /**
+ * An in memory DB for SmsProviderTestable to use
+ */
+ public static class InMemorySmsProviderDbHelper extends SQLiteOpenHelper {
+
+
+ public InMemorySmsProviderDbHelper() {
+ super(null, // no context is needed for in-memory db
+ null, // db file name is null for in-memory db
+ null, // CursorFactory is null by default
+ 1); // db version is no-op for tests
+ Log.d(TAG, "InMemorySmsProviderDbHelper creating in-memory database");
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ // Set up the sms tables
+ Log.d(TAG, "InMemorySmsProviderDbHelper onCreate creating the sms tables");
+ db.execSQL(MmsSmsDatabaseHelper.CREATE_SMS_TABLE_STRING);
+ db.execSQL(MmsSmsDatabaseHelper.CREATE_ATTACHMENTS_TABLE_STRING);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ Log.d(TAG, "InMemorySmsProviderDbHelper onUpgrade doing nothing");
+ return;
+ }
+ }
+}
+