merge in nyc-release history after reset to nyc-dev
diff --git a/src/com/android/providers/telephony/TelephonyBackupAgent.java b/src/com/android/providers/telephony/TelephonyBackupAgent.java
index 5f4acaa..7a9d701 100644
--- a/src/com/android/providers/telephony/TelephonyBackupAgent.java
+++ b/src/com/android/providers/telephony/TelephonyBackupAgent.java
@@ -160,6 +160,14 @@
// Order by Date entries from database. We start backup from the oldest.
private static final String ORDER_BY_DATE = "date ASC";
+ // This is a hard coded string rather than a localized one because we don't want it to
+ // change when you change locale.
+ @VisibleForTesting
+ static final String UNKNOWN_SENDER = "\u02BCUNKNOWN_SENDER!\u02BC";
+
+ // Thread id for UNKNOWN_SENDER.
+ private long mUnknownSenderThreadId;
+
// Columns from SMS database for backup/restore.
@VisibleForTesting
static final String[] SMS_PROJECTION = new String[] {
@@ -230,10 +238,9 @@
@VisibleForTesting
int mMaxMsgPerFile = 1000;
-
// Default values for SMS, MMS, Addresses restore.
- private static final ContentValues sDefaultValuesSms = new ContentValues(3);
- private static final ContentValues sDefaultValuesMms = new ContentValues(5);
+ private static ContentValues sDefaultValuesSms = new ContentValues(5);
+ private static ContentValues sDefaultValuesMms = new ContentValues(6);
private static final ContentValues sDefaultValuesAddr = new ContentValues(2);
// Shared preferences for the backup agent.
@@ -252,6 +259,7 @@
// Consider restored messages read and seen.
sDefaultValuesSms.put(Telephony.Sms.READ, 1);
sDefaultValuesSms.put(Telephony.Sms.SEEN, 1);
+ sDefaultValuesSms.put(Telephony.Sms.ADDRESS, UNKNOWN_SENDER);
// If there is no sub_id with self phone number on restore set it to -1.
sDefaultValuesSms.put(Telephony.Sms.SUBSCRIPTION_ID, -1);
@@ -298,6 +306,7 @@
}
}
mContentResolver = getContentResolver();
+ initUnknownSender();
}
@VisibleForTesting
@@ -310,6 +319,13 @@
mPhone2subId = phone2subId;
}
+ @VisibleForTesting
+ void initUnknownSender() {
+ mUnknownSenderThreadId = getOrCreateThreadId(null);
+ sDefaultValuesSms.put(Telephony.Sms.THREAD_ID, mUnknownSenderThreadId);
+ sDefaultValuesMms.put(Telephony.Mms.THREAD_ID, mUnknownSenderThreadId);
+ }
+
@Override
public void onFullBackup(FullBackupDataOutput data) throws IOException {
SharedPreferences sharedPreferences = getSharedPreferences(BACKUP_PREFS, MODE_PRIVATE);
@@ -348,18 +364,22 @@
final long smsDate = TimeUnit.MILLISECONDS.toSeconds(getMessageDate(smsCursor));
final long mmsDate = getMessageDate(mmsCursor);
if (smsDate < mmsDate) {
- backupAll(data, smsCursor, String.format(SMS_BACKUP_FILE_FORMAT, fileNum++));
+ backupAll(data, smsCursor,
+ String.format(Locale.US, SMS_BACKUP_FILE_FORMAT, fileNum++));
} else {
- backupAll(data, mmsCursor, String.format(MMS_BACKUP_FILE_FORMAT, fileNum++));
+ backupAll(data, mmsCursor, String.format(Locale.US,
+ MMS_BACKUP_FILE_FORMAT, fileNum++));
}
}
while (smsCursor != null && !smsCursor.isAfterLast()) {
- backupAll(data, smsCursor, String.format(SMS_BACKUP_FILE_FORMAT, fileNum++));
+ backupAll(data, smsCursor,
+ String.format(Locale.US, SMS_BACKUP_FILE_FORMAT, fileNum++));
}
while (mmsCursor != null && !mmsCursor.isAfterLast()) {
- backupAll(data, mmsCursor, String.format(MMS_BACKUP_FILE_FORMAT, fileNum++));
+ backupAll(data, mmsCursor,
+ String.format(Locale.US, MMS_BACKUP_FILE_FORMAT, fileNum++));
}
}
@@ -487,11 +507,11 @@
final String fileName = file.getName();
try (FileInputStream fileInputStream = new FileInputStream(file)) {
mTelephonyBackupAgent.doRestoreFile(fileName, fileInputStream.getFD());
+ } catch (Exception e) {
+ // Either IOException or RuntimeException.
+ Log.e(TAG, e.toString());
+ } finally {
file.delete();
- } catch (IOException e) {
- if (DEBUG) {
- Log.e(TAG, e.toString());
- }
}
}
} finally {
@@ -611,7 +631,7 @@
private static final int ID_IDX = 0;
private boolean doesSmsExist(ContentValues smsValues) {
- final String where = String.format("%s = %d and %s = %s",
+ 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)));
@@ -622,7 +642,7 @@
}
private boolean doesMmsExist(Mms mms) {
- final String where = String.format("%s = %d",
+ final String where = String.format(Locale.US, "%s = %d",
Telephony.Sms.DATE, mms.values.getAsLong(Telephony.Mms.DATE));
try (Cursor cursor = mContentResolver.query(Telephony.Mms.CONTENT_URI, PROJECTION_ID, where,
null, null)) {
@@ -680,8 +700,12 @@
}
private void handleThreadId(JsonWriter jsonWriter, long threadId) throws IOException {
- writeRecipientsToWriter(jsonWriter.name(RECIPIENTS),
- getRecipientsByThread(threadId));
+ final List<String> recipients = getRecipientsByThread(threadId);
+ if (recipients == null || recipients.isEmpty()) {
+ return;
+ }
+
+ writeRecipientsToWriter(jsonWriter.name(RECIPIENTS), recipients);
if (!mThreadArchived.containsKey(threadId)) {
boolean isArchived = isThreadArchived(threadId);
if (isArchived) {
@@ -702,7 +726,7 @@
try (Cursor cursor = getContentResolver().query(uri, THREAD_ARCHIVED_PROJECTION, null, null,
null)) {
- if (cursor.moveToFirst()) {
+ if (cursor != null && cursor.moveToFirst()) {
return cursor.getInt(THREAD_ARCHIVED_IDX) == 1;
}
}
@@ -722,7 +746,7 @@
private ContentValues readSmsValuesFromReader(JsonReader jsonReader)
throws IOException {
- ContentValues values = new ContentValues(8+sDefaultValuesSms.size());
+ ContentValues values = new ContentValues(6+sDefaultValuesSms.size());
values.putAll(sDefaultValuesSms);
long threadId = -1;
boolean isArchived = false;
@@ -829,7 +853,7 @@
private Mms readMmsFromReader(JsonReader jsonReader) throws IOException {
Mms mms = new Mms();
- mms.values = new ContentValues(6+sDefaultValuesMms.size());
+ mms.values = new ContentValues(5+sDefaultValuesMms.size());
mms.values.putAll(sDefaultValuesMms);
jsonReader.beginObject();
String bodyText = null;
@@ -1002,7 +1026,7 @@
final Uri partUri = Telephony.Mms.CONTENT_URI.buildUpon()
.appendPath(String.valueOf(dummyId)).appendPath("part").build();
- final String srcName = String.format("text.%06d.txt", 0);
+ final String srcName = String.format(Locale.US, "text.%06d.txt", 0);
{ // Insert SMIL part.
final String smilBody = String.format(sSmilTextPart, srcName);
final String smil = String.format(sSmilTextOnly, smilBody);
@@ -1129,13 +1153,29 @@
}
private long getOrCreateThreadId(Set<String> recipients) {
+ if (recipients == null) {
+ recipients = new ArraySet<String>();
+ }
+
+ if (recipients.isEmpty()) {
+ recipients.add(UNKNOWN_SENDER);
+ }
+
if (mCacheGetOrCreateThreadId == null) {
mCacheGetOrCreateThreadId = new HashMap<>();
}
if (!mCacheGetOrCreateThreadId.containsKey(recipients)) {
- mCacheGetOrCreateThreadId.put(recipients,
- Telephony.Threads.getOrCreateThreadId(this, recipients));
+ long threadId = mUnknownSenderThreadId;
+ try {
+ threadId = Telephony.Threads.getOrCreateThreadId(this, recipients);
+ } catch (RuntimeException e) {
+ if (DEBUG) {
+ Log.e(TAG, e.toString());
+ }
+ }
+ mCacheGetOrCreateThreadId.put(recipients, threadId);
+ return threadId;
}
return mCacheGetOrCreateThreadId.get(recipients);
diff --git a/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java b/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java
index 5869a84..4866dbd 100644
--- a/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java
+++ b/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java
@@ -36,7 +36,6 @@
import android.util.ArraySet;
import android.util.JsonReader;
import android.util.JsonWriter;
-import android.util.Log;
import android.util.SparseArray;
import org.json.JSONArray;
@@ -119,8 +118,8 @@
/* Generating test data */
- mSmsRows = new ContentValues[3];
- mSmsJson = new String[3];
+ mSmsRows = new ContentValues[4];
+ mSmsJson = new String[4];
mSmsRows[0] = createSmsRow(1, 1, "+1232132214124", "sms 1", "sms subject", 9087978987l,
999999999, 3, 44, 1);
mSmsJson[0] = "{\"self_phone\":\"+111111111111111\",\"address\":" +
@@ -145,6 +144,14 @@
"\"recipients\":[\"+1232221412433\",\"+1232221412444\"]}";
mThreadProvider.getOrCreateThreadId(new String[]{"+1232221412433", "+1232221412444"});
+
+ mSmsRows[3] = createSmsRow(5, 3, null, "sms 4", null,
+ 111111111111l, 999999999, 2, 3, 5);
+ mSmsJson[3] = "{\"self_phone\":\"+333333333333333\"," +
+ "\"body\":\"sms 4\",\"date\":\"111111111111\"," +
+ "\"date_sent\":" +
+ "\"999999999\",\"status\":\"2\",\"type\":\"3\"}";
+
mAllSmsJson = makeJsonArray(mSmsJson);
@@ -392,7 +399,7 @@
* @throws Exception
*/
public void testBackupSms_AllSmsWithExactFileLimit() throws Exception {
- mTelephonyBackupAgent.mMaxMsgPerFile = 3;
+ mTelephonyBackupAgent.mMaxMsgPerFile = 4;
mSmsTable.addAll(Arrays.asList(mSmsRows));
mTelephonyBackupAgent.putSmsMessagesToJson(mSmsCursor, new JsonWriter(mStringWriter));
assertEquals(mAllSmsJson, mStringWriter.toString());
@@ -416,6 +423,10 @@
mStringWriter = new StringWriter();
mTelephonyBackupAgent.putSmsMessagesToJson(mSmsCursor, new JsonWriter(mStringWriter));
assertEquals("[" + mSmsJson[2] + "]", mStringWriter.toString());
+
+ mStringWriter = new StringWriter();
+ mTelephonyBackupAgent.putSmsMessagesToJson(mSmsCursor, new JsonWriter(mStringWriter));
+ assertEquals("[" + mSmsJson[3] + "]", mStringWriter.toString());
}
/**
@@ -485,6 +496,7 @@
* @throws Exception
*/
public void testRestoreSms_AllSms() throws Exception {
+ mTelephonyBackupAgent.initUnknownSender();
JsonReader jsonReader = new JsonReader(new StringReader(addRandomDataToJson(mAllSmsJson)));
FakeSmsProvider smsProvider = new FakeSmsProvider(mSmsRows);
mMockContentResolver.addProvider("sms", smsProvider);
@@ -526,9 +538,9 @@
*/
public void testBackup_WithQuotaExceeded() throws Exception {
mTelephonyBackupAgent.mMaxMsgPerFile = 1;
- final int backupSize = 6144;
- final int backupSizeAfterFirstQuotaHit = 5120;
- final int backupSizeAfterSecondQuotaHit = 4096;
+ final int backupSize = 7168;
+ final int backupSizeAfterFirstQuotaHit = 6144;
+ final int backupSizeAfterSecondQuotaHit = 5120;
mSmsTable.addAll(Arrays.asList(mSmsRows));
mMmsTable.addAll(Arrays.asList(mMmsRows));
@@ -584,6 +596,10 @@
modifiedValues.put(Telephony.Sms.SUBSCRIPTION_ID, -1);
}
+ if (modifiedValues.get(Telephony.Sms.ADDRESS) == null) {
+ modifiedValues.put(Telephony.Sms.ADDRESS, TelephonyBackupAgent.UNKNOWN_SENDER);
+ }
+
assertEquals(modifiedValues, values);
return null;
}
@@ -712,6 +728,10 @@
public int getOrCreateThreadId(final String[] recipients) {
+ if (recipients == null || recipients.length == 0) {
+ throw new IllegalArgumentException("Unable to find or allocate a thread ID.");
+ }
+
Set<Integer> ids = new ArraySet<>();
for (String rec : recipients) {
if (!id2Recipient.contains(rec)) {
@@ -730,6 +750,10 @@
}
private String getSpaceSepIds(int threadId) {
+ if (id2Thread.size() < threadId) {
+ return null;
+ }
+
String spaceSepIds = null;
for (Integer id : id2Thread.get(threadId-1)) {
spaceSepIds = (spaceSepIds == null ? "" : spaceSepIds + " ") + String.valueOf(id);