/*
 * 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.
 */

package com.android.providers.telephony;

import static com.android.providers.telephony.SmsProvider.NO_ERROR_CODE;

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.content.pm.PackageManager;
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;
import android.provider.Telephony.Mms.Addr;
import android.provider.Telephony.Mms.Part;
import android.provider.Telephony.Mms.Rate;
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 com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.TelephonyStatsLog;

import com.google.android.mms.pdu.EncodedStringValue;
import com.google.android.mms.pdu.PduHeaders;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
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.
 *
 * From N, SMS and MMS tables are split into two groups with different levels of encryption.
 *   - the raw table, which lives inside DE(Device Encrypted) storage.
 *   - all other tables, which lives under CE(Credential Encrypted) storage.
 *
 * All tables are created by this class in the same database that can live either in DE or CE
 * storage. But not all tables in the same database should be used. Only DE tables should be used
 * in the database created in DE and only CE tables should be used in the database created in CE.
 * The only exception is a non-FBE device migrating from M to N, in which case the DE and CE tables
 * will actually live inside the same storage/database.
 *
 * This class provides methods to create instances that manage databases in different storage.
 * It's the responsibility of the clients of this class to make sure the right instance is
 * used to access tables that are supposed to live inside the intended storage.
 */
public class MmsSmsDatabaseHelper extends SQLiteOpenHelper {
    private static final String TAG = "MmsSmsDatabaseHelper";
    private static final int SECURITY_EXCEPTION = TelephonyStatsLog
            .MMS_SMS_DATABASE_HELPER_ON_UPGRADE_FAILED__FAILURE_CODE__FAILURE_SECURITY_EXCEPTION;
    private static final int FAILURE_UNKNOWN = TelephonyStatsLog
        .MMS_SMS_DATABASE_HELPER_ON_UPGRADE_FAILED__FAILURE_CODE__FAILURE_UNKNOWN;
    private static final int SQL_EXCEPTION = TelephonyStatsLog
            .MMS_SMS_DATABASE_HELPER_ON_UPGRADE_FAILED__FAILURE_CODE__FAILURE_SQL_EXCEPTION;
    private static final int IO_EXCEPTION = TelephonyStatsLog
            .MMS_SMS_DATABASE_HELPER_ON_UPGRADE_FAILED__FAILURE_CODE__FAILURE_IO_EXCEPTION;

    private static final String SMS_UPDATE_THREAD_READ_BODY =
                        "  UPDATE threads SET read = " +
                        "    CASE (SELECT COUNT(*)" +
                        "          FROM sms" +
                        "          WHERE " + Sms.READ + " = 0" +
                        "            AND " + Sms.THREAD_ID + " = threads._id)" +
                        "      WHEN 0 THEN 1" +
                        "      ELSE 0" +
                        "    END" +
                        "  WHERE threads._id = new." + Sms.THREAD_ID + "; ";

    private static final String UPDATE_THREAD_COUNT_ON_NEW =
                        "  UPDATE threads SET message_count = " +
                        "     (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
                        "      ON threads._id = " + Sms.THREAD_ID +
                        "      WHERE " + Sms.THREAD_ID + " = new.thread_id" +
                        "        AND sms." + Sms.TYPE + " != 3) + " +
                        "     (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
                        "      ON threads._id = " + Mms.THREAD_ID +
                        "      WHERE " + Mms.THREAD_ID + " = new.thread_id" +
                        "        AND (m_type=132 OR m_type=130 OR m_type=128)" +
                        "        AND " + Mms.MESSAGE_BOX + " != 3) " +
                        "  WHERE threads._id = new.thread_id; ";

    private static final String SMS_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE =
                        "BEGIN" +
                        "  UPDATE threads SET" +
                        "    date = (strftime('%s','now') * 1000), " +
                        "    snippet = new." + Sms.BODY + ", " +
                        "    snippet_cs = 0" +
                        "  WHERE threads._id = new." + Sms.THREAD_ID + "; " +
                        UPDATE_THREAD_COUNT_ON_NEW +
                        SMS_UPDATE_THREAD_READ_BODY +
                        "END;";

    private static final String PDU_UPDATE_THREAD_CONSTRAINTS =
                        "  WHEN new." + Mms.MESSAGE_TYPE + "=" +
                        PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF +
                        "    OR new." + Mms.MESSAGE_TYPE + "=" +
                        PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND +
                        "    OR new." + Mms.MESSAGE_TYPE + "=" +
                        PduHeaders.MESSAGE_TYPE_SEND_REQ + " ";

    // When looking in the pdu table for unread messages, only count messages that
    // are displayed to the user. The constants are defined in PduHeaders and could be used
    // here, but the string "(m_type=132 OR m_type=130 OR m_type=128)" is used throughout this
    // file and so it is used here to be consistent.
    //     m_type=128   = MESSAGE_TYPE_SEND_REQ
    //     m_type=130   = MESSAGE_TYPE_NOTIFICATION_IND
    //     m_type=132   = MESSAGE_TYPE_RETRIEVE_CONF
    private static final String PDU_UPDATE_THREAD_READ_BODY =
                        "  UPDATE threads SET read = " +
                        "    CASE (SELECT COUNT(*)" +
                        "          FROM " + MmsProvider.TABLE_PDU +
                        "          WHERE " + Mms.READ + " = 0" +
                        "            AND " + Mms.THREAD_ID + " = threads._id " +
                        "            AND (m_type=132 OR m_type=130 OR m_type=128)) " +
                        "      WHEN 0 THEN 1" +
                        "      ELSE 0" +
                        "    END" +
                        "  WHERE threads._id = new." + Mms.THREAD_ID + "; ";

    private static final String PDU_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE =
                        "BEGIN" +
                        "  UPDATE threads SET" +
                        "    date = (strftime('%s','now') * 1000), " +
                        "    snippet = new." + Mms.SUBJECT + ", " +
                        "    snippet_cs = new." + Mms.SUBJECT_CHARSET +
                        "  WHERE threads._id = new." + Mms.THREAD_ID + "; " +
                        UPDATE_THREAD_COUNT_ON_NEW +
                        PDU_UPDATE_THREAD_READ_BODY +
                        "END;";

    // When a part is inserted, if it is not text/plain or application/smil
    // (which both can exist with text-only MMSes), then there is an attachment.
    // Set has_attachment=1 in the threads table for the thread in question.
    private static final String PART_UPDATE_THREADS_ON_INSERT_TRIGGER =
                        "CREATE TRIGGER update_threads_on_insert_part " +
                        " AFTER INSERT ON part " +
                        " WHEN new.ct != 'text/plain' AND new.ct != 'application/smil' " +
                        " BEGIN " +
                        "  UPDATE threads SET has_attachment=1 WHERE _id IN " +
                        "   (SELECT pdu.thread_id FROM part JOIN pdu ON pdu._id=part.mid " +
                        "     WHERE part._id=new._id LIMIT 1); " +
                        " END";

    // When the 'mid' column in the part table is updated, we need to run the trigger to update
    // the threads table's has_attachment column, if the part is an attachment.
    private static final String PART_UPDATE_THREADS_ON_UPDATE_TRIGGER =
                        "CREATE TRIGGER update_threads_on_update_part " +
                        " AFTER UPDATE of " + Part.MSG_ID + " ON part " +
                        " WHEN new.ct != 'text/plain' AND new.ct != 'application/smil' " +
                        " BEGIN " +
                        "  UPDATE threads SET has_attachment=1 WHERE _id IN " +
                        "   (SELECT pdu.thread_id FROM part JOIN pdu ON pdu._id=part.mid " +
                        "     WHERE part._id=new._id LIMIT 1); " +
                        " END";

