DatabaseHelper.java revision 8ecaf5f5cfd18e0436db1a27ccf46a063e9aacd7
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.SQLiteDatabase.CursorFactory; 24import android.database.sqlite.SQLiteOpenHelper; 25import android.hardware.soundtrigger.SoundTrigger; 26import android.hardware.soundtrigger.Keyphrase; 27import android.hardware.soundtrigger.KeyphraseSoundModel; 28import android.util.Slog; 29 30import java.util.ArrayList; 31import java.util.List; 32import java.util.UUID; 33 34/** 35 * Helper to manage the database of the sound models that have been registered on the device. 36 * 37 * @hide 38 */ 39public class DatabaseHelper extends SQLiteOpenHelper { 40 static final String TAG = "SoundModelDBHelper"; 41 42 private static final String NAME = "sound_model.db"; 43 private static final int VERSION = 1; 44 45 public static interface KeyphraseContract { 46 public static final String TABLE = "keyphrase"; 47 public static final String KEY_ID = "_id"; 48 public static final String KEY_RECOGNITION_MODES = "modes"; 49 public static final String KEY_LOCALE = "locale"; 50 public static final String KEY_HINT_TEXT = "hint_text"; 51 public static final String KEY_USERS = "users"; 52 public static final String KEY_SOUND_MODEL_ID = "sound_model_id"; 53 } 54 55 public static interface SoundModelContract { 56 public static final String TABLE = "sound_model"; 57 public static final String KEY_ID = "_id"; 58 public static final String KEY_TYPE = "type"; 59 public static final String KEY_DATA = "data"; 60 } 61 62 // Table Create Statements 63 private static final String CREATE_TABLE_KEYPRHASES = "CREATE TABLE " 64 + KeyphraseContract.TABLE + "(" 65 + KeyphraseContract.KEY_ID + " INTEGER PRIMARY KEY," 66 + KeyphraseContract.KEY_RECOGNITION_MODES + " INTEGER," 67 + KeyphraseContract.KEY_USERS + " INTEGER," 68 + KeyphraseContract.KEY_SOUND_MODEL_ID + " TEXT," 69 + KeyphraseContract.KEY_LOCALE + " TEXT," 70 + KeyphraseContract.KEY_HINT_TEXT + " TEXT" + ")"; 71 72 private static final String CREATE_TABLE_SOUND_MODEL = "CREATE TABLE " 73 + SoundModelContract.TABLE + "(" 74 + SoundModelContract.KEY_ID + " TEXT PRIMARY KEY," 75 + SoundModelContract.KEY_TYPE + " INTEGER," 76 + SoundModelContract.KEY_DATA + " BLOB" + ")"; 77 78 public DatabaseHelper(Context context, CursorFactory factory) { 79 super(context, NAME, null, VERSION); 80 } 81 82 @Override 83 public void onCreate(SQLiteDatabase db) { 84 // creating required tables 85 db.execSQL(CREATE_TABLE_KEYPRHASES); 86 db.execSQL(CREATE_TABLE_SOUND_MODEL); 87 } 88 89 @Override 90 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 91 // TODO: For now, drop older tables and recreate new ones. 92 db.execSQL("DROP TABLE IF EXISTS " + KeyphraseContract.TABLE); 93 db.execSQL("DROP TABLE IF EXISTS " + SoundModelContract.TABLE); 94 onCreate(db); 95 } 96 97 /** 98 * TODO: Change to addOrUpdate to handle changes here. 99 */ 100 public void addKeyphraseSoundModel(KeyphraseSoundModel soundModel) { 101 SQLiteDatabase db = this.getWritableDatabase(); 102 ContentValues values = new ContentValues(); 103 // Generate a random ID for the model. 104 values.put(SoundModelContract.KEY_ID, soundModel.uuid.toString()); 105 values.put(SoundModelContract.KEY_DATA, soundModel.data); 106 values.put(SoundModelContract.KEY_TYPE, SoundTrigger.SoundModel.TYPE_KEYPHRASE); 107 108 if (db.insert(SoundModelContract.TABLE, null, values) != -1) { 109 for (Keyphrase keyphrase : soundModel.keyphrases) { 110 addKeyphrase(soundModel.uuid, keyphrase); 111 } 112 } else { 113 Slog.w(TAG, "Failed to persist sound model to database"); 114 } 115 } 116 117 /** 118 * TODO(sansid): Change to addOrUpdate to handle changes here. 119 */ 120 private void 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 Slog.w(TAG, "Failed to persist keyphrase to database"); 130 } 131 } 132 133 /** 134 * Lists all the keyphrase sound models currently registered with the system. 135 */ 136 public List<KeyphraseSoundModel> getKephraseSoundModels() { 137 List<KeyphraseSoundModel> models = new ArrayList<>(); 138 String selectQuery = "SELECT * FROM " + SoundModelContract.TABLE; 139 SQLiteDatabase db = this.getReadableDatabase(); 140 Cursor c = db.rawQuery(selectQuery, null); 141 142 // looping through all rows and adding to list 143 if (c.moveToFirst()) { 144 do { 145 int type = c.getInt(c.getColumnIndex(SoundModelContract.KEY_TYPE)); 146 if (type != SoundTrigger.SoundModel.TYPE_KEYPHRASE) { 147 // Ignore non-keyphrase sound models. 148 continue; 149 } 150 String id = c.getString(c.getColumnIndex(SoundModelContract.KEY_ID)); 151 byte[] data = c.getBlob(c.getColumnIndex(SoundModelContract.KEY_DATA)); 152 // Get all the keyphrases for this this sound model. 153 models.add(new KeyphraseSoundModel( 154 UUID.fromString(id), data, getKeyphrasesForSoundModel(id))); 155 } while (c.moveToNext()); 156 } 157 return models; 158 } 159 160 private Keyphrase[] getKeyphrasesForSoundModel(String modelId) { 161 List<Keyphrase> keyphrases = new ArrayList<>(); 162 String selectQuery = "SELECT * FROM " + KeyphraseContract.TABLE 163 + " WHERE " + KeyphraseContract.KEY_SOUND_MODEL_ID + " = '" + modelId + "'"; 164 SQLiteDatabase db = this.getReadableDatabase(); 165 Cursor c = db.rawQuery(selectQuery, null); 166 167 // looping through all rows and adding to list 168 if (c.moveToFirst()) { 169 do { 170 int id = c.getInt(c.getColumnIndex(KeyphraseContract.KEY_ID)); 171 int modes = c.getInt(c.getColumnIndex(KeyphraseContract.KEY_RECOGNITION_MODES)); 172 int[] users = {c.getInt(c.getColumnIndex(KeyphraseContract.KEY_USERS))}; 173 String locale = c.getString(c.getColumnIndex(KeyphraseContract.KEY_LOCALE)); 174 String hintText = c.getString(c.getColumnIndex(KeyphraseContract.KEY_HINT_TEXT)); 175 176 keyphrases.add(new Keyphrase(id, hintText, locale, modes, users)); 177 } while (c.moveToNext()); 178 } 179 Keyphrase[] keyphraseArr = new Keyphrase[keyphrases.size()]; 180 keyphrases.toArray(keyphraseArr); 181 return keyphraseArr; 182 } 183} 184