1d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha/**
2d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha * Copyright (C) 2014 The Android Open Source Project
3d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha *
4d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha * Licensed under the Apache License, Version 2.0 (the "License");
5d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha * you may not use this file except in compliance with the License.
6d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha * You may obtain a copy of the License at
7d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha *
8d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha *      http://www.apache.org/licenses/LICENSE-2.0
9d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha *
10d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha * Unless required by applicable law or agreed to in writing, software
11d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha * distributed under the License is distributed on an "AS IS" BASIS,
12d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha * See the License for the specific language governing permissions and
14d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha * limitations under the License.
15d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha */
16d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha
17d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthapackage com.android.server.voiceinteraction;
18d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha
19d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthaimport android.content.ContentValues;
20d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthaimport android.content.Context;
21d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthaimport android.database.Cursor;
22d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthaimport android.database.sqlite.SQLiteDatabase;
23d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthaimport android.database.sqlite.SQLiteOpenHelper;
24d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthaimport android.hardware.soundtrigger.SoundTrigger;
25055897208d659e9734a82def88be4a806ff55448Sandeep Siddharthaimport android.hardware.soundtrigger.SoundTrigger.Keyphrase;
26055897208d659e9734a82def88be4a806ff55448Sandeep Siddharthaimport android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
27055897208d659e9734a82def88be4a806ff55448Sandeep Siddharthaimport android.text.TextUtils;
28d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthaimport android.util.Slog;
29d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha
308cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddharthaimport java.util.Locale;
31d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthaimport java.util.UUID;
32d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha
33d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha/**
348ecaf5f5cfd18e0436db1a27ccf46a063e9aacd7Sandeep Siddhartha * Helper to manage the database of the sound models that have been registered on the device.
358ecaf5f5cfd18e0436db1a27ccf46a063e9aacd7Sandeep Siddhartha *
36d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha * @hide
37d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha */
38d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddharthapublic class DatabaseHelper extends SQLiteOpenHelper {
39d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    static final String TAG = "SoundModelDBHelper";
408cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha    static final boolean DBG = false;
41d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha
42d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    private static final String NAME = "sound_model.db";
43256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha    private static final int VERSION = 4;
44d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha
45d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    public static interface SoundModelContract {
46d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha        public static final String TABLE = "sound_model";
47452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha        public static final String KEY_MODEL_UUID = "model_uuid";
48256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha        public static final String KEY_KEYPHRASE_ID = "keyphrase_id";
49d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha        public static final String KEY_TYPE = "type";
50d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha        public static final String KEY_DATA = "data";
51452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha        public static final String KEY_RECOGNITION_MODES = "recognition_modes";
52452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha        public static final String KEY_LOCALE = "locale";
53452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha        public static final String KEY_HINT_TEXT = "hint_text";
54452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha        public static final String KEY_USERS = "users";
55d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    }
56d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha
57452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha    // Table Create Statement
58d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    private static final String CREATE_TABLE_SOUND_MODEL = "CREATE TABLE "
59d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha            + SoundModelContract.TABLE + "("
60256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha            + SoundModelContract.KEY_MODEL_UUID + " TEXT PRIMARY KEY,"
61256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha            + SoundModelContract.KEY_KEYPHRASE_ID + " INTEGER,"
62d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha            + SoundModelContract.KEY_TYPE + " INTEGER,"
63452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha            + SoundModelContract.KEY_DATA + " BLOB,"
64452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha            + SoundModelContract.KEY_RECOGNITION_MODES + " INTEGER,"
65452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha            + SoundModelContract.KEY_LOCALE + " TEXT,"
66452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha            + SoundModelContract.KEY_HINT_TEXT + " TEXT,"
67452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha            + SoundModelContract.KEY_USERS + " TEXT" + ")";
68d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha
692883ba69751de69811a38f086ecbe4c2032ca87dSandeep Siddhartha    public DatabaseHelper(Context context) {
70d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha        super(context, NAME, null, VERSION);
71d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    }
72d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha
73d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    @Override
74d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    public void onCreate(SQLiteDatabase db) {
75d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha        // creating required tables
76d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha        db.execSQL(CREATE_TABLE_SOUND_MODEL);
77d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    }
78d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha
79d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    @Override
80d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
818ecaf5f5cfd18e0436db1a27ccf46a063e9aacd7Sandeep Siddhartha        // TODO: For now, drop older tables and recreate new ones.
82d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha        db.execSQL("DROP TABLE IF EXISTS " + SoundModelContract.TABLE);
83d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha        onCreate(db);
84d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    }
85d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha
86452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha    /**
87452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha     * Updates the given keyphrase model, adds it, if it doesn't already exist.
88452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha     *
89452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha     * TODO: We only support one keyphrase currently.
90452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha     */
91452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha    public boolean updateKeyphraseSoundModel(KeyphraseSoundModel soundModel) {
92f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha        synchronized(this) {
93f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha            SQLiteDatabase db = getWritableDatabase();
94f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha            ContentValues values = new ContentValues();
95452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha            values.put(SoundModelContract.KEY_MODEL_UUID, soundModel.uuid.toString());
96f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha            values.put(SoundModelContract.KEY_TYPE, SoundTrigger.SoundModel.TYPE_KEYPHRASE);
97452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha            values.put(SoundModelContract.KEY_DATA, soundModel.data);
98452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha
99452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha            if (soundModel.keyphrases != null && soundModel.keyphrases.length == 1) {
100452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                values.put(SoundModelContract.KEY_KEYPHRASE_ID, soundModel.keyphrases[0].id);
101452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                values.put(SoundModelContract.KEY_RECOGNITION_MODES,
102452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                        soundModel.keyphrases[0].recognitionModes);
103452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                values.put(SoundModelContract.KEY_USERS,
104452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                        getCommaSeparatedString(soundModel.keyphrases[0].users));
105452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                values.put(SoundModelContract.KEY_LOCALE, soundModel.keyphrases[0].locale);
106452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                values.put(SoundModelContract.KEY_HINT_TEXT, soundModel.keyphrases[0].text);
107452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                try {
108452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                    return db.insertWithOnConflict(SoundModelContract.TABLE, null, values,
109452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                            SQLiteDatabase.CONFLICT_REPLACE) != -1;
110452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                } finally {
111452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                    db.close();
112f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha                }
113d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha            }
1142883ba69751de69811a38f086ecbe4c2032ca87dSandeep Siddhartha            return false;
115d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha        }
116d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    }
117d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha
118d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    /**
119f8cf71d753b86895f987f682c80491aa2967e0c2Sandeep Siddhartha     * Deletes the sound model and associated keyphrases.
120f8cf71d753b86895f987f682c80491aa2967e0c2Sandeep Siddhartha     */
1218cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha    public boolean deleteKeyphraseSoundModel(int keyphraseId, int userHandle, String bcp47Locale) {
1228cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha        // Sanitize the locale to guard against SQL injection.
1238cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha        bcp47Locale = Locale.forLanguageTag(bcp47Locale).toLanguageTag();
124f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha        synchronized(this) {
1258cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha            KeyphraseSoundModel soundModel = getKeyphraseSoundModel(keyphraseId, userHandle,
1268cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                    bcp47Locale);
1278cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha            if (soundModel == null) {
1288cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                return false;
1298cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha            }
130452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha
1318cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha            // Delete all sound models for the given keyphrase and specified user.
1328cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha            SQLiteDatabase db = getWritableDatabase();
1338cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha            String soundModelClause = SoundModelContract.KEY_MODEL_UUID
1348cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                    + "='" + soundModel.uuid.toString() + "'";
135452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha            try {
136452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                return db.delete(SoundModelContract.TABLE, soundModelClause, null) != 0;
137452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha            } finally {
138452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                db.close();
139f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha            }
140f8cf71d753b86895f987f682c80491aa2967e0c2Sandeep Siddhartha        }
141f8cf71d753b86895f987f682c80491aa2967e0c2Sandeep Siddhartha    }
142f8cf71d753b86895f987f682c80491aa2967e0c2Sandeep Siddhartha
143f8cf71d753b86895f987f682c80491aa2967e0c2Sandeep Siddhartha    /**
144452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha     * Returns a matching {@link KeyphraseSoundModel} for the keyphrase ID.
145452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha     * Returns null if a match isn't found.
146452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha     *
147452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha     * TODO: We only support one keyphrase currently.
148d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha     */
1498cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha    public KeyphraseSoundModel getKeyphraseSoundModel(int keyphraseId, int userHandle,
1508cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha            String bcp47Locale) {
1518cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha        // Sanitize the locale to guard against SQL injection.
1528cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha        bcp47Locale = Locale.forLanguageTag(bcp47Locale).toLanguageTag();
153f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha        synchronized(this) {
154452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha            // Find the corresponding sound model ID for the keyphrase.
155452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha            String selectQuery = "SELECT  * FROM " + SoundModelContract.TABLE
1568cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                    + " WHERE " + SoundModelContract.KEY_KEYPHRASE_ID + "= '" + keyphraseId
1578cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                    + "' AND " + SoundModelContract.KEY_LOCALE + "='" + bcp47Locale + "'";
158f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha            SQLiteDatabase db = getReadableDatabase();
159f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha            Cursor c = db.rawQuery(selectQuery, null);
160452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha
161452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha            try {
162452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                if (c.moveToFirst()) {
163256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                    do {
164256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                        int type = c.getInt(c.getColumnIndex(SoundModelContract.KEY_TYPE));
165256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                        if (type != SoundTrigger.SoundModel.TYPE_KEYPHRASE) {
1668cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                            if (DBG) {
1678cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                                Slog.w(TAG, "Ignoring SoundModel since it's type is incorrect");
1688cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                            }
169256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                            continue;
170256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                        }
171256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha
172256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                        String modelUuid = c.getString(
173256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                                c.getColumnIndex(SoundModelContract.KEY_MODEL_UUID));
174256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                        if (modelUuid == null) {
1758cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                            Slog.w(TAG, "Ignoring SoundModel since it doesn't specify an ID");
176256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                            continue;
177452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                        }
178256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha
179256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                        byte[] data = c.getBlob(c.getColumnIndex(SoundModelContract.KEY_DATA));
180256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                        int recognitionModes = c.getInt(
181256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                                c.getColumnIndex(SoundModelContract.KEY_RECOGNITION_MODES));
182256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                        int[] users = getArrayForCommaSeparatedString(
183256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                                c.getString(c.getColumnIndex(SoundModelContract.KEY_USERS)));
1848cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                        String modelLocale = c.getString(
185256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                                c.getColumnIndex(SoundModelContract.KEY_LOCALE));
186256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                        String text = c.getString(
187256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                                c.getColumnIndex(SoundModelContract.KEY_HINT_TEXT));
188256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha
189256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                        // Only add keyphrases meant for the current user.
190256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                        if (users == null) {
191256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                            // No users present in the keyphrase.
1928cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                            Slog.w(TAG, "Ignoring SoundModel since it doesn't specify users");
193256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                            continue;
194256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                        }
195256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha
196256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                        boolean isAvailableForCurrentUser = false;
197256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                        for (int user : users) {
1988cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                            if (userHandle == user) {
199256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                                isAvailableForCurrentUser = true;
200256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                                break;
201256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                            }
202256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                        }
203256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                        if (!isAvailableForCurrentUser) {
2048cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                            if (DBG) {
2058cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                                Slog.w(TAG, "Ignoring SoundModel since user handles don't match");
2068cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                            }
207256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                            continue;
2088cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                        } else {
2098cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                            if (DBG) Slog.d(TAG, "Found a SoundModel for user: " + userHandle);
210256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                        }
211256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha
212256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                        Keyphrase[] keyphrases = new Keyphrase[1];
213256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                        keyphrases[0] = new Keyphrase(
2148cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                                keyphraseId, recognitionModes, modelLocale, text, users);
2158cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                        KeyphraseSoundModel model = new KeyphraseSoundModel(
2168cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                                UUID.fromString(modelUuid),
217256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                                null /* FIXME use vendor UUID */, data, keyphrases);
2188cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                        if (DBG) {
2198cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                            Slog.d(TAG, "Found SoundModel for the given keyphrase/locale/user: "
2208cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                                    + model);
2218cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                        }
2228cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                        return model;
223256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha                    } while (c.moveToNext());
224452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                }
225452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                Slog.w(TAG, "No SoundModel available for the given keyphrase");
226452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha            } finally {
227452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                c.close();
228452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha                db.close();
229452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha            }
230452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha            return null;
231d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha        }
232d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha    }
233055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha
234f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha    private static String getCommaSeparatedString(int[] users) {
2358cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha        if (users == null) {
236055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha            return "";
237055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha        }
2388cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha        StringBuilder sb = new StringBuilder();
2398cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha        for (int i = 0; i < users.length; i++) {
2408cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha            if (i != 0) {
2418cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha                sb.append(',');
2428cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha            }
2438cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha            sb.append(users[i]);
244055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha        }
2458cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha        return sb.toString();
246055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha    }
247055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha
248f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha    private static int[] getArrayForCommaSeparatedString(String text) {
249055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha        if (TextUtils.isEmpty(text)) {
250055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha            return null;
251055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha        }
252055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha        String[] usersStr = text.split(",");
253055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha        int[] users = new int[usersStr.length];
254055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha        for (int i = 0; i < usersStr.length; i++) {
255055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha            users[i] = Integer.valueOf(usersStr[i]);
256055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha        }
257055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha        return users;
258055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha    }
259d4233c68fc17f0909e9e36494db85a634f8e2665Sandeep Siddhartha}
260