DatabaseHelper.java revision 2883ba69751de69811a38f086ecbe4c2032ca87d
1/** 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.voiceinteraction; 18 19import android.content.ContentValues; 20import android.content.Context; 21import android.database.Cursor; 22import android.database.sqlite.SQLiteDatabase; 23import android.database.sqlite.SQLiteOpenHelper; 24import android.hardware.soundtrigger.SoundTrigger; 25import android.hardware.soundtrigger.Keyphrase; 26import android.hardware.soundtrigger.KeyphraseSoundModel; 27import android.util.Slog; 28 29import java.util.ArrayList; 30import java.util.List; 31import java.util.UUID; 32 33/** 34 * Helper to manage the database of the sound models that have been registered on the device. 35 * 36 * @hide 37 */ 38public class DatabaseHelper extends SQLiteOpenHelper { 39 static final String TAG = "SoundModelDBHelper"; 40 41 private static final String NAME = "sound_model.db"; 42 private static final int VERSION = 1; 43 44 public static interface KeyphraseContract { 45 public static final String TABLE = "keyphrase"; 46 public static final String KEY_ID = "_id"; 47 public static final String KEY_RECOGNITION_MODES = "modes"; 48 public static final String KEY_LOCALE = "locale"; 49 public static final String KEY_HINT_TEXT = "hint_text"; 50 public static final String KEY_USERS = "users"; 51 public static final String KEY_SOUND_MODEL_ID = "sound_model_id"; 52 } 53 54 public static interface SoundModelContract { 55 public static final String TABLE = "sound_model"; 56 public static final String KEY_ID = "_id"; 57 public static final String KEY_TYPE = "type"; 58 public static final String KEY_DATA = "data"; 59 } 60 61 // Table Create Statements 62 private static final String CREATE_TABLE_KEYPRHASES = "CREATE TABLE " 63 + KeyphraseContract.TABLE + "(" 64 + KeyphraseContract.KEY_ID + " INTEGER PRIMARY KEY," 65 + KeyphraseContract.KEY_RECOGNITION_MODES + " INTEGER," 66 + KeyphraseContract.KEY_USERS + " INTEGER," 67 + KeyphraseContract.KEY_SOUND_MODEL_ID + " TEXT," 68 + KeyphraseContract.KEY_LOCALE + " TEXT," 69 + KeyphraseContract.KEY_HINT_TEXT + " TEXT" + ")"; 70 71 private static final String CREATE_TABLE_SOUND_MODEL = "CREATE TABLE " 72 + SoundModelContract.TABLE + "(" 73 + SoundModelContract.KEY_ID + " TEXT PRIMARY KEY," 74 + SoundModelContract.KEY_TYPE + " INTEGER," 75 + SoundModelContract.KEY_DATA + " BLOB" + ")"; 76 77 public DatabaseHelper(Context context) { 78 super(context, NAME, null, VERSION); 79 } 80 81 @Override 82 public void onCreate(SQLiteDatabase db) { 83 // creating required tables 84 db.execSQL(CREATE_TABLE_KEYPRHASES); 85 db.execSQL(CREATE_TABLE_SOUND_MODEL); 86 } 87 88 @Override 89 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 90 // TODO: For now, drop older tables and recreate new ones. 91 db.execSQL("DROP TABLE IF EXISTS " + KeyphraseContract.TABLE); 92 db.execSQL("DROP TABLE IF EXISTS " + SoundModelContract.TABLE); 93 onCreate(db); 94 } 95 96 public boolean addOrUpdateKeyphraseSoundModel(KeyphraseSoundModel soundModel) { 97 SQLiteDatabase db = this.getWritableDatabase(); 98 ContentValues values = new ContentValues(); 99 // Generate a random ID for the model. 100 values.put(SoundModelContract.KEY_ID, soundModel.uuid.toString()); 101 values.put(SoundModelContract.KEY_DATA, soundModel.data); 102 values.put(SoundModelContract.KEY_TYPE, SoundTrigger.SoundModel.TYPE_KEYPHRASE); 103 104 boolean status = true; 105 if (db.insertWithOnConflict( 106 SoundModelContract.TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE) != -1) { 107 for (Keyphrase keyphrase : soundModel.keyphrases) { 108 status &= addKeyphrase(soundModel.uuid, keyphrase); 109 } 110 return status; 111 } else { 112 Slog.w(TAG, "Failed to persist sound model to database"); 113 return false; 114 } 115 } 116 117 /** 118 * TODO(sansid): Change to addOrUpdate to handle changes here. 119 */ 120 private boolean addKeyphrase(UUID modelId, Keyphrase keyphrase) { 121 SQLiteDatabase db = this.getWritableDatabase(); 122 ContentValues values = new ContentValues(); 123 values.put(KeyphraseContract.KEY_ID, keyphrase.id); 124 values.put(KeyphraseContract.KEY_RECOGNITION_MODES, keyphrase.recognitionModeFlags); 125 values.put(KeyphraseContract.KEY_SOUND_MODEL_ID, keyphrase.id); 126 values.put(KeyphraseContract.KEY_HINT_TEXT, keyphrase.hintText); 127 values.put(KeyphraseContract.KEY_LOCALE, keyphrase.locale); 128 if (db.insert(KeyphraseContract.TABLE, null, values) != -1) { 129 return true; 130 } else { 131 Slog.w(TAG, "Failed to persist keyphrase to database"); 132 return false; 133 } 134 } 135 136 /** 137 * Lists all the keyphrase sound models currently registered with the system. 138 */ 139 public List<KeyphraseSoundModel> getKephraseSoundModels() { 140 List<KeyphraseSoundModel> models = new ArrayList<>(); 141 String selectQuery = "SELECT * FROM " + SoundModelContract.TABLE; 142 SQLiteDatabase db = this.getReadableDatabase(); 143 Cursor c = db.rawQuery(selectQuery, null); 144 145 // looping through all rows and adding to list 146 if (c.moveToFirst()) { 147 do { 148 int type = c.getInt(c.getColumnIndex(SoundModelContract.KEY_TYPE)); 149 if (type != SoundTrigger.SoundModel.TYPE_KEYPHRASE) { 150 // Ignore non-keyphrase sound models. 151 continue; 152 } 153 String id = c.getString(c.getColumnIndex(SoundModelContract.KEY_ID)); 154 byte[] data = c.getBlob(c.getColumnIndex(SoundModelContract.KEY_DATA)); 155 // Get all the keyphrases for this this sound model. 156 models.add(new KeyphraseSoundModel( 157 UUID.fromString(id), data, getKeyphrasesForSoundModel(id))); 158 } while (c.moveToNext()); 159 } 160 return models; 161 } 162 163 private Keyphrase[] getKeyphrasesForSoundModel(String modelId) { 164 List<Keyphrase> keyphrases = new ArrayList<>(); 165 String selectQuery = "SELECT * FROM " + KeyphraseContract.TABLE 166 + " WHERE " + KeyphraseContract.KEY_SOUND_MODEL_ID + " = '" + modelId + "'"; 167 SQLiteDatabase db = this.getReadableDatabase(); 168 Cursor c = db.rawQuery(selectQuery, null); 169 170 // looping through all rows and adding to list 171 if (c.moveToFirst()) { 172 do { 173 int id = c.getInt(c.getColumnIndex(KeyphraseContract.KEY_ID)); 174 int modes = c.getInt(c.getColumnIndex(KeyphraseContract.KEY_RECOGNITION_MODES)); 175 int[] users = {c.getInt(c.getColumnIndex(KeyphraseContract.KEY_USERS))}; 176 String locale = c.getString(c.getColumnIndex(KeyphraseContract.KEY_LOCALE)); 177 String hintText = c.getString(c.getColumnIndex(KeyphraseContract.KEY_HINT_TEXT)); 178 179 keyphrases.add(new Keyphrase(id, hintText, locale, modes, users)); 180 } while (c.moveToNext()); 181 } 182 Keyphrase[] keyphraseArr = new Keyphrase[keyphrases.size()]; 183 keyphrases.toArray(keyphraseArr); 184 return keyphraseArr; 185 } 186} 187