blob: cf3395abf1160f1df97d95a9cad397ce412f8c39 [file] [log] [blame]
Sandeepd7018202014-07-10 15:15:39 -07001/**
Eric Laurente48188c2014-04-18 17:44:11 -07002 * 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 android.hardware.soundtrigger;
18
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -080019import static android.system.OsConstants.EINVAL;
20import static android.system.OsConstants.ENODEV;
21import static android.system.OsConstants.ENOSYS;
22import static android.system.OsConstants.EPERM;
23import static android.system.OsConstants.EPIPE;
24
25import android.annotation.Nullable;
26import android.annotation.SystemApi;
Mathew Inwoodbcbe4402018-08-08 15:42:59 +010027import android.annotation.UnsupportedAppUsage;
Eric Laurentd3b82232014-07-30 08:57:39 -070028import android.media.AudioFormat;
Eric Laurente48188c2014-04-18 17:44:11 -070029import android.os.Handler;
Sandeep Siddhartha05589722014-07-17 16:21:54 -070030import android.os.Parcel;
31import android.os.Parcelable;
Eric Laurente48188c2014-04-18 17:44:11 -070032
33import java.util.ArrayList;
Sandeep Siddhartha05589722014-07-17 16:21:54 -070034import java.util.Arrays;
Eric Laurente48188c2014-04-18 17:44:11 -070035import java.util.UUID;
36
37/**
38 * The SoundTrigger class provides access via JNI to the native service managing
39 * the sound trigger HAL.
40 *
41 * @hide
42 */
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -080043@SystemApi
Eric Laurente48188c2014-04-18 17:44:11 -070044public class SoundTrigger {
45
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -080046 private SoundTrigger() {
47 }
48
49 /**
50 * Status code used when the operation succeeded
51 */
Eric Laurente48188c2014-04-18 17:44:11 -070052 public static final int STATUS_OK = 0;
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -080053 /** @hide */
Eric Laurente48188c2014-04-18 17:44:11 -070054 public static final int STATUS_ERROR = Integer.MIN_VALUE;
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -080055 /** @hide */
Lazar Trsic8ea56f62015-07-07 17:31:20 +020056 public static final int STATUS_PERMISSION_DENIED = -EPERM;
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -080057 /** @hide */
Lazar Trsic8ea56f62015-07-07 17:31:20 +020058 public static final int STATUS_NO_INIT = -ENODEV;
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -080059 /** @hide */
Lazar Trsic8ea56f62015-07-07 17:31:20 +020060 public static final int STATUS_BAD_VALUE = -EINVAL;
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -080061 /** @hide */
Lazar Trsic8ea56f62015-07-07 17:31:20 +020062 public static final int STATUS_DEAD_OBJECT = -EPIPE;
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -080063 /** @hide */
Lazar Trsic8ea56f62015-07-07 17:31:20 +020064 public static final int STATUS_INVALID_OPERATION = -ENOSYS;
Eric Laurente48188c2014-04-18 17:44:11 -070065
66 /*****************************************************************************
67 * A ModuleProperties describes a given sound trigger hardware module
68 * managed by the native sound trigger service. Each module has a unique
69 * ID used to target any API call to this paricular module. Module
70 * properties are returned by listModules() method.
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -080071 *
72 * @hide
Eric Laurente48188c2014-04-18 17:44:11 -070073 ****************************************************************************/
Sandeep Siddhartha05589722014-07-17 16:21:54 -070074 public static class ModuleProperties implements Parcelable {
Eric Laurente48188c2014-04-18 17:44:11 -070075 /** Unique module ID provided by the native service */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +010076 @UnsupportedAppUsage
Eric Laurente48188c2014-04-18 17:44:11 -070077 public final int id;
78
79 /** human readable voice detection engine implementor */
80 public final String implementor;
81
82 /** human readable voice detection engine description */
83 public final String description;
84
85 /** Unique voice engine Id (changes with each version) */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +010086 @UnsupportedAppUsage
Eric Laurente48188c2014-04-18 17:44:11 -070087 public final UUID uuid;
88
89 /** Voice detection engine version */
90 public final int version;
91
92 /** Maximum number of active sound models */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +010093 @UnsupportedAppUsage
Eric Laurente48188c2014-04-18 17:44:11 -070094 public final int maxSoundModels;
95
96 /** Maximum number of key phrases */
Sandeep Siddharthad4233c62014-06-12 18:31:19 -070097 public final int maxKeyphrases;
Eric Laurente48188c2014-04-18 17:44:11 -070098
99 /** Maximum number of users per key phrase */
100 public final int maxUsers;
101
102 /** Supported recognition modes (bit field, RECOGNITION_MODE_VOICE_TRIGGER ...) */
103 public final int recognitionModes;
104
105 /** Supports seamless transition to capture mode after recognition */
106 public final boolean supportsCaptureTransition;
107
108 /** Maximum buffering capacity in ms if supportsCaptureTransition() is true */
109 public final int maxBufferMs;
110
111 /** Supports capture by other use cases while detection is active */
112 public final boolean supportsConcurrentCapture;
113
114 /** Rated power consumption when detection is active with TDB silence/sound/speech ratio */
115 public final int powerConsumptionMw;
116
Eric Laurentd3b82232014-07-30 08:57:39 -0700117 /** Returns the trigger (key phrase) capture in the binary data of the
118 * recognition callback event */
119 public final boolean returnsTriggerInEvent;
120
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100121 @UnsupportedAppUsage
Eric Laurente48188c2014-04-18 17:44:11 -0700122 ModuleProperties(int id, String implementor, String description,
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700123 String uuid, int version, int maxSoundModels, int maxKeyphrases,
Eric Laurente48188c2014-04-18 17:44:11 -0700124 int maxUsers, int recognitionModes, boolean supportsCaptureTransition,
125 int maxBufferMs, boolean supportsConcurrentCapture,
Eric Laurentd3b82232014-07-30 08:57:39 -0700126 int powerConsumptionMw, boolean returnsTriggerInEvent) {
Eric Laurente48188c2014-04-18 17:44:11 -0700127 this.id = id;
128 this.implementor = implementor;
129 this.description = description;
130 this.uuid = UUID.fromString(uuid);
131 this.version = version;
132 this.maxSoundModels = maxSoundModels;
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700133 this.maxKeyphrases = maxKeyphrases;
Eric Laurente48188c2014-04-18 17:44:11 -0700134 this.maxUsers = maxUsers;
135 this.recognitionModes = recognitionModes;
136 this.supportsCaptureTransition = supportsCaptureTransition;
137 this.maxBufferMs = maxBufferMs;
138 this.supportsConcurrentCapture = supportsConcurrentCapture;
139 this.powerConsumptionMw = powerConsumptionMw;
Eric Laurentd3b82232014-07-30 08:57:39 -0700140 this.returnsTriggerInEvent = returnsTriggerInEvent;
Eric Laurente48188c2014-04-18 17:44:11 -0700141 }
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700142
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700143 public static final @android.annotation.NonNull Parcelable.Creator<ModuleProperties> CREATOR
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700144 = new Parcelable.Creator<ModuleProperties>() {
145 public ModuleProperties createFromParcel(Parcel in) {
146 return ModuleProperties.fromParcel(in);
147 }
148
149 public ModuleProperties[] newArray(int size) {
150 return new ModuleProperties[size];
151 }
152 };
153
154 private static ModuleProperties fromParcel(Parcel in) {
155 int id = in.readInt();
156 String implementor = in.readString();
157 String description = in.readString();
158 String uuid = in.readString();
159 int version = in.readInt();
160 int maxSoundModels = in.readInt();
161 int maxKeyphrases = in.readInt();
162 int maxUsers = in.readInt();
163 int recognitionModes = in.readInt();
164 boolean supportsCaptureTransition = in.readByte() == 1;
165 int maxBufferMs = in.readInt();
166 boolean supportsConcurrentCapture = in.readByte() == 1;
167 int powerConsumptionMw = in.readInt();
Eric Laurentd3b82232014-07-30 08:57:39 -0700168 boolean returnsTriggerInEvent = in.readByte() == 1;
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700169 return new ModuleProperties(id, implementor, description, uuid, version,
170 maxSoundModels, maxKeyphrases, maxUsers, recognitionModes,
171 supportsCaptureTransition, maxBufferMs, supportsConcurrentCapture,
Eric Laurentd3b82232014-07-30 08:57:39 -0700172 powerConsumptionMw, returnsTriggerInEvent);
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700173 }
174
175 @Override
176 public void writeToParcel(Parcel dest, int flags) {
177 dest.writeInt(id);
178 dest.writeString(implementor);
179 dest.writeString(description);
180 dest.writeString(uuid.toString());
181 dest.writeInt(version);
182 dest.writeInt(maxSoundModels);
183 dest.writeInt(maxKeyphrases);
184 dest.writeInt(maxUsers);
185 dest.writeInt(recognitionModes);
186 dest.writeByte((byte) (supportsCaptureTransition ? 1 : 0));
187 dest.writeInt(maxBufferMs);
188 dest.writeByte((byte) (supportsConcurrentCapture ? 1 : 0));
189 dest.writeInt(powerConsumptionMw);
Eric Laurentd3b82232014-07-30 08:57:39 -0700190 dest.writeByte((byte) (returnsTriggerInEvent ? 1 : 0));
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700191 }
192
193 @Override
194 public int describeContents() {
195 return 0;
196 }
197
198 @Override
199 public String toString() {
200 return "ModuleProperties [id=" + id + ", implementor=" + implementor + ", description="
201 + description + ", uuid=" + uuid + ", version=" + version + ", maxSoundModels="
202 + maxSoundModels + ", maxKeyphrases=" + maxKeyphrases + ", maxUsers="
203 + maxUsers + ", recognitionModes=" + recognitionModes
204 + ", supportsCaptureTransition=" + supportsCaptureTransition + ", maxBufferMs="
205 + maxBufferMs + ", supportsConcurrentCapture=" + supportsConcurrentCapture
Eric Laurentd3b82232014-07-30 08:57:39 -0700206 + ", powerConsumptionMw=" + powerConsumptionMw
207 + ", returnsTriggerInEvent=" + returnsTriggerInEvent + "]";
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700208 }
Eric Laurente48188c2014-04-18 17:44:11 -0700209 }
210
211 /*****************************************************************************
212 * A SoundModel describes the attributes and contains the binary data used by the hardware
213 * implementation to detect a particular sound pattern.
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700214 * A specialized version {@link KeyphraseSoundModel} is defined for key phrase
Eric Laurente48188c2014-04-18 17:44:11 -0700215 * sound models.
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800216 *
217 * @hide
Eric Laurente48188c2014-04-18 17:44:11 -0700218 ****************************************************************************/
219 public static class SoundModel {
220 /** Undefined sound model type */
221 public static final int TYPE_UNKNOWN = -1;
222
223 /** Keyphrase sound model */
224 public static final int TYPE_KEYPHRASE = 0;
225
Arunesh Mishraa772e5f2016-01-25 10:33:11 -0800226 /**
227 * A generic sound model. Use this type only for non-keyphrase sound models such as
228 * ones that match a particular sound pattern.
229 */
230 public static final int TYPE_GENERIC_SOUND = 1;
231
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700232 /** Unique sound model identifier */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100233 @UnsupportedAppUsage
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700234 public final UUID uuid;
235
Eric Laurente48188c2014-04-18 17:44:11 -0700236 /** Sound model type (e.g. TYPE_KEYPHRASE); */
237 public final int type;
238
Eric Laurentd3b82232014-07-30 08:57:39 -0700239 /** Unique sound model vendor identifier */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100240 @UnsupportedAppUsage
Eric Laurentd3b82232014-07-30 08:57:39 -0700241 public final UUID vendorUuid;
242
Eric Laurente48188c2014-04-18 17:44:11 -0700243 /** Opaque data. For use by vendor implementation and enrollment application */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100244 @UnsupportedAppUsage
Eric Laurente48188c2014-04-18 17:44:11 -0700245 public final byte[] data;
246
Eric Laurentd3b82232014-07-30 08:57:39 -0700247 public SoundModel(UUID uuid, UUID vendorUuid, int type, byte[] data) {
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700248 this.uuid = uuid;
Eric Laurentd3b82232014-07-30 08:57:39 -0700249 this.vendorUuid = vendorUuid;
Eric Laurente48188c2014-04-18 17:44:11 -0700250 this.type = type;
251 this.data = data;
252 }
Sandeep Siddhartha45c00b52014-10-16 16:17:11 -0700253
254 @Override
255 public int hashCode() {
256 final int prime = 31;
257 int result = 1;
258 result = prime * result + Arrays.hashCode(data);
259 result = prime * result + type;
260 result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
261 result = prime * result + ((vendorUuid == null) ? 0 : vendorUuid.hashCode());
262 return result;
263 }
264
265 @Override
266 public boolean equals(Object obj) {
267 if (this == obj)
268 return true;
269 if (obj == null)
270 return false;
271 if (!(obj instanceof SoundModel))
272 return false;
273 SoundModel other = (SoundModel) obj;
274 if (!Arrays.equals(data, other.data))
275 return false;
276 if (type != other.type)
277 return false;
278 if (uuid == null) {
279 if (other.uuid != null)
280 return false;
281 } else if (!uuid.equals(other.uuid))
282 return false;
283 if (vendorUuid == null) {
284 if (other.vendorUuid != null)
285 return false;
286 } else if (!vendorUuid.equals(other.vendorUuid))
287 return false;
288 return true;
289 }
Eric Laurente48188c2014-04-18 17:44:11 -0700290 }
291
292 /*****************************************************************************
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700293 * A Keyphrase describes a key phrase that can be detected by a
294 * {@link KeyphraseSoundModel}
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800295 *
296 * @hide
Eric Laurente48188c2014-04-18 17:44:11 -0700297 ****************************************************************************/
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700298 public static class Keyphrase implements Parcelable {
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700299 /** Unique identifier for this keyphrase */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100300 @UnsupportedAppUsage
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700301 public final int id;
302
Eric Laurente48188c2014-04-18 17:44:11 -0700303 /** Recognition modes supported for this key phrase in the model */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100304 @UnsupportedAppUsage
Eric Laurente48188c2014-04-18 17:44:11 -0700305 public final int recognitionModes;
306
307 /** Locale of the keyphrase. JAVA Locale string e.g en_US */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100308 @UnsupportedAppUsage
Eric Laurente48188c2014-04-18 17:44:11 -0700309 public final String locale;
310
311 /** Key phrase text */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100312 @UnsupportedAppUsage
Eric Laurente48188c2014-04-18 17:44:11 -0700313 public final String text;
314
Eric Laurent013f66b2014-07-06 16:35:00 -0700315 /** Users this key phrase has been trained for. countains sound trigger specific user IDs
316 * derived from system user IDs {@link android.os.UserHandle#getIdentifier()}. */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100317 @UnsupportedAppUsage
Eric Laurent013f66b2014-07-06 16:35:00 -0700318 public final int[] users;
Eric Laurente48188c2014-04-18 17:44:11 -0700319
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100320 @UnsupportedAppUsage
Eric Laurent013f66b2014-07-06 16:35:00 -0700321 public Keyphrase(int id, int recognitionModes, String locale, String text, int[] users) {
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700322 this.id = id;
Eric Laurente48188c2014-04-18 17:44:11 -0700323 this.recognitionModes = recognitionModes;
324 this.locale = locale;
325 this.text = text;
Eric Laurent013f66b2014-07-06 16:35:00 -0700326 this.users = users;
Eric Laurente48188c2014-04-18 17:44:11 -0700327 }
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700328
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700329 public static final @android.annotation.NonNull Parcelable.Creator<Keyphrase> CREATOR
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700330 = new Parcelable.Creator<Keyphrase>() {
331 public Keyphrase createFromParcel(Parcel in) {
332 return Keyphrase.fromParcel(in);
333 }
334
335 public Keyphrase[] newArray(int size) {
336 return new Keyphrase[size];
337 }
338 };
339
340 private static Keyphrase fromParcel(Parcel in) {
341 int id = in.readInt();
342 int recognitionModes = in.readInt();
343 String locale = in.readString();
344 String text = in.readString();
345 int[] users = null;
346 int numUsers = in.readInt();
Sandeep Siddhartha110f5692014-07-20 12:22:56 -0700347 if (numUsers >= 0) {
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700348 users = new int[numUsers];
349 in.readIntArray(users);
350 }
351 return new Keyphrase(id, recognitionModes, locale, text, users);
352 }
353
354 @Override
355 public void writeToParcel(Parcel dest, int flags) {
356 dest.writeInt(id);
357 dest.writeInt(recognitionModes);
358 dest.writeString(locale);
359 dest.writeString(text);
360 if (users != null) {
361 dest.writeInt(users.length);
362 dest.writeIntArray(users);
363 } else {
Sandeep Siddhartha110f5692014-07-20 12:22:56 -0700364 dest.writeInt(-1);
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700365 }
366 }
367
368 @Override
369 public int describeContents() {
370 return 0;
371 }
372
373 @Override
374 public int hashCode() {
375 final int prime = 31;
376 int result = 1;
377 result = prime * result + ((text == null) ? 0 : text.hashCode());
378 result = prime * result + id;
379 result = prime * result + ((locale == null) ? 0 : locale.hashCode());
380 result = prime * result + recognitionModes;
381 result = prime * result + Arrays.hashCode(users);
382 return result;
383 }
384
385 @Override
386 public boolean equals(Object obj) {
387 if (this == obj)
388 return true;
389 if (obj == null)
390 return false;
391 if (getClass() != obj.getClass())
392 return false;
393 Keyphrase other = (Keyphrase) obj;
394 if (text == null) {
395 if (other.text != null)
396 return false;
397 } else if (!text.equals(other.text))
398 return false;
399 if (id != other.id)
400 return false;
401 if (locale == null) {
402 if (other.locale != null)
403 return false;
404 } else if (!locale.equals(other.locale))
405 return false;
406 if (recognitionModes != other.recognitionModes)
407 return false;
408 if (!Arrays.equals(users, other.users))
409 return false;
410 return true;
411 }
412
413 @Override
414 public String toString() {
415 return "Keyphrase [id=" + id + ", recognitionModes=" + recognitionModes + ", locale="
416 + locale + ", text=" + text + ", users=" + Arrays.toString(users) + "]";
417 }
Eric Laurente48188c2014-04-18 17:44:11 -0700418 }
419
420 /*****************************************************************************
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700421 * A KeyphraseSoundModel is a specialized {@link SoundModel} for key phrases.
Eric Laurente48188c2014-04-18 17:44:11 -0700422 * It contains data needed by the hardware to detect a certain number of key phrases
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700423 * and the list of corresponding {@link Keyphrase} descriptors.
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800424 *
425 * @hide
Eric Laurente48188c2014-04-18 17:44:11 -0700426 ****************************************************************************/
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700427 public static class KeyphraseSoundModel extends SoundModel implements Parcelable {
Eric Laurente48188c2014-04-18 17:44:11 -0700428 /** Key phrases in this sound model */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100429 @UnsupportedAppUsage
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700430 public final Keyphrase[] keyphrases; // keyword phrases in model
Eric Laurente48188c2014-04-18 17:44:11 -0700431
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100432 @UnsupportedAppUsage
Eric Laurentd3b82232014-07-30 08:57:39 -0700433 public KeyphraseSoundModel(
434 UUID uuid, UUID vendorUuid, byte[] data, Keyphrase[] keyphrases) {
435 super(uuid, vendorUuid, TYPE_KEYPHRASE, data);
Sandeep Siddharthad4233c62014-06-12 18:31:19 -0700436 this.keyphrases = keyphrases;
Eric Laurente48188c2014-04-18 17:44:11 -0700437 }
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700438
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700439 public static final @android.annotation.NonNull Parcelable.Creator<KeyphraseSoundModel> CREATOR
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700440 = new Parcelable.Creator<KeyphraseSoundModel>() {
441 public KeyphraseSoundModel createFromParcel(Parcel in) {
442 return KeyphraseSoundModel.fromParcel(in);
443 }
444
445 public KeyphraseSoundModel[] newArray(int size) {
446 return new KeyphraseSoundModel[size];
447 }
448 };
449
450 private static KeyphraseSoundModel fromParcel(Parcel in) {
451 UUID uuid = UUID.fromString(in.readString());
Eric Laurentd3b82232014-07-30 08:57:39 -0700452 UUID vendorUuid = null;
453 int length = in.readInt();
454 if (length >= 0) {
455 vendorUuid = UUID.fromString(in.readString());
456 }
Sandeep Siddhartha39c12fa2014-07-25 18:37:29 -0700457 byte[] data = in.readBlob();
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700458 Keyphrase[] keyphrases = in.createTypedArray(Keyphrase.CREATOR);
Eric Laurentd3b82232014-07-30 08:57:39 -0700459 return new KeyphraseSoundModel(uuid, vendorUuid, data, keyphrases);
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700460 }
461
462 @Override
463 public int describeContents() {
464 return 0;
465 }
466
467 @Override
468 public void writeToParcel(Parcel dest, int flags) {
469 dest.writeString(uuid.toString());
Eric Laurentd3b82232014-07-30 08:57:39 -0700470 if (vendorUuid == null) {
471 dest.writeInt(-1);
472 } else {
473 dest.writeInt(vendorUuid.toString().length());
474 dest.writeString(vendorUuid.toString());
475 }
Sandeep Siddhartha39c12fa2014-07-25 18:37:29 -0700476 dest.writeBlob(data);
Sandeep Siddhartha68173372014-07-28 13:25:30 -0700477 dest.writeTypedArray(keyphrases, flags);
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700478 }
Sandeep Siddhartha110f5692014-07-20 12:22:56 -0700479
480 @Override
481 public String toString() {
Eric Laurentd3b82232014-07-30 08:57:39 -0700482 return "KeyphraseSoundModel [keyphrases=" + Arrays.toString(keyphrases)
483 + ", uuid=" + uuid + ", vendorUuid=" + vendorUuid
484 + ", type=" + type + ", data=" + (data == null ? 0 : data.length) + "]";
Sandeep Siddhartha110f5692014-07-20 12:22:56 -0700485 }
Sandeep Siddhartha45c00b52014-10-16 16:17:11 -0700486
487 @Override
488 public int hashCode() {
489 final int prime = 31;
490 int result = super.hashCode();
491 result = prime * result + Arrays.hashCode(keyphrases);
492 return result;
493 }
494
495 @Override
496 public boolean equals(Object obj) {
497 if (this == obj)
498 return true;
499 if (!super.equals(obj))
500 return false;
501 if (!(obj instanceof KeyphraseSoundModel))
502 return false;
503 KeyphraseSoundModel other = (KeyphraseSoundModel) obj;
504 if (!Arrays.equals(keyphrases, other.keyphrases))
505 return false;
506 return true;
507 }
Eric Laurente48188c2014-04-18 17:44:11 -0700508 }
509
Arunesh Mishraa772e5f2016-01-25 10:33:11 -0800510
511 /*****************************************************************************
512 * A GenericSoundModel is a specialized {@link SoundModel} for non-voice sound
513 * patterns.
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800514 *
515 * @hide
Arunesh Mishraa772e5f2016-01-25 10:33:11 -0800516 ****************************************************************************/
517 public static class GenericSoundModel extends SoundModel implements Parcelable {
518
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700519 public static final @android.annotation.NonNull Parcelable.Creator<GenericSoundModel> CREATOR
Arunesh Mishraa772e5f2016-01-25 10:33:11 -0800520 = new Parcelable.Creator<GenericSoundModel>() {
521 public GenericSoundModel createFromParcel(Parcel in) {
522 return GenericSoundModel.fromParcel(in);
523 }
524
525 public GenericSoundModel[] newArray(int size) {
526 return new GenericSoundModel[size];
527 }
528 };
529
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100530 @UnsupportedAppUsage
Arunesh Mishraa772e5f2016-01-25 10:33:11 -0800531 public GenericSoundModel(UUID uuid, UUID vendorUuid, byte[] data) {
532 super(uuid, vendorUuid, TYPE_GENERIC_SOUND, data);
533 }
534
535 @Override
536 public int describeContents() {
537 return 0;
538 }
539
540 private static GenericSoundModel fromParcel(Parcel in) {
541 UUID uuid = UUID.fromString(in.readString());
542 UUID vendorUuid = null;
543 int length = in.readInt();
544 if (length >= 0) {
545 vendorUuid = UUID.fromString(in.readString());
546 }
547 byte[] data = in.readBlob();
548 return new GenericSoundModel(uuid, vendorUuid, data);
549 }
550
551 @Override
552 public void writeToParcel(Parcel dest, int flags) {
553 dest.writeString(uuid.toString());
554 if (vendorUuid == null) {
555 dest.writeInt(-1);
556 } else {
557 dest.writeInt(vendorUuid.toString().length());
558 dest.writeString(vendorUuid.toString());
559 }
560 dest.writeBlob(data);
561 }
562
563 @Override
564 public String toString() {
565 return "GenericSoundModel [uuid=" + uuid + ", vendorUuid=" + vendorUuid
566 + ", type=" + type + ", data=" + (data == null ? 0 : data.length) + "]";
567 }
568 }
569
Eric Laurente48188c2014-04-18 17:44:11 -0700570 /**
571 * Modes for key phrase recognition
572 */
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800573
574 /**
575 * Simple recognition of the key phrase
576 *
577 * @hide
578 */
Eric Laurente48188c2014-04-18 17:44:11 -0700579 public static final int RECOGNITION_MODE_VOICE_TRIGGER = 0x1;
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800580 /**
581 * Trigger only if one user is identified
582 *
583 * @hide
584 */
Eric Laurente48188c2014-04-18 17:44:11 -0700585 public static final int RECOGNITION_MODE_USER_IDENTIFICATION = 0x2;
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800586 /**
587 * Trigger only if one user is authenticated
588 *
589 * @hide
590 */
Eric Laurente48188c2014-04-18 17:44:11 -0700591 public static final int RECOGNITION_MODE_USER_AUTHENTICATION = 0x4;
592
593 /**
594 * Status codes for {@link RecognitionEvent}
595 */
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800596 /**
597 * Recognition success
598 *
599 * @hide
600 */
Eric Laurente48188c2014-04-18 17:44:11 -0700601 public static final int RECOGNITION_STATUS_SUCCESS = 0;
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800602 /**
603 * Recognition aborted (e.g. capture preempted by anotehr use case
604 *
605 * @hide
606 */
Eric Laurente48188c2014-04-18 17:44:11 -0700607 public static final int RECOGNITION_STATUS_ABORT = 1;
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800608 /**
609 * Recognition failure
610 *
611 * @hide
612 */
Eric Laurente48188c2014-04-18 17:44:11 -0700613 public static final int RECOGNITION_STATUS_FAILURE = 2;
mike dooleyb2ab04a2018-11-07 15:48:54 +0100614 /**
615 * Recognition event was triggered by a getModelState request, not by the
616 * DSP.
617 *
618 * @hide
619 */
620 public static final int RECOGNITION_STATUS_GET_STATE_RESPONSE = 3;
Eric Laurente48188c2014-04-18 17:44:11 -0700621
622 /**
623 * A RecognitionEvent is provided by the
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800624 * {@code StatusListener#onRecognition(RecognitionEvent)}
Eric Laurente48188c2014-04-18 17:44:11 -0700625 * callback upon recognition success or failure.
626 */
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800627 public static class RecognitionEvent {
628 /**
629 * Recognition status e.g RECOGNITION_STATUS_SUCCESS
630 *
631 * @hide
632 */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100633 @UnsupportedAppUsage
Eric Laurente48188c2014-04-18 17:44:11 -0700634 public final int status;
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800635 /**
636 *
637 * Sound Model corresponding to this event callback
638 *
639 * @hide
640 */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100641 @UnsupportedAppUsage
Eric Laurente48188c2014-04-18 17:44:11 -0700642 public final int soundModelHandle;
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800643 /**
644 * True if it is possible to capture audio from this utterance buffered by the hardware
645 *
646 * @hide
647 */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100648 @UnsupportedAppUsage
Eric Laurente48188c2014-04-18 17:44:11 -0700649 public final boolean captureAvailable;
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800650 /**
651 * Audio session ID to be used when capturing the utterance with an AudioRecord
652 * if captureAvailable() is true.
653 *
654 * @hide
655 */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100656 @UnsupportedAppUsage
Eric Laurente48188c2014-04-18 17:44:11 -0700657 public final int captureSession;
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800658 /**
659 * Delay in ms between end of model detection and start of audio available for capture.
660 * A negative value is possible (e.g. if keyphrase is also available for capture)
661 *
662 * @hide
663 */
Eric Laurente48188c2014-04-18 17:44:11 -0700664 public final int captureDelayMs;
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800665 /**
666 * Duration in ms of audio captured before the start of the trigger. 0 if none.
667 *
668 * @hide
669 */
Eric Laurent013f66b2014-07-06 16:35:00 -0700670 public final int capturePreambleMs;
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800671 /**
672 * True if the trigger (key phrase capture is present in binary data
673 *
674 * @hide
675 */
Eric Laurentd3b82232014-07-30 08:57:39 -0700676 public final boolean triggerInData;
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800677 /**
678 * Audio format of either the trigger in event data or to use for capture of the
679 * rest of the utterance
680 *
681 * @hide
682 */
683 public final AudioFormat captureFormat;
684 /**
685 * Opaque data for use by system applications who know about voice engine internals,
686 * typically during enrollment.
687 *
688 * @hide
689 */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100690 @UnsupportedAppUsage
Eric Laurente48188c2014-04-18 17:44:11 -0700691 public final byte[] data;
692
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800693 /** @hide */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100694 @UnsupportedAppUsage
Sandeep Siddhartha39c12fa2014-07-25 18:37:29 -0700695 public RecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
Eric Laurentd3b82232014-07-30 08:57:39 -0700696 int captureSession, int captureDelayMs, int capturePreambleMs,
697 boolean triggerInData, AudioFormat captureFormat, byte[] data) {
Eric Laurente48188c2014-04-18 17:44:11 -0700698 this.status = status;
699 this.soundModelHandle = soundModelHandle;
700 this.captureAvailable = captureAvailable;
701 this.captureSession = captureSession;
702 this.captureDelayMs = captureDelayMs;
Eric Laurent013f66b2014-07-06 16:35:00 -0700703 this.capturePreambleMs = capturePreambleMs;
Eric Laurentd3b82232014-07-30 08:57:39 -0700704 this.triggerInData = triggerInData;
705 this.captureFormat = captureFormat;
Eric Laurente48188c2014-04-18 17:44:11 -0700706 this.data = data;
707 }
Sandeep Siddhartha39c12fa2014-07-25 18:37:29 -0700708
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800709 /**
710 * Check if is possible to capture audio from this utterance buffered by the hardware.
711 *
712 * @return {@code true} iff a capturing is possible
713 */
714 public boolean isCaptureAvailable() {
715 return captureAvailable;
716 }
717
718 /**
719 * Get the audio format of either the trigger in event data or to use for capture of the
720 * rest of the utterance
721 *
722 * @return the audio format
723 */
724 @Nullable public AudioFormat getCaptureFormat() {
725 return captureFormat;
726 }
727
728 /**
729 * Get Audio session ID to be used when capturing the utterance with an {@link AudioRecord}
730 * if {@link #isCaptureAvailable()} is true.
731 *
732 * @return The id of the capture session
733 */
734 public int getCaptureSession() {
735 return captureSession;
736 }
737
738 /**
739 * Get the opaque data for use by system applications who know about voice engine
740 * internals, typically during enrollment.
741 *
742 * @return The data of the event
743 */
744 public byte[] getData() {
745 return data;
746 }
747
748 /** @hide */
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700749 public static final @android.annotation.NonNull Parcelable.Creator<RecognitionEvent> CREATOR
Sandeep Siddhartha39c12fa2014-07-25 18:37:29 -0700750 = new Parcelable.Creator<RecognitionEvent>() {
751 public RecognitionEvent createFromParcel(Parcel in) {
752 return RecognitionEvent.fromParcel(in);
753 }
754
755 public RecognitionEvent[] newArray(int size) {
756 return new RecognitionEvent[size];
757 }
758 };
759
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800760 /** @hide */
Arunesh Mishraf47f1732016-02-18 16:16:12 -0800761 protected static RecognitionEvent fromParcel(Parcel in) {
Sandeep Siddhartha39c12fa2014-07-25 18:37:29 -0700762 int status = in.readInt();
763 int soundModelHandle = in.readInt();
764 boolean captureAvailable = in.readByte() == 1;
765 int captureSession = in.readInt();
766 int captureDelayMs = in.readInt();
767 int capturePreambleMs = in.readInt();
Eric Laurentd3b82232014-07-30 08:57:39 -0700768 boolean triggerInData = in.readByte() == 1;
769 AudioFormat captureFormat = null;
Eric Laurent39fcca02014-09-05 16:44:19 -0700770 if (in.readByte() == 1) {
Eric Laurentd3b82232014-07-30 08:57:39 -0700771 int sampleRate = in.readInt();
772 int encoding = in.readInt();
773 int channelMask = in.readInt();
774 captureFormat = (new AudioFormat.Builder())
775 .setChannelMask(channelMask)
776 .setEncoding(encoding)
777 .setSampleRate(sampleRate)
778 .build();
779 }
Sandeep Siddhartha39c12fa2014-07-25 18:37:29 -0700780 byte[] data = in.readBlob();
781 return new RecognitionEvent(status, soundModelHandle, captureAvailable, captureSession,
Eric Laurentd3b82232014-07-30 08:57:39 -0700782 captureDelayMs, capturePreambleMs, triggerInData, captureFormat, data);
Sandeep Siddhartha39c12fa2014-07-25 18:37:29 -0700783 }
784
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800785 /** @hide */
Sandeep Siddhartha39c12fa2014-07-25 18:37:29 -0700786 public int describeContents() {
787 return 0;
788 }
789
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800790 /** @hide */
Sandeep Siddhartha39c12fa2014-07-25 18:37:29 -0700791 public void writeToParcel(Parcel dest, int flags) {
792 dest.writeInt(status);
793 dest.writeInt(soundModelHandle);
794 dest.writeByte((byte) (captureAvailable ? 1 : 0));
795 dest.writeInt(captureSession);
796 dest.writeInt(captureDelayMs);
797 dest.writeInt(capturePreambleMs);
Eric Laurent39fcca02014-09-05 16:44:19 -0700798 dest.writeByte((byte) (triggerInData ? 1 : 0));
799 if (captureFormat != null) {
Eric Laurentd3b82232014-07-30 08:57:39 -0700800 dest.writeByte((byte)1);
801 dest.writeInt(captureFormat.getSampleRate());
802 dest.writeInt(captureFormat.getEncoding());
803 dest.writeInt(captureFormat.getChannelMask());
804 } else {
805 dest.writeByte((byte)0);
806 }
Sandeep Siddhartha39c12fa2014-07-25 18:37:29 -0700807 dest.writeBlob(data);
808 }
809
810 @Override
811 public int hashCode() {
812 final int prime = 31;
813 int result = 1;
814 result = prime * result + (captureAvailable ? 1231 : 1237);
815 result = prime * result + captureDelayMs;
816 result = prime * result + capturePreambleMs;
817 result = prime * result + captureSession;
Eric Laurentd3b82232014-07-30 08:57:39 -0700818 result = prime * result + (triggerInData ? 1231 : 1237);
819 if (captureFormat != null) {
820 result = prime * result + captureFormat.getSampleRate();
821 result = prime * result + captureFormat.getEncoding();
822 result = prime * result + captureFormat.getChannelMask();
823 }
Sandeep Siddhartha39c12fa2014-07-25 18:37:29 -0700824 result = prime * result + Arrays.hashCode(data);
825 result = prime * result + soundModelHandle;
826 result = prime * result + status;
827 return result;
828 }
829
830 @Override
831 public boolean equals(Object obj) {
832 if (this == obj)
833 return true;
834 if (obj == null)
835 return false;
836 if (getClass() != obj.getClass())
837 return false;
838 RecognitionEvent other = (RecognitionEvent) obj;
839 if (captureAvailable != other.captureAvailable)
840 return false;
841 if (captureDelayMs != other.captureDelayMs)
842 return false;
843 if (capturePreambleMs != other.capturePreambleMs)
844 return false;
845 if (captureSession != other.captureSession)
846 return false;
847 if (!Arrays.equals(data, other.data))
848 return false;
849 if (soundModelHandle != other.soundModelHandle)
850 return false;
851 if (status != other.status)
852 return false;
Eric Laurentd3b82232014-07-30 08:57:39 -0700853 if (triggerInData != other.triggerInData)
854 return false;
Ryan Bavettaea04e8f2016-03-02 18:34:50 -0800855 if (captureFormat == null) {
856 if (other.captureFormat != null)
857 return false;
858 } else {
859 if (other.captureFormat == null)
860 return false;
861 if (captureFormat.getSampleRate() != other.captureFormat.getSampleRate())
862 return false;
863 if (captureFormat.getEncoding() != other.captureFormat.getEncoding())
864 return false;
865 if (captureFormat.getChannelMask() != other.captureFormat.getChannelMask())
866 return false;
867 }
Sandeep Siddhartha39c12fa2014-07-25 18:37:29 -0700868 return true;
869 }
Sandeep Siddhartha68173372014-07-28 13:25:30 -0700870
871 @Override
872 public String toString() {
873 return "RecognitionEvent [status=" + status + ", soundModelHandle=" + soundModelHandle
874 + ", captureAvailable=" + captureAvailable + ", captureSession="
875 + captureSession + ", captureDelayMs=" + captureDelayMs
876 + ", capturePreambleMs=" + capturePreambleMs
Eric Laurentd3b82232014-07-30 08:57:39 -0700877 + ", triggerInData=" + triggerInData
878 + ((captureFormat == null) ? "" :
879 (", sampleRate=" + captureFormat.getSampleRate()))
880 + ((captureFormat == null) ? "" :
881 (", encoding=" + captureFormat.getEncoding()))
882 + ((captureFormat == null) ? "" :
883 (", channelMask=" + captureFormat.getChannelMask()))
Sandeep Siddhartha68173372014-07-28 13:25:30 -0700884 + ", data=" + (data == null ? 0 : data.length) + "]";
885 }
Eric Laurente48188c2014-04-18 17:44:11 -0700886 }
887
888 /**
Eric Laurent013f66b2014-07-06 16:35:00 -0700889 * A RecognitionConfig is provided to
890 * {@link SoundTriggerModule#startRecognition(int, RecognitionConfig)} to configure the
891 * recognition request.
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800892 *
893 * @hide
Eric Laurent013f66b2014-07-06 16:35:00 -0700894 */
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700895 public static class RecognitionConfig implements Parcelable {
Eric Laurent013f66b2014-07-06 16:35:00 -0700896 /** True if the DSP should capture the trigger sound and make it available for further
897 * capture. */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100898 @UnsupportedAppUsage
Eric Laurent013f66b2014-07-06 16:35:00 -0700899 public final boolean captureRequested;
Sandeep Siddhartha2c0273e2014-08-01 11:32:03 -0700900 /**
901 * True if the service should restart listening after the DSP triggers.
902 * Note: This config flag is currently used at the service layer rather than by the DSP.
903 */
904 public final boolean allowMultipleTriggers;
Eric Laurent013f66b2014-07-06 16:35:00 -0700905 /** List of all keyphrases in the sound model for which recognition should be performed with
906 * options for each keyphrase. */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100907 @UnsupportedAppUsage
Eric Laurent013f66b2014-07-06 16:35:00 -0700908 public final KeyphraseRecognitionExtra keyphrases[];
909 /** Opaque data for use by system applications who know about voice engine internals,
910 * typically during enrollment. */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100911 @UnsupportedAppUsage
Eric Laurent013f66b2014-07-06 16:35:00 -0700912 public final byte[] data;
913
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100914 @UnsupportedAppUsage
Sandeep Siddhartha2c0273e2014-08-01 11:32:03 -0700915 public RecognitionConfig(boolean captureRequested, boolean allowMultipleTriggers,
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800916 KeyphraseRecognitionExtra[] keyphrases, byte[] data) {
Eric Laurent013f66b2014-07-06 16:35:00 -0700917 this.captureRequested = captureRequested;
Sandeep Siddhartha2c0273e2014-08-01 11:32:03 -0700918 this.allowMultipleTriggers = allowMultipleTriggers;
Eric Laurent013f66b2014-07-06 16:35:00 -0700919 this.keyphrases = keyphrases;
920 this.data = data;
921 }
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700922
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700923 public static final @android.annotation.NonNull Parcelable.Creator<RecognitionConfig> CREATOR
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700924 = new Parcelable.Creator<RecognitionConfig>() {
925 public RecognitionConfig createFromParcel(Parcel in) {
926 return RecognitionConfig.fromParcel(in);
927 }
928
929 public RecognitionConfig[] newArray(int size) {
930 return new RecognitionConfig[size];
931 }
932 };
933
934 private static RecognitionConfig fromParcel(Parcel in) {
935 boolean captureRequested = in.readByte() == 1;
Sandeep Siddhartha2c0273e2014-08-01 11:32:03 -0700936 boolean allowMultipleTriggers = in.readByte() == 1;
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700937 KeyphraseRecognitionExtra[] keyphrases =
938 in.createTypedArray(KeyphraseRecognitionExtra.CREATOR);
Sandeep Siddhartha39c12fa2014-07-25 18:37:29 -0700939 byte[] data = in.readBlob();
Sandeep Siddhartha2c0273e2014-08-01 11:32:03 -0700940 return new RecognitionConfig(captureRequested, allowMultipleTriggers, keyphrases, data);
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700941 }
942
943 @Override
944 public void writeToParcel(Parcel dest, int flags) {
945 dest.writeByte((byte) (captureRequested ? 1 : 0));
Sandeep Siddhartha2c0273e2014-08-01 11:32:03 -0700946 dest.writeByte((byte) (allowMultipleTriggers ? 1 : 0));
Sandeep Siddhartha68173372014-07-28 13:25:30 -0700947 dest.writeTypedArray(keyphrases, flags);
Sandeep Siddhartha39c12fa2014-07-25 18:37:29 -0700948 dest.writeBlob(data);
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700949 }
950
951 @Override
952 public int describeContents() {
953 return 0;
954 }
Sandeep Siddhartha110f5692014-07-20 12:22:56 -0700955
956 @Override
957 public String toString() {
Sandeep Siddhartha2c0273e2014-08-01 11:32:03 -0700958 return "RecognitionConfig [captureRequested=" + captureRequested
959 + ", allowMultipleTriggers=" + allowMultipleTriggers + ", keyphrases="
960 + Arrays.toString(keyphrases) + ", data=" + Arrays.toString(data) + "]";
Sandeep Siddhartha110f5692014-07-20 12:22:56 -0700961 }
Eric Laurent013f66b2014-07-06 16:35:00 -0700962 }
963
964 /**
965 * Confidence level for users defined in a keyphrase.
966 * - The confidence level is expressed in percent (0% -100%).
967 * When used in a {@link KeyphraseRecognitionEvent} it indicates the detected confidence level
968 * When used in a {@link RecognitionConfig} it indicates the minimum confidence level that
969 * should trigger a recognition.
970 * - The user ID is derived from the system ID {@link android.os.UserHandle#getIdentifier()}.
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -0800971 *
972 * @hide
Eric Laurent013f66b2014-07-06 16:35:00 -0700973 */
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700974 public static class ConfidenceLevel implements Parcelable {
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100975 @UnsupportedAppUsage
Eric Laurent013f66b2014-07-06 16:35:00 -0700976 public final int userId;
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100977 @UnsupportedAppUsage
Eric Laurent013f66b2014-07-06 16:35:00 -0700978 public final int confidenceLevel;
979
Mathew Inwoodbcbe4402018-08-08 15:42:59 +0100980 @UnsupportedAppUsage
Eric Laurent013f66b2014-07-06 16:35:00 -0700981 public ConfidenceLevel(int userId, int confidenceLevel) {
982 this.userId = userId;
983 this.confidenceLevel = confidenceLevel;
984 }
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700985
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700986 public static final @android.annotation.NonNull Parcelable.Creator<ConfidenceLevel> CREATOR
Sandeep Siddhartha05589722014-07-17 16:21:54 -0700987 = new Parcelable.Creator<ConfidenceLevel>() {
988 public ConfidenceLevel createFromParcel(Parcel in) {
989 return ConfidenceLevel.fromParcel(in);
990 }
991
992 public ConfidenceLevel[] newArray(int size) {
993 return new ConfidenceLevel[size];
994 }
995 };
996
997 private static ConfidenceLevel fromParcel(Parcel in) {
998 int userId = in.readInt();
999 int confidenceLevel = in.readInt();
1000 return new ConfidenceLevel(userId, confidenceLevel);
1001 }
1002
1003 @Override
1004 public void writeToParcel(Parcel dest, int flags) {
1005 dest.writeInt(userId);
1006 dest.writeInt(confidenceLevel);
1007 }
1008
1009 @Override
1010 public int describeContents() {
1011 return 0;
1012 }
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001013
1014 @Override
1015 public int hashCode() {
1016 final int prime = 31;
1017 int result = 1;
1018 result = prime * result + confidenceLevel;
1019 result = prime * result + userId;
1020 return result;
1021 }
1022
1023 @Override
1024 public boolean equals(Object obj) {
1025 if (this == obj)
1026 return true;
1027 if (obj == null)
1028 return false;
1029 if (getClass() != obj.getClass())
1030 return false;
1031 ConfidenceLevel other = (ConfidenceLevel) obj;
1032 if (confidenceLevel != other.confidenceLevel)
1033 return false;
1034 if (userId != other.userId)
1035 return false;
1036 return true;
1037 }
1038
1039 @Override
1040 public String toString() {
1041 return "ConfidenceLevel [userId=" + userId
1042 + ", confidenceLevel=" + confidenceLevel + "]";
1043 }
Eric Laurent013f66b2014-07-06 16:35:00 -07001044 }
1045
1046 /**
Sandeep Siddharthad4233c62014-06-12 18:31:19 -07001047 * Additional data conveyed by a {@link KeyphraseRecognitionEvent}
Eric Laurente48188c2014-04-18 17:44:11 -07001048 * for a key phrase detection.
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -08001049 *
1050 * @hide
Eric Laurente48188c2014-04-18 17:44:11 -07001051 */
Sandeep Siddhartha05589722014-07-17 16:21:54 -07001052 public static class KeyphraseRecognitionExtra implements Parcelable {
1053 /** The keyphrase ID */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +01001054 @UnsupportedAppUsage
Eric Laurent013f66b2014-07-06 16:35:00 -07001055 public final int id;
Eric Laurente48188c2014-04-18 17:44:11 -07001056
1057 /** Recognition modes matched for this event */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +01001058 @UnsupportedAppUsage
Eric Laurente48188c2014-04-18 17:44:11 -07001059 public final int recognitionModes;
1060
Eric Laurentd3b82232014-07-30 08:57:39 -07001061 /** Confidence level for mode RECOGNITION_MODE_VOICE_TRIGGER when user identification
1062 * is not performed */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +01001063 @UnsupportedAppUsage
Eric Laurentd3b82232014-07-30 08:57:39 -07001064 public final int coarseConfidenceLevel;
1065
Eric Laurent013f66b2014-07-06 16:35:00 -07001066 /** Confidence levels for all users recognized (KeyphraseRecognitionEvent) or to
1067 * be recognized (RecognitionConfig) */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +01001068 @UnsupportedAppUsage
Eric Laurent013f66b2014-07-06 16:35:00 -07001069 public final ConfidenceLevel[] confidenceLevels;
1070
Mathew Inwoodbcbe4402018-08-08 15:42:59 +01001071 @UnsupportedAppUsage
Eric Laurentd3b82232014-07-30 08:57:39 -07001072 public KeyphraseRecognitionExtra(int id, int recognitionModes, int coarseConfidenceLevel,
1073 ConfidenceLevel[] confidenceLevels) {
Eric Laurent013f66b2014-07-06 16:35:00 -07001074 this.id = id;
Eric Laurente48188c2014-04-18 17:44:11 -07001075 this.recognitionModes = recognitionModes;
Eric Laurentd3b82232014-07-30 08:57:39 -07001076 this.coarseConfidenceLevel = coarseConfidenceLevel;
Eric Laurent013f66b2014-07-06 16:35:00 -07001077 this.confidenceLevels = confidenceLevels;
Eric Laurente48188c2014-04-18 17:44:11 -07001078 }
Sandeep Siddhartha05589722014-07-17 16:21:54 -07001079
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07001080 public static final @android.annotation.NonNull Parcelable.Creator<KeyphraseRecognitionExtra> CREATOR
Sandeep Siddhartha05589722014-07-17 16:21:54 -07001081 = new Parcelable.Creator<KeyphraseRecognitionExtra>() {
1082 public KeyphraseRecognitionExtra createFromParcel(Parcel in) {
1083 return KeyphraseRecognitionExtra.fromParcel(in);
1084 }
1085
1086 public KeyphraseRecognitionExtra[] newArray(int size) {
1087 return new KeyphraseRecognitionExtra[size];
1088 }
1089 };
1090
1091 private static KeyphraseRecognitionExtra fromParcel(Parcel in) {
1092 int id = in.readInt();
1093 int recognitionModes = in.readInt();
Eric Laurentd3b82232014-07-30 08:57:39 -07001094 int coarseConfidenceLevel = in.readInt();
Sandeep Siddhartha05589722014-07-17 16:21:54 -07001095 ConfidenceLevel[] confidenceLevels = in.createTypedArray(ConfidenceLevel.CREATOR);
Eric Laurentd3b82232014-07-30 08:57:39 -07001096 return new KeyphraseRecognitionExtra(id, recognitionModes, coarseConfidenceLevel,
1097 confidenceLevels);
Sandeep Siddhartha05589722014-07-17 16:21:54 -07001098 }
1099
1100 @Override
1101 public void writeToParcel(Parcel dest, int flags) {
1102 dest.writeInt(id);
1103 dest.writeInt(recognitionModes);
Eric Laurentd3b82232014-07-30 08:57:39 -07001104 dest.writeInt(coarseConfidenceLevel);
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001105 dest.writeTypedArray(confidenceLevels, flags);
Sandeep Siddhartha05589722014-07-17 16:21:54 -07001106 }
1107
1108 @Override
1109 public int describeContents() {
1110 return 0;
1111 }
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001112
1113 @Override
1114 public int hashCode() {
1115 final int prime = 31;
1116 int result = 1;
1117 result = prime * result + Arrays.hashCode(confidenceLevels);
1118 result = prime * result + id;
1119 result = prime * result + recognitionModes;
Eric Laurentd3b82232014-07-30 08:57:39 -07001120 result = prime * result + coarseConfidenceLevel;
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001121 return result;
1122 }
1123
1124 @Override
1125 public boolean equals(Object obj) {
1126 if (this == obj)
1127 return true;
1128 if (obj == null)
1129 return false;
1130 if (getClass() != obj.getClass())
1131 return false;
1132 KeyphraseRecognitionExtra other = (KeyphraseRecognitionExtra) obj;
1133 if (!Arrays.equals(confidenceLevels, other.confidenceLevels))
1134 return false;
1135 if (id != other.id)
1136 return false;
1137 if (recognitionModes != other.recognitionModes)
1138 return false;
Eric Laurentd3b82232014-07-30 08:57:39 -07001139 if (coarseConfidenceLevel != other.coarseConfidenceLevel)
1140 return false;
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001141 return true;
1142 }
1143
1144 @Override
1145 public String toString() {
1146 return "KeyphraseRecognitionExtra [id=" + id + ", recognitionModes=" + recognitionModes
Eric Laurentd3b82232014-07-30 08:57:39 -07001147 + ", coarseConfidenceLevel=" + coarseConfidenceLevel
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001148 + ", confidenceLevels=" + Arrays.toString(confidenceLevels) + "]";
1149 }
Eric Laurente48188c2014-04-18 17:44:11 -07001150 }
1151
1152 /**
1153 * Specialized {@link RecognitionEvent} for a key phrase detection.
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -08001154 *
1155 * @hide
Eric Laurente48188c2014-04-18 17:44:11 -07001156 */
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -08001157 public static class KeyphraseRecognitionEvent extends RecognitionEvent implements Parcelable {
Eric Laurente48188c2014-04-18 17:44:11 -07001158 /** Indicates if the key phrase is present in the buffered audio available for capture */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +01001159 @UnsupportedAppUsage
Sandeep Siddharthad4233c62014-06-12 18:31:19 -07001160 public final KeyphraseRecognitionExtra[] keyphraseExtras;
Eric Laurente48188c2014-04-18 17:44:11 -07001161
Mathew Inwoodbcbe4402018-08-08 15:42:59 +01001162 @UnsupportedAppUsage
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001163 public KeyphraseRecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
Eric Laurentd3b82232014-07-30 08:57:39 -07001164 int captureSession, int captureDelayMs, int capturePreambleMs,
1165 boolean triggerInData, AudioFormat captureFormat, byte[] data,
1166 KeyphraseRecognitionExtra[] keyphraseExtras) {
Eric Laurent013f66b2014-07-06 16:35:00 -07001167 super(status, soundModelHandle, captureAvailable, captureSession, captureDelayMs,
Eric Laurentd3b82232014-07-30 08:57:39 -07001168 capturePreambleMs, triggerInData, captureFormat, data);
Sandeep Siddharthad4233c62014-06-12 18:31:19 -07001169 this.keyphraseExtras = keyphraseExtras;
Eric Laurente48188c2014-04-18 17:44:11 -07001170 }
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001171
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07001172 public static final @android.annotation.NonNull Parcelable.Creator<KeyphraseRecognitionEvent> CREATOR
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001173 = new Parcelable.Creator<KeyphraseRecognitionEvent>() {
1174 public KeyphraseRecognitionEvent createFromParcel(Parcel in) {
Arunesh Mishraf47f1732016-02-18 16:16:12 -08001175 return KeyphraseRecognitionEvent.fromParcelForKeyphrase(in);
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001176 }
1177
1178 public KeyphraseRecognitionEvent[] newArray(int size) {
1179 return new KeyphraseRecognitionEvent[size];
1180 }
1181 };
1182
Arunesh Mishraf47f1732016-02-18 16:16:12 -08001183 private static KeyphraseRecognitionEvent fromParcelForKeyphrase(Parcel in) {
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001184 int status = in.readInt();
1185 int soundModelHandle = in.readInt();
1186 boolean captureAvailable = in.readByte() == 1;
1187 int captureSession = in.readInt();
1188 int captureDelayMs = in.readInt();
1189 int capturePreambleMs = in.readInt();
Eric Laurentd3b82232014-07-30 08:57:39 -07001190 boolean triggerInData = in.readByte() == 1;
1191 AudioFormat captureFormat = null;
Eric Laurent75b433f2014-09-12 15:45:47 -07001192 if (in.readByte() == 1) {
Eric Laurentd3b82232014-07-30 08:57:39 -07001193 int sampleRate = in.readInt();
1194 int encoding = in.readInt();
1195 int channelMask = in.readInt();
1196 captureFormat = (new AudioFormat.Builder())
Ryan Bavettaea04e8f2016-03-02 18:34:50 -08001197 .setChannelMask(channelMask)
1198 .setEncoding(encoding)
1199 .setSampleRate(sampleRate)
1200 .build();
Eric Laurentd3b82232014-07-30 08:57:39 -07001201 }
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001202 byte[] data = in.readBlob();
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001203 KeyphraseRecognitionExtra[] keyphraseExtras =
1204 in.createTypedArray(KeyphraseRecognitionExtra.CREATOR);
1205 return new KeyphraseRecognitionEvent(status, soundModelHandle, captureAvailable,
Eric Laurentd3b82232014-07-30 08:57:39 -07001206 captureSession, captureDelayMs, capturePreambleMs, triggerInData,
1207 captureFormat, data, keyphraseExtras);
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001208 }
1209
1210 @Override
1211 public void writeToParcel(Parcel dest, int flags) {
1212 dest.writeInt(status);
1213 dest.writeInt(soundModelHandle);
1214 dest.writeByte((byte) (captureAvailable ? 1 : 0));
1215 dest.writeInt(captureSession);
1216 dest.writeInt(captureDelayMs);
1217 dest.writeInt(capturePreambleMs);
Eric Laurent75b433f2014-09-12 15:45:47 -07001218 dest.writeByte((byte) (triggerInData ? 1 : 0));
1219 if (captureFormat != null) {
Eric Laurentd3b82232014-07-30 08:57:39 -07001220 dest.writeByte((byte)1);
1221 dest.writeInt(captureFormat.getSampleRate());
1222 dest.writeInt(captureFormat.getEncoding());
1223 dest.writeInt(captureFormat.getChannelMask());
1224 } else {
1225 dest.writeByte((byte)0);
1226 }
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001227 dest.writeBlob(data);
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001228 dest.writeTypedArray(keyphraseExtras, flags);
1229 }
1230
1231 @Override
1232 public int describeContents() {
1233 return 0;
1234 }
1235
1236 @Override
1237 public int hashCode() {
1238 final int prime = 31;
1239 int result = super.hashCode();
1240 result = prime * result + Arrays.hashCode(keyphraseExtras);
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001241 return result;
1242 }
1243
1244 @Override
1245 public boolean equals(Object obj) {
1246 if (this == obj)
1247 return true;
1248 if (!super.equals(obj))
1249 return false;
1250 if (getClass() != obj.getClass())
1251 return false;
1252 KeyphraseRecognitionEvent other = (KeyphraseRecognitionEvent) obj;
1253 if (!Arrays.equals(keyphraseExtras, other.keyphraseExtras))
1254 return false;
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001255 return true;
1256 }
1257
1258 @Override
1259 public String toString() {
1260 return "KeyphraseRecognitionEvent [keyphraseExtras=" + Arrays.toString(keyphraseExtras)
Eric Laurentd3b82232014-07-30 08:57:39 -07001261 + ", status=" + status
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001262 + ", soundModelHandle=" + soundModelHandle + ", captureAvailable="
1263 + captureAvailable + ", captureSession=" + captureSession + ", captureDelayMs="
1264 + captureDelayMs + ", capturePreambleMs=" + capturePreambleMs
Eric Laurentd3b82232014-07-30 08:57:39 -07001265 + ", triggerInData=" + triggerInData
1266 + ((captureFormat == null) ? "" :
1267 (", sampleRate=" + captureFormat.getSampleRate()))
1268 + ((captureFormat == null) ? "" :
1269 (", encoding=" + captureFormat.getEncoding()))
1270 + ((captureFormat == null) ? "" :
1271 (", channelMask=" + captureFormat.getChannelMask()))
Sandeep Siddhartha68173372014-07-28 13:25:30 -07001272 + ", data=" + (data == null ? 0 : data.length) + "]";
1273 }
Eric Laurente48188c2014-04-18 17:44:11 -07001274 }
1275
1276 /**
Arunesh Mishraa772e5f2016-01-25 10:33:11 -08001277 * Sub-class of RecognitionEvent specifically for sound-trigger based sound
1278 * models(non-keyphrase). Currently does not contain any additional fields.
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -08001279 *
1280 * @hide
Arunesh Mishraa772e5f2016-01-25 10:33:11 -08001281 */
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -08001282 public static class GenericRecognitionEvent extends RecognitionEvent implements Parcelable {
Mathew Inwoodbcbe4402018-08-08 15:42:59 +01001283 @UnsupportedAppUsage
Arunesh Mishraa772e5f2016-01-25 10:33:11 -08001284 public GenericRecognitionEvent(int status, int soundModelHandle,
1285 boolean captureAvailable, int captureSession, int captureDelayMs,
1286 int capturePreambleMs, boolean triggerInData, AudioFormat captureFormat,
1287 byte[] data) {
1288 super(status, soundModelHandle, captureAvailable, captureSession,
1289 captureDelayMs, capturePreambleMs, triggerInData, captureFormat,
1290 data);
1291 }
Arunesh Mishraf47f1732016-02-18 16:16:12 -08001292
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07001293 public static final @android.annotation.NonNull Parcelable.Creator<GenericRecognitionEvent> CREATOR
Arunesh Mishraf47f1732016-02-18 16:16:12 -08001294 = new Parcelable.Creator<GenericRecognitionEvent>() {
1295 public GenericRecognitionEvent createFromParcel(Parcel in) {
1296 return GenericRecognitionEvent.fromParcelForGeneric(in);
1297 }
1298
1299 public GenericRecognitionEvent[] newArray(int size) {
1300 return new GenericRecognitionEvent[size];
1301 }
1302 };
1303
1304 private static GenericRecognitionEvent fromParcelForGeneric(Parcel in) {
1305 RecognitionEvent event = RecognitionEvent.fromParcel(in);
1306 return new GenericRecognitionEvent(event.status, event.soundModelHandle,
1307 event.captureAvailable, event.captureSession, event.captureDelayMs,
1308 event.capturePreambleMs, event.triggerInData, event.captureFormat, event.data);
1309 }
1310
1311 @Override
1312 public boolean equals(Object obj) {
1313 if (this == obj)
1314 return true;
1315 if (obj == null)
1316 return false;
1317 if (getClass() != obj.getClass()) return false;
1318 RecognitionEvent other = (RecognitionEvent) obj;
1319 return super.equals(obj);
1320 }
1321
1322 @Override
1323 public String toString() {
1324 return "GenericRecognitionEvent ::" + super.toString();
1325 }
Arunesh Mishraa772e5f2016-01-25 10:33:11 -08001326 }
1327
1328 /**
Eric Laurentd3b82232014-07-30 08:57:39 -07001329 * Status codes for {@link SoundModelEvent}
1330 */
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -08001331 /**
1332 * Sound Model was updated
1333 *
1334 * @hide
1335 */
Eric Laurentd3b82232014-07-30 08:57:39 -07001336 public static final int SOUNDMODEL_STATUS_UPDATED = 0;
1337
1338 /**
1339 * A SoundModelEvent is provided by the
1340 * {@link StatusListener#onSoundModelUpdate(SoundModelEvent)}
1341 * callback when a sound model has been updated by the implementation
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -08001342 *
1343 * @hide
Eric Laurentd3b82232014-07-30 08:57:39 -07001344 */
1345 public static class SoundModelEvent implements Parcelable {
1346 /** Status e.g {@link #SOUNDMODEL_STATUS_UPDATED} */
1347 public final int status;
1348 /** The updated sound model handle */
1349 public final int soundModelHandle;
1350 /** New sound model data */
1351 public final byte[] data;
1352
Mathew Inwoodbcbe4402018-08-08 15:42:59 +01001353 @UnsupportedAppUsage
Eric Laurentd3b82232014-07-30 08:57:39 -07001354 SoundModelEvent(int status, int soundModelHandle, byte[] data) {
1355 this.status = status;
1356 this.soundModelHandle = soundModelHandle;
1357 this.data = data;
1358 }
1359
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07001360 public static final @android.annotation.NonNull Parcelable.Creator<SoundModelEvent> CREATOR
Eric Laurentd3b82232014-07-30 08:57:39 -07001361 = new Parcelable.Creator<SoundModelEvent>() {
1362 public SoundModelEvent createFromParcel(Parcel in) {
1363 return SoundModelEvent.fromParcel(in);
1364 }
1365
1366 public SoundModelEvent[] newArray(int size) {
1367 return new SoundModelEvent[size];
1368 }
1369 };
1370
1371 private static SoundModelEvent fromParcel(Parcel in) {
1372 int status = in.readInt();
1373 int soundModelHandle = in.readInt();
1374 byte[] data = in.readBlob();
1375 return new SoundModelEvent(status, soundModelHandle, data);
1376 }
1377
1378 @Override
1379 public int describeContents() {
1380 return 0;
1381 }
1382
1383 @Override
1384 public void writeToParcel(Parcel dest, int flags) {
1385 dest.writeInt(status);
1386 dest.writeInt(soundModelHandle);
1387 dest.writeBlob(data);
1388 }
1389
1390 @Override
1391 public int hashCode() {
1392 final int prime = 31;
1393 int result = 1;
1394 result = prime * result + Arrays.hashCode(data);
1395 result = prime * result + soundModelHandle;
1396 result = prime * result + status;
1397 return result;
1398 }
1399
1400 @Override
1401 public boolean equals(Object obj) {
1402 if (this == obj)
1403 return true;
1404 if (obj == null)
1405 return false;
1406 if (getClass() != obj.getClass())
1407 return false;
1408 SoundModelEvent other = (SoundModelEvent) obj;
1409 if (!Arrays.equals(data, other.data))
1410 return false;
1411 if (soundModelHandle != other.soundModelHandle)
1412 return false;
1413 if (status != other.status)
1414 return false;
1415 return true;
1416 }
1417
1418 @Override
1419 public String toString() {
1420 return "SoundModelEvent [status=" + status + ", soundModelHandle=" + soundModelHandle
1421 + ", data=" + (data == null ? 0 : data.length) + "]";
1422 }
1423 }
1424
1425 /**
1426 * Native service state. {@link StatusListener#onServiceStateChange(int)}
1427 */
1428 // Keep in sync with system/core/include/system/sound_trigger.h
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -08001429 /**
1430 * Sound trigger service is enabled
1431 *
1432 * @hide
1433 */
Eric Laurentd3b82232014-07-30 08:57:39 -07001434 public static final int SERVICE_STATE_ENABLED = 0;
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -08001435 /**
1436 * Sound trigger service is disabled
1437 *
1438 * @hide
1439 */
Eric Laurentd3b82232014-07-30 08:57:39 -07001440 public static final int SERVICE_STATE_DISABLED = 1;
1441
1442 /**
Arunesh Mishraa772e5f2016-01-25 10:33:11 -08001443 * Returns a list of descriptors for all hardware modules loaded.
Eric Laurente48188c2014-04-18 17:44:11 -07001444 * @param modules A ModuleProperties array where the list will be returned.
1445 * @return - {@link #STATUS_OK} in case of success
1446 * - {@link #STATUS_ERROR} in case of unspecified error
1447 * - {@link #STATUS_PERMISSION_DENIED} if the caller does not have system permission
1448 * - {@link #STATUS_NO_INIT} if the native service cannot be reached
1449 * - {@link #STATUS_BAD_VALUE} if modules is null
1450 * - {@link #STATUS_DEAD_OBJECT} if the binder transaction to the native service fails
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -08001451 *
1452 * @hide
Eric Laurente48188c2014-04-18 17:44:11 -07001453 */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +01001454 @UnsupportedAppUsage
Eric Laurente48188c2014-04-18 17:44:11 -07001455 public static native int listModules(ArrayList <ModuleProperties> modules);
1456
1457 /**
1458 * Get an interface on a hardware module to control sound models and recognition on
1459 * this module.
1460 * @param moduleId Sound module system identifier {@link ModuleProperties#id}. mandatory.
1461 * @param listener {@link StatusListener} interface. Mandatory.
1462 * @param handler the Handler that will receive the callabcks. Can be null if default handler
1463 * is OK.
1464 * @return a valid sound module in case of success or null in case of error.
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -08001465 *
1466 * @hide
Eric Laurente48188c2014-04-18 17:44:11 -07001467 */
Mathew Inwoodbcbe4402018-08-08 15:42:59 +01001468 @UnsupportedAppUsage
Eric Laurente48188c2014-04-18 17:44:11 -07001469 public static SoundTriggerModule attachModule(int moduleId,
1470 StatusListener listener,
1471 Handler handler) {
1472 if (listener == null) {
1473 return null;
1474 }
1475 SoundTriggerModule module = new SoundTriggerModule(moduleId, listener, handler);
1476 return module;
1477 }
1478
1479 /**
1480 * Interface provided by the client application when attaching to a {@link SoundTriggerModule}
1481 * to received recognition and error notifications.
Philip P. Moltmanna5fd0292018-03-06 13:44:07 -08001482 *
1483 * @hide
Eric Laurente48188c2014-04-18 17:44:11 -07001484 */
1485 public static interface StatusListener {
1486 /**
1487 * Called when recognition succeeds of fails
1488 */
1489 public abstract void onRecognition(RecognitionEvent event);
1490
1491 /**
Eric Laurentd3b82232014-07-30 08:57:39 -07001492 * Called when a sound model has been updated
1493 */
1494 public abstract void onSoundModelUpdate(SoundModelEvent event);
1495
1496 /**
1497 * Called when the sound trigger native service state changes.
1498 * @param state Native service state. One of {@link SoundTrigger#SERVICE_STATE_ENABLED},
1499 * {@link SoundTrigger#SERVICE_STATE_DISABLED}
1500 */
1501 public abstract void onServiceStateChange(int state);
1502
1503 /**
Eric Laurente48188c2014-04-18 17:44:11 -07001504 * Called when the sound trigger native service dies
1505 */
1506 public abstract void onServiceDied();
1507 }
1508}