    // When the 'thread_id' column in the pdu table is updated, we need to run the trigger to update
    // the threads table's has_attachment column, if the message has an attachment in 'part' table
    private static final String PDU_UPDATE_THREADS_ON_UPDATE_TRIGGER =
                        "CREATE TRIGGER update_threads_on_update_pdu " +
                        " AFTER UPDATE of thread_id ON pdu " +
                        " BEGIN " +
                        "  UPDATE threads SET has_attachment=1 WHERE _id IN " +
                        "   (SELECT pdu.thread_id FROM part JOIN pdu " +
                        "     WHERE part.ct != 'text/plain' AND part.ct != 'application/smil' " +
                        "     AND part.mid = pdu._id);" +
                        " END";

    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];

    private static boolean sTriedAutoIncrement = false;
    private static boolean sFakeLowStorageTest = false;     // for testing only

    private static final String NO_SUCH_COLUMN_EXCEPTION_MESSAGE = "no such column";
    private static final String NO_SUCH_TABLE_EXCEPTION_MESSAGE = "no such table";

    static final String DATABASE_NAME = "mmssms.db";
    static final int DATABASE_VERSION = 67;
    private static final int IDLE_CONNECTION_TIMEOUT_MS = 30000;

    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);

    /**
     * The primary purpose of this DatabaseErrorHandler is to broadcast an intent on corruption and
     * print a Log.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();
            localLogWtf(logMsg);
            sendDbLostIntent(mContext, true);
            // Let the default error handler take other actions
            mDefaultDatabaseErrorHandler.onCorruption(dbObj);
        }
    }

    @VisibleForTesting
    MmsSmsDatabaseHelper(Context context, MmsSmsDatabaseErrorHandler dbErrorHandler) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION, dbErrorHandler);
        mContext = context;
        // Memory optimization - close idle connections after 30s of inactivity
        setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
        setWriteAheadLoggingEnabled(false);
        try {
            PhoneFactory.addLocalLog(TAG, 64);
        } catch (IllegalArgumentException e) {
            // ignore
        }
    }

    private static synchronized MmsSmsDatabaseErrorHandler getDbErrorHandler(Context context) {
        if (sDbErrorHandler == null) {
            sDbErrorHandler = new MmsSmsDatabaseErrorHandler(context);
        }
        return sDbErrorHandler;
    }

    private static void sendDbLostIntent(Context context, boolean isCorrupted) {
        // Broadcast ACTION_SMS_MMS_DB_LOST
        Intent intent = new Intent(Sms.Intents.ACTION_SMS_MMS_DB_LOST);
        intent.putExtra(Sms.Intents.EXTRA_IS_CORRUPTED, isCorrupted);
        intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
        context.sendBroadcast(intent);
    }
    /**
     * Returns a singleton helper for the combined MMS and SMS database in device encrypted storage.
     */
    /* package */ static synchronized MmsSmsDatabaseHelper getInstanceForDe(Context context) {
        if (sDeInstance == null) {
            Context deContext = ProviderUtil.getDeviceEncryptedContext(context);
            sDeInstance = new MmsSmsDatabaseHelper(deContext, getDbErrorHandler(deContext));
        }
        return sDeInstance;
    }

    /**
     * Returns a singleton helper for the combined MMS and SMS database in credential encrypted
     * storage. If FBE is not available, use the device encrypted storage instead.
     */
    /* package */ static synchronized MmsSmsDatabaseHelper getInstanceForCe(Context context) {
        if (sCeInstance == null) {
            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
                Context ceContext = ProviderUtil.getCredentialEncryptedContext(context);
                sCeInstance = new MmsSmsDatabaseHelper(ceContext, getDbErrorHandler(ceContext));
            } else {
                sCeInstance = getInstanceForDe(context);
            }
        }
        return sCeInstance;
    }

    /**
     * Look through all the recipientIds referenced by the threads and then delete any
     * unreferenced rows from the canonical_addresses table.
     */
    private static void removeUnferencedCanonicalAddresses(SQLiteDatabase db) {
        Cursor c = db.query(MmsSmsProvider.TABLE_THREADS, new String[] { "recipient_ids" },
                null, null, null, null, null);
        if (c != null) {
            try {
                if (c.getCount() == 0) {
                    // no threads, delete all addresses
                    int rows = db.delete("canonical_addresses", null, null);
                } else {
                    // Find all the referenced recipient_ids from the threads. recipientIds is
                    // a space-separated list of recipient ids: "1 14 21"
                    HashSet<Integer> recipientIds = new HashSet<Integer>();
                    while (c.moveToNext()) {
                        String[] recips = c.getString(0).split(" ");
                        for (String recip : recips) {
                            try {
                                int recipientId = Integer.parseInt(recip);
                                recipientIds.add(recipientId);
                            } catch (Exception e) {
                            }
                        }
                    }
                    // Now build a selection string of all the unique recipient ids
                    StringBuilder sb = new StringBuilder();
                    Iterator<Integer> iter = recipientIds.iterator();
                    sb.append("_id NOT IN (");
                    while (iter.hasNext()) {
                        sb.append(iter.next());
                        if (iter.hasNext()) {
                            sb.append(",");
                        }
                    }
                    sb.append(")");
                    int rows = db.delete("canonical_addresses", sb.toString(), null);
                }
            } finally {
                c.close();
            }
        }
    }

    public static void updateThread(SQLiteDatabase db, long thread_id) {
        if (thread_id < 0) {
            updateThreads(db, null, null);
            return;
        }
        updateThreads(db, "(thread_id = ?)", new String[]{ String.valueOf(thread_id) });
    }

    /**
     * Update all threads containing SMS matching the 'where' condition. Note that the condition
     * is applied to individual messages in the sms table, NOT the threads table.
     */
    public static void updateThreads(SQLiteDatabase db, String where, String[] whereArgs) {
        if (where == null) {
            where = "1";
        }
        if (whereArgs == null) {
            whereArgs = BIND_ARGS_NONE;
        }
        db.beginTransaction();
        try {
            // Delete rows in the threads table if
            // there are no more messages attached to it in either
            // the sms or pdu tables.
            // Note that we do this regardless of whether they match 'where'.
            int rows = db.delete(MmsSmsProvider.TABLE_THREADS,
                    "_id NOT IN (" +
                        " SELECT DISTINCT thread_id FROM sms WHERE thread_id IS NOT NULL" +
                        " UNION" +
                        " SELECT DISTINCT thread_id FROM pdu WHERE thread_id IS NOT NULL)",
                        null);
            if (rows > 0) {
                // If this deleted a row, let's remove orphaned canonical_addresses
                removeUnferencedCanonicalAddresses(db);
            }

            // Update the message count in the threads table as the sum
            // of all messages in both the sms and pdu tables.
            db.execSQL(
                    " UPDATE threads" +
                    " SET message_count = (" +
                        " SELECT COUNT(sms._id) FROM sms" +
                        " WHERE " + Sms.THREAD_ID + " = threads._id" +
                        " AND sms." + Sms.TYPE + " != 3" +
                    " ) + (" +
                        " SELECT COUNT(pdu._id) FROM pdu" +
                        " WHERE " + Mms.THREAD_ID + " = threads._id" +
                        " AND (m_type=132 OR m_type=130 OR m_type=128)" +
                        " AND " + Mms.MESSAGE_BOX + " != 3" +
                    " )" +
                    " WHERE EXISTS (" +
                        " SELECT _id" +
                        " FROM sms" +
                        " WHERE thread_id = threads._id" +
                        " AND (" + where + ")" +
                        " LIMIT 1" +
                    " );",
                    whereArgs);

            // Update the date and the snippet (and its character set) in
            // the threads table to be that of the most recent message in
            // the thread.
            db.execSQL(
                    " WITH matches AS (" +
                        " SELECT date * 1000 AS date, sub AS snippet, sub_cs AS snippet_cs, thread_id" +
                        " FROM pdu" +
                        " WHERE thread_id = threads._id" +
                        " UNION" +
                        " SELECT date, body AS snippet, 0 AS snippet_cs, thread_id" +
                        " FROM sms" +
                        " WHERE thread_id = threads._id" +
                        " ORDER BY date DESC" +
                        " LIMIT 1" +
                    " )" +
                    " UPDATE threads" +
                    " SET date   = (SELECT date FROM matches)," +
                        " snippet    = (SELECT snippet FROM matches)," +
                        " snippet_cs = (SELECT snippet_cs FROM matches)" +
                    " WHERE EXISTS (" +
                        " SELECT _id" +
                        " FROM sms" +
                        " WHERE thread_id = threads._id" +
                        " AND (" + where + ")" +
                        " LIMIT 1" +
                    " );",
                    whereArgs);

            // Update the error column of the thread to indicate if there
            // are any messages in it that have failed to send.
            // First check to see if there are any messages with errors in this thread.
            db.execSQL(
                    " UPDATE threads" +
                    " SET error = EXISTS (" +
                        " SELECT type" +
                        " FROM sms" +
                        " WHERE type=" + Telephony.TextBasedSmsColumns.MESSAGE_TYPE_FAILED +
                        " AND thread_id = threads._id" +
                    " )" +
                    " WHERE EXISTS (" +
                        " SELECT _id" +
                        " FROM sms" +
                        " WHERE thread_id = threads._id" +
                        " AND (" + where + ")" +
                        " LIMIT 1" +
                    " );",
                    whereArgs);

            db.setTransactionSuccessful();
        } catch (Throwable ex) {
            Log.e(TAG, ex.getMessage(), ex);
        } finally {
            db.endTransaction();
        }
    }

    private static void updateThreadDate(SQLiteDatabase db, long thread_id) {
        if (thread_id <= 0) {
            return;
        }

        try {
            db.execSQL(
                    "  UPDATE threads" +
                            "  SET" +
                            "  date =" +
                            "    (SELECT date FROM" +
                            "        (SELECT date * 1000 AS date, thread_id FROM pdu" +
                            "         UNION SELECT date, thread_id FROM sms)" +
                            "     WHERE thread_id = " + thread_id + " ORDER BY date DESC LIMIT 1)" +
                            "  WHERE threads._id = " + thread_id + ";");
        } catch (Throwable ex) {
            Log.e(TAG, ex.getMessage(), ex);
        }
    }

    public static void updateThreadsDate(SQLiteDatabase db, String where, String[] whereArgs) {
        db.beginTransaction();
        try {
            if (where == null) {
                where = "";
            } else {
                where = "WHERE (" + where + ")";
            }
            String query = "SELECT _id FROM threads " + where;
            Cursor c = db.rawQuery(query, whereArgs);
            if (c != null) {
                try {
                    Log.d(TAG, "updateThread count : " + c.getCount());
                    while (c.moveToNext()) {
                        updateThreadDate(db, c.getInt(0));
                    }
                } finally {
                    c.close();
                }
            }
            db.setTransactionSuccessful();
        } catch (Throwable ex) {
            Log.e(TAG, ex.getMessage(), ex);
        } finally {
            db.endTransaction();
        }
    }

    public static int deleteOneSms(SQLiteDatabase db, int message_id) {
        int thread_id = -1;
        // Find the thread ID that the specified SMS belongs to.
        Cursor c = db.query("sms", new String[] { "thread_id" },
                            "_id=" + message_id, null, null, null, null);
        if (c != null) {
            if (c.moveToFirst()) {
                thread_id = c.getInt(0);
            }
            c.close();
        }

        // Delete the specified message.
        int rows = db.delete("sms", "_id=" + message_id, null);
        if (thread_id > 0) {
            // Update its thread.
            updateThread(db, thread_id);
        }
        return rows;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        localLog("onCreate: Creating all SMS-MMS tables.");

        createMmsTables(db);
        createSmsTables(db);
        createCommonTables(db);
        createCommonTriggers(db);
        createMmsTriggers(db);
        createWordsTables(db);
        createIndices(db);

        // if FBE is not supported, or if this onCreate is for CE partition database
        if (!StorageManager.isFileEncryptedNativeOrEmulated()
                || (mContext != null && 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);
        }
    }

    private static void localLog(String logMsg) {
        Log.d(TAG, logMsg);
        PhoneFactory.localLog(TAG, logMsg);
    }

    private static void localLogWtf(String logMsg) {
        Log.wtf(TAG, logMsg);
        PhoneFactory.localLog(TAG, logMsg);
    }

    @Override
    public void onOpen(SQLiteDatabase db) {
        try {
            // Try to access the table and create it if "no such table"
            db.query(SmsProvider.TABLE_SMS, null, null, null, null, null, null);
            checkAndUpdateSmsTable(db);
        } catch (SQLiteException e) {
            Log.e(TAG, "onOpen: ex. ", e);
            if (e.getMessage().startsWith(NO_SUCH_TABLE_EXCEPTION_MESSAGE)) {
                createSmsTables(db);
            }
        }
        try {
            // Try to access the table and create it if "no such table"
            db.query(MmsSmsProvider.TABLE_THREADS, null, null, null, null, null, null);
            checkAndUpdateThreadsTable(db);
        } catch (SQLiteException e) {
            Log.e(TAG, "onOpen: ex. ", e);
            if (e.getMessage().startsWith(NO_SUCH_TABLE_EXCEPTION_MESSAGE)) {
                createCommonTables(db);
            }
        }

        // Improve the performance of deleting Mms.
        dropMmsTriggers(db);
    }

    private void dropMmsTriggers(SQLiteDatabase db) {
        db.execSQL("DROP TRIGGER IF EXISTS update_threads_on_delete_part");
        db.execSQL("DROP TRIGGER IF EXISTS mms_words_delete");
        db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_on_delete");
    }

    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) {
        final String TABLE_WORDS = "words";
        {
            Cursor smsRows = db.query(
                    "sms",
                    new String[] { Sms._ID, Sms.BODY },
                    null,
                    null,
                    null,
                    null,
                    null);
            try {
                if (smsRows != null) {
                    smsRows.moveToPosition(-1);
                    ContentValues cv = new ContentValues();
                    while (smsRows.moveToNext()) {
                        cv.clear();

                        long id = smsRows.getLong(0);        // 0 for Sms._ID
                        String body = smsRows.getString(1);  // 1 for Sms.BODY

                        cv.put(Telephony.MmsSms.WordsTable.ID, id);
                        cv.put(Telephony.MmsSms.WordsTable.INDEXED_TEXT, body);
                        cv.put(Telephony.MmsSms.WordsTable.SOURCE_ROW_ID, id);
                        cv.put(Telephony.MmsSms.WordsTable.TABLE_ID, 1);
                        db.insert(TABLE_WORDS, Telephony.MmsSms.WordsTable.INDEXED_TEXT, cv);
                    }
                }
            } finally {
                if (smsRows != null) {
                    smsRows.close();
                }
            }
        }

        {
            Cursor mmsRows = db.query(
                    "part",
                    new String[] { Part._ID, Part.TEXT },
                    "ct = 'text/plain'",
                    null,
                    null,
                    null,
                    null);
            try {
                if (mmsRows != null) {
                    mmsRows.moveToPosition(-1);
                    ContentValues cv = new ContentValues();
                    while (mmsRows.moveToNext()) {
                        cv.clear();

                        long id = mmsRows.getLong(0);         // 0 for Part._ID
                        String body = mmsRows.getString(1);   // 1 for Part.TEXT

                        cv.put(Telephony.MmsSms.WordsTable.ID, id);
                        cv.put(Telephony.MmsSms.WordsTable.INDEXED_TEXT, body);
                        cv.put(Telephony.MmsSms.WordsTable.SOURCE_ROW_ID, id);
                        cv.put(Telephony.MmsSms.WordsTable.TABLE_ID, 1);
                        db.insert(TABLE_WORDS, Telephony.MmsSms.WordsTable.INDEXED_TEXT, cv);
                    }
                }
            } finally {
                if (mmsRows != null) {
                    mmsRows.close();
                }
            }
        }
    }

    private void createWordsTables(SQLiteDatabase db) {
        createWordsTables(db, -1, -1, -1);
    }

    private void createWordsTables(
            SQLiteDatabase db, int oldVersion, int currentVersion, int upgradeVersion) {
        try {
            db.execSQL("CREATE VIRTUAL TABLE words USING FTS3 (_id INTEGER PRIMARY KEY, index_text TEXT, source_id INTEGER, table_to_use INTEGER);");

            // monitor the sms table
            // NOTE don't handle inserts using a trigger because it has an unwanted
            // side effect:  the value returned for the last row ends up being the
            // id of one of the trigger insert not the original row insert.
            // Handle inserts manually in the provider.
            db.execSQL("CREATE TRIGGER sms_words_update AFTER UPDATE ON sms BEGIN UPDATE words " +
                    " SET index_text = NEW.body WHERE (source_id=NEW._id AND table_to_use=1); " +
                    " END;");
            db.execSQL("CREATE TRIGGER sms_words_delete AFTER DELETE ON sms BEGIN DELETE FROM " +
                    "  words WHERE source_id = OLD._id AND table_to_use = 1; END;");

            populateWordsTable(db);
        } catch (Exception ex) {
            Log.e(TAG, "got exception creating words table: " + ex.toString());
            logException(ex, oldVersion, currentVersion, upgradeVersion);
        }
    }

    private void createIndices(SQLiteDatabase db) {
        createThreadIdIndex(db);
        createThreadIdDateIndex(db);
        createPartMidIndex(db);
        createAddrMsgIdIndex(db);
        createPduPartIndex(db);
    }

    private void createPduPartIndex(SQLiteDatabase db) {
        try {
            db.execSQL("CREATE INDEX IF NOT EXISTS index_part ON " + MmsProvider.TABLE_PART +
                        " (mid);");
        } catch (Exception ex) {
            Log.e(TAG, "got exception creating indices: " + ex.toString());
        }
     }

    private void createThreadIdIndex(SQLiteDatabase db) {
        createThreadIdIndex(db, -1, -1, -1);
    }

    private void createThreadIdIndex(
            SQLiteDatabase db, int oldVersion, int currentVersion, int upgradeVersion) {
        try {
            db.execSQL("CREATE INDEX IF NOT EXISTS typeThreadIdIndex ON sms" +
            " (type, thread_id);");
        } catch (Exception ex) {
            Log.e(TAG, "got exception creating indices: " + ex.toString());
            logException(ex, oldVersion, currentVersion, upgradeVersion);
        }
    }

    private void createThreadIdDateIndex(SQLiteDatabase db) {
        createThreadIdDateIndex(db, -1, -1, -1);
    }

    private void createThreadIdDateIndex(
            SQLiteDatabase db, int oldVersion, int currentVersion, int upgradeVersion) {
        try {
            db.execSQL("CREATE INDEX IF NOT EXISTS threadIdDateIndex ON sms" +
            " (thread_id, date);");
        } catch (Exception ex) {
            Log.e(TAG, "got exception creating indices: " + ex.toString());
            logException(ex, oldVersion, currentVersion, upgradeVersion);
        }
    }

    private void createPartMidIndex(SQLiteDatabase db) {
        createPartMidIndex(db, -1, -1, -1);
    }

    private void createPartMidIndex(
            SQLiteDatabase db, int oldVersion, int currentVersion, int upgradeVersion) {
        try {
            db.execSQL("CREATE INDEX IF NOT EXISTS partMidIndex ON part (mid)");
        } catch (Exception ex) {
            Log.e(TAG, "got exception creating indices: " + ex.toString());
            logException(ex, oldVersion, currentVersion, upgradeVersion);
        }
    }

    private void createAddrMsgIdIndex(SQLiteDatabase db) {
        createAddrMsgIdIndex(db, -1, -1, -1);
    }

    private void createAddrMsgIdIndex(
            SQLiteDatabase db, int oldVersion, int currentVersion, int upgradeVersion) {
        try {
            db.execSQL("CREATE INDEX IF NOT EXISTS addrMsgIdIndex ON addr (msg_id)");
        } catch (Exception ex) {
            Log.e(TAG, "got exception creating indices: " + ex.toString());
            logException(ex, oldVersion, currentVersion, upgradeVersion);
        }
    }

    @VisibleForTesting
    public static String CREATE_ADDR_TABLE_STR =
            "CREATE TABLE " + MmsProvider.TABLE_ADDR + " (" +
                    Addr._ID + " INTEGER PRIMARY KEY," +
                    Addr.MSG_ID + " INTEGER," +
                    Addr.CONTACT_ID + " INTEGER," +
                    Addr.ADDRESS + " TEXT," +
                    Addr.TYPE + " INTEGER," +
                    Addr.CHARSET + " INTEGER);";

    @VisibleForTesting
    public static String CREATE_PART_TABLE_STR =
            "CREATE TABLE " + MmsProvider.TABLE_PART + " (" +
                    Part._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                    Part.MSG_ID + " INTEGER," +
                    Part.SEQ + " INTEGER DEFAULT 0," +
                    Part.CONTENT_TYPE + " TEXT," +
                    Part.NAME + " TEXT," +
                    Part.CHARSET + " INTEGER," +
                    Part.CONTENT_DISPOSITION + " TEXT," +
                    Part.FILENAME + " TEXT," +
                    Part.CONTENT_ID + " TEXT," +
                    Part.CONTENT_LOCATION + " TEXT," +
                    Part.CT_START + " INTEGER," +
                    Part.CT_TYPE + " TEXT," +
                    Part._DATA + " TEXT," +
                    Part.TEXT + " TEXT);";

    public static String CREATE_PDU_TABLE_STR =
            "CREATE TABLE " + MmsProvider.TABLE_PDU + " (" +
                    Mms._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                    Mms.THREAD_ID + " INTEGER," +
                    Mms.DATE + " INTEGER," +
                    Mms.DATE_SENT + " INTEGER DEFAULT 0," +
                    Mms.MESSAGE_BOX + " INTEGER," +
                    Mms.READ + " INTEGER DEFAULT 0," +
                    Mms.MESSAGE_ID + " TEXT," +
                    Mms.SUBJECT + " TEXT," +
                    Mms.SUBJECT_CHARSET + " INTEGER," +
                    Mms.CONTENT_TYPE + " TEXT," +
                    Mms.CONTENT_LOCATION + " TEXT," +
                    Mms.EXPIRY + " INTEGER," +
                    Mms.MESSAGE_CLASS + " TEXT," +
                    Mms.MESSAGE_TYPE + " INTEGER," +
                    Mms.MMS_VERSION + " INTEGER," +
                    Mms.MESSAGE_SIZE + " INTEGER," +
                    Mms.PRIORITY + " INTEGER," +
                    Mms.READ_REPORT + " INTEGER," +
                    Mms.REPORT_ALLOWED + " INTEGER," +
                    Mms.RESPONSE_STATUS + " INTEGER," +
                    Mms.STATUS + " INTEGER," +
                    Mms.TRANSACTION_ID + " TEXT," +
                    Mms.RETRIEVE_STATUS + " INTEGER," +
                    Mms.RETRIEVE_TEXT + " TEXT," +
                    Mms.RETRIEVE_TEXT_CHARSET + " INTEGER," +
                    Mms.READ_STATUS + " INTEGER," +
                    Mms.CONTENT_CLASS + " INTEGER," +
                    Mms.RESPONSE_TEXT + " TEXT," +
                    Mms.DELIVERY_TIME + " INTEGER," +
                    Mms.DELIVERY_REPORT + " INTEGER," +
                    Mms.LOCKED + " INTEGER DEFAULT 0," +
                    Mms.SUBSCRIPTION_ID + " INTEGER DEFAULT "
                    + SubscriptionManager.INVALID_SUBSCRIPTION_ID + ", " +
                    Mms.SEEN + " INTEGER DEFAULT 0," +
                    Mms.CREATOR + " TEXT," +
                    Mms.TEXT_ONLY + " INTEGER DEFAULT 0);";

    @VisibleForTesting
    public static String CREATE_RATE_TABLE_STR =
            "CREATE TABLE " + MmsProvider.TABLE_RATE + " (" +
                    Rate.SENT_TIME + " INTEGER);";

    @VisibleForTesting
    public static String CREATE_DRM_TABLE_STR =
            "CREATE TABLE " + MmsProvider.TABLE_DRM + " (" +
                    BaseColumns._ID + " INTEGER PRIMARY KEY," +
                    "_data TEXT);";

    @VisibleForTesting
    void createMmsTables(SQLiteDatabase db) {
        // N.B.: Whenever the columns here are changed, the columns in
        // {@ref MmsSmsProvider} must be changed to match.
        db.execSQL(CREATE_PDU_TABLE_STR);

        db.execSQL(CREATE_ADDR_TABLE_STR);

        db.execSQL(CREATE_PART_TABLE_STR);

        db.execSQL(CREATE_RATE_TABLE_STR);

        db.execSQL(CREATE_DRM_TABLE_STR);

        // Restricted view of pdu table, only sent/received messages without wap pushes
        db.execSQL("CREATE VIEW " + MmsProvider.VIEW_PDU_RESTRICTED + " AS " +
                "SELECT * FROM " + MmsProvider.TABLE_PDU + " WHERE " +
                "(" + Mms.MESSAGE_BOX + "=" + Mms.MESSAGE_BOX_INBOX +
                " OR " +
                Mms.MESSAGE_BOX + "=" + Mms.MESSAGE_BOX_SENT + ")" +
                " AND " +
                "(" + Mms.MESSAGE_TYPE + "!=" + PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND + ");");
    }

    // Unlike the other trigger-creating functions, this function can be called multiple times
    // without harm.
    private void createMmsTriggers(SQLiteDatabase db) {
        // Cleans up parts when a MM is deleted.
        db.execSQL("DROP TRIGGER IF EXISTS part_cleanup");
        db.execSQL("CREATE TRIGGER part_cleanup DELETE ON " + MmsProvider.TABLE_PDU + " " +
                "BEGIN " +
                "  DELETE FROM " + MmsProvider.TABLE_PART +
                "  WHERE " + Part.MSG_ID + "=old._id;" +
                "END;");

        // Cleans up address info when a MM is deleted.
        db.execSQL("DROP TRIGGER IF EXISTS addr_cleanup");
        db.execSQL("CREATE TRIGGER addr_cleanup DELETE ON " + MmsProvider.TABLE_PDU + " " +
                "BEGIN " +
                "  DELETE FROM " + MmsProvider.TABLE_ADDR +
                "  WHERE " + Addr.MSG_ID + "=old._id;" +
                "END;");

        // Delete obsolete delivery-report, read-report while deleting their
        // associated Send.req.
        db.execSQL("DROP TRIGGER IF EXISTS cleanup_delivery_and_read_report");
        db.execSQL("CREATE TRIGGER cleanup_delivery_and_read_report " +
                "AFTER DELETE ON " + MmsProvider.TABLE_PDU + " " +
                "WHEN old." + Mms.MESSAGE_TYPE + "=" + PduHeaders.MESSAGE_TYPE_SEND_REQ + " " +
                "BEGIN " +
                "  DELETE FROM " + MmsProvider.TABLE_PDU +
                "  WHERE (" + Mms.MESSAGE_TYPE + "=" + PduHeaders.MESSAGE_TYPE_DELIVERY_IND +
                "    OR " + Mms.MESSAGE_TYPE + "=" + PduHeaders.MESSAGE_TYPE_READ_ORIG_IND +
                ")" +
                "    AND " + Mms.MESSAGE_ID + "=old." + Mms.MESSAGE_ID + "; " +
                "END;");

        db.execSQL("DROP TRIGGER IF EXISTS update_threads_on_insert_part");
        db.execSQL(PART_UPDATE_THREADS_ON_INSERT_TRIGGER);

        db.execSQL("DROP TRIGGER IF EXISTS update_threads_on_update_part");
        db.execSQL(PART_UPDATE_THREADS_ON_UPDATE_TRIGGER);

        db.execSQL("DROP TRIGGER IF EXISTS update_threads_on_update_pdu");
        db.execSQL(PDU_UPDATE_THREADS_ON_UPDATE_TRIGGER);

        // Delete pending status for a message when it is deleted.
        db.execSQL("DROP TRIGGER IF EXISTS delete_mms_pending_on_delete");
        db.execSQL("CREATE TRIGGER delete_mms_pending_on_delete " +
                   "AFTER DELETE ON " + MmsProvider.TABLE_PDU + " " +
                   "BEGIN " +
                   "  DELETE FROM " + MmsSmsProvider.TABLE_PENDING_MSG +
                   "  WHERE " + PendingMessages.MSG_ID + "=old._id; " +
                   "END;");

        // When a message is moved out of Outbox, delete its pending status.
        db.execSQL("DROP TRIGGER IF EXISTS delete_mms_pending_on_update");
        db.execSQL("CREATE TRIGGER delete_mms_pending_on_update " +
                   "AFTER UPDATE ON " + MmsProvider.TABLE_PDU + " " +
                   "WHEN old." + Mms.MESSAGE_BOX + "=" + Mms.MESSAGE_BOX_OUTBOX +
                   "  AND new." + Mms.MESSAGE_BOX + "!=" + Mms.MESSAGE_BOX_OUTBOX + " " +
                   "BEGIN " +
                   "  DELETE FROM " + MmsSmsProvider.TABLE_PENDING_MSG +
                   "  WHERE " + PendingMessages.MSG_ID + "=new._id; " +
                   "END;");

        // Insert pending status for M-Notification.ind or M-ReadRec.ind
        // when they are inserted into Inbox/Outbox.
        db.execSQL("DROP TRIGGER IF EXISTS insert_mms_pending_on_insert");
        db.execSQL("CREATE TRIGGER insert_mms_pending_on_insert " +
                   "AFTER INSERT ON pdu " +
                   "WHEN new." + Mms.MESSAGE_TYPE + "=" + PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND +
                   "  OR new." + Mms.MESSAGE_TYPE + "=" + PduHeaders.MESSAGE_TYPE_READ_REC_IND +
                   " " +
                   "BEGIN " +
                   "  INSERT INTO " + MmsSmsProvider.TABLE_PENDING_MSG +
                   "    (" + PendingMessages.PROTO_TYPE + "," +
                   "     " + PendingMessages.MSG_ID + "," +
                   "     " + PendingMessages.MSG_TYPE + "," +
                   "     " + PendingMessages.ERROR_TYPE + "," +
                   "     " + PendingMessages.ERROR_CODE + "," +
                   "     " + PendingMessages.RETRY_INDEX + "," +
                   "     " + PendingMessages.DUE_TIME + ") " +
                   "  VALUES " +
                   "    (" + MmsSms.MMS_PROTO + "," +
                   "      new." + BaseColumns._ID + "," +
                   "      new." + Mms.MESSAGE_TYPE + ",0,0,0,0);" +
                   "END;");


        // Insert pending status for M-Send.req when it is moved into Outbox.
        db.execSQL("DROP TRIGGER IF EXISTS insert_mms_pending_on_update");
        db.execSQL("CREATE TRIGGER insert_mms_pending_on_update " +
                   "AFTER UPDATE ON pdu " +
                   "WHEN new." + Mms.MESSAGE_TYPE + "=" + PduHeaders.MESSAGE_TYPE_SEND_REQ +
                   "  AND new." + Mms.MESSAGE_BOX + "=" + Mms.MESSAGE_BOX_OUTBOX +
                   "  AND old." + Mms.MESSAGE_BOX + "!=" + Mms.MESSAGE_BOX_OUTBOX + " " +
                   "BEGIN " +
                   "  INSERT INTO " + MmsSmsProvider.TABLE_PENDING_MSG +
                   "    (" + PendingMessages.PROTO_TYPE + "," +
                   "     " + PendingMessages.MSG_ID + "," +
                   "     " + PendingMessages.MSG_TYPE + "," +
                   "     " + PendingMessages.ERROR_TYPE + "," +
                   "     " + PendingMessages.ERROR_CODE + "," +
                   "     " + PendingMessages.RETRY_INDEX + "," +
                   "     " + PendingMessages.DUE_TIME + ") " +
                   "  VALUES " +
                   "    (" + MmsSms.MMS_PROTO + "," +
                   "      new." + BaseColumns._ID + "," +
                   "      new." + Mms.MESSAGE_TYPE + ",0,0,0,0);" +
                   "END;");

        // monitor the mms table
        db.execSQL("DROP TRIGGER IF EXISTS mms_words_update");
        db.execSQL("CREATE TRIGGER mms_words_update AFTER UPDATE ON part BEGIN UPDATE words " +
                " SET index_text = NEW.text WHERE (source_id=NEW._id AND table_to_use=2); " +
                " END;");

        // Updates threads table whenever a message in pdu is updated.
        db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_date_subject_on_update");
        db.execSQL("CREATE TRIGGER pdu_update_thread_date_subject_on_update AFTER" +
                   "  UPDATE OF " + Mms.DATE + ", " + Mms.SUBJECT + ", " + Mms.MESSAGE_BOX +
                   "  ON " + MmsProvider.TABLE_PDU + " " +
                   PDU_UPDATE_THREAD_CONSTRAINTS +
                   PDU_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE);

        // Updates threads table whenever a message is added to pdu.
        db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_on_insert");
        db.execSQL("CREATE TRIGGER pdu_update_thread_on_insert AFTER INSERT ON " +
                   MmsProvider.TABLE_PDU + " " +
                   PDU_UPDATE_THREAD_CONSTRAINTS +
                   PDU_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE);

        // Updates threads table whenever a message in pdu is updated.
        db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_read_on_update");
        db.execSQL("CREATE TRIGGER pdu_update_thread_read_on_update AFTER" +
                   "  UPDATE OF " + Mms.READ +
                   "  ON " + MmsProvider.TABLE_PDU + " " +
                   PDU_UPDATE_THREAD_CONSTRAINTS +
                   "BEGIN " +
                   PDU_UPDATE_THREAD_READ_BODY +
                   "END;");

        // Update the error flag of threads when delete pending message.
        db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_delete_mms");
        db.execSQL("CREATE TRIGGER update_threads_error_on_delete_mms " +
                   "  BEFORE DELETE ON pdu" +
                   "  WHEN OLD._id IN (SELECT DISTINCT msg_id" +
                   "                   FROM pending_msgs" +
                   "                   WHERE err_type >= 10) " +
                   "BEGIN " +
                   "  UPDATE threads SET error = error - 1" +
                   "  WHERE _id = OLD.thread_id; " +
                   "END;");

        // Update the error flag of threads while moving an MM out of Outbox,
        // which was failed to be sent permanently.
        db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_move_mms");
        db.execSQL("CREATE TRIGGER update_threads_error_on_move_mms " +
                   "  BEFORE UPDATE OF msg_box ON pdu " +
                   "  WHEN (OLD.msg_box = 4 AND NEW.msg_box != 4) " +
                   "  AND (OLD._id IN (SELECT DISTINCT msg_id" +
                   "                   FROM pending_msgs" +
                   "                   WHERE err_type >= 10)) " +
                   "BEGIN " +
                   "  UPDATE threads SET error = error - 1" +
                   "  WHERE _id = OLD.thread_id; " +
                   "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 " + NO_ERROR_CODE + ", " +
            "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);";

    /**
     * This table is used by the SMS dispatcher to hold
     * incomplete partial messages until all the parts arrive.
     */
    @VisibleForTesting
    public static String CREATE_RAW_TABLE_STRING =
            "CREATE TABLE raw (" +
            "_id INTEGER PRIMARY KEY," +
            "date INTEGER," +
            "reference_number INTEGER," + // one per full message
            "count INTEGER," + // the number of parts
            "sequence INTEGER," + // the part number of this message
            "destination_port INTEGER," +
            "address TEXT," +
            "sub_id INTEGER DEFAULT " + SubscriptionManager.INVALID_SUBSCRIPTION_ID + ", " +
            "pdu TEXT," + // the raw PDU for this part
            "deleted INTEGER DEFAULT 0," + // bool to indicate if row is deleted
            "message_body TEXT," + // message body
            "display_originating_addr TEXT);";
    // email address if from an email gateway, otherwise same as address
    @VisibleForTesting
    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_SMS_TABLE_STRING);

        db.execSQL(CREATE_RAW_TABLE_STRING);

        db.execSQL(CREATE_ATTACHMENTS_TABLE_STRING);

        /**
         * This table is used by the SMS dispatcher to hold pending
         * delivery status report intents.
         */
        db.execSQL("CREATE TABLE sr_pending (" +
                   "reference_number INTEGER," +
                   "action TEXT," +
                   "data TEXT);");

        // Restricted view of sms table, only sent/received messages
        db.execSQL("CREATE VIEW " + SmsProvider.VIEW_SMS_RESTRICTED + " AS " +
                   "SELECT * FROM " + SmsProvider.TABLE_SMS + " WHERE " +
                   Sms.TYPE + "=" + Sms.MESSAGE_TYPE_INBOX +
                   " OR " +
                   Sms.TYPE + "=" + Sms.MESSAGE_TYPE_SENT + ";");

        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
            // Create a table to keep track of changes to SMS table - specifically on update to read
            // and deletion of msgs
            db.execSQL("CREATE TABLE sms_changes (" +
                       "_id INTEGER PRIMARY KEY," +
                       "orig_rowid INTEGER," +
                       "sub_id INTEGER," +
                       "type INTEGER," +
                       "new_read_status INTEGER" +
                       ");");
            db.execSQL("CREATE TRIGGER sms_update_on_read_change_row " +
                        "AFTER UPDATE OF read ON sms WHEN NEW.read != OLD.read " +
                        "BEGIN " +
                        "  INSERT INTO sms_changes VALUES(null, NEW._id, NEW.sub_id, " +
                        "0, NEW.read); " +
                        "END;");
            db.execSQL("CREATE TRIGGER sms_delete_change_row " +
                       "AFTER DELETE ON sms " +
                       "BEGIN " +
                       "  INSERT INTO sms_changes values(null, OLD._id, OLD.sub_id, 1, null); " +
                       "END;");
        }
    }

    @VisibleForTesting
    void createCommonTables(SQLiteDatabase db) {
        // TODO Ensure that each entry is removed when the last use of
        // any address equivalent to its address is removed.

        /**
         * This table maps the first instance seen of any particular
         * MMS/SMS address to an ID, which is then used as its
         * canonical representation.  If the same address or an
         * equivalent address (as determined by our Sqlite
         * PHONE_NUMBERS_EQUAL extension) is seen later, this same ID
         * will be used. The _id is created with AUTOINCREMENT so it
         * will never be reused again if a recipient is deleted.
         */
        db.execSQL("CREATE TABLE canonical_addresses (" +
                   "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
                   "address TEXT);");

        /**
         * This table maps the subject and an ordered set of recipient
         * IDs, separated by spaces, to a unique thread ID.  The IDs
         * come from the canonical_addresses table.  This works
         * because messages are considered to be part of the same
         * thread if they have the same subject (or a null subject)
         * and the same set of recipients.
         */
        db.execSQL("CREATE TABLE threads (" +
                   Threads._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                   Threads.DATE + " INTEGER DEFAULT 0," +
                   Threads.MESSAGE_COUNT + " INTEGER DEFAULT 0," +
                   Threads.RECIPIENT_IDS + " TEXT," +
                   Threads.SNIPPET + " TEXT," +
                   Threads.SNIPPET_CHARSET + " INTEGER DEFAULT 0," +
                   Threads.READ + " INTEGER DEFAULT 1," +
                   Threads.ARCHIVED + " INTEGER DEFAULT 0," +
                   Threads.TYPE + " INTEGER DEFAULT 0," +
                   Threads.ERROR + " INTEGER DEFAULT 0," +
                   Threads.HAS_ATTACHMENT + " INTEGER DEFAULT 0," +
                   Threads.ATTACHMENT_INFO + " TEXT," +
                   Threads.NOTIFICATION + " INTEGER DEFAULT 0);");

        /**
         * This table stores the queue of messages to be sent/downloaded.
         */
        db.execSQL("CREATE TABLE " + MmsSmsProvider.TABLE_PENDING_MSG +" (" +
                   PendingMessages._ID + " INTEGER PRIMARY KEY," +
                   PendingMessages.PROTO_TYPE + " INTEGER," +
                   PendingMessages.MSG_ID + " INTEGER," +
                   PendingMessages.MSG_TYPE + " INTEGER," +
                   PendingMessages.ERROR_TYPE + " INTEGER," +
                   PendingMessages.ERROR_CODE + " INTEGER," +
                   PendingMessages.RETRY_INDEX + " INTEGER NOT NULL DEFAULT 0," +
                   PendingMessages.DUE_TIME + " INTEGER," +
                   PendingMessages.SUBSCRIPTION_ID + " INTEGER DEFAULT " +
                           SubscriptionManager.INVALID_SUBSCRIPTION_ID + ", " +
                   PendingMessages.LAST_TRY + " INTEGER);");

    }

    // TODO Check the query plans for these triggers.
    private void createCommonTriggers(SQLiteDatabase db) {
        // Updates threads table whenever a message is added to sms.
        db.execSQL("CREATE TRIGGER sms_update_thread_on_insert AFTER INSERT ON sms " +
                   SMS_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE);

        // Updates threads table whenever a message in sms is updated.
        db.execSQL("CREATE TRIGGER sms_update_thread_date_subject_on_update AFTER" +
                   "  UPDATE OF " + Sms.DATE + ", " + Sms.BODY + ", " + Sms.TYPE +
                   "  ON sms " +
                   SMS_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE);

        // Updates threads table whenever a message in sms is updated.
        db.execSQL("CREATE TRIGGER sms_update_thread_read_on_update AFTER" +
                   "  UPDATE OF " + Sms.READ +
                   "  ON sms " +
                   "BEGIN " +
                   SMS_UPDATE_THREAD_READ_BODY +
                   "END;");

        // As of DATABASE_VERSION 55, we've removed these triggers that delete empty threads.
        // These triggers interfere with saving drafts on brand new threads. Instead of
        // triggers cleaning up empty threads, the empty threads should be cleaned up by
        // an explicit call to delete with Threads.OBSOLETE_THREADS_URI.

//        // When the last message in a thread is deleted, these
//        // triggers ensure that the entry for its thread ID is removed
//        // from the threads table.
//        db.execSQL("CREATE TRIGGER delete_obsolete_threads_pdu " +
//                   "AFTER DELETE ON pdu " +
//                   "BEGIN " +
//                   "  DELETE FROM threads " +
//                   "  WHERE " +
//                   "    _id = old.thread_id " +
//                   "    AND _id NOT IN " +
//                   "    (SELECT thread_id FROM sms " +
//                   "     UNION SELECT thread_id from pdu); " +
//                   "END;");
//
//        db.execSQL("CREATE TRIGGER delete_obsolete_threads_when_update_pdu " +
//                   "AFTER UPDATE OF " + Mms.THREAD_ID + " ON pdu " +
//                   "WHEN old." + Mms.THREAD_ID + " != new." + Mms.THREAD_ID + " " +
//                   "BEGIN " +
//                   "  DELETE FROM threads " +
//                   "  WHERE " +
//                   "    _id = old.thread_id " +
//                   "    AND _id NOT IN " +
//                   "    (SELECT thread_id FROM sms " +
//                   "     UNION SELECT thread_id from pdu); " +
//                   "END;");

        // TODO Add triggers for SMS retry-status management.

        // Update the error flag of threads when the error type of
        // a pending MM is updated.
        db.execSQL("CREATE TRIGGER update_threads_error_on_update_mms " +
                   "  AFTER UPDATE OF err_type ON pending_msgs " +
                   "  WHEN (OLD.err_type < 10 AND NEW.err_type >= 10)" +
                   "    OR (OLD.err_type >= 10 AND NEW.err_type < 10) " +
                   "BEGIN" +
                   "  UPDATE threads SET error = " +
                   "    CASE" +
                   "      WHEN NEW.err_type >= 10 THEN error + 1" +
                   "      ELSE error - 1" +
                   "    END " +
                   "  WHERE _id =" +
                   "   (SELECT DISTINCT thread_id" +
                   "    FROM pdu" +
                   "    WHERE _id = NEW.msg_id); " +
                   "END;");

        // Update the error flag of threads after a text message was
        // failed to send/receive.
        db.execSQL("CREATE TRIGGER update_threads_error_on_update_sms " +
                   "  AFTER UPDATE OF type ON sms" +
                   "  WHEN (OLD.type != 5 AND NEW.type = 5)" +
                   "    OR (OLD.type = 5 AND NEW.type != 5) " +
                   "BEGIN " +
                   "  UPDATE threads SET error = " +
                   "    CASE" +
                   "      WHEN NEW.type = 5 THEN error + 1" +
                   "      ELSE error - 1" +
                   "    END " +
                   "  WHERE _id = NEW.thread_id; " +
                   "END;");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
        Log.w(TAG, "Upgrading database from version " + oldVersion
                + " to " + currentVersion + ".");

        switch (oldVersion) {
        case 40:
            if (currentVersion <= 40) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion41(db);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 41);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 41:
            if (currentVersion <= 41) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion42(db);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 42);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 42:
            if (currentVersion <= 42) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion43(db);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 43);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 43:
            if (currentVersion <= 43) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion44(db);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 44);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 44:
            if (currentVersion <= 44) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion45(db);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 45);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 45:
            if (currentVersion <= 45) {
                return;
            }
            db.beginTransaction();
            try {
                upgradeDatabaseToVersion46(db, oldVersion, currentVersion);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 46);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 46:
            if (currentVersion <= 46) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion47(db);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 47);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 47:
            if (currentVersion <= 47) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion48(db);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 48);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 48:
            if (currentVersion <= 48) {
                return;
            }

            db.beginTransaction();
            try {
                createWordsTables(db, oldVersion, currentVersion, 49);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 49);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 49:
            if (currentVersion <= 49) {
                return;
            }
            db.beginTransaction();
            try {
                createThreadIdIndex(db, oldVersion, currentVersion, 50);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 50);
                break; // force to destroy all old data;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 50:
            if (currentVersion <= 50) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion51(db);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 51);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 51:
            if (currentVersion <= 51) {
                return;
            }
            // 52 was adding a new meta_data column, but that was removed.
            // fall through
        case 52:
            if (currentVersion <= 52) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion53(db);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 53);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 53:
            if (currentVersion <= 53) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion54(db);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 54);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 54:
            if (currentVersion <= 54) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion55(db);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 55);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 55:
            if (currentVersion <= 55) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion56(db);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 56);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 56:
            if (currentVersion <= 56) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion57(db);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 57);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 57:
            if (currentVersion <= 57) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion58(db);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 58);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 58:
            if (currentVersion <= 58) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion59(db);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 59);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 59:
            if (currentVersion <= 59) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion60(db);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 60);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 60:
            if (currentVersion <= 60) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion61(db);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 61);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 61:
            if (currentVersion <= 61) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion62(db, oldVersion, currentVersion);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 62);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 62:
            if (currentVersion <= 62) {
                return;
            }

            db.beginTransaction();
            try {
                // upgrade to 63: just add a happy little index.
                createThreadIdDateIndex(db, oldVersion, currentVersion, 63);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 63);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 63:
            if (currentVersion <= 63) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion64(db);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 64);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 64:
            if (currentVersion <= 64) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion65(db, oldVersion, currentVersion);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 65);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 65:
            if (currentVersion <= 65) {
                return;
            }

            db.beginTransaction();
            try {
                upgradeDatabaseToVersion66(db, oldVersion, currentVersion);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 66);
                break;
            } finally {
                db.endTransaction();
            }
            // fall through
        case 66:
            if (currentVersion <= 66) {
                return;
            }
            db.beginTransaction();
            try {
                createPartMidIndex(db, oldVersion, currentVersion, 67);
                createAddrMsgIdIndex(db, oldVersion, currentVersion, 67);
                db.setTransactionSuccessful();
            } catch (Throwable ex) {
                Log.e(TAG, ex.getMessage(), ex);
                logException(ex, oldVersion, currentVersion, 67);
                break; // force to destroy all old data;
            } finally {
                db.endTransaction();
            }
            return;
        }

        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);
    }

    private void logException(
            Throwable ex, int oldVersion, int currentVersion, int upgradeVersion) {
        int exception = FAILURE_UNKNOWN;
        if (ex instanceof SQLiteException) {
            exception = SQL_EXCEPTION;
        } else if (ex instanceof IOException) {
            exception = IO_EXCEPTION;
        } else if (ex instanceof SecurityException) {
            exception = SECURITY_EXCEPTION;
        }
        TelephonyStatsLog.write(
            TelephonyStatsLog.MMS_SMS_DATABASE_HELPER_ON_UPGRADE_FAILED,
            oldVersion,
            currentVersion,
            upgradeVersion,
            exception);
    }

    private void dropAll(SQLiteDatabase db) {
        // 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);
        db.execSQL("DROP TABLE IF EXISTS sms");
        db.execSQL("DROP TABLE IF EXISTS raw");
        db.execSQL("DROP TABLE IF EXISTS attachments");
        db.execSQL("DROP TABLE IF EXISTS thread_ids");
        db.execSQL("DROP TABLE IF EXISTS sr_pending");
        db.execSQL("DROP TABLE IF EXISTS " + MmsProvider.TABLE_PDU + ";");
        db.execSQL("DROP TABLE IF EXISTS " + MmsProvider.TABLE_ADDR + ";");
        db.execSQL("DROP TABLE IF EXISTS " + MmsProvider.TABLE_PART + ";");
        db.execSQL("DROP TABLE IF EXISTS " + MmsProvider.TABLE_RATE + ";");
        db.execSQL("DROP TABLE IF EXISTS " + MmsProvider.TABLE_DRM + ";");
    }

    private void upgradeDatabaseToVersion41(SQLiteDatabase db) {
        db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_move_mms");
        db.execSQL("CREATE TRIGGER update_threads_error_on_move_mms " +
                   "  BEFORE UPDATE OF msg_box ON pdu " +
                   "  WHEN (OLD.msg_box = 4 AND NEW.msg_box != 4) " +
                   "  AND (OLD._id IN (SELECT DISTINCT msg_id" +
                   "                   FROM pending_msgs" +
                   "                   WHERE err_type >= 10)) " +
                   "BEGIN " +
                   "  UPDATE threads SET error = error - 1" +
                   "  WHERE _id = OLD.thread_id; " +
                   "END;");
    }

    private void upgradeDatabaseToVersion42(SQLiteDatabase db) {
        db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_delete");
        db.execSQL("DROP TRIGGER IF EXISTS delete_obsolete_threads_sms");
        db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_delete_sms");
    }

    private void upgradeDatabaseToVersion43(SQLiteDatabase db) {
        // Add 'has_attachment' column to threads table.
        db.execSQL("ALTER TABLE threads ADD COLUMN has_attachment INTEGER DEFAULT 0");

        updateThreadsAttachmentColumn(db);

        // Add insert and delete triggers for keeping it up to date.
        db.execSQL(PART_UPDATE_THREADS_ON_INSERT_TRIGGER);
    }

    private void upgradeDatabaseToVersion44(SQLiteDatabase db) {
        updateThreadsAttachmentColumn(db);

        // add the update trigger for keeping the threads up to date.
        db.execSQL(PART_UPDATE_THREADS_ON_UPDATE_TRIGGER);
    }

    private void upgradeDatabaseToVersion45(SQLiteDatabase db) {
        // Add 'locked' column to sms table.
        db.execSQL("ALTER TABLE sms ADD COLUMN " + Sms.LOCKED + " INTEGER DEFAULT 0");

        // Add 'locked' column to pdu table.
        db.execSQL("ALTER TABLE pdu ADD COLUMN " + Mms.LOCKED + " INTEGER DEFAULT 0");
    }

    private void upgradeDatabaseToVersion46(SQLiteDatabase db, int oldVersion, int currentVersion) {
        // add the "text" column for caching inline text (e.g. strings) instead of
        // putting them in an external file
        db.execSQL("ALTER TABLE part ADD COLUMN " + Part.TEXT + " TEXT");

        Cursor textRows = db.query(
                "part",
                new String[] { Part._ID, Part._DATA, Part.TEXT},
                "ct = 'text/plain' OR ct == 'application/smil'",
                null,
                null,
                null,
                null);
        ArrayList<String> filesToDelete = new ArrayList<String>();
        try {
            db.beginTransaction();
            if (textRows != null) {
                int partDataColumn = textRows.getColumnIndex(Part._DATA);

                // This code is imperfect in that we can't guarantee that all the
                // backing files get deleted.  For example if the system aborts after
                // the database is updated but before we complete the process of
                // deleting files.
                while (textRows.moveToNext()) {
                    String path = textRows.getString(partDataColumn);
                    if (path != null) {
                        try {
                            InputStream is = new FileInputStream(path);
                            byte [] data = new byte[is.available()];
                            is.read(data);
                            EncodedStringValue v = new EncodedStringValue(data);
                            db.execSQL("UPDATE part SET " + Part._DATA + " = NULL, " +
                                    Part.TEXT + " = ?", new String[] { v.getString() });
                            is.close();
                            filesToDelete.add(path);
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                            logException(e, oldVersion, currentVersion, 46);
                        }
                    }
                }
            }
            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
            for (String pathToDelete : filesToDelete) {
                try {
                    (new File(pathToDelete)).delete();
                } catch (SecurityException ex) {
                    Log.e(TAG, "unable to clean up old mms file for " + pathToDelete, ex);
                    logException(ex, oldVersion, currentVersion, 46);
                }
            }
            if (textRows != null) {
                textRows.close();
            }
        }
    }

    private void upgradeDatabaseToVersion47(SQLiteDatabase db) {
        updateThreadsAttachmentColumn(db);

        // add the update trigger for keeping the threads up to date.
        db.execSQL(PDU_UPDATE_THREADS_ON_UPDATE_TRIGGER);
    }

    private void upgradeDatabaseToVersion48(SQLiteDatabase db) {
        // Add 'error_code' column to sms table.
        db.execSQL("ALTER TABLE sms ADD COLUMN error_code INTEGER DEFAULT " + NO_ERROR_CODE);
    }

    private void upgradeDatabaseToVersion51(SQLiteDatabase db) {
        db.execSQL("ALTER TABLE sms add COLUMN seen INTEGER DEFAULT 0");
        db.execSQL("ALTER TABLE pdu add COLUMN seen INTEGER DEFAULT 0");

        try {
            // update the existing sms and pdu tables so the new "seen" column is the same as
            // the "read" column for each row.
            ContentValues contentValues = new ContentValues();
            contentValues.put("seen", 1);
            int count = db.update("sms", contentValues, "read=1", null);
            Log.d(TAG, "[MmsSmsDb] upgradeDatabaseToVersion51: updated " + count +
                    " rows in sms table to have READ=1");
            count = db.update("pdu", contentValues, "read=1", null);
            Log.d(TAG, "[MmsSmsDb] upgradeDatabaseToVersion51: updated " + count +
                    " rows in pdu table to have READ=1");
        } catch (Exception ex) {
            Log.e(TAG, "[MmsSmsDb] upgradeDatabaseToVersion51 caught ", ex);
        }
    }

    private void upgradeDatabaseToVersion53(SQLiteDatabase db) {
        db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_read_on_update");

        // Updates threads table whenever a message in pdu is updated.
        db.execSQL("CREATE TRIGGER pdu_update_thread_read_on_update AFTER" +
                   "  UPDATE OF " + Mms.READ +
                   "  ON " + MmsProvider.TABLE_PDU + " " +
                   PDU_UPDATE_THREAD_CONSTRAINTS +
                   "BEGIN " +
                   PDU_UPDATE_THREAD_READ_BODY +
                   "END;");
    }

    private void upgradeDatabaseToVersion54(SQLiteDatabase db) {
        // Add 'date_sent' column to sms table.
        db.execSQL("ALTER TABLE sms ADD COLUMN " + Sms.DATE_SENT + " INTEGER DEFAULT 0");

        // Add 'date_sent' column to pdu table.
        db.execSQL("ALTER TABLE pdu ADD COLUMN " + Mms.DATE_SENT + " INTEGER DEFAULT 0");
    }

    private void upgradeDatabaseToVersion55(SQLiteDatabase db) {
        // Drop removed triggers
        db.execSQL("DROP TRIGGER IF EXISTS delete_obsolete_threads_pdu");
        db.execSQL("DROP TRIGGER IF EXISTS delete_obsolete_threads_when_update_pdu");
    }

    private void upgradeDatabaseToVersion56(SQLiteDatabase db) {
        // Add 'text_only' column to pdu table.
        db.execSQL("ALTER TABLE " + MmsProvider.TABLE_PDU + " ADD COLUMN " + Mms.TEXT_ONLY +
                " INTEGER DEFAULT 0");
    }

    private void upgradeDatabaseToVersion57(SQLiteDatabase db) {
        // Clear out bad rows, those with empty threadIds, from the pdu table.
        db.execSQL("DELETE FROM " + MmsProvider.TABLE_PDU + " WHERE " + Mms.THREAD_ID + " IS NULL");
    }

    private void upgradeDatabaseToVersion58(SQLiteDatabase db) {
        db.execSQL("ALTER TABLE " + MmsProvider.TABLE_PDU +
                " ADD COLUMN " + Mms.SUBSCRIPTION_ID
                + " INTEGER DEFAULT " + SubscriptionManager.INVALID_SUBSCRIPTION_ID);
        db.execSQL("ALTER TABLE " + MmsSmsProvider.TABLE_PENDING_MSG
                +" ADD COLUMN " + "pending_sub_id"
                + " INTEGER DEFAULT " + SubscriptionManager.INVALID_SUBSCRIPTION_ID);
        db.execSQL("ALTER TABLE " + SmsProvider.TABLE_SMS
                + " ADD COLUMN " + Sms.SUBSCRIPTION_ID
                + " INTEGER DEFAULT " + SubscriptionManager.INVALID_SUBSCRIPTION_ID);
        db.execSQL("ALTER TABLE " + SmsProvider.TABLE_RAW
                +" ADD COLUMN " + Sms.SUBSCRIPTION_ID
                + " INTEGER DEFAULT " + SubscriptionManager.INVALID_SUBSCRIPTION_ID);
    }

    private void upgradeDatabaseToVersion59(SQLiteDatabase db) {
        db.execSQL("ALTER TABLE " + MmsProvider.TABLE_PDU +" ADD COLUMN "
                + Mms.CREATOR + " TEXT");
        db.execSQL("ALTER TABLE " + SmsProvider.TABLE_SMS +" ADD COLUMN "
                + Sms.CREATOR + " TEXT");
    }

    private void upgradeDatabaseToVersion60(SQLiteDatabase db) {
        db.execSQL("ALTER TABLE " + MmsSmsProvider.TABLE_THREADS +" ADD COLUMN "
                + Threads.ARCHIVED + " INTEGER DEFAULT 0");
    }

    private void upgradeDatabaseToVersion61(SQLiteDatabase db) {
        db.execSQL("CREATE VIEW " + SmsProvider.VIEW_SMS_RESTRICTED + " AS " +
                   "SELECT * FROM " + SmsProvider.TABLE_SMS + " WHERE " +
                   Sms.TYPE + "=" + Sms.MESSAGE_TYPE_INBOX +
                   " OR " +
                   Sms.TYPE + "=" + Sms.MESSAGE_TYPE_SENT + ";");
        db.execSQL("CREATE VIEW " + MmsProvider.VIEW_PDU_RESTRICTED + "  AS " +
                   "SELECT * FROM " + MmsProvider.TABLE_PDU + " WHERE " +
                   "(" + Mms.MESSAGE_BOX + "=" + Mms.MESSAGE_BOX_INBOX +
                   " OR " +
                   Mms.MESSAGE_BOX + "=" + Mms.MESSAGE_BOX_SENT + ")" +
                   " AND " +
                   "(" + Mms.MESSAGE_TYPE + "!=" + PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND + ");");

    }

    private void upgradeDatabaseToVersion62(SQLiteDatabase db, int oldVersion, int currentVersion) {
        // When a non-FBE device is upgraded to N, all MMS attachment files are moved from
        // /data/data to /data/user_de. We need to update the paths stored in the parts table to
        // reflect this change.
        String newPartsDirPath;
        try {
            newPartsDirPath = mContext.getDir(MmsProvider.PARTS_DIR_NAME, 0).getCanonicalPath();
        }
        catch (IOException e){
            Log.e(TAG, "openFile: check file path failed " + e, e);
            logException(e, oldVersion, currentVersion, 62);
            return;
        }

        // The old path of the part files will be something like this:
        //   /data/data/0/com.android.providers.telephony/app_parts
        // The new path of the part files will be something like this:
        //   /data/user_de/0/com.android.providers.telephony/app_parts
        int partsDirIndex = newPartsDirPath.lastIndexOf(
            File.separator, newPartsDirPath.lastIndexOf(MmsProvider.PARTS_DIR_NAME));
        String partsDirName = newPartsDirPath.substring(partsDirIndex) + File.separator;
        // The query to update the part path will be:
        //   UPDATE part SET _data = '/data/user_de/0/com.android.providers.telephony' ||
        //                           SUBSTR(_data, INSTR(_data, '/app_parts/'))
        //   WHERE INSTR(_data, '/app_parts/') > 0
        db.execSQL("UPDATE " + MmsProvider.TABLE_PART +
            " SET " + Part._DATA + " = '" + newPartsDirPath.substring(0, partsDirIndex) + "' ||" +
            " SUBSTR(" + Part._DATA + ", INSTR(" + Part._DATA + ", '" + partsDirName + "'))" +
            " WHERE INSTR(" + Part._DATA + ", '" + partsDirName + "') > 0");
    }

    private void upgradeDatabaseToVersion64(SQLiteDatabase db) {
        db.execSQL("ALTER TABLE " + SmsProvider.TABLE_RAW +" ADD COLUMN deleted INTEGER DEFAULT 0");
    }

    private void upgradeDatabaseToVersion65(SQLiteDatabase db, int oldVersion, int currentVersion) {
        // aosp and internal code diverged at version 63. Aosp did createThreadIdDateIndex() on
        // upgrading to 63, whereas internal (nyc) added column 'deleted'. A device upgrading from
        // nyc will have columns deleted and message_body in raw table with version 64, but not
        // createThreadIdDateIndex()
        try {
            db.execSQL("ALTER TABLE " + SmsProvider.TABLE_RAW + " ADD COLUMN message_body TEXT");
        } catch (SQLiteException e) {
            Log.w(TAG, "[upgradeDatabaseToVersion65] Exception adding column message_body; " +
                    "trying createThreadIdDateIndex() instead: " + e);
            logException(e, oldVersion, currentVersion, 65);
            createThreadIdDateIndex(db);
        }
    }

    private void upgradeDatabaseToVersion66(SQLiteDatabase db, int oldVersion, int currentVersion) {
        try {
            db.execSQL("ALTER TABLE " + SmsProvider.TABLE_RAW
                    + " ADD COLUMN display_originating_addr TEXT");
        } catch (SQLiteException e) {
            Log.e(TAG, "[upgradeDatabaseToVersion66] Exception adding column "
                    + "display_originating_addr; " + e);
            logException(e, oldVersion, currentVersion, 66);
        }
    }
    private void checkAndUpdateSmsTable(SQLiteDatabase db) {
        try {
            db.query(SmsProvider.TABLE_SMS, new String[] {"priority"}, null, null, null, null,
                    null);
        } catch (SQLiteException e) {
            Log.e(TAG, "checkAndUpgradeSmsTable: ex. ", e);
            if (e.getMessage().startsWith(NO_SUCH_COLUMN_EXCEPTION_MESSAGE)) {
                db.execSQL("ALTER TABLE " + SmsProvider.TABLE_SMS + " ADD COLUMN "
                        + "priority INTEGER DEFAULT -1");
            }
        }
    }

    private void checkAndUpdateThreadsTable(SQLiteDatabase db) {
        try {
            db.query(MmsSmsProvider.TABLE_THREADS, new String[] {Threads.ATTACHMENT_INFO},
                    null, null, null, null, null);
        } catch (SQLiteException e) {
            Log.e(TAG, "checkAndUpdateThreadsTable: ex. ", e);
            if (e.getMessage().startsWith(NO_SUCH_COLUMN_EXCEPTION_MESSAGE)) {
                db.execSQL("ALTER TABLE " + MmsSmsProvider.TABLE_THREADS + " ADD COLUMN "
                        + Threads.ATTACHMENT_INFO + " TEXT");
            }
        }

        try {
            db.query(MmsSmsProvider.TABLE_THREADS, new String[] {Threads.NOTIFICATION},
                    null, null, null, null, null);
        } catch (SQLiteException e) {
            Log.e(TAG, "checkAndUpdateThreadsTable: ex. ", e);
            if (e.getMessage().startsWith(NO_SUCH_COLUMN_EXCEPTION_MESSAGE)) {
                db.execSQL("ALTER TABLE " + MmsSmsProvider.TABLE_THREADS + " ADD COLUMN "
                        + Threads.NOTIFICATION + " INTEGER DEFAULT 0");
            }
        }
    }

    @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");
            String logMsg = "[getWritableDatabase]" +
                    " hasAutoIncrementThreads: " + hasAutoIncrementThreads +
                    " hasAutoIncrementAddresses: " + hasAutoIncrementAddresses +
                    " hasAutoIncrementPart: " + hasAutoIncrementPart +
                    " hasAutoIncrementPdu: " + hasAutoIncrementPdu;
            Log.d(TAG, logMsg);
            localLog(logMsg);
            boolean autoIncrementThreadsSuccess = true;
            boolean autoIncrementAddressesSuccess = true;
            boolean autoIncrementPartSuccess = true;
            boolean autoIncrementPduSuccess = true;
            if (!hasAutoIncrementThreads) {
                db.beginTransaction();
                try {
                    if (false && sFakeLowStorageTest) {
                        Log.d(TAG, "[getWritableDatabase] mFakeLowStorageTest is true " +
                                " - fake exception");
                        throw new Exception("FakeLowStorageTest");
                    }
                    upgradeThreadsTableToAutoIncrement(db);     // a no-op if already upgraded
                    db.setTransactionSuccessful();
                } catch (Throwable ex) {
                    Log.e(TAG, "Failed to add autoIncrement to threads;: " + ex.getMessage(), ex);
                    autoIncrementThreadsSuccess = false;
                } finally {
                    db.endTransaction();
                }
            }
            if (!hasAutoIncrementAddresses) {
                db.beginTransaction();
                try {
                    if (false && sFakeLowStorageTest) {
                        Log.d(TAG, "[getWritableDatabase] mFakeLowStorageTest is true " +
                        " - fake exception");
                        throw new Exception("FakeLowStorageTest");
                    }
                    upgradeAddressTableToAutoIncrement(db);     // a no-op if already upgraded
                    db.setTransactionSuccessful();
                } catch (Throwable ex) {
                    Log.e(TAG, "Failed to add autoIncrement to canonical_addresses: " +
                            ex.getMessage(), ex);
                    autoIncrementAddressesSuccess = false;
                } finally {
                    db.endTransaction();
                }
            }
            if (!hasAutoIncrementPart) {
                db.beginTransaction();
                try {
                    if (false && sFakeLowStorageTest) {
                        Log.d(TAG, "[getWritableDatabase] mFakeLowStorageTest is true " +
                        " - fake exception");
                        throw new Exception("FakeLowStorageTest");
                    }
                    upgradePartTableToAutoIncrement(db);     // a no-op if already upgraded
                    db.setTransactionSuccessful();
                } catch (Throwable ex) {
                    Log.e(TAG, "Failed to add autoIncrement to part: " +
                            ex.getMessage(), ex);
                    autoIncrementPartSuccess = false;
                } finally {
                    db.endTransaction();
                }
            }
            if (!hasAutoIncrementPdu) {
                db.beginTransaction();
                try {
                    if (false && sFakeLowStorageTest) {
                        Log.d(TAG, "[getWritableDatabase] mFakeLowStorageTest is true " +
                        " - fake exception");
                        throw new Exception("FakeLowStorageTest");
                    }
                    upgradePduTableToAutoIncrement(db);     // a no-op if already upgraded
                    db.setTransactionSuccessful();
                } catch (Throwable ex) {
                    Log.e(TAG, "Failed to add autoIncrement to pdu: " +
                            ex.getMessage(), ex);
                    autoIncrementPduSuccess = false;
                } finally {
                    db.endTransaction();
                }
            }
            if (autoIncrementThreadsSuccess &&
                    autoIncrementAddressesSuccess &&
                    autoIncrementPartSuccess &&
                    autoIncrementPduSuccess) {
                if (mLowStorageMonitor != null) {
                    // We've already updated the database. This receiver is no longer necessary.
                    Log.d(TAG, "Unregistering mLowStorageMonitor - we've upgraded");
                    mContext.unregisterReceiver(mLowStorageMonitor);
                    mLowStorageMonitor = null;
                }
            } else {
                if (sFakeLowStorageTest) {
                    sFakeLowStorageTest = false;
                }

                // We failed, perhaps because of low storage. Turn on a receiver to watch for
                // storage space.
                if (mLowStorageMonitor == null) {
                    Log.d(TAG, "[getWritableDatabase] turning on storage monitor");
                    mLowStorageMonitor = new LowStorageMonitor();
                    IntentFilter intentFilter = new IntentFilter();
                    intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_LOW);
                    intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
                    mContext.registerReceiver(mLowStorageMonitor, intentFilter);
                }
            }
        }
        return db;
    }

    // Determine whether a particular table has AUTOINCREMENT in its schema.
    private boolean hasAutoIncrement(SQLiteDatabase db, String tableName) {
        boolean result = false;
        String query = "SELECT sql FROM sqlite_master WHERE type='table' AND name='" +
                        tableName + "'";
        Cursor c = db.rawQuery(query, null);
        if (c != null) {
            try {
                if (c.moveToFirst()) {
                    String schema = c.getString(0);
                    result = schema != null ? schema.contains("AUTOINCREMENT") : false;
                    Log.d(TAG, "[MmsSmsDb] tableName: " + tableName + " hasAutoIncrement: " +
                            schema + " result: " + result);
                }
            } finally {
                c.close();
            }
        }
        return result;
    }

    // upgradeThreadsTableToAutoIncrement() is called to add the AUTOINCREMENT keyword to
    // the threads table. This could fail if the user has a lot of conversations and not enough
    // storage to make a copy of the threads table. That's ok. This upgrade is optional. It'll
    // be called again next time the device is rebooted.
    private void upgradeThreadsTableToAutoIncrement(SQLiteDatabase db) {
        if (hasAutoIncrement(db, MmsSmsProvider.TABLE_THREADS)) {
            Log.d(TAG, "[MmsSmsDb] upgradeThreadsTableToAutoIncrement: already upgraded");
            return;
        }
        Log.d(TAG, "[MmsSmsDb] upgradeThreadsTableToAutoIncrement: upgrading");

        // Make the _id of the threads table autoincrement so we never re-use thread ids
        // Have to create a new temp threads table. Copy all the info from the old table.
        // Drop the old table and rename the new table to that of the old.
        db.execSQL("CREATE TABLE threads_temp (" +
                Threads._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                Threads.DATE + " INTEGER DEFAULT 0," +
                Threads.MESSAGE_COUNT + " INTEGER DEFAULT 0," +
                Threads.RECIPIENT_IDS + " TEXT," +
                Threads.SNIPPET + " TEXT," +
                Threads.SNIPPET_CHARSET + " INTEGER DEFAULT 0," +
                Threads.READ + " INTEGER DEFAULT 1," +
                Threads.TYPE + " INTEGER DEFAULT 0," +
                Threads.ERROR + " INTEGER DEFAULT 0," +
                Threads.HAS_ATTACHMENT + " INTEGER DEFAULT 0," +
                Threads.ATTACHMENT_INFO + " TEXT," +
                Threads.NOTIFICATION + " INTEGER DEFAULT 0);");

        db.execSQL("INSERT INTO threads_temp SELECT * from threads;");
        db.execSQL("DROP TABLE threads;");
        db.execSQL("ALTER TABLE threads_temp RENAME TO threads;");
    }

    // upgradeAddressTableToAutoIncrement() is called to add the AUTOINCREMENT keyword to
    // the canonical_addresses table. This could fail if the user has a lot of people they've
    // messaged with and not enough storage to make a copy of the canonical_addresses table.
    // That's ok. This upgrade is optional. It'll be called again next time the device is rebooted.
    private void upgradeAddressTableToAutoIncrement(SQLiteDatabase db) {
        if (hasAutoIncrement(db, "canonical_addresses")) {
            Log.d(TAG, "[MmsSmsDb] upgradeAddressTableToAutoIncrement: already upgraded");
            return;
        }
        Log.d(TAG, "[MmsSmsDb] upgradeAddressTableToAutoIncrement: upgrading");

        // Make the _id of the canonical_addresses table autoincrement so we never re-use ids
        // Have to create a new temp canonical_addresses table. Copy all the info from the old
        // table. Drop the old table and rename the new table to that of the old.
        db.execSQL("CREATE TABLE canonical_addresses_temp (_id INTEGER PRIMARY KEY AUTOINCREMENT," +
                "address TEXT);");

        db.execSQL("INSERT INTO canonical_addresses_temp SELECT * from canonical_addresses;");
        db.execSQL("DROP TABLE canonical_addresses;");
        db.execSQL("ALTER TABLE canonical_addresses_temp RENAME TO canonical_addresses;");
    }

    // upgradePartTableToAutoIncrement() is called to add the AUTOINCREMENT keyword to
    // the part table. This could fail if the user has a lot of sound/video/picture attachments
    // and not enough storage to make a copy of the part table.
    // That's ok. This upgrade is optional. It'll be called again next time the device is rebooted.
    private void upgradePartTableToAutoIncrement(SQLiteDatabase db) {
        if (hasAutoIncrement(db, "part")) {
            Log.d(TAG, "[MmsSmsDb] upgradePartTableToAutoIncrement: already upgraded");
            return;
        }
        Log.d(TAG, "[MmsSmsDb] upgradePartTableToAutoIncrement: upgrading");

        // Make the _id of the part table autoincrement so we never re-use ids
        // Have to create a new temp part table. Copy all the info from the old
        // table. Drop the old table and rename the new table to that of the old.
        db.execSQL("CREATE TABLE part_temp (" +
                Part._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                Part.MSG_ID + " INTEGER," +
                Part.SEQ + " INTEGER DEFAULT 0," +
                Part.CONTENT_TYPE + " TEXT," +
                Part.NAME + " TEXT," +
                Part.CHARSET + " INTEGER," +
                Part.CONTENT_DISPOSITION + " TEXT," +
                Part.FILENAME + " TEXT," +
                Part.CONTENT_ID + " TEXT," +
                Part.CONTENT_LOCATION + " TEXT," +
                Part.CT_START + " INTEGER," +
                Part.CT_TYPE + " TEXT," +
                Part._DATA + " TEXT," +
                Part.TEXT + " TEXT);");

        db.execSQL("INSERT INTO part_temp SELECT * from part;");
        db.execSQL("DROP TABLE part;");
        db.execSQL("ALTER TABLE part_temp RENAME TO part;");

        // part-related triggers get tossed when the part table is dropped -- rebuild them.
        createMmsTriggers(db);
    }

    // upgradePduTableToAutoIncrement() is called to add the AUTOINCREMENT keyword to
    // the pdu table. This could fail if the user has a lot of mms messages
    // and not enough storage to make a copy of the pdu table.
    // That's ok. This upgrade is optional. It'll be called again next time the device is rebooted.
    private void upgradePduTableToAutoIncrement(SQLiteDatabase db) {
        if (hasAutoIncrement(db, "pdu")) {
            Log.d(TAG, "[MmsSmsDb] upgradePduTableToAutoIncrement: already upgraded");
            return;
        }
        Log.d(TAG, "[MmsSmsDb] upgradePduTableToAutoIncrement: upgrading");

        // Make the _id of the part table autoincrement so we never re-use ids
        // Have to create a new temp part table. Copy all the info from the old
        // table. Drop the old table and rename the new table to that of the old.
        db.execSQL("CREATE TABLE pdu_temp (" +
                Mms._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                Mms.THREAD_ID + " INTEGER," +
                Mms.DATE + " INTEGER," +
                Mms.DATE_SENT + " INTEGER DEFAULT 0," +
                Mms.MESSAGE_BOX + " INTEGER," +
                Mms.READ + " INTEGER DEFAULT 0," +
                Mms.MESSAGE_ID + " TEXT," +
                Mms.SUBJECT + " TEXT," +
                Mms.SUBJECT_CHARSET + " INTEGER," +
                Mms.CONTENT_TYPE + " TEXT," +
                Mms.CONTENT_LOCATION + " TEXT," +
                Mms.EXPIRY + " INTEGER," +
                Mms.MESSAGE_CLASS + " TEXT," +
                Mms.MESSAGE_TYPE + " INTEGER," +
                Mms.MMS_VERSION + " INTEGER," +
                Mms.MESSAGE_SIZE + " INTEGER," +
                Mms.PRIORITY + " INTEGER," +
                Mms.READ_REPORT + " INTEGER," +
                Mms.REPORT_ALLOWED + " INTEGER," +
                Mms.RESPONSE_STATUS + " INTEGER," +
                Mms.STATUS + " INTEGER," +
                Mms.TRANSACTION_ID + " TEXT," +
                Mms.RETRIEVE_STATUS + " INTEGER," +
                Mms.RETRIEVE_TEXT + " TEXT," +
                Mms.RETRIEVE_TEXT_CHARSET + " INTEGER," +
                Mms.READ_STATUS + " INTEGER," +
                Mms.CONTENT_CLASS + " INTEGER," +
                Mms.RESPONSE_TEXT + " TEXT," +
                Mms.DELIVERY_TIME + " INTEGER," +
                Mms.DELIVERY_REPORT + " INTEGER," +
                Mms.LOCKED + " INTEGER DEFAULT 0," +
                Mms.SUBSCRIPTION_ID + " INTEGER DEFAULT "
                        + SubscriptionManager.INVALID_SUBSCRIPTION_ID + ", " +
                Mms.SEEN + " INTEGER DEFAULT 0," +
                Mms.TEXT_ONLY + " INTEGER DEFAULT 0" +
                ");");

        db.execSQL("INSERT INTO pdu_temp SELECT * from pdu;");
        db.execSQL("DROP TABLE pdu;");
        db.execSQL("ALTER TABLE pdu_temp RENAME TO pdu;");

        // pdu-related triggers get tossed when the part table is dropped -- rebuild them.
        createMmsTriggers(db);
    }

    private class LowStorageMonitor extends BroadcastReceiver {

        public LowStorageMonitor() {
        }

        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            Log.d(TAG, "[LowStorageMonitor] onReceive intent " + action);

            if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) {
                sTriedAutoIncrement = false;    // try to upgrade on the next getWriteableDatabase
            }
        }
    }

    private void updateThreadsAttachmentColumn(SQLiteDatabase db) {
        // Set the values of that column correctly based on the current
        // contents of the database.
        db.execSQL("UPDATE threads SET has_attachment=1 WHERE _id IN " +
                   "  (SELECT DISTINCT pdu.thread_id FROM part " +
                   "   JOIN pdu ON pdu._id=part.mid " +
                   "   WHERE part.ct != 'text/plain' AND part.ct != 'application/smil')");
    }
}
