Merge changes from topics "presubmit-am-41e144351270485b94f495fc32653e46", "presubmit-am-d52b531f305c4668b1dfe4f906403ae6" into tm-dev am: 36e2df5b5f

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17626108

Change-Id: I13f4f96a0bff8aea38fa588840420576630e1ba5
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
TreeHugger Robot
2022-04-11 21:54:42 +00:00
committed by Automerger Merge Worker

View File

@@ -84,9 +84,6 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
private static final int INVALID_VALUE = Integer.MIN_VALUE; private static final int INVALID_VALUE = Integer.MIN_VALUE;
/** Maximum time to wait for a model stop confirmation before giving up. */
private static final long STOP_TIMEOUT_MS = 5000;
/** The {@link ModuleProperties} for the system, or null if none exists. */ /** The {@link ModuleProperties} for the system, or null if none exists. */
final ModuleProperties mModuleProperties; final ModuleProperties mModuleProperties;
@@ -398,20 +395,8 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
return STATUS_OK; return STATUS_OK;
} }
int status = prepareForRecognition(modelData); return updateRecognitionLocked(modelData,
if (status != STATUS_OK) {
Slog.w(TAG, "startRecognition failed to prepare model for recognition");
return status;
}
status = startRecognitionLocked(modelData,
false /* Don't notify for synchronous calls */); false /* Don't notify for synchronous calls */);
// Initialize power save, call active state monitoring logic.
if (status == STATUS_OK) {
initializeDeviceStateListeners();
}
return status;
} }
} }
@@ -560,7 +545,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
} }
} }
if (unloadModel && modelData.isModelLoaded()) { if (unloadModel && (modelData.isModelLoaded() || modelData.isStopPending())) {
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;
@@ -834,7 +819,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
} }
if (!event.recognitionStillActive) { if (!event.recognitionStillActive) {
model.setStoppedLocked(); model.setStopped();
} }
try { try {
@@ -920,8 +905,8 @@ 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()) { if (modelData != null && (modelData.isModelStarted() || modelData.isStopPending())) {
modelData.setStoppedLocked(); modelData.setStopped();
try { try {
IRecognitionStatusCallback callback = modelData.getCallback(); IRecognitionStatusCallback callback = modelData.getCallback();
if (callback != null) { if (callback != null) {
@@ -932,6 +917,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
} catch (RemoteException e) { } catch (RemoteException e) {
Slog.w(TAG, "RemoteException in onRecognitionPaused", e); Slog.w(TAG, "RemoteException in onRecognitionPaused", e);
} }
updateRecognitionLocked(modelData, true);
} }
} }
@@ -978,7 +964,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
} }
if (!event.recognitionStillActive) { if (!event.recognitionStillActive) {
modelData.setStoppedLocked(); modelData.setStopped();
} }
try { try {
@@ -1011,16 +997,22 @@ 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()) { if (shouldStartModel == model.isModelStarted() || model.isStopPending()) {
// No-op. // No-op.
return STATUS_OK; return STATUS_OK;
} }
if (shouldStartModel) { if (shouldStartModel) {
int status = prepareForRecognition(model); int status = prepareForRecognition(model);
if (status != STATUS_OK) { if (status != STATUS_OK) {
Slog.w(TAG, "startRecognition failed to prepare model for recognition");
return status; return status;
} }
return startRecognitionLocked(model, notifyClientOnError); status = startRecognitionLocked(model, notifyClientOnError);
// Initialize power save, call active state monitoring logic.
if (status == STATUS_OK) {
initializeDeviceStateListeners();
}
return status;
} else { } else {
return stopRecognitionLocked(model, notifyClientOnError); return stopRecognitionLocked(model, notifyClientOnError);
} }
@@ -1203,10 +1195,13 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
if (mModule == null) { if (mModule == null) {
return; return;
} }
if (modelData.isModelStarted()) { if (modelData.isStopPending()) {
// 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.setStoppedLocked(); modelData.setStopped();
modelData.setRequested(false); modelData.setRequested(false);
} else { } else {
Slog.e(TAG, "Failed to stop model " + modelData.getHandle()); Slog.e(TAG, "Failed to stop model " + modelData.getHandle());
@@ -1255,7 +1250,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
private ModelData getOrCreateGenericModelDataLocked(UUID modelId) { private ModelData getOrCreateGenericModelDataLocked(UUID modelId) {
ModelData modelData = mModelDataMap.get(modelId); ModelData modelData = mModelDataMap.get(modelId);
if (modelData == null) { if (modelData == null) {
modelData = createGenericModelData(modelId); modelData = ModelData.createGenericModelData(modelId);
mModelDataMap.put(modelId, modelData); mModelDataMap.put(modelId, modelData);
} else if (!modelData.isGenericModel()) { } else if (!modelData.isGenericModel()) {
Slog.e(TAG, "UUID already used for non-generic model."); Slog.e(TAG, "UUID already used for non-generic model.");
@@ -1287,7 +1282,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
mKeyphraseUuidMap.remove(keyphraseId); mKeyphraseUuidMap.remove(keyphraseId);
mModelDataMap.remove(modelId); mModelDataMap.remove(modelId);
mKeyphraseUuidMap.put(keyphraseId, modelId); mKeyphraseUuidMap.put(keyphraseId, modelId);
ModelData modelData = createKeyphraseModelData(modelId); ModelData modelData = ModelData.createKeyphraseModelData(modelId);
mModelDataMap.put(modelId, modelData); mModelDataMap.put(modelId, modelData);
return modelData; return modelData;
} }
@@ -1419,17 +1414,8 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
Slog.w(TAG, "RemoteException in onError", e); Slog.w(TAG, "RemoteException in onError", e);
} }
} }
return status; } else {
} modelData.setStopPending();
// Wait for model to be stopped.
try {
modelData.waitStoppedLocked(STOP_TIMEOUT_MS);
} catch (InterruptedException e) {
Slog.e(TAG, "Didn't receive model stop callback");
return SoundTrigger.STATUS_ERROR;
}
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) {
@@ -1441,6 +1427,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
Slog.w(TAG, "RemoteException in onRecognitionPaused", e); Slog.w(TAG, "RemoteException in onRecognitionPaused", e);
} }
} }
}
if (DBG) { if (DBG) {
Slog.d(TAG, "Model being stopped :" + modelData.toString()); Slog.d(TAG, "Model being stopped :" + modelData.toString());
} }
@@ -1473,7 +1460,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
// This class encapsulates the callbacks, state, handles and any other information that // This class encapsulates the callbacks, state, handles and any other information that
// represents a model. // represents a model.
private class ModelData { private static class ModelData {
// Model not loaded (and hence not started). // Model not loaded (and hence not started).
static final int MODEL_NOTLOADED = 0; static final int MODEL_NOTLOADED = 0;
@@ -1483,6 +1470,9 @@ 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;
@@ -1530,9 +1520,17 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
mModelType = modelType; mModelType = modelType;
} }
static ModelData createKeyphraseModelData(UUID modelId) {
return new ModelData(modelId, SoundModel.TYPE_KEYPHRASE);
}
static ModelData createGenericModelData(UUID modelId) {
return new ModelData(modelId, SoundModel.TYPE_GENERIC_SOUND);
}
// Note that most of the functionality in this Java class will not work for // Note that most of the functionality in this Java class will not work for
// SoundModel.TYPE_UNKNOWN nevertheless we have it since lower layers support it. // SoundModel.TYPE_UNKNOWN nevertheless we have it since lower layers support it.
ModelData createModelDataOfUnknownType(UUID modelId) { static ModelData createModelDataOfUnknownType(UUID modelId) {
return new ModelData(modelId, SoundModel.TYPE_UNKNOWN); return new ModelData(modelId, SoundModel.TYPE_UNKNOWN);
} }
@@ -1552,24 +1550,20 @@ 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 setStoppedLocked() { synchronized void setStopped() {
mModelState = MODEL_LOADED; mModelState = MODEL_LOADED;
mLock.notifyAll();
} }
void waitStoppedLocked(long timeoutMs) throws InterruptedException { synchronized void setStopPending() {
long deadline = System.currentTimeMillis() + timeoutMs; mModelState = MODEL_STOP_PENDING;
while (mModelState == MODEL_STARTED) {
long waitTime = deadline - System.currentTimeMillis();
if (waitTime <= 0) {
throw new InterruptedException();
}
mLock.wait(waitTime);
}
} }
synchronized void setLoaded() { synchronized void setLoaded() {
@@ -1589,7 +1583,6 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
mRecognitionConfig = null; mRecognitionConfig = null;
mRequested = false; mRequested = false;
mCallback = null; mCallback = null;
notifyAll();
} }
synchronized void clearCallback() { synchronized void clearCallback() {
@@ -1694,12 +1687,4 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
return "Model type: " + type + "\n"; return "Model type: " + type + "\n";
} }
} }
ModelData createKeyphraseModelData(UUID modelId) {
return new ModelData(modelId, SoundModel.TYPE_KEYPHRASE);
}
ModelData createGenericModelData(UUID modelId) {
return new ModelData(modelId, SoundModel.TYPE_GENERIC_SOUND);
}
} }