Loading services/voiceinteraction/java/com/android/server/voiceinteraction/DatabaseHelper.java +117 −4 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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"; Loading @@ -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," Loading @@ -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); Loading @@ -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++; } } /** Loading Loading @@ -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; } } } Loading
services/voiceinteraction/java/com/android/server/voiceinteraction/DatabaseHelper.java +117 −4 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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"; Loading @@ -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," Loading @@ -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); Loading @@ -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++; } } /** Loading Loading @@ -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; } } }