Merge changes from topic "st_stopping" into udc-dev am: 9e6c6ca843
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22787401 Change-Id: Iec6453015a184e2382f9c46d075bd3237a096854 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -232,7 +232,8 @@ public class ConversionUtil {
|
|||||||
recognitionEvent.captureAvailable, captureSession, recognitionEvent.captureDelayMs,
|
recognitionEvent.captureAvailable, captureSession, recognitionEvent.captureDelayMs,
|
||||||
recognitionEvent.capturePreambleMs, recognitionEvent.triggerInData, audioFormat,
|
recognitionEvent.capturePreambleMs, recognitionEvent.triggerInData, audioFormat,
|
||||||
recognitionEvent.data,
|
recognitionEvent.data,
|
||||||
recognitionEvent.recognitionStillActive, aidlEvent.halEventReceivedMillis);
|
recognitionEvent.recognitionStillActive, aidlEvent.halEventReceivedMillis,
|
||||||
|
aidlEvent.token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SoundTrigger.RecognitionEvent aidl2apiPhraseRecognitionEvent(
|
public static SoundTrigger.RecognitionEvent aidl2apiPhraseRecognitionEvent(
|
||||||
@@ -254,7 +255,8 @@ public class ConversionUtil {
|
|||||||
recognitionEvent.common.captureDelayMs,
|
recognitionEvent.common.captureDelayMs,
|
||||||
recognitionEvent.common.capturePreambleMs, recognitionEvent.common.triggerInData,
|
recognitionEvent.common.capturePreambleMs, recognitionEvent.common.triggerInData,
|
||||||
audioFormat,
|
audioFormat,
|
||||||
recognitionEvent.common.data, apiExtras, aidlEvent.halEventReceivedMillis);
|
recognitionEvent.common.data, apiExtras, aidlEvent.halEventReceivedMillis,
|
||||||
|
aidlEvent.token);
|
||||||
}
|
}
|
||||||
|
|
||||||
// In case of a null input returns a non-null valid output.
|
// In case of a null input returns a non-null valid output.
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1226,6 +1227,14 @@ public class SoundTrigger {
|
|||||||
@ElapsedRealtimeLong
|
@ElapsedRealtimeLong
|
||||||
public final long halEventReceivedMillis;
|
public final long halEventReceivedMillis;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binder token returned by {@link SoundTriggerModule#startRecognitionWithToken(
|
||||||
|
* int soundModelHandle, SoundTrigger.RecognitionConfig config)}
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public final IBinder token;
|
||||||
|
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
@TestApi
|
@TestApi
|
||||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||||||
@@ -1235,14 +1244,16 @@ public class SoundTrigger {
|
|||||||
@ElapsedRealtimeLong long halEventReceivedMillis) {
|
@ElapsedRealtimeLong long halEventReceivedMillis) {
|
||||||
this(status, soundModelHandle, captureAvailable,
|
this(status, soundModelHandle, captureAvailable,
|
||||||
captureSession, captureDelayMs, capturePreambleMs, triggerInData, captureFormat,
|
captureSession, captureDelayMs, capturePreambleMs, triggerInData, captureFormat,
|
||||||
data, status == RECOGNITION_STATUS_GET_STATE_RESPONSE, halEventReceivedMillis);
|
data, status == RECOGNITION_STATUS_GET_STATE_RESPONSE, halEventReceivedMillis,
|
||||||
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public RecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
|
public RecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
|
||||||
int captureSession, int captureDelayMs, int capturePreambleMs,
|
int captureSession, int captureDelayMs, int capturePreambleMs,
|
||||||
boolean triggerInData, @NonNull AudioFormat captureFormat, @Nullable byte[] data,
|
boolean triggerInData, @NonNull AudioFormat captureFormat, @Nullable byte[] data,
|
||||||
boolean recognitionStillActive, @ElapsedRealtimeLong long halEventReceivedMillis) {
|
boolean recognitionStillActive, @ElapsedRealtimeLong long halEventReceivedMillis,
|
||||||
|
IBinder token) {
|
||||||
this.status = status;
|
this.status = status;
|
||||||
this.soundModelHandle = soundModelHandle;
|
this.soundModelHandle = soundModelHandle;
|
||||||
this.captureAvailable = captureAvailable;
|
this.captureAvailable = captureAvailable;
|
||||||
@@ -1254,6 +1265,7 @@ public class SoundTrigger {
|
|||||||
this.data = data != null ? data : new byte[0];
|
this.data = data != null ? data : new byte[0];
|
||||||
this.recognitionStillActive = recognitionStillActive;
|
this.recognitionStillActive = recognitionStillActive;
|
||||||
this.halEventReceivedMillis = halEventReceivedMillis;
|
this.halEventReceivedMillis = halEventReceivedMillis;
|
||||||
|
this.token = token;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1311,6 +1323,16 @@ public class SoundTrigger {
|
|||||||
return halEventReceivedMillis;
|
return halEventReceivedMillis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get token associated with this recognition session returned by
|
||||||
|
*{@link SoundTriggerModule#startRecognitionWithToken(
|
||||||
|
* int soundModelHandle, SoundTrigger.RecognitionConfig config)}
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public IBinder getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public static final @android.annotation.NonNull Parcelable.Creator<RecognitionEvent> CREATOR
|
public static final @android.annotation.NonNull Parcelable.Creator<RecognitionEvent> CREATOR
|
||||||
= new Parcelable.Creator<RecognitionEvent>() {
|
= new Parcelable.Creator<RecognitionEvent>() {
|
||||||
@@ -1346,9 +1368,10 @@ public class SoundTrigger {
|
|||||||
byte[] data = in.readBlob();
|
byte[] data = in.readBlob();
|
||||||
boolean recognitionStillActive = in.readBoolean();
|
boolean recognitionStillActive = in.readBoolean();
|
||||||
long halEventReceivedMillis = in.readLong();
|
long halEventReceivedMillis = in.readLong();
|
||||||
|
IBinder token = in.readStrongBinder();
|
||||||
return new RecognitionEvent(status, soundModelHandle, captureAvailable, captureSession,
|
return new RecognitionEvent(status, soundModelHandle, captureAvailable, captureSession,
|
||||||
captureDelayMs, capturePreambleMs, triggerInData, captureFormat, data,
|
captureDelayMs, capturePreambleMs, triggerInData, captureFormat, data,
|
||||||
recognitionStillActive, halEventReceivedMillis);
|
recognitionStillActive, halEventReceivedMillis, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
@@ -1376,6 +1399,7 @@ public class SoundTrigger {
|
|||||||
dest.writeBlob(data);
|
dest.writeBlob(data);
|
||||||
dest.writeBoolean(recognitionStillActive);
|
dest.writeBoolean(recognitionStillActive);
|
||||||
dest.writeLong(halEventReceivedMillis);
|
dest.writeLong(halEventReceivedMillis);
|
||||||
|
dest.writeStrongBinder(token);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
@@ -1396,6 +1420,7 @@ public class SoundTrigger {
|
|||||||
result = prime * result + status;
|
result = prime * result + status;
|
||||||
result = result + (recognitionStillActive ? 1289 : 1291);
|
result = result + (recognitionStillActive ? 1289 : 1291);
|
||||||
result = prime * result + Long.hashCode(halEventReceivedMillis);
|
result = prime * result + Long.hashCode(halEventReceivedMillis);
|
||||||
|
result = prime * result + Objects.hashCode(token);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1425,6 +1450,9 @@ public class SoundTrigger {
|
|||||||
if (halEventReceivedMillis != other.halEventReceivedMillis) {
|
if (halEventReceivedMillis != other.halEventReceivedMillis) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!Objects.equals(token, other.token)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (status != other.status)
|
if (status != other.status)
|
||||||
return false;
|
return false;
|
||||||
if (triggerInData != other.triggerInData)
|
if (triggerInData != other.triggerInData)
|
||||||
@@ -1462,8 +1490,8 @@ public class SoundTrigger {
|
|||||||
+ ", data=" + (data == null ? 0 : data.length)
|
+ ", data=" + (data == null ? 0 : data.length)
|
||||||
+ ", recognitionStillActive=" + recognitionStillActive
|
+ ", recognitionStillActive=" + recognitionStillActive
|
||||||
+ ", halEventReceivedMillis=" + halEventReceivedMillis
|
+ ", halEventReceivedMillis=" + halEventReceivedMillis
|
||||||
+ "]";
|
+ ", token=" + token
|
||||||
}
|
+ "]"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1886,10 +1914,12 @@ public class SoundTrigger {
|
|||||||
int captureSession, int captureDelayMs, int capturePreambleMs,
|
int captureSession, int captureDelayMs, int capturePreambleMs,
|
||||||
boolean triggerInData, @NonNull AudioFormat captureFormat, @Nullable byte[] data,
|
boolean triggerInData, @NonNull AudioFormat captureFormat, @Nullable byte[] data,
|
||||||
@Nullable KeyphraseRecognitionExtra[] keyphraseExtras,
|
@Nullable KeyphraseRecognitionExtra[] keyphraseExtras,
|
||||||
@ElapsedRealtimeLong long halEventReceivedMillis) {
|
@ElapsedRealtimeLong long halEventReceivedMillis,
|
||||||
|
IBinder token) {
|
||||||
this(status, soundModelHandle, captureAvailable, captureSession, captureDelayMs,
|
this(status, soundModelHandle, captureAvailable, captureSession, captureDelayMs,
|
||||||
capturePreambleMs, triggerInData, captureFormat, data, keyphraseExtras,
|
capturePreambleMs, triggerInData, captureFormat, data, keyphraseExtras,
|
||||||
status == RECOGNITION_STATUS_GET_STATE_RESPONSE, halEventReceivedMillis);
|
status == RECOGNITION_STATUS_GET_STATE_RESPONSE, halEventReceivedMillis,
|
||||||
|
token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyphraseRecognitionEvent(int status, int soundModelHandle,
|
public KeyphraseRecognitionEvent(int status, int soundModelHandle,
|
||||||
@@ -1897,10 +1927,11 @@ public class SoundTrigger {
|
|||||||
int captureSession, int captureDelayMs, int capturePreambleMs,
|
int captureSession, int captureDelayMs, int capturePreambleMs,
|
||||||
boolean triggerInData, @NonNull AudioFormat captureFormat, @Nullable byte[] data,
|
boolean triggerInData, @NonNull AudioFormat captureFormat, @Nullable byte[] data,
|
||||||
@Nullable KeyphraseRecognitionExtra[] keyphraseExtras,
|
@Nullable KeyphraseRecognitionExtra[] keyphraseExtras,
|
||||||
boolean recognitionStillActive, @ElapsedRealtimeLong long halEventReceivedMillis) {
|
boolean recognitionStillActive, @ElapsedRealtimeLong long halEventReceivedMillis,
|
||||||
|
IBinder token) {
|
||||||
super(status, soundModelHandle, captureAvailable,
|
super(status, soundModelHandle, captureAvailable,
|
||||||
captureSession, captureDelayMs, capturePreambleMs, triggerInData, captureFormat,
|
captureSession, captureDelayMs, capturePreambleMs, triggerInData, captureFormat,
|
||||||
data, recognitionStillActive, halEventReceivedMillis);
|
data, recognitionStillActive, halEventReceivedMillis, token);
|
||||||
this.keyphraseExtras =
|
this.keyphraseExtras =
|
||||||
keyphraseExtras != null ? keyphraseExtras : new KeyphraseRecognitionExtra[0];
|
keyphraseExtras != null ? keyphraseExtras : new KeyphraseRecognitionExtra[0];
|
||||||
}
|
}
|
||||||
@@ -1938,12 +1969,13 @@ public class SoundTrigger {
|
|||||||
byte[] data = in.readBlob();
|
byte[] data = in.readBlob();
|
||||||
boolean recognitionStillActive = in.readBoolean();
|
boolean recognitionStillActive = in.readBoolean();
|
||||||
long halEventReceivedMillis = in.readLong();
|
long halEventReceivedMillis = in.readLong();
|
||||||
|
IBinder token = in.readStrongBinder();
|
||||||
KeyphraseRecognitionExtra[] keyphraseExtras =
|
KeyphraseRecognitionExtra[] keyphraseExtras =
|
||||||
in.createTypedArray(KeyphraseRecognitionExtra.CREATOR);
|
in.createTypedArray(KeyphraseRecognitionExtra.CREATOR);
|
||||||
return new KeyphraseRecognitionEvent(status, soundModelHandle,
|
return new KeyphraseRecognitionEvent(status, soundModelHandle,
|
||||||
captureAvailable, captureSession, captureDelayMs, capturePreambleMs,
|
captureAvailable, captureSession, captureDelayMs, capturePreambleMs,
|
||||||
triggerInData, captureFormat, data, keyphraseExtras, recognitionStillActive,
|
triggerInData, captureFormat, data, keyphraseExtras, recognitionStillActive,
|
||||||
halEventReceivedMillis);
|
halEventReceivedMillis, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1966,6 +1998,7 @@ public class SoundTrigger {
|
|||||||
dest.writeBlob(data);
|
dest.writeBlob(data);
|
||||||
dest.writeBoolean(recognitionStillActive);
|
dest.writeBoolean(recognitionStillActive);
|
||||||
dest.writeLong(halEventReceivedMillis);
|
dest.writeLong(halEventReceivedMillis);
|
||||||
|
dest.writeStrongBinder(token);
|
||||||
dest.writeTypedArray(keyphraseExtras, flags);
|
dest.writeTypedArray(keyphraseExtras, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2015,6 +2048,7 @@ public class SoundTrigger {
|
|||||||
+ ", data=" + (data == null ? 0 : data.length)
|
+ ", data=" + (data == null ? 0 : data.length)
|
||||||
+ ", recognitionStillActive=" + recognitionStillActive
|
+ ", recognitionStillActive=" + recognitionStillActive
|
||||||
+ ", halEventReceivedMillis=" + halEventReceivedMillis
|
+ ", halEventReceivedMillis=" + halEventReceivedMillis
|
||||||
|
+ ", token=" + token
|
||||||
+ "]";
|
+ "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2030,20 +2064,23 @@ public class SoundTrigger {
|
|||||||
public GenericRecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
|
public GenericRecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
|
||||||
int captureSession, int captureDelayMs, int capturePreambleMs,
|
int captureSession, int captureDelayMs, int capturePreambleMs,
|
||||||
boolean triggerInData, @NonNull AudioFormat captureFormat, @Nullable byte[] data,
|
boolean triggerInData, @NonNull AudioFormat captureFormat, @Nullable byte[] data,
|
||||||
@ElapsedRealtimeLong long halEventReceivedMillis) {
|
@ElapsedRealtimeLong long halEventReceivedMillis,
|
||||||
|
IBinder token) {
|
||||||
this(status, soundModelHandle, captureAvailable,
|
this(status, soundModelHandle, captureAvailable,
|
||||||
captureSession, captureDelayMs,
|
captureSession, captureDelayMs,
|
||||||
capturePreambleMs, triggerInData, captureFormat, data,
|
capturePreambleMs, triggerInData, captureFormat, data,
|
||||||
status == RECOGNITION_STATUS_GET_STATE_RESPONSE, halEventReceivedMillis);
|
status == RECOGNITION_STATUS_GET_STATE_RESPONSE,
|
||||||
|
halEventReceivedMillis, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GenericRecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
|
public GenericRecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
|
||||||
int captureSession, int captureDelayMs, int capturePreambleMs,
|
int captureSession, int captureDelayMs, int capturePreambleMs,
|
||||||
boolean triggerInData, @NonNull AudioFormat captureFormat, @Nullable byte[] data,
|
boolean triggerInData, @NonNull AudioFormat captureFormat, @Nullable byte[] data,
|
||||||
boolean recognitionStillActive, @ElapsedRealtimeLong long halEventReceivedMillis) {
|
boolean recognitionStillActive, @ElapsedRealtimeLong long halEventReceivedMillis,
|
||||||
|
IBinder token) {
|
||||||
super(status, soundModelHandle, captureAvailable,
|
super(status, soundModelHandle, captureAvailable,
|
||||||
captureSession, captureDelayMs, capturePreambleMs, triggerInData, captureFormat,
|
captureSession, captureDelayMs, capturePreambleMs, triggerInData, captureFormat,
|
||||||
data, recognitionStillActive, halEventReceivedMillis);
|
data, recognitionStillActive, halEventReceivedMillis, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final @android.annotation.NonNull Parcelable.Creator<GenericRecognitionEvent> CREATOR
|
public static final @android.annotation.NonNull Parcelable.Creator<GenericRecognitionEvent> CREATOR
|
||||||
@@ -2062,7 +2099,7 @@ public class SoundTrigger {
|
|||||||
return new GenericRecognitionEvent(event.status, event.soundModelHandle,
|
return new GenericRecognitionEvent(event.status, event.soundModelHandle,
|
||||||
event.captureAvailable, event.captureSession, event.captureDelayMs,
|
event.captureAvailable, event.captureSession, event.captureDelayMs,
|
||||||
event.capturePreambleMs, event.triggerInData, event.captureFormat, event.data,
|
event.capturePreambleMs, event.triggerInData, event.captureFormat, event.data,
|
||||||
event.recognitionStillActive, event.halEventReceivedMillis);
|
event.recognitionStillActive, event.halEventReceivedMillis, event.token);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -2092,7 +2129,7 @@ public class SoundTrigger {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
static int handleException(Exception e) {
|
public static int handleException(Exception e) {
|
||||||
Log.w(TAG, "Exception caught", e);
|
Log.w(TAG, "Exception caught", e);
|
||||||
if (e instanceof RemoteException) {
|
if (e instanceof RemoteException) {
|
||||||
return STATUS_DEAD_OBJECT;
|
return STATUS_DEAD_OBJECT;
|
||||||
|
|||||||
@@ -246,6 +246,16 @@ public class SoundTriggerModule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as above, but return a binder token associated with the session.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public synchronized IBinder startRecognitionWithToken(int soundModelHandle,
|
||||||
|
SoundTrigger.RecognitionConfig config) throws RemoteException {
|
||||||
|
return mService.startRecognition(soundModelHandle,
|
||||||
|
ConversionUtil.api2aidlRecognitionConfig(config));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop listening to all key phrases in a {@link SoundTrigger.SoundModel}
|
* Stop listening to all key phrases in a {@link SoundTrigger.SoundModel}
|
||||||
* @param soundModelHandle The sound model handle to stop listening to
|
* @param soundModelHandle The sound model handle to stop listening to
|
||||||
|
|||||||
@@ -984,7 +984,8 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
|||||||
new KeyphraseRecognitionEvent(status, soundModelHandle, captureAvailable,
|
new KeyphraseRecognitionEvent(status, soundModelHandle, captureAvailable,
|
||||||
captureSession, captureDelayMs, capturePreambleMs, triggerInData,
|
captureSession, captureDelayMs, capturePreambleMs, triggerInData,
|
||||||
captureFormat, data, keyphraseRecognitionExtras.toArray(
|
captureFormat, data, keyphraseRecognitionExtras.toArray(
|
||||||
new KeyphraseRecognitionExtra[0]), halEventReceivedMillis),
|
new KeyphraseRecognitionExtra[0]), halEventReceivedMillis,
|
||||||
|
new Binder()),
|
||||||
mInternalCallback);
|
mInternalCallback);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw e.rethrowFromSystemServer();
|
throw e.rethrowFromSystemServer();
|
||||||
|
|||||||
@@ -79,8 +79,9 @@ interface ISoundTriggerModule {
|
|||||||
*
|
*
|
||||||
* May throw a ServiceSpecificException with an RESOURCE_CONTENTION status to indicate that
|
* May throw a ServiceSpecificException with an RESOURCE_CONTENTION status to indicate that
|
||||||
* resources required for starting the model are currently consumed by other clients.
|
* resources required for starting the model are currently consumed by other clients.
|
||||||
|
* @return - A token delivered along with future recognition events.
|
||||||
*/
|
*/
|
||||||
void startRecognition(int modelHandle, in RecognitionConfig config);
|
IBinder startRecognition(int modelHandle, in RecognitionConfig config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop a recognition of a previously active recognition. Will NOT generate a recognition event.
|
* Stop a recognition of a previously active recognition. Will NOT generate a recognition event.
|
||||||
|
|||||||
@@ -33,4 +33,9 @@ parcelable PhraseRecognitionEventSys {
|
|||||||
*/
|
*/
|
||||||
// @ElapsedRealtimeLong
|
// @ElapsedRealtimeLong
|
||||||
long halEventReceivedMillis = -1;
|
long halEventReceivedMillis = -1;
|
||||||
|
/**
|
||||||
|
* Token relating this event to a particular recognition session, returned by
|
||||||
|
* {@link ISoundTriggerModule.startRecognition(int, RecognitionConfig}
|
||||||
|
*/
|
||||||
|
IBinder token;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,4 +33,9 @@ parcelable RecognitionEventSys {
|
|||||||
*/
|
*/
|
||||||
// @ElapsedRealtimeLong
|
// @ElapsedRealtimeLong
|
||||||
long halEventReceivedMillis = -1;
|
long halEventReceivedMillis = -1;
|
||||||
|
/**
|
||||||
|
* Token relating this event to a particular recognition session, returned by
|
||||||
|
* {@link ISoundTriggerModule.startRecognition(int, RecognitionConfig}
|
||||||
|
*/
|
||||||
|
IBinder token;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import android.os.Parcel;
|
|||||||
import android.test.InstrumentationTestCase;
|
import android.test.InstrumentationTestCase;
|
||||||
import android.test.suitebuilder.annotation.LargeTest;
|
import android.test.suitebuilder.annotation.LargeTest;
|
||||||
import android.test.suitebuilder.annotation.SmallTest;
|
import android.test.suitebuilder.annotation.SmallTest;
|
||||||
|
import android.os.Binder;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@@ -346,7 +347,8 @@ public class SoundTriggerTest extends InstrumentationTestCase {
|
|||||||
.build(),
|
.build(),
|
||||||
null /* data */,
|
null /* data */,
|
||||||
null /* keyphraseExtras */,
|
null /* keyphraseExtras */,
|
||||||
12345678 /* halEventReceivedMillis */);
|
12345678 /* halEventReceivedMillis */,
|
||||||
|
new Binder() /* token */);
|
||||||
|
|
||||||
// Write to a parcel
|
// Write to a parcel
|
||||||
Parcel parcel = Parcel.obtain();
|
Parcel parcel = Parcel.obtain();
|
||||||
@@ -379,7 +381,8 @@ public class SoundTriggerTest extends InstrumentationTestCase {
|
|||||||
.build(),
|
.build(),
|
||||||
new byte[1] /* data */,
|
new byte[1] /* data */,
|
||||||
kpExtra,
|
kpExtra,
|
||||||
12345678 /* halEventReceivedMillis */);
|
12345678 /* halEventReceivedMillis */,
|
||||||
|
new Binder() /* token */);
|
||||||
|
|
||||||
// Write to a parcel
|
// Write to a parcel
|
||||||
Parcel parcel = Parcel.obtain();
|
Parcel parcel = Parcel.obtain();
|
||||||
@@ -428,7 +431,8 @@ public class SoundTriggerTest extends InstrumentationTestCase {
|
|||||||
.build(),
|
.build(),
|
||||||
data,
|
data,
|
||||||
kpExtra,
|
kpExtra,
|
||||||
12345678 /* halEventReceivedMillis */);
|
12345678 /* halEventReceivedMillis */,
|
||||||
|
new Binder() /* token */);
|
||||||
|
|
||||||
// Write to a parcel
|
// Write to a parcel
|
||||||
Parcel parcel = Parcel.obtain();
|
Parcel parcel = Parcel.obtain();
|
||||||
|
|||||||
@@ -225,13 +225,6 @@ public class SoundTriggerMiddlewareImplTest {
|
|||||||
// Stop the recognition.
|
// Stop the recognition.
|
||||||
stopRecognition(module, handle, hwHandle);
|
stopRecognition(module, handle, hwHandle);
|
||||||
|
|
||||||
ArgumentCaptor<RecognitionEventSys> eventCaptor = ArgumentCaptor.forClass(
|
|
||||||
RecognitionEventSys.class);
|
|
||||||
verify(callback).onRecognition(eq(handle), eventCaptor.capture(), eq(101));
|
|
||||||
RecognitionEventSys lastEvent = eventCaptor.getValue();
|
|
||||||
assertEquals(-1, lastEvent.halEventReceivedMillis);
|
|
||||||
assertEquals(RecognitionStatus.ABORTED, lastEvent.recognitionEvent.status);
|
|
||||||
|
|
||||||
// Unload the model.
|
// Unload the model.
|
||||||
unloadModel(module, handle, hwHandle);
|
unloadModel(module, handle, hwHandle);
|
||||||
module.detach();
|
module.detach();
|
||||||
@@ -276,13 +269,6 @@ public class SoundTriggerMiddlewareImplTest {
|
|||||||
// Stop the recognition.
|
// Stop the recognition.
|
||||||
stopRecognition(module, handle, hwHandle);
|
stopRecognition(module, handle, hwHandle);
|
||||||
|
|
||||||
ArgumentCaptor<PhraseRecognitionEventSys> eventCaptor = ArgumentCaptor.forClass(
|
|
||||||
PhraseRecognitionEventSys.class);
|
|
||||||
verify(callback).onPhraseRecognition(eq(handle), eventCaptor.capture(), eq(101));
|
|
||||||
PhraseRecognitionEventSys lastEvent = eventCaptor.getValue();
|
|
||||||
assertEquals(-1, lastEvent.halEventReceivedMillis);
|
|
||||||
assertEquals(RecognitionStatus.ABORTED, lastEvent.phraseRecognitionEvent.common.status);
|
|
||||||
|
|
||||||
// Unload the model.
|
// Unload the model.
|
||||||
unloadModel(module, handle, hwHandle);
|
unloadModel(module, handle, hwHandle);
|
||||||
module.detach();
|
module.detach();
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import android.hardware.soundtrigger.SoundTriggerModule;
|
|||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.DeadObjectException;
|
import android.os.DeadObjectException;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.os.IBinder;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
@@ -487,7 +488,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unloadModel && (modelData.isModelLoaded() || modelData.isStopPending())) {
|
if (unloadModel && modelData.isModelLoaded()) {
|
||||||
Slog.d(TAG, "Unloading previously loaded stale model.");
|
Slog.d(TAG, "Unloading previously loaded stale model.");
|
||||||
if (mModule == null) {
|
if (mModule == null) {
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
@@ -788,6 +789,10 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ModelData model = getModelDataForLocked(event.soundModelHandle);
|
ModelData model = getModelDataForLocked(event.soundModelHandle);
|
||||||
|
if (!Objects.equals(event.getToken(), model.getToken())) {
|
||||||
|
// Stale event, do nothing
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (model == null || !model.isGenericModel()) {
|
if (model == null || !model.isGenericModel()) {
|
||||||
Slog.w(TAG, "Generic recognition event: Model does not exist for handle: "
|
Slog.w(TAG, "Generic recognition event: Model does not exist for handle: "
|
||||||
+ event.soundModelHandle);
|
+ event.soundModelHandle);
|
||||||
@@ -870,7 +875,11 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
Slog.w(TAG, "Recognition aborted");
|
Slog.w(TAG, "Recognition aborted");
|
||||||
MetricsLogger.count(mContext, "sth_recognition_aborted", 1);
|
MetricsLogger.count(mContext, "sth_recognition_aborted", 1);
|
||||||
ModelData modelData = getModelDataForLocked(event.soundModelHandle);
|
ModelData modelData = getModelDataForLocked(event.soundModelHandle);
|
||||||
if (modelData != null && (modelData.isModelStarted() || modelData.isStopPending())) {
|
if (!Objects.equals(event.getToken(), modelData.getToken())) {
|
||||||
|
// Stale event, do nothing
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (modelData != null && modelData.isModelStarted()) {
|
||||||
modelData.setStopped();
|
modelData.setStopped();
|
||||||
try {
|
try {
|
||||||
IRecognitionStatusCallback callback = modelData.getCallback();
|
IRecognitionStatusCallback callback = modelData.getCallback();
|
||||||
@@ -884,7 +893,6 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
.printLog(ALOGW, TAG));
|
.printLog(ALOGW, TAG));
|
||||||
forceStopAndUnloadModelLocked(modelData, e);
|
forceStopAndUnloadModelLocked(modelData, e);
|
||||||
}
|
}
|
||||||
updateRecognitionLocked(modelData, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -908,6 +916,10 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
MetricsLogger.count(mContext, "sth_keyphrase_recognition_event", 1);
|
MetricsLogger.count(mContext, "sth_keyphrase_recognition_event", 1);
|
||||||
int keyphraseId = getKeyphraseIdFromEvent(event);
|
int keyphraseId = getKeyphraseIdFromEvent(event);
|
||||||
ModelData modelData = getKeyphraseModelDataLocked(keyphraseId);
|
ModelData modelData = getKeyphraseModelDataLocked(keyphraseId);
|
||||||
|
if (!Objects.equals(event.getToken(), modelData.getToken())) {
|
||||||
|
// Stale event, do nothing
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (modelData == null || !modelData.isKeyphraseModel()) {
|
if (modelData == null || !modelData.isKeyphraseModel()) {
|
||||||
Slog.e(TAG, "Keyphase model data does not exist for ID:" + keyphraseId);
|
Slog.e(TAG, "Keyphase model data does not exist for ID:" + keyphraseId);
|
||||||
@@ -955,7 +967,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
|
|
||||||
private int updateRecognitionLocked(ModelData model, boolean notifyClientOnError) {
|
private int updateRecognitionLocked(ModelData model, boolean notifyClientOnError) {
|
||||||
boolean shouldStartModel = model.isRequested() && isRecognitionAllowedByDeviceState(model);
|
boolean shouldStartModel = model.isRequested() && isRecognitionAllowedByDeviceState(model);
|
||||||
if (shouldStartModel == model.isModelStarted() || model.isStopPending()) {
|
if (shouldStartModel == model.isModelStarted()) {
|
||||||
// No-op.
|
// No-op.
|
||||||
return STATUS_OK;
|
return STATUS_OK;
|
||||||
}
|
}
|
||||||
@@ -1060,10 +1072,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
if (mModule == null) {
|
if (mModule == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (modelData.isStopPending()) {
|
if (modelData.isModelStarted()) {
|
||||||
// No need to wait for the stop to be confirmed.
|
|
||||||
modelData.setStopped();
|
|
||||||
} else if (modelData.isModelStarted()) {
|
|
||||||
Slog.d(TAG, "Stopping previously started dangling model " + modelData.getHandle());
|
Slog.d(TAG, "Stopping previously started dangling model " + modelData.getHandle());
|
||||||
if (mModule.stopRecognition(modelData.getHandle()) == STATUS_OK) {
|
if (mModule.stopRecognition(modelData.getHandle()) == STATUS_OK) {
|
||||||
modelData.setStopped();
|
modelData.setStopped();
|
||||||
@@ -1207,7 +1216,12 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
if (mModule == null) {
|
if (mModule == null) {
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
int status = mModule.startRecognition(modelData.getHandle(), config);
|
int status = STATUS_OK;
|
||||||
|
try {
|
||||||
|
modelData.setToken(mModule.startRecognitionWithToken(modelData.getHandle(), config));
|
||||||
|
} catch (Exception e) {
|
||||||
|
status = SoundTrigger.handleException(e);
|
||||||
|
}
|
||||||
if (status != SoundTrigger.STATUS_OK) {
|
if (status != SoundTrigger.STATUS_OK) {
|
||||||
Slog.w(TAG, "startRecognition failed with " + status);
|
Slog.w(TAG, "startRecognition failed with " + status);
|
||||||
MetricsLogger.count(mContext, "sth_start_recognition_error", 1);
|
MetricsLogger.count(mContext, "sth_start_recognition_error", 1);
|
||||||
@@ -1275,7 +1289,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
modelData.setStopPending();
|
modelData.setStopped();
|
||||||
MetricsLogger.count(mContext, "sth_stop_recognition_success", 1);
|
MetricsLogger.count(mContext, "sth_stop_recognition_success", 1);
|
||||||
// Notify of pause if needed.
|
// Notify of pause if needed.
|
||||||
if (notify) {
|
if (notify) {
|
||||||
@@ -1322,9 +1336,6 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
// Started implies model was successfully loaded and start was called.
|
// Started implies model was successfully loaded and start was called.
|
||||||
static final int MODEL_STARTED = 2;
|
static final int MODEL_STARTED = 2;
|
||||||
|
|
||||||
// Model stop request has been sent. Waiting for an event to signal model being stopped.
|
|
||||||
static final int MODEL_STOP_PENDING = 3;
|
|
||||||
|
|
||||||
// One of MODEL_NOTLOADED, MODEL_LOADED, MODEL_STARTED (which implies loaded).
|
// One of MODEL_NOTLOADED, MODEL_LOADED, MODEL_STARTED (which implies loaded).
|
||||||
private int mModelState;
|
private int mModelState;
|
||||||
private UUID mModelId;
|
private UUID mModelId;
|
||||||
@@ -1365,6 +1376,9 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
// The SoundModel instance, one of KeyphraseSoundModel or GenericSoundModel.
|
// The SoundModel instance, one of KeyphraseSoundModel or GenericSoundModel.
|
||||||
private SoundModel mSoundModel = null;
|
private SoundModel mSoundModel = null;
|
||||||
|
|
||||||
|
// Token used to disambiguate recognition sessions.
|
||||||
|
private IBinder mRecognitionToken = null;
|
||||||
|
|
||||||
private ModelData(UUID modelId, int modelType) {
|
private ModelData(UUID modelId, int modelType) {
|
||||||
mModelId = modelId;
|
mModelId = modelId;
|
||||||
// Private constructor, since we require modelType to be one of TYPE_GENERIC,
|
// Private constructor, since we require modelType to be one of TYPE_GENERIC,
|
||||||
@@ -1402,22 +1416,17 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
return mModelState == MODEL_NOTLOADED;
|
return mModelState == MODEL_NOTLOADED;
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized boolean isStopPending() {
|
|
||||||
return mModelState == MODEL_STOP_PENDING;
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized void setStarted() {
|
synchronized void setStarted() {
|
||||||
mModelState = MODEL_STARTED;
|
mModelState = MODEL_STARTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void setStopped() {
|
synchronized void setStopped() {
|
||||||
|
// If we are moving to the stopped state, we should clear out our
|
||||||
|
// startRecognition token
|
||||||
|
mRecognitionToken = null;
|
||||||
mModelState = MODEL_LOADED;
|
mModelState = MODEL_LOADED;
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void setStopPending() {
|
|
||||||
mModelState = MODEL_STOP_PENDING;
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized void setLoaded() {
|
synchronized void setLoaded() {
|
||||||
mModelState = MODEL_LOADED;
|
mModelState = MODEL_LOADED;
|
||||||
}
|
}
|
||||||
@@ -1486,6 +1495,14 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
return mSoundModel;
|
return mSoundModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
synchronized IBinder getToken() {
|
||||||
|
return mRecognitionToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized void setToken(IBinder token) {
|
||||||
|
mRecognitionToken = token;
|
||||||
|
}
|
||||||
|
|
||||||
synchronized int getModelType() {
|
synchronized int getModelType() {
|
||||||
return mModelType;
|
return mModelType;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ public class SoundTriggerHalEnforcer implements ISoundTriggerHal {
|
|||||||
public void recognitionCallback(int model, RecognitionEventSys event) {
|
public void recognitionCallback(int model, RecognitionEventSys event) {
|
||||||
synchronized (mModelStates) {
|
synchronized (mModelStates) {
|
||||||
ModelState state = mModelStates.get(model);
|
ModelState state = mModelStates.get(model);
|
||||||
if (state == null || state == ModelState.INACTIVE) {
|
if (state == null) {
|
||||||
Log.wtfStack(TAG, "Unexpected recognition event for model: " + model);
|
Log.wtfStack(TAG, "Unexpected recognition event for model: " + model);
|
||||||
reboot();
|
reboot();
|
||||||
return;
|
return;
|
||||||
@@ -282,7 +282,7 @@ public class SoundTriggerHalEnforcer implements ISoundTriggerHal {
|
|||||||
public void phraseRecognitionCallback(int model, PhraseRecognitionEventSys event) {
|
public void phraseRecognitionCallback(int model, PhraseRecognitionEventSys event) {
|
||||||
synchronized (mModelStates) {
|
synchronized (mModelStates) {
|
||||||
ModelState state = mModelStates.get(model);
|
ModelState state = mModelStates.get(model);
|
||||||
if (state == null || state == ModelState.INACTIVE) {
|
if (state == null) {
|
||||||
Log.wtfStack(TAG, "Unexpected recognition event for model: " + model);
|
Log.wtfStack(TAG, "Unexpected recognition event for model: " + model);
|
||||||
reboot();
|
reboot();
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -241,13 +241,14 @@ public class SoundTriggerMiddlewareLogging implements ISoundTriggerMiddlewareInt
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startRecognition(int modelHandle, RecognitionConfig config)
|
public IBinder startRecognition(int modelHandle, RecognitionConfig config)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
try {
|
try {
|
||||||
mDelegate.startRecognition(modelHandle, config);
|
var result = mDelegate.startRecognition(modelHandle, config);
|
||||||
mEventLogger.enqueue(SessionEvent.createForVoid(
|
mEventLogger.enqueue(SessionEvent.createForReturn(
|
||||||
START_RECOGNITION, modelHandle, config)
|
START_RECOGNITION, result, modelHandle, config)
|
||||||
.printLog(ALOGI, TAG));
|
.printLog(ALOGI, TAG));
|
||||||
|
return result;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
mEventLogger.enqueue(SessionEvent.createForException(
|
mEventLogger.enqueue(SessionEvent.createForException(
|
||||||
START_RECOGNITION, e, modelHandle, config)
|
START_RECOGNITION, e, modelHandle, config)
|
||||||
|
|||||||
@@ -241,10 +241,10 @@ public class SoundTriggerMiddlewarePermission implements ISoundTriggerMiddleware
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startRecognition(int modelHandle, @NonNull RecognitionConfig config)
|
public IBinder startRecognition(int modelHandle, @NonNull RecognitionConfig config)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
enforcePermissions();
|
enforcePermissions();
|
||||||
mDelegate.startRecognition(modelHandle, config);
|
return mDelegate.startRecognition(modelHandle, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import android.media.soundtrigger_middleware.ISoundTriggerInjection;
|
|||||||
import android.media.soundtrigger_middleware.ISoundTriggerMiddlewareService;
|
import android.media.soundtrigger_middleware.ISoundTriggerMiddlewareService;
|
||||||
import android.media.soundtrigger_middleware.ISoundTriggerModule;
|
import android.media.soundtrigger_middleware.ISoundTriggerModule;
|
||||||
import android.media.soundtrigger_middleware.SoundTriggerModuleDescriptor;
|
import android.media.soundtrigger_middleware.SoundTriggerModuleDescriptor;
|
||||||
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
|
||||||
import com.android.server.SystemService;
|
import com.android.server.SystemService;
|
||||||
@@ -176,10 +177,10 @@ public class SoundTriggerMiddlewareService extends ISoundTriggerMiddlewareServic
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startRecognition(int modelHandle, RecognitionConfig config)
|
public IBinder startRecognition(int modelHandle, RecognitionConfig config)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
|
try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
|
||||||
mDelegate.startRecognition(modelHandle, config);
|
return mDelegate.startRecognition(modelHandle, config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -434,7 +434,7 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startRecognition(int modelHandle, @NonNull RecognitionConfig config) {
|
public IBinder startRecognition(int modelHandle, @NonNull RecognitionConfig config) {
|
||||||
// Input validation.
|
// Input validation.
|
||||||
ValidationUtil.validateRecognitionConfig(config);
|
ValidationUtil.validateRecognitionConfig(config);
|
||||||
|
|
||||||
@@ -458,9 +458,10 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware
|
|||||||
|
|
||||||
// From here on, every exception isn't client's fault.
|
// From here on, every exception isn't client's fault.
|
||||||
try {
|
try {
|
||||||
mDelegate.startRecognition(modelHandle, config);
|
var result = mDelegate.startRecognition(modelHandle, config);
|
||||||
modelState.config = config;
|
modelState.config = config;
|
||||||
modelState.activityState = ModelState.Activity.ACTIVE;
|
modelState.activityState = ModelState.Activity.ACTIVE;
|
||||||
|
return result;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw handleException(e);
|
throw handleException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import android.media.soundtrigger.PhraseSoundModel;
|
|||||||
import android.media.soundtrigger.Properties;
|
import android.media.soundtrigger.Properties;
|
||||||
import android.media.soundtrigger.RecognitionConfig;
|
import android.media.soundtrigger.RecognitionConfig;
|
||||||
import android.media.soundtrigger.SoundModel;
|
import android.media.soundtrigger.SoundModel;
|
||||||
import android.media.soundtrigger.SoundModelType;
|
|
||||||
import android.media.soundtrigger.Status;
|
import android.media.soundtrigger.Status;
|
||||||
import android.media.soundtrigger_middleware.ISoundTriggerCallback;
|
import android.media.soundtrigger_middleware.ISoundTriggerCallback;
|
||||||
import android.media.soundtrigger_middleware.ISoundTriggerModule;
|
import android.media.soundtrigger_middleware.ISoundTriggerModule;
|
||||||
@@ -304,10 +303,10 @@ class SoundTriggerModule implements IBinder.DeathRecipient, ISoundTriggerHal.Glo
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startRecognition(int modelHandle, @NonNull RecognitionConfig config) {
|
public IBinder startRecognition(int modelHandle, @NonNull RecognitionConfig config) {
|
||||||
synchronized (SoundTriggerModule.this) {
|
synchronized (SoundTriggerModule.this) {
|
||||||
checkValid();
|
checkValid();
|
||||||
mLoadedModels.get(modelHandle).startRecognition(config);
|
return mLoadedModels.get(modelHandle).startRecognition(config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -385,8 +384,9 @@ class SoundTriggerModule implements IBinder.DeathRecipient, ISoundTriggerHal.Glo
|
|||||||
private class Model implements ISoundTriggerHal.ModelCallback {
|
private class Model implements ISoundTriggerHal.ModelCallback {
|
||||||
public int mHandle;
|
public int mHandle;
|
||||||
private ModelState mState = ModelState.INIT;
|
private ModelState mState = ModelState.INIT;
|
||||||
private int mType = SoundModelType.INVALID;
|
|
||||||
private SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession mSession;
|
private SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession mSession;
|
||||||
|
private IBinder mRecognitionToken = null;
|
||||||
|
private boolean mIsStopping = false;
|
||||||
|
|
||||||
private @NonNull
|
private @NonNull
|
||||||
ModelState getState() {
|
ModelState getState() {
|
||||||
@@ -402,7 +402,6 @@ class SoundTriggerModule implements IBinder.DeathRecipient, ISoundTriggerHal.Glo
|
|||||||
SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession audioSession) {
|
SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession audioSession) {
|
||||||
mSession = audioSession;
|
mSession = audioSession;
|
||||||
mHandle = mHalService.loadSoundModel(model, this);
|
mHandle = mHalService.loadSoundModel(model, this);
|
||||||
mType = SoundModelType.GENERIC;
|
|
||||||
setState(ModelState.LOADED);
|
setState(ModelState.LOADED);
|
||||||
mLoadedModels.put(mHandle, this);
|
mLoadedModels.put(mHandle, this);
|
||||||
return mHandle;
|
return mHandle;
|
||||||
@@ -412,7 +411,7 @@ class SoundTriggerModule implements IBinder.DeathRecipient, ISoundTriggerHal.Glo
|
|||||||
SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession audioSession) {
|
SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession audioSession) {
|
||||||
mSession = audioSession;
|
mSession = audioSession;
|
||||||
mHandle = mHalService.loadPhraseSoundModel(model, this);
|
mHandle = mHalService.loadPhraseSoundModel(model, this);
|
||||||
mType = SoundModelType.KEYPHRASE;
|
|
||||||
setState(ModelState.LOADED);
|
setState(ModelState.LOADED);
|
||||||
mLoadedModels.put(mHandle, this);
|
mLoadedModels.put(mHandle, this);
|
||||||
return mHandle;
|
return mHandle;
|
||||||
@@ -428,10 +427,15 @@ class SoundTriggerModule implements IBinder.DeathRecipient, ISoundTriggerHal.Glo
|
|||||||
return mSession.mSessionHandle;
|
return mSession.mSessionHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startRecognition(@NonNull RecognitionConfig config) {
|
private IBinder startRecognition(@NonNull RecognitionConfig config) {
|
||||||
|
if (mIsStopping == true) {
|
||||||
|
throw new RecoverableException(Status.INTERNAL_ERROR, "Race occurred");
|
||||||
|
}
|
||||||
mHalService.startRecognition(mHandle, mSession.mDeviceHandle,
|
mHalService.startRecognition(mHandle, mSession.mDeviceHandle,
|
||||||
mSession.mIoHandle, config);
|
mSession.mIoHandle, config);
|
||||||
|
mRecognitionToken = new Binder();
|
||||||
setState(ModelState.ACTIVE);
|
setState(ModelState.ACTIVE);
|
||||||
|
return mRecognitionToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stopRecognition() {
|
private void stopRecognition() {
|
||||||
@@ -440,35 +444,13 @@ class SoundTriggerModule implements IBinder.DeathRecipient, ISoundTriggerHal.Glo
|
|||||||
// This call is idempotent in order to avoid races.
|
// This call is idempotent in order to avoid races.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
mRecognitionToken = null;
|
||||||
|
mIsStopping = true;
|
||||||
}
|
}
|
||||||
// This must be invoked outside the lock.
|
|
||||||
mHalService.stopRecognition(mHandle);
|
mHalService.stopRecognition(mHandle);
|
||||||
|
|
||||||
// No more callbacks for this model after this point.
|
|
||||||
synchronized (SoundTriggerModule.this) {
|
synchronized (SoundTriggerModule.this) {
|
||||||
// Generate an abortion callback to the client if the model is still active.
|
mIsStopping = false;
|
||||||
if (getState() == ModelState.ACTIVE) {
|
setState(ModelState.LOADED);
|
||||||
if (mCallback != null) {
|
|
||||||
try {
|
|
||||||
switch (mType) {
|
|
||||||
case SoundModelType.GENERIC:
|
|
||||||
mCallback.onRecognition(mHandle, AidlUtil.newAbortEvent(),
|
|
||||||
mSession.mSessionHandle);
|
|
||||||
break;
|
|
||||||
case SoundModelType.KEYPHRASE:
|
|
||||||
mCallback.onPhraseRecognition(mHandle,
|
|
||||||
AidlUtil.newAbortPhraseEvent(),
|
|
||||||
mSession.mSessionHandle);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new RuntimeException(
|
|
||||||
"Unexpected model type: " + mType);
|
|
||||||
}
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setState(ModelState.LOADED);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -502,9 +484,13 @@ class SoundTriggerModule implements IBinder.DeathRecipient, ISoundTriggerHal.Glo
|
|||||||
@NonNull RecognitionEventSys event) {
|
@NonNull RecognitionEventSys event) {
|
||||||
ISoundTriggerCallback callback;
|
ISoundTriggerCallback callback;
|
||||||
synchronized (SoundTriggerModule.this) {
|
synchronized (SoundTriggerModule.this) {
|
||||||
|
if (mRecognitionToken == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!event.recognitionEvent.recognitionStillActive) {
|
if (!event.recognitionEvent.recognitionStillActive) {
|
||||||
setState(ModelState.LOADED);
|
setState(ModelState.LOADED);
|
||||||
}
|
}
|
||||||
|
event.token = mRecognitionToken;
|
||||||
callback = mCallback;
|
callback = mCallback;
|
||||||
}
|
}
|
||||||
// The callback must be invoked outside of the lock.
|
// The callback must be invoked outside of the lock.
|
||||||
@@ -523,12 +509,15 @@ class SoundTriggerModule implements IBinder.DeathRecipient, ISoundTriggerHal.Glo
|
|||||||
@NonNull PhraseRecognitionEventSys event) {
|
@NonNull PhraseRecognitionEventSys event) {
|
||||||
ISoundTriggerCallback callback;
|
ISoundTriggerCallback callback;
|
||||||
synchronized (SoundTriggerModule.this) {
|
synchronized (SoundTriggerModule.this) {
|
||||||
|
if (mRecognitionToken == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!event.phraseRecognitionEvent.common.recognitionStillActive) {
|
if (!event.phraseRecognitionEvent.common.recognitionStillActive) {
|
||||||
setState(ModelState.LOADED);
|
setState(ModelState.LOADED);
|
||||||
}
|
}
|
||||||
|
event.token = mRecognitionToken;
|
||||||
callback = mCallback;
|
callback = mCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The callback must be invoked outside of the lock.
|
// The callback must be invoked outside of the lock.
|
||||||
try {
|
try {
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
@@ -559,5 +548,4 @@ class SoundTriggerModule implements IBinder.DeathRecipient, ISoundTriggerHal.Glo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user