Merge pi-dr1-dev to aosp-master am: a7712d7cd7
am: 34a4f7a103
Change-Id: Ide8d7bb95120894c415c54e043c47b30e2cadda9
diff --git a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
index 75885bd..b0265fa 100644
--- a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
+++ b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
@@ -16,16 +16,22 @@
package com.android.providers.telephony;
+import static android.Manifest.permission.MODIFY_PHONE_STATE;
+
import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.SharedPreferences;
import android.database.Cursor;
+import android.database.DatabaseErrorHandler;
+import android.database.DefaultDatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.storage.StorageManager;
+import android.preference.PreferenceManager;
import android.provider.BaseColumns;
import android.provider.Telephony;
import android.provider.Telephony.Mms;
@@ -37,16 +43,22 @@
import android.provider.Telephony.Sms;
import android.provider.Telephony.Threads;
import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.util.LocalLog;
import android.util.Log;
+import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.PhoneFactory;
import com.google.android.mms.pdu.EncodedStringValue;
import com.google.android.mms.pdu.PduHeaders;
import java.io.File;
+import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
@@ -233,6 +245,7 @@
private static MmsSmsDatabaseHelper sDeInstance = null;
private static MmsSmsDatabaseHelper sCeInstance = null;
+ private static MmsSmsDatabaseErrorHandler sDbErrorHandler = null;
private static final String[] BIND_ARGS_NONE = new String[0];
@@ -246,12 +259,57 @@
private final Context mContext;
private LowStorageMonitor mLowStorageMonitor;
+ // SharedPref key used to check if initial create has been done (if onCreate has already been
+ // called once)
+ private static final String INITIAL_CREATE_DONE = "initial_create_done";
- private MmsSmsDatabaseHelper(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ /**
+ * The primary purpose of this DatabaseErrorHandler is to print a Slog.wtf so database
+ * corruption can be caught earlier.
+ */
+ private static class MmsSmsDatabaseErrorHandler implements DatabaseErrorHandler {
+ private DefaultDatabaseErrorHandler mDefaultDatabaseErrorHandler
+ = new DefaultDatabaseErrorHandler();
+ private Context mContext;
+
+ MmsSmsDatabaseErrorHandler(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public void onCorruption(SQLiteDatabase dbObj) {
+ String logMsg = "Corruption reported by sqlite on database: " + dbObj.getPath();
+ Slog.wtf(TAG, logMsg);
+ PhoneFactory.localLog(TAG, logMsg);
+ sendDbErrorIntents(mContext, true);
+ mDefaultDatabaseErrorHandler.onCorruption(dbObj);
+ }
+ }
+
+ private MmsSmsDatabaseHelper(Context context, MmsSmsDatabaseErrorHandler dbErrHandler) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION, dbErrHandler);
mContext = context;
// Memory optimization - close idle connections after 30s of inactivity
setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
+ try {
+ PhoneFactory.addLocalLog(TAG, 100);
+ } catch (IllegalArgumentException e) {
+ // ignore
+ }
+ }
+
+ private static void sendDbErrorIntents(Context context, boolean isCorrupted) {
+ Intent intent = new Intent(TelephonyManager.ACTION_MMSSMS_DATABASE_LOST);
+ intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+ intent.putExtra(TelephonyManager.EXTRA_IS_CORRUPTED, isCorrupted);
+ context.sendBroadcast(intent, MODIFY_PHONE_STATE);
+ }
+
+ private static synchronized MmsSmsDatabaseErrorHandler getDbErrorHandler(Context context) {
+ if (sDbErrorHandler == null) {
+ sDbErrorHandler = new MmsSmsDatabaseErrorHandler(context);
+ }
+ return sDbErrorHandler;
}
/**
@@ -259,7 +317,9 @@
*/
/* package */ static synchronized MmsSmsDatabaseHelper getInstanceForDe(Context context) {
if (sDeInstance == null) {
- sDeInstance = new MmsSmsDatabaseHelper(ProviderUtil.getDeviceEncryptedContext(context));
+ sDeInstance = new MmsSmsDatabaseHelper(
+ ProviderUtil.getDeviceEncryptedContext(context),
+ getDbErrorHandler(context));
}
return sDeInstance;
}
@@ -272,7 +332,8 @@
if (sCeInstance == null) {
if (StorageManager.isFileEncryptedNativeOrEmulated()) {
sCeInstance = new MmsSmsDatabaseHelper(
- ProviderUtil.getCredentialEncryptedContext(context));
+ ProviderUtil.getCredentialEncryptedContext(context),
+ getDbErrorHandler(context));
} else {
sCeInstance = getInstanceForDe(context);
}
@@ -463,6 +524,17 @@
@Override
public void onCreate(SQLiteDatabase db) {
+ PhoneFactory.localLog(TAG, "onCreate: Creating all SMS-MMS tables.");
+ if (isInitialCreateDone()) {
+ // this onCreate is called after onCreate was called once initially. The db file
+ // disappeared mysteriously?
+ String logMsg = "onCreate: was already called once earlier";
+ Slog.wtf(TAG, logMsg);
+ PhoneFactory.localLog(TAG, logMsg);
+ sendDbErrorIntents(mContext, false);
+ } else {
+ setInitialCreateDone();
+ }
createMmsTables(db);
createSmsTables(db);
createCommonTables(db);
@@ -472,6 +544,18 @@
createIndices(db);
}
+ private boolean isInitialCreateDone() {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+ return sp.getBoolean(INITIAL_CREATE_DONE, false);
+ }
+
+ private void setInitialCreateDone() {
+ SharedPreferences.Editor editor
+ = PreferenceManager.getDefaultSharedPreferences(mContext).edit();
+ editor.putBoolean(INITIAL_CREATE_DONE, true);
+ editor.commit();
+ }
+
// When upgrading the database we need to populate the words
// table with the rows out of sms and part.
private void populateWordsTable(SQLiteDatabase db) {
@@ -1526,6 +1610,8 @@
}
Log.e(TAG, "Destroying all old data.");
+ PhoneFactory.localLog(TAG, "onUpgrade: Calling dropAll() and onCreate(). Upgrading database from version "
+ + oldVersion + " to " + currentVersion + "failed.");
dropAll(db);
onCreate(db);
}
@@ -1534,6 +1620,7 @@
// Clean the database out in order to start over from scratch.
// We don't need to drop our triggers here because SQLite automatically
// drops a trigger when its attached database is dropped.
+ PhoneFactory.localLog(TAG, "****DROPPING ALL SMS-MMS TABLES****");
db.execSQL("DROP TABLE IF EXISTS canonical_addresses");
db.execSQL("DROP TABLE IF EXISTS threads");
db.execSQL("DROP TABLE IF EXISTS " + MmsSmsProvider.TABLE_PENDING_MSG);
@@ -1834,10 +1921,13 @@
boolean hasAutoIncrementAddresses = hasAutoIncrement(db, "canonical_addresses");
boolean hasAutoIncrementPart = hasAutoIncrement(db, "part");
boolean hasAutoIncrementPdu = hasAutoIncrement(db, "pdu");
- Log.d(TAG, "[getWritableDatabase] hasAutoIncrementThreads: " + hasAutoIncrementThreads +
+ String logMsg = "[getWritableDatabase]" +
+ " hasAutoIncrementThreads: " + hasAutoIncrementThreads +
" hasAutoIncrementAddresses: " + hasAutoIncrementAddresses +
" hasAutoIncrementPart: " + hasAutoIncrementPart +
- " hasAutoIncrementPdu: " + hasAutoIncrementPdu);
+ " hasAutoIncrementPdu: " + hasAutoIncrementPdu;
+ Log.d(TAG, logMsg);
+ PhoneFactory.localLog(TAG, logMsg);
boolean autoIncrementThreadsSuccess = true;
boolean autoIncrementAddressesSuccess = true;
boolean autoIncrementPartSuccess = true;
@@ -2139,4 +2229,8 @@
" JOIN pdu ON pdu._id=part.mid " +
" WHERE part.ct != 'text/plain' AND part.ct != 'application/smil')");
}
+
+ public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+ writer.println("MmsSmsDatabaseHelper:");
+ }
}
diff --git a/src/com/android/providers/telephony/MmsSmsProvider.java b/src/com/android/providers/telephony/MmsSmsProvider.java
index 1653cd9..80c6d7a 100644
--- a/src/com/android/providers/telephony/MmsSmsProvider.java
+++ b/src/com/android/providers/telephony/MmsSmsProvider.java
@@ -1392,6 +1392,9 @@
defaultSmsApp = "None";
}
writer.println("Default SMS app: " + defaultSmsApp);
+ if (mOpenHelper != null) {
+ ((MmsSmsDatabaseHelper) mOpenHelper).dump(fd, writer, args);
+ }
}
@Override