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

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

Merge "Adding GetModelState button to SoundTriggerTestApp"

parents d6a7bfed 09539c9d
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -73,6 +73,14 @@
            android:text="@string/play_trigger"
            android:onClick="onPlayTriggerButtonClicked"
            android:padding="20dp" />

        <Button
            android:id="@+id/get_state_id"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/get_model_state"
            android:onClick="onGetModelStateButtonClicked"
            android:padding="20dp" />
    </LinearLayout>

    <LinearLayout
+1 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
    <string name="start_recog">Start</string>
    <string name="stop_recog">Stop</string>
    <string name="play_trigger">Play Trigger Audio</string>
    <string name="get_model_state">Get State</string>
    <string name="capture">Capture Audio</string>
    <string name="stop_capture">Stop Capturing Audio</string>
    <string name="play_capture">Play Captured Audio</string>
+8 −0
Original line number Diff line number Diff line
@@ -257,6 +257,14 @@ public class SoundTriggerTestActivity extends Activity implements SoundTriggerTe
        }
    }

    public synchronized void onGetModelStateButtonClicked(View v) {
        if (mService == null) {
            Log.e(TAG, "Can't get model state: not bound to SoundTriggerTestService");
        } else {
            mService.getModelState(mSelectedModelUuid);
        }
    }

    public synchronized void onCaptureAudioCheckboxClicked(View v) {
        // See if we have the right permissions
        if (!mService.hasMicrophonePermission()) {
+63 −7
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent;
import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
import android.media.AudioAttributes;
import android.media.AudioFormat;
import android.media.AudioManager;
@@ -46,6 +48,7 @@ import java.util.Properties;
import java.util.Random;
import java.util.UUID;


public class SoundTriggerTestService extends Service {
    private static final String TAG = "SoundTriggerTestSrv";
    private static final String INTENT_ACTION = "com.android.intent.action.MANAGE_SOUND_TRIGGER";
@@ -57,6 +60,8 @@ public class SoundTriggerTestService extends Service {
    private Random mRandom;
    private UserActivity mUserActivity;

    private static int captureCount;

    public interface UserActivity {
        void addModel(UUID modelUuid, String state);
        void setModelState(UUID modelUuid, String state);
@@ -131,6 +136,8 @@ public class SoundTriggerTestService extends Service {
                        } else if (command.equals("set_capture_timeout")) {
                            setCaptureAudioTimeout(getModelUuidFromIntent(intent),
                                    intent.getIntExtra("timeout", 5000));
                        } else if (command.equals("get_model_state")) {
                            getModelState(getModelUuidFromIntent(intent));
                        } else {
                            Log.e(TAG, "Unknown command '" + command + "'");
                        }
@@ -432,6 +439,17 @@ public class SoundTriggerTestService extends Service {
        return modelInfo != null && modelInfo.captureAudioTrack != null;
    }

    public synchronized void getModelState(UUID modelUuid) {
        ModelInfo modelInfo = mModelInfoMap.get(modelUuid);
        if (modelInfo == null) {
            postError("Could not find model for: " + modelUuid.toString());
            return;
        }
        int status = mSoundTriggerUtil.getModelState(modelUuid);
        postMessage("GetModelState for: " + modelInfo.name + " returns: "
            + status);
    }

    private void loadModelsInDataDir() {
        // Load all the models in the data dir.
        boolean loadedModel = false;
@@ -527,18 +545,29 @@ public class SoundTriggerTestService extends Service {
        }
    }


    private class CaptureAudioRecorder implements Runnable {
        private final ModelInfo mModelInfo;

        // EventPayload and RecognitionEvent are equivalant.  Only one will be non-null.
        private final SoundTriggerDetector.EventPayload mEvent;
        private final RecognitionEvent mRecognitionEvent;

        public CaptureAudioRecorder(ModelInfo modelInfo, SoundTriggerDetector.EventPayload event) {
            mModelInfo = modelInfo;
            mEvent = event;
            mRecognitionEvent = null;
        }

        public CaptureAudioRecorder(ModelInfo modelInfo, RecognitionEvent event) {
            mModelInfo = modelInfo;
            mEvent = null;
            mRecognitionEvent = event;
        }

        @Override
        public void run() {
            AudioFormat format = mEvent.getCaptureAudioFormat();
            AudioFormat format = getAudioFormat();
            if (format == null) {
                postErrorToast("No audio format in recognition event.");
                return;
@@ -600,18 +629,21 @@ public class SoundTriggerTestService extends Service {
                }

                audioRecord = new AudioRecord(attributes, format, bytesRequired,
                        mEvent.getCaptureSession());
                        getCaptureSession());

                byte[] buffer = new byte[bytesRequired];

                // Create a file so we can save the output data there for analysis later.
                FileOutputStream fos  = null;
                try {
                    fos = new FileOutputStream( new File(
                    File file = new File(
                        getFilesDir() + File.separator
                        + mModelInfo.name.replace(' ', '_')
                        + "_capture_" + format.getChannelCount() + "ch_"
                                    + format.getSampleRate() + "hz_" + encoding + ".pcm"));
                        + format.getSampleRate() + "hz_" + encoding
                        + "_" + (++captureCount) + ".pcm");
                    Log.i(TAG, "Writing audio to: " + file);
                    fos = new FileOutputStream(file);
                } catch (IOException e) {
                    Log.e(TAG, "Failed to open output for saving PCM data", e);
                    postErrorToast("Failed to open output for saving PCM data: "
@@ -635,6 +667,10 @@ public class SoundTriggerTestService extends Service {
                    bytesRequired -= bytesRead;
                }
                audioRecord.stop();
                if (fos != null) {
                  fos.flush();
                  fos.close();
                }
            } catch (Exception e) {
                Log.e(TAG, "Error recording trigger audio", e);
                postErrorToast("Error recording trigger audio: " + e.getMessage());
@@ -651,6 +687,26 @@ public class SoundTriggerTestService extends Service {
                setModelState(mModelInfo, "Recording finished");
            }
        }

        private AudioFormat getAudioFormat() {
            if (mEvent != null) {
                return mEvent.getCaptureAudioFormat();
            }
            if (mRecognitionEvent != null) {
                return mRecognitionEvent.captureFormat;
            }
            return null;
        }

        private int getCaptureSession() {
            if (mEvent != null) {
                return mEvent.getCaptureSession();
            }
            if (mRecognitionEvent != null) {
                return mRecognitionEvent.captureSession;
            }
            return 0;
        }
    }

    // Implementation of SoundTriggerDetector.Callback.
+32 −1
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.test.soundtrigger;

import android.annotation.Nullable;
import android.content.Context;
import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent;
import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
import android.media.soundtrigger.SoundTriggerDetector;
import android.media.soundtrigger.SoundTriggerManager;
import android.os.RemoteException;
@@ -27,6 +29,7 @@ import android.util.Log;

import com.android.internal.app.ISoundTriggerService;

import java.lang.reflect.Method;
import java.lang.RuntimeException;
import java.util.UUID;

@@ -50,13 +53,31 @@ public class SoundTriggerUtil {
     * The sound model must contain a valid UUID.
     *
     * @param soundModel The sound model to add/update.
     * @return The true if the model was loaded successfully, false otherwise.
     */
    public boolean addOrUpdateSoundModel(SoundTriggerManager.Model soundModel) {
        if (soundModel == null) {
            throw new RuntimeException("Bad sound model");
        }
        mSoundTriggerManager.updateModel(soundModel);
        return true;
        // TODO: call loadSoundModel in the soundtrigger manager updateModel method
        // instead of here. It is needed to keep soundtrigger manager internal
        // state consistent.
        return mSoundTriggerManager
                .loadSoundModel(getGenericSoundModel(soundModel)) == 0;
    }

    private GenericSoundModel getGenericSoundModel(
        SoundTriggerManager.Model soundModel) {
        try {
            Method method = SoundTriggerManager.Model.class
                            .getDeclaredMethod("getGenericSoundModel");
            method.setAccessible(true);
            return (GenericSoundModel) method.invoke(soundModel);
        } catch (ReflectiveOperationException e) {
            Log.e(TAG, "Failed to getGenericSoundModel: " + soundModel, e);
            return null;
        }
    }

    /**
@@ -92,6 +113,16 @@ public class SoundTriggerUtil {
        return true;
    }

    /**
     * Get the current model state
     *
     * @param modelId The model ID to look-up the sound model for.
     * @return 0 if the call succeeds, or an error code if it fails.
     */
    public int getModelState(UUID modelId) {
        return mSoundTriggerManager.getModelState(modelId);
    }

    public SoundTriggerDetector createSoundTriggerDetector(UUID modelId,
            SoundTriggerDetector.Callback callback) {
        return mSoundTriggerManager.createSoundTriggerDetector(modelId, callback, null);