Merge "Broadcast ACTION_SMS_MMS_DB_CREATED when mmssms.db is created."
diff --git a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
index 75885bd..f4ae9cc 100644
--- a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
+++ b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
@@ -21,11 +21,13 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.SharedPreferences;
import android.database.Cursor;
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;
@@ -35,11 +37,14 @@
import android.provider.Telephony.MmsSms;
import android.provider.Telephony.MmsSms.PendingMessages;
import android.provider.Telephony.Sms;
+import android.provider.Telephony.Sms.Intents;
import android.provider.Telephony.Threads;
import android.telephony.SubscriptionManager;
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;
@@ -50,6 +55,7 @@
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* A {@link SQLiteOpenHelper} that handles DB management of SMS and MMS tables.
@@ -246,12 +252,22 @@
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";
+ // cache for INITIAL_CREATE_DONE shared pref so access to it can be avoided when possible
+ private static AtomicBoolean sInitialCreateDone = new AtomicBoolean(false);
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);
+ try {
+ PhoneFactory.addLocalLog(TAG, 100);
+ } catch (IllegalArgumentException e) {
+ // ignore
+ }
}
/**
@@ -463,6 +479,27 @@
@Override
public void onCreate(SQLiteDatabase db) {
+ localLog("onCreate: Creating all SMS-MMS tables.");
+ // if FBE is not supported, or if this onCreate is for CE partition database
+ if (!StorageManager.isFileEncryptedNativeOrEmulated()
+ || mContext.isCredentialProtectedStorage()) {
+ localLog("onCreate: broadcasting ACTION_SMS_MMS_DB_CREATED");
+ // Broadcast ACTION_SMS_MMS_DB_CREATED
+ Intent intent = new Intent(Sms.Intents.ACTION_SMS_MMS_DB_CREATED);
+ intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+
+ if (isInitialCreateDone()) {
+ // this onCreate is called after onCreate was called once initially. The db file
+ // disappeared mysteriously?
+ localLogWtf("onCreate: was already called once earlier");
+ intent.putExtra(Intents.EXTRA_IS_INITIAL_CREATE, false);
+ } else {
+ setInitialCreateDone();
+ intent.putExtra(Intents.EXTRA_IS_INITIAL_CREATE, true);
+ }
+
+ mContext.sendBroadcast(intent, android.Manifest.permission.READ_SMS);
+ }
createMmsTables(db);
createSmsTables(db);
createCommonTables(db);
@@ -472,6 +509,30 @@
createIndices(db);
}
+ private void localLog(String logMsg) {
+ Log.d(TAG, logMsg);
+ PhoneFactory.localLog(TAG, logMsg);
+ }
+
+ private void localLogWtf(String logMsg) {
+ Slog.wtf(TAG, logMsg);
+ PhoneFactory.localLog(TAG, logMsg);
+ }
+
+ private boolean isInitialCreateDone() {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+ return sp.getBoolean(INITIAL_CREATE_DONE, false);
+ }
+
+ private void setInitialCreateDone() {
+ if (!sInitialCreateDone.getAndSet(true)) {
+ 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 +1587,8 @@
}
Log.e(TAG, "Destroying all old data.");
+ localLog("onUpgrade: Calling dropAll() and onCreate(). Upgrading database"
+ + " from version " + oldVersion + " to " + currentVersion + "failed.");
dropAll(db);
onCreate(db);
}
@@ -1534,6 +1597,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.
+ localLog("****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);
@@ -1825,19 +1889,41 @@
}
@Override
+ public synchronized SQLiteDatabase getReadableDatabase() {
+ SQLiteDatabase db = super.getWritableDatabase();
+
+ // getReadableDatabase gets or creates a database. So we know for sure that a database has
+ // already been created at this point.
+ if (mContext.isCredentialProtectedStorage()) {
+ setInitialCreateDone();
+ }
+
+ return db;
+ }
+
+ @Override
public synchronized SQLiteDatabase getWritableDatabase() {
SQLiteDatabase db = super.getWritableDatabase();
+ // getWritableDatabase gets or creates a database. So we know for sure that a database has
+ // already been created at this point.
+ if (mContext.isCredentialProtectedStorage()) {
+ setInitialCreateDone();
+ }
+
if (!sTriedAutoIncrement) {
sTriedAutoIncrement = true;
boolean hasAutoIncrementThreads = hasAutoIncrement(db, MmsSmsProvider.TABLE_THREADS);
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);
+ localLog(logMsg);
boolean autoIncrementThreadsSuccess = true;
boolean autoIncrementAddressesSuccess = true;
boolean autoIncrementPartSuccess = true;