Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c81e1f15 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Update primary key in VIS sound model database." into nyc-mr1-dev

parents d183e0b9 5bd5cf75
Loading
Loading
Loading
Loading
+117 −4
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ import android.util.Slog;

import java.util.Locale;
import java.util.UUID;
import java.util.List;
import java.util.ArrayList;

/**
 * Helper to manage the database of the sound models that have been registered on the device.
@@ -40,7 +42,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
    static final boolean DBG = false;

    private static final String NAME = "sound_model.db";
    private static final int VERSION = 5;
    private static final int VERSION = 6;

    public static interface SoundModelContract {
        public static final String TABLE = "sound_model";
@@ -58,7 +60,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
    // Table Create Statement
    private static final String CREATE_TABLE_SOUND_MODEL = "CREATE TABLE "
            + SoundModelContract.TABLE + "("
            + SoundModelContract.KEY_MODEL_UUID + " TEXT PRIMARY KEY,"
            + SoundModelContract.KEY_MODEL_UUID + " TEXT,"
            + SoundModelContract.KEY_VENDOR_UUID + " TEXT,"
            + SoundModelContract.KEY_KEYPHRASE_ID + " INTEGER,"
            + SoundModelContract.KEY_TYPE + " INTEGER,"
@@ -66,7 +68,11 @@ public class DatabaseHelper extends SQLiteOpenHelper {
            + SoundModelContract.KEY_RECOGNITION_MODES + " INTEGER,"
            + SoundModelContract.KEY_LOCALE + " TEXT,"
            + SoundModelContract.KEY_HINT_TEXT + " TEXT,"
            + SoundModelContract.KEY_USERS + " TEXT" + ")";
            + SoundModelContract.KEY_USERS + " TEXT,"
            + "PRIMARY KEY (" + SoundModelContract.KEY_KEYPHRASE_ID + ","
                              + SoundModelContract.KEY_LOCALE + ","
                              + SoundModelContract.KEY_USERS + ")"
            + ")";

    public DatabaseHelper(Context context) {
        super(context, NAME, null, VERSION);
@@ -93,6 +99,44 @@ public class DatabaseHelper extends SQLiteOpenHelper {
                oldVersion++;
            }
        }
        if (oldVersion == 5) {
            // We need to enforce the new primary key constraint that the
            // keyphrase id, locale, and users are unique. We have to first pull
            // everything out of the database, remove duplicates, create the new
            // table, then push everything back in.
            String selectQuery = "SELECT * FROM " + SoundModelContract.TABLE;
            Cursor c = db.rawQuery(selectQuery, null);
            List<SoundModelRecord> old_records = new ArrayList<SoundModelRecord>();
            try {
                if (c.moveToFirst()) {
                    do {
                        try {
                            old_records.add(new SoundModelRecord(5, c));
                        } catch (Exception e) {
                            Slog.e(TAG, "Failed to extract V5 record", e);
                        }
                    } while (c.moveToNext());
                }
            } finally {
                c.close();
            }
            db.execSQL("DROP TABLE IF EXISTS " + SoundModelContract.TABLE);
            onCreate(db);
            for (SoundModelRecord record : old_records) {
                if (!record.violatesV6PrimaryKeyConstraint(old_records)) {
                    try {
                        long return_value = record.writeToDatabase(6, db);
                        if (return_value == -1) {
                            Slog.e(TAG, "Database write failed " + record.modelUuid + ": "
                                    + return_value);
                        }
                    } catch (Exception e) {
                        Slog.e(TAG, "Failed to update V6 record " + record.modelUuid, e);
                    }
                }
            }
            oldVersion++;
        }
    }

    /**
@@ -279,4 +323,73 @@ public class DatabaseHelper extends SQLiteOpenHelper {
        }
        return users;
    }

    private static class SoundModelRecord {
        public final String modelUuid;
        public final String vendorUuid;
        public final int keyphraseId;
        public final int type;
        public final byte[] data;
        public final int recognitionModes;
        public final String locale;
        public final String hintText;
        public final String users;

        public SoundModelRecord(int version, Cursor c) {
            modelUuid = c.getString(c.getColumnIndex(SoundModelContract.KEY_MODEL_UUID));
            if (version >= 5) {
                vendorUuid = c.getString(c.getColumnIndex(SoundModelContract.KEY_VENDOR_UUID));
            } else {
                vendorUuid = null;
            }
            keyphraseId = c.getInt(c.getColumnIndex(SoundModelContract.KEY_KEYPHRASE_ID));
            type = c.getInt(c.getColumnIndex(SoundModelContract.KEY_TYPE));
            data = c.getBlob(c.getColumnIndex(SoundModelContract.KEY_DATA));
            recognitionModes = c.getInt(c.getColumnIndex(SoundModelContract.KEY_RECOGNITION_MODES));
            locale = c.getString(c.getColumnIndex(SoundModelContract.KEY_LOCALE));
            hintText = c.getString(c.getColumnIndex(SoundModelContract.KEY_HINT_TEXT));
            users = c.getString(c.getColumnIndex(SoundModelContract.KEY_USERS));
        }

        // Check to see if this record conflicts with some other record in the list of records.
        public boolean violatesV6PrimaryKeyConstraint(List<SoundModelRecord> records) {
            for (SoundModelRecord record : records) {
                if (this == record) {
                    continue;
                }
                if (keyphraseId == record.keyphraseId
                        && stringComparisonHelper(locale, record.locale)
                        && stringComparisonHelper(users, record.users)) {
                    return true;
                }
            }
            return false;
        }

        public long writeToDatabase(int version, SQLiteDatabase db) {
            ContentValues values = new ContentValues();
            values.put(SoundModelContract.KEY_MODEL_UUID, modelUuid);
            if (version >= 5) {
                values.put(SoundModelContract.KEY_VENDOR_UUID, vendorUuid);
            }
            values.put(SoundModelContract.KEY_KEYPHRASE_ID, keyphraseId);
            values.put(SoundModelContract.KEY_TYPE, type);
            values.put(SoundModelContract.KEY_DATA, data);
            values.put(SoundModelContract.KEY_RECOGNITION_MODES, recognitionModes);
            values.put(SoundModelContract.KEY_LOCALE, locale);
            values.put(SoundModelContract.KEY_HINT_TEXT, hintText);
            values.put(SoundModelContract.KEY_USERS, users);

            return db.insertWithOnConflict(
                       SoundModelContract.TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
        }

        // Helper for checking string equality - including the case when they are null.
        static private boolean stringComparisonHelper(String a, String b) {
          if (a != null) {
            return a.equals(b);
          }
          return a == b;
        }
    }
}