Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac0ceb03 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Clean up dead objects when detected in the SoundTriggerHelper"

parents ca2cd33b 2411a2c3
Loading
Loading
Loading
Loading
+62 −11
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent;
import android.hardware.soundtrigger.SoundTrigger.SoundModel;
import android.hardware.soundtrigger.SoundTrigger.SoundModelEvent;
import android.hardware.soundtrigger.SoundTriggerModule;
import android.os.DeadObjectException;
import android.os.PowerManager;
import android.os.RemoteException;
import android.telephony.PhoneStateListener;
@@ -46,6 +47,8 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;

/**
@@ -376,7 +379,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {

            ModelData modelData = getKeyphraseModelDataLocked(keyphraseId);
            if (modelData == null || !modelData.isKeyphraseModel()) {
                Slog.e(TAG, "No model exists for given keyphrase Id.");
                Slog.e(TAG, "No model exists for given keyphrase Id " + keyphraseId);
                return STATUS_ERROR;
            }

@@ -609,13 +612,16 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
            return;
        }

        model.setStopped();
        try {
            callback.onGenericSoundTriggerDetected((GenericRecognitionEvent) event);
        } catch (DeadObjectException e) {
            forceStopAndUnloadModel(model, e);
            return;
        } catch (RemoteException e) {
            Slog.w(TAG, "RemoteException in onGenericSoundTriggerDetected", e);
        }

        model.setStopped();
        RecognitionConfig config = model.getRecognitionConfig();
        if (config == null) {
            Slog.w(TAG, "Generic recognition event: Null RecognitionConfig for model handle: " +
@@ -699,6 +705,8 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
            modelData.setStopped();
            try {
                modelData.getCallback().onRecognitionPaused();
            } catch (DeadObjectException e) {
                forceStopAndUnloadModel(modelData, e);
            } catch (RemoteException e) {
                Slog.w(TAG, "RemoteException in onRecognitionPaused", e);
            }
@@ -710,8 +718,6 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
        MetricsLogger.count(mContext, "sth_recognition_failure_event", 1);
        try {
            sendErrorCallbacksToAll(STATUS_ERROR);
        } catch (RemoteException e) {
            Slog.w(TAG, "RemoteException in onError", e);
        } finally {
            internalClearModelStateLocked();
            internalClearGlobalStateLocked();
@@ -748,15 +754,17 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
            Slog.w(TAG, "Received onRecognition event without callback for keyphrase model.");
            return;
        }
        modelData.setStopped();

        try {
            modelData.getCallback().onKeyphraseDetected((KeyphraseRecognitionEvent) event);
        } catch (DeadObjectException e) {
            forceStopAndUnloadModel(modelData, e);
            return;
        } catch (RemoteException e) {
            Slog.w(TAG, "RemoteException in onKeyphraseDetected", e);
        }

        modelData.setStopped();

        RecognitionConfig config = modelData.getRecognitionConfig();
        if (config != null) {
            // Whether we should continue by starting this again.
@@ -793,8 +801,6 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
        try {
            MetricsLogger.count(mContext, "sth_service_died", 1);
            sendErrorCallbacksToAll(SoundTrigger.STATUS_DEAD_OBJECT);
        } catch (RemoteException e) {
            Slog.w(TAG, "RemoteException in onError", e);
        } finally {
            internalClearModelStateLocked();
            internalClearGlobalStateLocked();
@@ -879,11 +885,48 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
    }

    // Sends an error callback to all models with a valid registered callback.
    private void sendErrorCallbacksToAll(int errorCode) throws RemoteException {
    private void sendErrorCallbacksToAll(int errorCode) {
        for (ModelData modelData : mModelDataMap.values()) {
            IRecognitionStatusCallback callback = modelData.getCallback();
            if (callback != null) {
                callback.onError(STATUS_ERROR);
                try {
                    callback.onError(errorCode);
                } catch (RemoteException e) {
                    Slog.w(TAG, "RemoteException sendErrorCallbacksToAll for model handle " +
                            modelData.getHandle(), e);
                }
            }
        }
    }

    private void forceStopAndUnloadModel(ModelData modelData, Exception exception) {
        if (exception != null) {
          Slog.e(TAG, "forceStopAndUnloadModel", exception);
        }
        if (modelData.isModelStarted()) {
            Slog.d(TAG, "Stopping previously started dangling model " + modelData.getHandle());
            if (mModule.stopRecognition(modelData.getHandle()) != STATUS_OK) {
                modelData.setStopped();
                modelData.setRequested(false);
            } else {
                Slog.e(TAG, "Failed to stop model " + modelData.getHandle());
            }
        }
        if (modelData.isModelLoaded()) {
            Slog.d(TAG, "Unloading previously loaded dangling model " + modelData.getHandle());
            if (mModule.unloadSoundModel(modelData.getHandle()) == STATUS_OK) {
                // Remove the model data from existence.
                mModelDataMap.remove(modelData.getModelId());
                Iterator it = mKeyphraseUuidMap.entrySet().iterator();
                while (it.hasNext()) {
                    Map.Entry pair = (Map.Entry) it.next();
                    if (pair.getValue().equals(modelData.getModelId())) {
                        it.remove();
                    }
                }
                modelData.clearState();
            } else {
                Slog.e(TAG, "Failed to unload model " + modelData.getHandle());
            }
        }
    }
@@ -976,6 +1019,8 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
            if (notify) {
                try {
                    callback.onError(status);
                } catch (DeadObjectException e) {
                    forceStopAndUnloadModel(modelData, e);
                } catch (RemoteException e) {
                    Slog.w(TAG, "RemoteException in onError", e);
                }
@@ -988,6 +1033,8 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
            if (notify) {
                try {
                    callback.onRecognitionResumed();
                } catch (DeadObjectException e) {
                    forceStopAndUnloadModel(modelData, e);
                } catch (RemoteException e) {
                    Slog.w(TAG, "RemoteException in onRecognitionResumed", e);
                }
@@ -1013,6 +1060,8 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
            if (notify) {
                try {
                    callback.onError(status);
                } catch (DeadObjectException e) {
                    forceStopAndUnloadModel(modelData, e);
                } catch (RemoteException e) {
                    Slog.w(TAG, "RemoteException in onError", e);
                }
@@ -1024,6 +1073,8 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
            if (notify) {
                try {
                    callback.onRecognitionPaused();
                } catch (DeadObjectException e) {
                    forceStopAndUnloadModel(modelData, e);
                } catch (RemoteException e) {
                    Slog.w(TAG, "RemoteException in onRecognitionPaused", e);
                }