Protect STHelper from calls after detach am: 14de650038
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22477697 Change-Id: I97c32184b64d25960e249112d843140d32dbe30e Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -49,6 +49,7 @@ import android.telephony.PhoneStateListener;
|
|||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.logging.MetricsLogger;
|
import com.android.internal.logging.MetricsLogger;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
@@ -129,6 +130,9 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
private final Function<SoundTrigger.StatusListener, SoundTriggerModule> mModuleProvider;
|
private final Function<SoundTrigger.StatusListener, SoundTriggerModule> mModuleProvider;
|
||||||
private final Supplier<List<ModuleProperties>> mModulePropertiesProvider;
|
private final Supplier<List<ModuleProperties>> mModulePropertiesProvider;
|
||||||
|
|
||||||
|
@GuardedBy("mLock")
|
||||||
|
private boolean mIsDetached = false;
|
||||||
|
|
||||||
SoundTriggerHelper(Context context,
|
SoundTriggerHelper(Context context,
|
||||||
@NonNull Function<SoundTrigger.StatusListener, SoundTriggerModule> moduleProvider,
|
@NonNull Function<SoundTrigger.StatusListener, SoundTriggerModule> moduleProvider,
|
||||||
int moduleId,
|
int moduleId,
|
||||||
@@ -184,7 +188,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
* recognition.
|
* recognition.
|
||||||
* @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
|
* @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
|
||||||
*/
|
*/
|
||||||
int startGenericRecognition(UUID modelId, GenericSoundModel soundModel,
|
public int startGenericRecognition(UUID modelId, GenericSoundModel soundModel,
|
||||||
IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig,
|
IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig,
|
||||||
boolean runInBatterySaverMode) {
|
boolean runInBatterySaverMode) {
|
||||||
MetricsLogger.count(mContext, "sth_start_recognition", 1);
|
MetricsLogger.count(mContext, "sth_start_recognition", 1);
|
||||||
@@ -195,6 +199,9 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
|
if (mIsDetached) {
|
||||||
|
throw new IllegalStateException("SoundTriggerHelper has been detached");
|
||||||
|
}
|
||||||
ModelData modelData = getOrCreateGenericModelDataLocked(modelId);
|
ModelData modelData = getOrCreateGenericModelDataLocked(modelId);
|
||||||
if (modelData == null) {
|
if (modelData == null) {
|
||||||
Slog.w(TAG, "Irrecoverable error occurred, check UUID / sound model data.");
|
Slog.w(TAG, "Irrecoverable error occurred, check UUID / sound model data.");
|
||||||
@@ -214,7 +221,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
* @param callback The callback for the recognition events related to the given keyphrase.
|
* @param callback The callback for the recognition events related to the given keyphrase.
|
||||||
* @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
|
* @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
|
||||||
*/
|
*/
|
||||||
int startKeyphraseRecognition(int keyphraseId, KeyphraseSoundModel soundModel,
|
public int startKeyphraseRecognition(int keyphraseId, KeyphraseSoundModel soundModel,
|
||||||
IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig,
|
IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig,
|
||||||
boolean runInBatterySaverMode) {
|
boolean runInBatterySaverMode) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
@@ -223,6 +230,10 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mIsDetached) {
|
||||||
|
throw new IllegalStateException("SoundTriggerHelper has been detached");
|
||||||
|
}
|
||||||
|
|
||||||
if (DBG) {
|
if (DBG) {
|
||||||
Slog.d(TAG, "startKeyphraseRecognition for keyphraseId=" + keyphraseId
|
Slog.d(TAG, "startKeyphraseRecognition for keyphraseId=" + keyphraseId
|
||||||
+ " soundModel=" + soundModel + ", callback=" + callback.asBinder()
|
+ " soundModel=" + soundModel + ", callback=" + callback.asBinder()
|
||||||
@@ -311,7 +322,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
* for the recognition.
|
* for the recognition.
|
||||||
* @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
|
* @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
|
||||||
*/
|
*/
|
||||||
int startRecognition(SoundModel soundModel, ModelData modelData,
|
private int startRecognition(SoundModel soundModel, ModelData modelData,
|
||||||
IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig,
|
IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig,
|
||||||
int keyphraseId, boolean runInBatterySaverMode) {
|
int keyphraseId, boolean runInBatterySaverMode) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
@@ -385,7 +396,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
*
|
*
|
||||||
* @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
|
* @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
|
||||||
*/
|
*/
|
||||||
int stopGenericRecognition(UUID modelId, IRecognitionStatusCallback callback) {
|
public int stopGenericRecognition(UUID modelId, IRecognitionStatusCallback callback) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
MetricsLogger.count(mContext, "sth_stop_recognition", 1);
|
MetricsLogger.count(mContext, "sth_stop_recognition", 1);
|
||||||
if (callback == null || modelId == null) {
|
if (callback == null || modelId == null) {
|
||||||
@@ -393,7 +404,9 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
modelId);
|
modelId);
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
if (mIsDetached) {
|
||||||
|
throw new IllegalStateException("SoundTriggerHelper has been detached");
|
||||||
|
}
|
||||||
ModelData modelData = mModelDataMap.get(modelId);
|
ModelData modelData = mModelDataMap.get(modelId);
|
||||||
if (modelData == null || !modelData.isGenericModel()) {
|
if (modelData == null || !modelData.isGenericModel()) {
|
||||||
Slog.w(TAG, "Attempting stopRecognition on invalid model with id:" + modelId);
|
Slog.w(TAG, "Attempting stopRecognition on invalid model with id:" + modelId);
|
||||||
@@ -418,7 +431,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
*
|
*
|
||||||
* @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
|
* @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
|
||||||
*/
|
*/
|
||||||
int stopKeyphraseRecognition(int keyphraseId, IRecognitionStatusCallback callback) {
|
public int stopKeyphraseRecognition(int keyphraseId, IRecognitionStatusCallback callback) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
MetricsLogger.count(mContext, "sth_stop_recognition", 1);
|
MetricsLogger.count(mContext, "sth_stop_recognition", 1);
|
||||||
if (callback == null) {
|
if (callback == null) {
|
||||||
@@ -426,7 +439,9 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
keyphraseId);
|
keyphraseId);
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
if (mIsDetached) {
|
||||||
|
throw new IllegalStateException("SoundTriggerHelper has been detached");
|
||||||
|
}
|
||||||
ModelData modelData = getKeyphraseModelDataLocked(keyphraseId);
|
ModelData modelData = getKeyphraseModelDataLocked(keyphraseId);
|
||||||
if (modelData == null || !modelData.isKeyphraseModel()) {
|
if (modelData == null || !modelData.isKeyphraseModel()) {
|
||||||
Slog.w(TAG, "No model exists for given keyphrase Id " + keyphraseId);
|
Slog.w(TAG, "No model exists for given keyphrase Id " + keyphraseId);
|
||||||
@@ -538,6 +553,11 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ModuleProperties getModuleProperties() {
|
public ModuleProperties getModuleProperties() {
|
||||||
|
synchronized (mLock) {
|
||||||
|
if (mIsDetached) {
|
||||||
|
throw new IllegalStateException("SoundTriggerHelper has been detached");
|
||||||
|
}
|
||||||
|
}
|
||||||
for (ModuleProperties moduleProperties : mModulePropertiesProvider.get()) {
|
for (ModuleProperties moduleProperties : mModulePropertiesProvider.get()) {
|
||||||
if (moduleProperties.getId() == mModuleId) {
|
if (moduleProperties.getId() == mModuleId) {
|
||||||
return moduleProperties;
|
return moduleProperties;
|
||||||
@@ -547,7 +567,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
int unloadKeyphraseSoundModel(int keyphraseId) {
|
public int unloadKeyphraseSoundModel(int keyphraseId) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
MetricsLogger.count(mContext, "sth_unload_keyphrase_sound_model", 1);
|
MetricsLogger.count(mContext, "sth_unload_keyphrase_sound_model", 1);
|
||||||
ModelData modelData = getKeyphraseModelDataLocked(keyphraseId);
|
ModelData modelData = getKeyphraseModelDataLocked(keyphraseId);
|
||||||
@@ -555,7 +575,9 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
|| !modelData.isKeyphraseModel()) {
|
|| !modelData.isKeyphraseModel()) {
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
if (mIsDetached) {
|
||||||
|
throw new IllegalStateException("SoundTriggerHelper has been detached");
|
||||||
|
}
|
||||||
// Stop recognition if it's the current one.
|
// Stop recognition if it's the current one.
|
||||||
modelData.setRequested(false);
|
modelData.setRequested(false);
|
||||||
int status = updateRecognitionLocked(modelData, false);
|
int status = updateRecognitionLocked(modelData, false);
|
||||||
@@ -574,12 +596,15 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int unloadGenericSoundModel(UUID modelId) {
|
public int unloadGenericSoundModel(UUID modelId) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
MetricsLogger.count(mContext, "sth_unload_generic_sound_model", 1);
|
MetricsLogger.count(mContext, "sth_unload_generic_sound_model", 1);
|
||||||
if (modelId == null || mModule == null) {
|
if (modelId == null || mModule == null) {
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
if (mIsDetached) {
|
||||||
|
throw new IllegalStateException("SoundTriggerHelper has been detached");
|
||||||
|
}
|
||||||
ModelData modelData = mModelDataMap.get(modelId);
|
ModelData modelData = mModelDataMap.get(modelId);
|
||||||
if (modelData == null || !modelData.isGenericModel()) {
|
if (modelData == null || !modelData.isGenericModel()) {
|
||||||
Slog.w(TAG, "Unload error: Attempting unload invalid generic model with id:" +
|
Slog.w(TAG, "Unload error: Attempting unload invalid generic model with id:" +
|
||||||
@@ -615,19 +640,25 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isRecognitionRequested(UUID modelId) {
|
public boolean isRecognitionRequested(UUID modelId) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
|
if (mIsDetached) {
|
||||||
|
throw new IllegalStateException("SoundTriggerHelper has been detached");
|
||||||
|
}
|
||||||
ModelData modelData = mModelDataMap.get(modelId);
|
ModelData modelData = mModelDataMap.get(modelId);
|
||||||
return modelData != null && modelData.isRequested();
|
return modelData != null && modelData.isRequested();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int getGenericModelState(UUID modelId) {
|
public int getGenericModelState(UUID modelId) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
MetricsLogger.count(mContext, "sth_get_generic_model_state", 1);
|
MetricsLogger.count(mContext, "sth_get_generic_model_state", 1);
|
||||||
if (modelId == null || mModule == null) {
|
if (modelId == null || mModule == null) {
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
if (mIsDetached) {
|
||||||
|
throw new IllegalStateException("SoundTriggerHelper has been detached");
|
||||||
|
}
|
||||||
ModelData modelData = mModelDataMap.get(modelId);
|
ModelData modelData = mModelDataMap.get(modelId);
|
||||||
if (modelData == null || !modelData.isGenericModel()) {
|
if (modelData == null || !modelData.isGenericModel()) {
|
||||||
Slog.w(TAG, "GetGenericModelState error: Invalid generic model id:" +
|
Slog.w(TAG, "GetGenericModelState error: Invalid generic model id:" +
|
||||||
@@ -647,19 +678,20 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int getKeyphraseModelState(UUID modelId) {
|
public int setParameter(UUID modelId, @ModelParams int modelParam, int value) {
|
||||||
Slog.w(TAG, "GetKeyphraseModelState error: Not implemented");
|
|
||||||
return STATUS_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int setParameter(UUID modelId, @ModelParams int modelParam, int value) {
|
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
|
if (mIsDetached) {
|
||||||
|
throw new IllegalStateException("SoundTriggerHelper has been detached");
|
||||||
|
}
|
||||||
return setParameterLocked(mModelDataMap.get(modelId), modelParam, value);
|
return setParameterLocked(mModelDataMap.get(modelId), modelParam, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int setKeyphraseParameter(int keyphraseId, @ModelParams int modelParam, int value) {
|
public int setKeyphraseParameter(int keyphraseId, @ModelParams int modelParam, int value) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
|
if (mIsDetached) {
|
||||||
|
throw new IllegalStateException("SoundTriggerHelper has been detached");
|
||||||
|
}
|
||||||
return setParameterLocked(getKeyphraseModelDataLocked(keyphraseId), modelParam, value);
|
return setParameterLocked(getKeyphraseModelDataLocked(keyphraseId), modelParam, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -678,14 +710,20 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
return mModule.setParameter(modelData.getHandle(), modelParam, value);
|
return mModule.setParameter(modelData.getHandle(), modelParam, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
int getParameter(@NonNull UUID modelId, @ModelParams int modelParam) {
|
public int getParameter(@NonNull UUID modelId, @ModelParams int modelParam) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
|
if (mIsDetached) {
|
||||||
|
throw new IllegalStateException("SoundTriggerHelper has been detached");
|
||||||
|
}
|
||||||
return getParameterLocked(mModelDataMap.get(modelId), modelParam);
|
return getParameterLocked(mModelDataMap.get(modelId), modelParam);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int getKeyphraseParameter(int keyphraseId, @ModelParams int modelParam) {
|
public int getKeyphraseParameter(int keyphraseId, @ModelParams int modelParam) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
|
if (mIsDetached) {
|
||||||
|
throw new IllegalStateException("SoundTriggerHelper has been detached");
|
||||||
|
}
|
||||||
return getParameterLocked(getKeyphraseModelDataLocked(keyphraseId), modelParam);
|
return getParameterLocked(getKeyphraseModelDataLocked(keyphraseId), modelParam);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -707,15 +745,21 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
ModelParamRange queryParameter(@NonNull UUID modelId, @ModelParams int modelParam) {
|
public ModelParamRange queryParameter(@NonNull UUID modelId, @ModelParams int modelParam) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
|
if (mIsDetached) {
|
||||||
|
throw new IllegalStateException("SoundTriggerHelper has been detached");
|
||||||
|
}
|
||||||
return queryParameterLocked(mModelDataMap.get(modelId), modelParam);
|
return queryParameterLocked(mModelDataMap.get(modelId), modelParam);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
ModelParamRange queryKeyphraseParameter(int keyphraseId, @ModelParams int modelParam) {
|
public ModelParamRange queryKeyphraseParameter(int keyphraseId, @ModelParams int modelParam) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
|
if (mIsDetached) {
|
||||||
|
throw new IllegalStateException("SoundTriggerHelper has been detached");
|
||||||
|
}
|
||||||
return queryParameterLocked(getKeyphraseModelDataLocked(keyphraseId), modelParam);
|
return queryParameterLocked(getKeyphraseModelDataLocked(keyphraseId), modelParam);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1115,12 +1159,14 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
*/
|
*/
|
||||||
public void detach() {
|
public void detach() {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
|
if (mIsDetached) return;
|
||||||
for (ModelData model : mModelDataMap.values()) {
|
for (ModelData model : mModelDataMap.values()) {
|
||||||
forceStopAndUnloadModelLocked(model, null);
|
forceStopAndUnloadModelLocked(model, null);
|
||||||
}
|
}
|
||||||
mModelDataMap.clear();
|
mModelDataMap.clear();
|
||||||
internalClearGlobalStateLocked();
|
internalClearGlobalStateLocked();
|
||||||
if (mModule != null) {
|
if (mModule != null) {
|
||||||
|
mIsDetached = true;
|
||||||
mModule.detach();
|
mModule.detach();
|
||||||
mModule = null;
|
mModule = null;
|
||||||
}
|
}
|
||||||
@@ -1289,7 +1335,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
|
|||||||
* @param modelData Model data to be used for recognition
|
* @param modelData Model data to be used for recognition
|
||||||
* @return True if device state allows recognition to run, false if not.
|
* @return True if device state allows recognition to run, false if not.
|
||||||
*/
|
*/
|
||||||
boolean isRecognitionAllowedByPowerState(ModelData modelData) {
|
private boolean isRecognitionAllowedByPowerState(ModelData modelData) {
|
||||||
return mSoundTriggerPowerSaveMode == PowerManager.SOUND_TRIGGER_MODE_ALL_ENABLED
|
return mSoundTriggerPowerSaveMode == PowerManager.SOUND_TRIGGER_MODE_ALL_ENABLED
|
||||||
|| (mSoundTriggerPowerSaveMode == PowerManager.SOUND_TRIGGER_MODE_CRITICAL_ONLY
|
|| (mSoundTriggerPowerSaveMode == PowerManager.SOUND_TRIGGER_MODE_CRITICAL_ONLY
|
||||||
&& modelData.shouldRunInBatterySaverMode());
|
&& modelData.shouldRunInBatterySaverMode());
|
||||||
|
|||||||
Reference in New Issue
Block a user