Merge "Snap for 7110675 from 4f1685621b991185fcb8c05cb5dc33f47ee10ec4 to sdk-release" into sdk-release
diff --git a/assets/latest_carrier_id/carrier_list.pb b/assets/latest_carrier_id/carrier_list.pb
index 486f1ae..0770454 100644
--- a/assets/latest_carrier_id/carrier_list.pb
+++ b/assets/latest_carrier_id/carrier_list.pb
Binary files differ
diff --git a/assets/latest_carrier_id/carrier_list.textpb b/assets/latest_carrier_id/carrier_list.textpb
index 60064d6..7d22143 100644
--- a/assets/latest_carrier_id/carrier_list.textpb
+++ b/assets/latest_carrier_id/carrier_list.textpb
Binary files differ
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 309a57b..9bcbd19 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -16,6 +16,6 @@
<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">"تهيئة شبكة الجوال"</string>
+ <string name="app_label" product="tablet" msgid="9194799012395299737">"إعداد شبكة الجوال"</string>
<string name="app_label" product="default" msgid="8338087656149558019">"مساحة تخزين للهاتف والرسائل"</string>
</resources>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index 1c1c927..dc13503 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -17,5 +17,5 @@
<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">"Мобайль Сүлжээний Тохируулга"</string>
- <string name="app_label" product="default" msgid="8338087656149558019">"Гар утас болон Зурвасын Санах ой"</string>
+ <string name="app_label" product="default" msgid="8338087656149558019">"Гар утас болон Мессежийн Санах ой"</string>
</resources>
diff --git a/src/com/android/providers/telephony/MmsSmsProvider.java b/src/com/android/providers/telephony/MmsSmsProvider.java
index f5aeadc..8e01bcc 100644
--- a/src/com/android/providers/telephony/MmsSmsProvider.java
+++ b/src/com/android/providers/telephony/MmsSmsProvider.java
@@ -305,7 +305,6 @@
private SQLiteOpenHelper mOpenHelper;
private boolean mUseStrictPhoneNumberComparation;
- private int mMinMatch;
private static final String METHOD_IS_RESTORING = "is_restoring";
private static final String IS_RESTORING_KEY = "restoring";
@@ -317,9 +316,6 @@
mUseStrictPhoneNumberComparation =
getContext().getResources().getBoolean(
com.android.internal.R.bool.config_use_strict_phone_number_comparation);
- mMinMatch =
- getContext().getResources().getInteger(
- com.android.internal.R.integer.config_phonenumber_compare_min_match);
TelephonyBackupAgent.DeferredSmsMmsRestoreService.startIfFilesExist(getContext());
return true;
}
@@ -551,12 +547,15 @@
String selection = "address=?";
String[] selectionArgs;
long retVal = -1L;
+ int minMatch =
+ getContext().getResources().getInteger(
+ com.android.internal.R.integer.config_phonenumber_compare_min_match);
if (!isPhoneNumber) {
selectionArgs = new String[] { refinedAddress };
} else {
selection += " OR PHONE_NUMBERS_EQUAL(address, ?, " +
- (mUseStrictPhoneNumberComparation ? "1)" : "0, " + mMinMatch + ")");
+ (mUseStrictPhoneNumberComparation ? "1)" : "0, " + minMatch + ")");
selectionArgs = new String[] { refinedAddress, refinedAddress };
}
@@ -1011,19 +1010,22 @@
* FROM pdu, (SELECT msg_id AS address_msg_id
* FROM addr
* WHERE (address='<phoneNumber>' OR
- * PHONE_NUMBERS_EQUAL(addr.address, '<phoneNumber>', 1/0, none/mMinMatch)))
+ * PHONE_NUMBERS_EQUAL(addr.address, '<phoneNumber>', 1/0, none/minMatch)))
* AS matching_addresses
* WHERE pdu._id = matching_addresses.address_msg_id
* UNION
* SELECT ...
* FROM sms
* WHERE (address='<phoneNumber>' OR
- * PHONE_NUMBERS_EQUAL(sms.address, '<phoneNumber>', 1/0, none/mMinMatch));
+ * PHONE_NUMBERS_EQUAL(sms.address, '<phoneNumber>', 1/0, none/minMatch));
*/
private Cursor getMessagesByPhoneNumber(
String phoneNumber, String[] projection, String selection,
String sortOrder, String smsTable, String pduTable) {
String escapedPhoneNumber = DatabaseUtils.sqlEscapeString(phoneNumber);
+ int minMatch =
+ getContext().getResources().getInteger(
+ com.android.internal.R.integer.config_phonenumber_compare_min_match);
String finalMmsSelection =
concatSelections(
selection,
@@ -1033,7 +1035,7 @@
selection,
"(address=" + escapedPhoneNumber + " OR PHONE_NUMBERS_EQUAL(address, " +
escapedPhoneNumber +
- (mUseStrictPhoneNumberComparation ? ", 1))" : ", 0, " + mMinMatch + "))"));
+ (mUseStrictPhoneNumberComparation ? ", 1))" : ", 0, " + minMatch + "))"));
SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
@@ -1045,7 +1047,7 @@
"FROM addr WHERE (address=" + escapedPhoneNumber +
" OR PHONE_NUMBERS_EQUAL(addr.address, " +
escapedPhoneNumber +
- (mUseStrictPhoneNumberComparation ? ", 1))) " : ", 0, " + mMinMatch + "))) ") +
+ (mUseStrictPhoneNumberComparation ? ", 1))) " : ", 0, " + minMatch + "))) ") +
"AS matching_addresses");
smsQueryBuilder.setTables(smsTable);
diff --git a/src/com/android/providers/telephony/TelephonyBackupAgent.java b/src/com/android/providers/telephony/TelephonyBackupAgent.java
index 958c929..6ce5da1 100644
--- a/src/com/android/providers/telephony/TelephonyBackupAgent.java
+++ b/src/com/android/providers/telephony/TelephonyBackupAgent.java
@@ -631,12 +631,16 @@
ContentValues[] values = new ContentValues[bulkInsertSize];
while (jsonReader.hasNext()) {
ContentValues cv = readSmsValuesFromReader(jsonReader);
- if (doesSmsExist(cv)) {
- continue;
- }
- values[(msgCount++) % bulkInsertSize] = cv;
- if (msgCount % bulkInsertSize == 0) {
- mContentResolver.bulkInsert(Telephony.Sms.CONTENT_URI, values);
+ try {
+ if (mSmsProviderQuery.doesSmsExist(cv)) {
+ continue;
+ }
+ values[(msgCount++) % bulkInsertSize] = cv;
+ if (msgCount % bulkInsertSize == 0) {
+ mContentResolver.bulkInsert(Telephony.Sms.CONTENT_URI, values);
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "putSmsMessagesToProvider", e);
}
}
if (msgCount % bulkInsertSize > 0) {
@@ -655,16 +659,20 @@
if (DEBUG) {
Log.d(TAG, "putMmsMessagesToProvider " + mms);
}
- if (doesMmsExist(mms)) {
- if (DEBUG) {
- Log.e(TAG, String.format("Mms: %s already exists", mms.toString()));
- } else {
- Log.w(TAG, "Mms: Found duplicate MMS");
+ try {
+ if (doesMmsExist(mms)) {
+ if (DEBUG) {
+ Log.e(TAG, String.format("Mms: %s already exists", mms.toString()));
+ } else {
+ Log.w(TAG, "Mms: Found duplicate MMS");
+ }
+ continue;
}
- continue;
+ total++;
+ addMmsMessage(mms);
+ } catch (Exception e) {
+ Log.e(TAG, "putMmsMessagesToProvider", e);
}
- total++;
- addMmsMessage(mms);
}
Log.d(TAG, "putMmsMessagesToProvider handled " + total + " new messages.");
}
@@ -673,15 +681,34 @@
static final String[] PROJECTION_ID = {BaseColumns._ID};
private static final int ID_IDX = 0;
- private boolean doesSmsExist(ContentValues smsValues) {
- final String where = String.format(Locale.US, "%s = %d and %s = %s",
- Telephony.Sms.DATE, smsValues.getAsLong(Telephony.Sms.DATE),
- Telephony.Sms.BODY,
- DatabaseUtils.sqlEscapeString(smsValues.getAsString(Telephony.Sms.BODY)));
- try (Cursor cursor = mContentResolver.query(Telephony.Sms.CONTENT_URI, PROJECTION_ID, where,
- null, null)) {
- return cursor != null && cursor.getCount() > 0;
+ /**
+ * Interface to allow mocking method for testing.
+ */
+ public interface SmsProviderQuery {
+ boolean doesSmsExist(ContentValues smsValues);
+ }
+
+ private SmsProviderQuery mSmsProviderQuery = new SmsProviderQuery() {
+ @Override
+ public boolean doesSmsExist(ContentValues smsValues) {
+ // The SMS body might contain '\0' characters (U+0000) such as in the case of
+ // http://b/160801497 . SQLite does not allow '\0' in String literals, but as of SQLite
+ // version 3.32.2 2020-06-04, it does allow them as selectionArgs; therefore, we're
+ // using the latter approach here.
+ final String selection = String.format(Locale.US, "%s=%d AND %s=?",
+ Telephony.Sms.DATE, smsValues.getAsLong(Telephony.Sms.DATE),
+ Telephony.Sms.BODY);
+ String[] selectionArgs = new String[] { smsValues.getAsString(Telephony.Sms.BODY)};
+ try (Cursor cursor = mContentResolver.query(Telephony.Sms.CONTENT_URI, PROJECTION_ID,
+ selection, selectionArgs, null)) {
+ return cursor != null && cursor.getCount() > 0;
+ }
}
+ };
+
+ @VisibleForTesting
+ public void setSmsProviderQuery(SmsProviderQuery smsProviderQuery) {
+ mSmsProviderQuery = smsProviderQuery;
}
private boolean doesMmsExist(Mms mms) {
diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index 98bc81e..8e89ab3 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -128,6 +128,7 @@
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.Integer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -147,7 +148,7 @@
private static final boolean DBG = true;
private static final boolean VDBG = false; // STOPSHIP if true
- private static final int DATABASE_VERSION = 45 << 16;
+ private static final int DATABASE_VERSION = 47 << 16;
private static final int URL_UNKNOWN = 0;
private static final int URL_TELEPHONY = 1;
private static final int URL_CURRENT = 2;
@@ -470,7 +471,9 @@
+ Telephony.SimInfo.COLUMN_IMSI + " TEXT,"
+ Telephony.SimInfo.COLUMN_UICC_APPLICATIONS_ENABLED + " INTEGER DEFAULT 1,"
+ Telephony.SimInfo.COLUMN_ALLOWED_NETWORK_TYPES + " BIGINT DEFAULT -1,"
- + Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED + " INTEGER DEFAULT 0"
+ + Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED + " INTEGER DEFAULT 0,"
+ + Telephony.SimInfo.COLUMN_CROSS_SIM_CALLING_ENABLED + " INTEGER DEFAULT 0,"
+ + Telephony.SimInfo.COLUMN_RCS_CONFIG + " BLOB"
+ ");";
}
@@ -752,7 +755,7 @@
try {
XmlUtils.beginDocument(parser, "apns");
publicversion = Integer.parseInt(parser.getAttributeValue(null, "version"));
- loadApns(db, parser);
+ loadApns(db, parser, true);
} catch (Exception e) {
loge("Got exception while loading APN database." + e);
} finally {
@@ -782,7 +785,7 @@
+ confFile.getAbsolutePath());
}
- loadApns(db, confparser);
+ loadApns(db, confparser, false);
} catch (FileNotFoundException e) {
// It's ok if the file isn't found. It means there isn't a confidential file
// Log.e(TAG, "File not found: '" + confFile.getAbsolutePath() + "'");
@@ -1484,6 +1487,36 @@
oldVersion = 45 << 16 | 6;
}
+ if (oldVersion < (46 << 16 | 6)) {
+ try {
+ // Try to update the siminfo table. It might not be there.
+ db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+ + Telephony.SimInfo.COLUMN_CROSS_SIM_CALLING_ENABLED
+ + " INTEGER DEFAULT 0;");
+ } catch (SQLiteException e) {
+ if (DBG) {
+ log("onUpgrade skipping " + SIMINFO_TABLE + " upgrade. " +
+ "The table will get created in onOpen.");
+ }
+ }
+ oldVersion = 46 << 16 | 6;
+ }
+
+ if (oldVersion < (47 << 16 | 6)) {
+ try {
+ // Try to update the siminfo table. It might not be there.
+ db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+ + Telephony.SimInfo.COLUMN_RCS_CONFIG
+ + " BLOB;");
+ } catch (SQLiteException e) {
+ if (DBG) {
+ log("onUpgrade skipping " + SIMINFO_TABLE + " upgrade. " +
+ "The table will get created in onOpen.");
+ }
+ }
+ oldVersion = 47 << 16 | 6;
+ }
+
if (DBG) {
log("dbh.onUpgrade:- db=" + db + " oldV=" + oldVersion + " newV=" + newVersion);
}
@@ -1669,7 +1702,7 @@
try {
XmlUtils.nextElement(parser);
while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
- ContentValues row = getRow(parser);
+ ContentValues row = getRow(parser, false);
if (row == null) {
throw new XmlPullParserException("Expected 'apn' tag", parser, null);
}
@@ -2076,9 +2109,10 @@
* Gets the next row of apn values.
*
* @param parser the parser
+ * @param isOverlay If the xml file comes from an overlay MCC/MNC are treated as integers
* @return the row or null if it's not an apn
*/
- private ContentValues getRow(XmlPullParser parser) {
+ private ContentValues getRow(XmlPullParser parser, boolean isOverlay) {
if (!"apn".equals(parser.getName())) {
return null;
}
@@ -2087,11 +2121,21 @@
String mcc = parser.getAttributeValue(null, "mcc");
String mnc = parser.getAttributeValue(null, "mnc");
- String numeric = mcc + mnc;
+ String mccString = mcc;
+ String mncString = mnc;
+ // Since an mnc can have both two and three digits and it is hard to verify
+ // all OEM's Global APN lists we only do this for overlays.
+ if (isOverlay) {
+ mccString = String.format("%03d", Integer.parseInt(mcc));
+ // Looks up a two digit mnc in the carrier id DB
+ // if not found a three digit mnc value is chosen
+ mncString = getBestStringMnc(mContext, mccString, Integer.parseInt(mnc));
+ }
+ String numeric = mccString + mncString;
map.put(NUMERIC, numeric);
- map.put(MCC, mcc);
- map.put(MNC, mnc);
+ map.put(MCC, mccString);
+ map.put(MNC, mncString);
map.put(NAME, parser.getAttributeValue(null, "carrier"));
// do not add NULL to the map so that default values can be inserted in db
@@ -2160,7 +2204,6 @@
map.put(MVNO_MATCH_DATA, mvno_match_data);
}
}
-
return map;
}
@@ -2193,15 +2236,15 @@
*
* @param db the sqlite database to write to
* @param parser the xml parser
- *
+ * @param isOverlay, if we are parsing an xml in an overlay
*/
- private void loadApns(SQLiteDatabase db, XmlPullParser parser) {
+ private void loadApns(SQLiteDatabase db, XmlPullParser parser, boolean isOverlay) {
if (parser != null) {
try {
db.beginTransaction();
XmlUtils.nextElement(parser);
while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
- ContentValues row = getRow(parser);
+ ContentValues row = getRow(parser, isOverlay);
if (row == null) {
throw new XmlPullParserException("Expected 'apn' tag", parser, null);
}
@@ -3474,6 +3517,7 @@
if (initialValues != null) {
if(initialValues.containsKey(COLUMN_APN_ID)) {
setPreferredApnId(initialValues.getAsLong(COLUMN_APN_ID), subId, true);
+ notify = true;
}
}
break;
@@ -3923,6 +3967,12 @@
Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED), usingSubId, subId),
null, true, UserHandle.USER_ALL);
}
+ if (values.containsKey(Telephony.SimInfo.COLUMN_CROSS_SIM_CALLING_ENABLED)) {
+ getContext().getContentResolver().notifyChange(getNotifyContentUri(
+ Uri.withAppendedPath(Telephony.SimInfo.CONTENT_URI,
+ Telephony.SimInfo.COLUMN_CROSS_SIM_CALLING_ENABLED),
+ usingSubId, subId), null, true, UserHandle.USER_ALL);
+ }
break;
default:
getContext().getContentResolver().notifyChange(
diff --git a/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java b/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java
index 643a18f..00bb15e 100644
--- a/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java
+++ b/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java
@@ -615,6 +615,35 @@
}
/**
+ * Test that crashing for one sms does not block restore of other messages.
+ * @throws Exception
+ */
+ public void testRestoreSms_WithException() throws Exception {
+ mTelephonyBackupAgent.initUnknownSender();
+ JsonReader jsonReader = new JsonReader(new StringReader(addRandomDataToJson(mAllSmsJson)));
+ FakeSmsProvider smsProvider = new FakeSmsProvider(mSmsRows, false);
+ mMockContentResolver.addProvider("sms", smsProvider);
+ TelephonyBackupAgent.SmsProviderQuery smsProviderQuery =
+ new TelephonyBackupAgent.SmsProviderQuery() {
+ int mIteration = 0;
+ @Override
+ public boolean doesSmsExist(ContentValues smsValues) {
+ if (mIteration == 0) {
+ mIteration++;
+ throw new RuntimeException("fake crash for first message");
+ }
+ return false;
+ }
+ };
+ mTelephonyBackupAgent.setSmsProviderQuery(smsProviderQuery);
+
+ mTelephonyBackupAgent.putSmsMessagesToProvider(jsonReader);
+ // the "- 1" is due to exception thrown for one of the messages
+ assertEquals(mSmsRows.length - 1, smsProvider.getRowsAdded());
+ assertEquals(mThreadProvider.mIsThreadArchived, mThreadProvider.mUpdateThreadsArchived);
+ }
+
+ /**
* Test restore mms with the empty json array "[]".
* @throws Exception
*/
@@ -750,11 +779,17 @@
private class FakeSmsProvider extends MockContentProvider {
private int nextRow = 0;
private ContentValues[] mSms;
+ private boolean mCheckInsertedValues = true;
public FakeSmsProvider(ContentValues[] sms) {
this.mSms = sms;
}
+ public FakeSmsProvider(ContentValues[] sms, boolean checkInsertedValues) {
+ this.mSms = sms;
+ mCheckInsertedValues = checkInsertedValues;
+ }
+
@Override
public Uri insert(Uri uri, ContentValues values) {
assertEquals(Telephony.Sms.CONTENT_URI, uri);
@@ -770,7 +805,7 @@
modifiedValues.put(Telephony.Sms.ADDRESS, TelephonyBackupAgent.UNKNOWN_SENDER);
}
- assertEquals(modifiedValues, values);
+ if (mCheckInsertedValues) assertEquals(modifiedValues, values);
return null;
}
diff --git a/tests/src/com/android/providers/telephony/TelephonyDatabaseHelperTest.java b/tests/src/com/android/providers/telephony/TelephonyDatabaseHelperTest.java
index 0666169..50be3b3 100644
--- a/tests/src/com/android/providers/telephony/TelephonyDatabaseHelperTest.java
+++ b/tests/src/com/android/providers/telephony/TelephonyDatabaseHelperTest.java
@@ -201,6 +201,22 @@
Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED));
}
+ @Test
+ public void databaseHelperOnUpgrade_hasRcsConfigField() {
+ Log.d(TAG, "databaseHelperOnUpgrade_hasRcsConfigField");
+ // (5 << 16 | 6) is the first upgrade trigger in onUpgrade
+ SQLiteDatabase db = mInMemoryDbHelper.getWritableDatabase();
+ mHelper.onUpgrade(db, (4 << 16), TelephonyProvider.getVersion(mContext));
+
+ // the upgraded db must have the Telephony.SimInfo.COLUMN_RCS_CONFIG field
+ Cursor cursor = db.query("siminfo", null, null, null, null, null, null);
+ String[] upgradedColumns = cursor.getColumnNames();
+ Log.d(TAG, "siminfo columns: " + Arrays.toString(upgradedColumns));
+
+ assertTrue(Arrays.asList(upgradedColumns).contains(
+ Telephony.SimInfo.COLUMN_RCS_CONFIG));
+ }
+
/**
* Helper for an in memory DB used to test the TelephonyProvider#DatabaseHelper.
*