Merge "Prevent ConcurrentModificationException in updateAllRecognitions" into oc-dev

am: 484fb951e0

Change-Id: Ice2c1b83135368f11884f4d8b2cfab138715e69a
This commit is contained in:
Chris Thornton
2017-06-12 16:25:59 +00:00
committed by android-build-merger

View File

@@ -191,7 +191,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
// Process existing model first. // Process existing model first.
if (model != null && !model.getModelId().equals(soundModel.uuid)) { if (model != null && !model.getModelId().equals(soundModel.uuid)) {
// The existing model has a different UUID, should be replaced. // The existing model has a different UUID, should be replaced.
int status = cleanUpExistingKeyphraseModel(model); int status = cleanUpExistingKeyphraseModelLocked(model);
if (status != STATUS_OK) { if (status != STATUS_OK) {
return status; return status;
} }
@@ -210,7 +210,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
} }
} }
private int cleanUpExistingKeyphraseModel(ModelData modelData) { private int cleanUpExistingKeyphraseModelLocked(ModelData modelData) {
// Stop and clean up a previous ModelData if one exists. This usually is used when the // Stop and clean up a previous ModelData if one exists. This usually is used when the
// previous model has a different UUID for the same keyphrase ID. // previous model has a different UUID for the same keyphrase ID.
int status = tryStopAndUnloadLocked(modelData, true /* stop */, true /* unload */); int status = tryStopAndUnloadLocked(modelData, true /* stop */, true /* unload */);
@@ -616,7 +616,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
try { try {
callback.onGenericSoundTriggerDetected((GenericRecognitionEvent) event); callback.onGenericSoundTriggerDetected((GenericRecognitionEvent) event);
} catch (DeadObjectException e) { } catch (DeadObjectException e) {
forceStopAndUnloadModel(model, e); forceStopAndUnloadModelLocked(model, e);
return; return;
} catch (RemoteException e) { } catch (RemoteException e) {
Slog.w(TAG, "RemoteException in onGenericSoundTriggerDetected", e); Slog.w(TAG, "RemoteException in onGenericSoundTriggerDetected", e);
@@ -706,7 +706,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
try { try {
modelData.getCallback().onRecognitionPaused(); modelData.getCallback().onRecognitionPaused();
} catch (DeadObjectException e) { } catch (DeadObjectException e) {
forceStopAndUnloadModel(modelData, e); forceStopAndUnloadModelLocked(modelData, e);
} catch (RemoteException e) { } catch (RemoteException e) {
Slog.w(TAG, "RemoteException in onRecognitionPaused", e); Slog.w(TAG, "RemoteException in onRecognitionPaused", e);
} }
@@ -717,7 +717,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
Slog.w(TAG, "Recognition failure"); Slog.w(TAG, "Recognition failure");
MetricsLogger.count(mContext, "sth_recognition_failure_event", 1); MetricsLogger.count(mContext, "sth_recognition_failure_event", 1);
try { try {
sendErrorCallbacksToAll(STATUS_ERROR); sendErrorCallbacksToAllLocked(STATUS_ERROR);
} finally { } finally {
internalClearModelStateLocked(); internalClearModelStateLocked();
internalClearGlobalStateLocked(); internalClearGlobalStateLocked();
@@ -759,7 +759,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
try { try {
modelData.getCallback().onKeyphraseDetected((KeyphraseRecognitionEvent) event); modelData.getCallback().onKeyphraseDetected((KeyphraseRecognitionEvent) event);
} catch (DeadObjectException e) { } catch (DeadObjectException e) {
forceStopAndUnloadModel(modelData, e); forceStopAndUnloadModelLocked(modelData, e);
return; return;
} catch (RemoteException e) { } catch (RemoteException e) {
Slog.w(TAG, "RemoteException in onKeyphraseDetected", e); Slog.w(TAG, "RemoteException in onKeyphraseDetected", e);
@@ -778,7 +778,9 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
private void updateAllRecognitionsLocked(boolean notify) { private void updateAllRecognitionsLocked(boolean notify) {
boolean isAllowed = isRecognitionAllowed(); boolean isAllowed = isRecognitionAllowed();
for (ModelData modelData : mModelDataMap.values()) { // updateRecognitionLocked can possibly update the list of models
ArrayList<ModelData> modelDatas = new ArrayList<ModelData>(mModelDataMap.values());
for (ModelData modelData : modelDatas) {
updateRecognitionLocked(modelData, isAllowed, notify); updateRecognitionLocked(modelData, isAllowed, notify);
} }
} }
@@ -800,7 +802,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
private void onServiceDiedLocked() { private void onServiceDiedLocked() {
try { try {
MetricsLogger.count(mContext, "sth_service_died", 1); MetricsLogger.count(mContext, "sth_service_died", 1);
sendErrorCallbacksToAll(SoundTrigger.STATUS_DEAD_OBJECT); sendErrorCallbacksToAllLocked(SoundTrigger.STATUS_DEAD_OBJECT);
} finally { } finally {
internalClearModelStateLocked(); internalClearModelStateLocked();
internalClearGlobalStateLocked(); internalClearGlobalStateLocked();
@@ -885,21 +887,21 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
} }
// Sends an error callback to all models with a valid registered callback. // Sends an error callback to all models with a valid registered callback.
private void sendErrorCallbacksToAll(int errorCode) { private void sendErrorCallbacksToAllLocked(int errorCode) {
for (ModelData modelData : mModelDataMap.values()) { for (ModelData modelData : mModelDataMap.values()) {
IRecognitionStatusCallback callback = modelData.getCallback(); IRecognitionStatusCallback callback = modelData.getCallback();
if (callback != null) { if (callback != null) {
try { try {
callback.onError(errorCode); callback.onError(errorCode);
} catch (RemoteException e) { } catch (RemoteException e) {
Slog.w(TAG, "RemoteException sendErrorCallbacksToAll for model handle " + Slog.w(TAG, "RemoteException sendErrorCallbacksToAllLocked for model handle " +
modelData.getHandle(), e); modelData.getHandle(), e);
} }
} }
} }
} }
private void forceStopAndUnloadModel(ModelData modelData, Exception exception) { private void forceStopAndUnloadModelLocked(ModelData modelData, Exception exception) {
if (exception != null) { if (exception != null) {
Slog.e(TAG, "forceStopAndUnloadModel", exception); Slog.e(TAG, "forceStopAndUnloadModel", exception);
} }
@@ -1020,7 +1022,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
try { try {
callback.onError(status); callback.onError(status);
} catch (DeadObjectException e) { } catch (DeadObjectException e) {
forceStopAndUnloadModel(modelData, e); forceStopAndUnloadModelLocked(modelData, e);
} catch (RemoteException e) { } catch (RemoteException e) {
Slog.w(TAG, "RemoteException in onError", e); Slog.w(TAG, "RemoteException in onError", e);
} }
@@ -1034,7 +1036,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
try { try {
callback.onRecognitionResumed(); callback.onRecognitionResumed();
} catch (DeadObjectException e) { } catch (DeadObjectException e) {
forceStopAndUnloadModel(modelData, e); forceStopAndUnloadModelLocked(modelData, e);
} catch (RemoteException e) { } catch (RemoteException e) {
Slog.w(TAG, "RemoteException in onRecognitionResumed", e); Slog.w(TAG, "RemoteException in onRecognitionResumed", e);
} }
@@ -1061,7 +1063,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
try { try {
callback.onError(status); callback.onError(status);
} catch (DeadObjectException e) { } catch (DeadObjectException e) {
forceStopAndUnloadModel(modelData, e); forceStopAndUnloadModelLocked(modelData, e);
} catch (RemoteException e) { } catch (RemoteException e) {
Slog.w(TAG, "RemoteException in onError", e); Slog.w(TAG, "RemoteException in onError", e);
} }
@@ -1074,7 +1076,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
try { try {
callback.onRecognitionPaused(); callback.onRecognitionPaused();
} catch (DeadObjectException e) { } catch (DeadObjectException e) {
forceStopAndUnloadModel(modelData, e); forceStopAndUnloadModelLocked(modelData, e);
} catch (RemoteException e) { } catch (RemoteException e) {
Slog.w(TAG, "RemoteException in onRecognitionPaused", e); Slog.w(TAG, "RemoteException in onRecognitionPaused", e);
} }