Merge "Fix unsynchronized access to model hashmap" into nyc-dev

This commit is contained in:
Ryan Bavetta
2016-03-09 00:05:31 +00:00
committed by Android (Google) Code Review

View File

@@ -171,7 +171,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
// Fetch a ModelData instance from the hash map. Creates a new one if none // Fetch a ModelData instance from the hash map. Creates a new one if none
// exists. // exists.
ModelData modelData = getOrCreateGenericModelData(modelId); ModelData modelData = getOrCreateGenericModelDataLocked(modelId);
IRecognitionStatusCallback oldCallback = modelData.getCallback(); IRecognitionStatusCallback oldCallback = modelData.getCallback();
if (oldCallback != null) { if (oldCallback != null) {
@@ -373,7 +373,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
// Also clear the internal state once the recognition has been stopped. // Also clear the internal state once the recognition has been stopped.
modelData.setLoaded(); modelData.setLoaded();
modelData.clearCallback(); modelData.clearCallback();
if (!computeRecognitionRunning()) { if (!computeRecognitionRunningLocked()) {
internalClearGlobalStateLocked(); internalClearGlobalStateLocked();
} }
return status; return status;
@@ -505,12 +505,12 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
if (modelId == null || mModule == null) { if (modelId == null || mModule == null) {
return STATUS_ERROR; return STATUS_ERROR;
} }
ModelData modelData = mGenericModelDataMap.get(modelId);
if (modelData == null) {
Slog.w(TAG, "Unload error: Attempting unload invalid generic model with id:" + modelId);
return STATUS_ERROR;
}
synchronized (mLock) { synchronized (mLock) {
ModelData modelData = mGenericModelDataMap.get(modelId);
if (modelData == null) {
Slog.w(TAG, "Unload error: Attempting unload invalid generic model with id:" + modelId);
return STATUS_ERROR;
}
if (!modelData.isModelLoaded()) { if (!modelData.isModelLoaded()) {
// Nothing to do here. // Nothing to do here.
Slog.i(TAG, "Unload: Given generic model is not loaded:" + modelId); Slog.i(TAG, "Unload: Given generic model is not loaded:" + modelId);
@@ -530,7 +530,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
Slog.w(TAG, "unloadGenericSoundModel() force-marking model as unloaded."); Slog.w(TAG, "unloadGenericSoundModel() force-marking model as unloaded.");
} }
mGenericModelDataMap.remove(modelId); mGenericModelDataMap.remove(modelId);
if (DBG) dumpGenericModelState(); if (DBG) dumpGenericModelStateLocked();
return status; return status;
} }
} }
@@ -580,7 +580,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
if (event.status != SoundTrigger.RECOGNITION_STATUS_SUCCESS) { if (event.status != SoundTrigger.RECOGNITION_STATUS_SUCCESS) {
return; return;
} }
ModelData model = getModelDataFor(event.soundModelHandle); ModelData model = getModelDataForLocked(event.soundModelHandle);
if (model == null) { if (model == null) {
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);
@@ -919,7 +919,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
mIsPowerSaveMode = mPowerManager.isPowerSaveMode(); mIsPowerSaveMode = mPowerManager.isPowerSaveMode();
} }
private ModelData getOrCreateGenericModelData(UUID modelId) { private ModelData getOrCreateGenericModelDataLocked(UUID modelId) {
ModelData modelData = mGenericModelDataMap.get(modelId); ModelData modelData = mGenericModelDataMap.get(modelId);
if (modelData == null) { if (modelData == null) {
modelData = new ModelData(modelId); modelData = new ModelData(modelId);
@@ -932,7 +932,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
// Instead of maintaining a second hashmap of modelHandle -> ModelData, we just // Instead of maintaining a second hashmap of modelHandle -> ModelData, we just
// iterate through to find the right object (since we don't expect 100s of models // iterate through to find the right object (since we don't expect 100s of models
// to be stored). // to be stored).
private ModelData getModelDataFor(int modelHandle) { private ModelData getModelDataForLocked(int modelHandle) {
// Fetch ModelData object corresponding to the model handle. // Fetch ModelData object corresponding to the model handle.
for (ModelData model : mGenericModelDataMap.values()) { for (ModelData model : mGenericModelDataMap.values()) {
if (model.getHandle() == modelHandle) { if (model.getHandle() == modelHandle) {
@@ -988,7 +988,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
} }
} }
} }
if (DBG) dumpGenericModelState(); if (DBG) dumpGenericModelStateLocked();
return status; return status;
} }
@@ -1017,11 +1017,11 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
} }
} }
} }
if (DBG) dumpGenericModelState(); if (DBG) dumpGenericModelStateLocked();
return status; return status;
} }
private void dumpGenericModelState() { private void dumpGenericModelStateLocked() {
for (UUID modelId : mGenericModelDataMap.keySet()) { for (UUID modelId : mGenericModelDataMap.keySet()) {
ModelData modelData = mGenericModelDataMap.get(modelId); ModelData modelData = mGenericModelDataMap.get(modelId);
Slog.i(TAG, "Model :" + modelData.toString()); Slog.i(TAG, "Model :" + modelData.toString());
@@ -1030,28 +1030,24 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
// Computes whether we have any recognition running at all (voice or generic). Sets // Computes whether we have any recognition running at all (voice or generic). Sets
// the mRecognitionRunning variable with the result. // the mRecognitionRunning variable with the result.
private boolean computeRecognitionRunning() { private boolean computeRecognitionRunningLocked() {
synchronized (mLock) { if (mModuleProperties == null || mModule == null) {
if (mModuleProperties == null || mModule == null) { mRecognitionRunning = false;
mRecognitionRunning = false; return mRecognitionRunning;
return mRecognitionRunning; }
} if (mKeyphraseListener != null && mKeyphraseStarted &&
if (mKeyphraseListener != null && mCurrentKeyphraseModelHandle != INVALID_VALUE && mCurrentSoundModel != null) {
mKeyphraseStarted && mRecognitionRunning = true;
mCurrentKeyphraseModelHandle != INVALID_VALUE && return mRecognitionRunning;
mCurrentSoundModel != null) { }
for (UUID modelId : mGenericModelDataMap.keySet()) {
ModelData modelData = mGenericModelDataMap.get(modelId);
if (modelData.isModelStarted()) {
mRecognitionRunning = true; mRecognitionRunning = true;
return mRecognitionRunning; return mRecognitionRunning;
} }
for (UUID modelId : mGenericModelDataMap.keySet()) {
ModelData modelData = mGenericModelDataMap.get(modelId);
if (modelData.isModelStarted()) {
mRecognitionRunning = true;
return mRecognitionRunning;
}
}
mRecognitionRunning = false;
} }
mRecognitionRunning = false;
return mRecognitionRunning; return mRecognitionRunning;
} }