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

Commit caa4db5e authored by Ziyang Cheng's avatar Ziyang Cheng Committed by Android (Google) Code Review
Browse files

Merge "Expose SoundTriggerManager apis as SystemApi" into main

parents 95ed338a 1b1abc4b
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -6822,6 +6822,17 @@ package android.hardware.soundtrigger {
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.soundtrigger.SoundTrigger.ModuleProperties> CREATOR;
  }
  @FlaggedApi("android.media.soundtrigger.manager_api") public static final class SoundTrigger.RecognitionConfig implements android.os.Parcelable {
    method public int describeContents();
    method public int getAudioCapabilities();
    method @NonNull public byte[] getData();
    method @NonNull public java.util.List<android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra> getKeyphrases();
    method public boolean isAllowMultipleTriggers();
    method public boolean isCaptureRequested();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.soundtrigger.SoundTrigger.RecognitionConfig> CREATOR;
  }
  public static class SoundTrigger.RecognitionEvent {
    method @Nullable public android.media.AudioFormat getCaptureFormat();
    method public int getCaptureSession();
@@ -7772,10 +7783,16 @@ package android.media.soundtrigger {
    method @Deprecated @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public void deleteModel(java.util.UUID);
    method public int getDetectionServiceOperationsTimeout();
    method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public android.media.soundtrigger.SoundTriggerManager.Model getModel(java.util.UUID);
    method @FlaggedApi("android.media.soundtrigger.manager_api") @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public int getModelState(@NonNull java.util.UUID);
    method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public android.hardware.soundtrigger.SoundTrigger.ModuleProperties getModuleProperties();
    method @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public int getParameter(@NonNull java.util.UUID, int);
    method @FlaggedApi("android.media.soundtrigger.manager_api") @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public boolean isRecognitionActive(@NonNull java.util.UUID);
    method @FlaggedApi("android.media.soundtrigger.manager_api") @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public int loadSoundModel(@NonNull android.hardware.soundtrigger.SoundTrigger.SoundModel);
    method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public android.hardware.soundtrigger.SoundTrigger.ModelParamRange queryParameter(@Nullable java.util.UUID, int);
    method @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public int setParameter(@Nullable java.util.UUID, int, int);
    method @FlaggedApi("android.media.soundtrigger.manager_api") @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public int startRecognition(@NonNull java.util.UUID, @Nullable android.os.Bundle, @NonNull android.content.ComponentName, @NonNull android.hardware.soundtrigger.SoundTrigger.RecognitionConfig);
    method @FlaggedApi("android.media.soundtrigger.manager_api") @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public int stopRecognition(@NonNull java.util.UUID);
    method @FlaggedApi("android.media.soundtrigger.manager_api") @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public int unloadSoundModel(@NonNull java.util.UUID);
    method @Deprecated @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public void updateModel(android.media.soundtrigger.SoundTriggerManager.Model);
  }
+2 −11
Original line number Diff line number Diff line
@@ -1886,17 +1886,9 @@ package android.hardware.soundtrigger {
    ctor public SoundTrigger.ModuleProperties(int, @NonNull String, @NonNull String, @NonNull String, int, @NonNull String, int, int, int, int, boolean, int, boolean, int, boolean, int);
  }

  public static final class SoundTrigger.RecognitionConfig implements android.os.Parcelable {
  @FlaggedApi("android.media.soundtrigger.manager_api") public static final class SoundTrigger.RecognitionConfig implements android.os.Parcelable {
    ctor public SoundTrigger.RecognitionConfig(boolean, boolean, @Nullable android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra[], @Nullable byte[], int);
    ctor public SoundTrigger.RecognitionConfig(boolean, boolean, @Nullable android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra[], @Nullable byte[]);
    method public int describeContents();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.soundtrigger.SoundTrigger.RecognitionConfig> CREATOR;
    field public final boolean allowMultipleTriggers;
    field public final int audioCapabilities;
    field public final boolean captureRequested;
    field @NonNull public final byte[] data;
    field @NonNull public final android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra[] keyphrases;
  }

  public static class SoundTrigger.RecognitionEvent {
@@ -2217,7 +2209,7 @@ package android.media.soundtrigger {
  public class SoundTriggerInstrumentation.RecognitionSession {
    method public void clearRecognitionCallback();
    method public int getAudioSession();
    method @NonNull public android.hardware.soundtrigger.SoundTrigger.RecognitionConfig getRecognitionConfig();
    method @FlaggedApi("android.media.soundtrigger.manager_api") @NonNull public android.hardware.soundtrigger.SoundTrigger.RecognitionConfig getRecognitionConfig();
    method public void setRecognitionCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.soundtrigger.SoundTriggerInstrumentation.RecognitionCallback);
    method public void triggerAbortRecognition();
    method public void triggerRecognitionEvent(@NonNull byte[], @Nullable java.util.List<android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra>);
@@ -2228,7 +2220,6 @@ package android.media.soundtrigger {
    method @NonNull public android.media.soundtrigger.SoundTriggerManager createManagerForModule(@NonNull android.hardware.soundtrigger.SoundTrigger.ModuleProperties);
    method @NonNull public android.media.soundtrigger.SoundTriggerManager createManagerForTestModule();
    method @NonNull public static java.util.List<android.hardware.soundtrigger.SoundTrigger.ModuleProperties> listModuleProperties();
    method @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public int loadSoundModel(@NonNull android.hardware.soundtrigger.SoundTrigger.SoundModel);
  }

  public static class SoundTriggerManager.Model {
+7 −7
Original line number Diff line number Diff line
@@ -155,16 +155,16 @@ public class ConversionUtil {
    public static RecognitionConfig api2aidlRecognitionConfig(
            SoundTrigger.RecognitionConfig apiConfig) {
        RecognitionConfig aidlConfig = new RecognitionConfig();
        aidlConfig.captureRequested = apiConfig.captureRequested;
        // apiConfig.allowMultipleTriggers is ignored by the lower layers.
        aidlConfig.captureRequested = apiConfig.isCaptureRequested();
        // apiConfig.isAllowMultipleTriggers() is ignored by the lower layers.
        aidlConfig.phraseRecognitionExtras =
                new PhraseRecognitionExtra[apiConfig.keyphrases.length];
        for (int i = 0; i < apiConfig.keyphrases.length; ++i) {
                new PhraseRecognitionExtra[apiConfig.getKeyphrases().size()];
        for (int i = 0; i < apiConfig.getKeyphrases().size(); ++i) {
            aidlConfig.phraseRecognitionExtras[i] = api2aidlPhraseRecognitionExtra(
                    apiConfig.keyphrases[i]);
                    apiConfig.getKeyphrases().get(i));
        }
        aidlConfig.data = Arrays.copyOf(apiConfig.data, apiConfig.data.length);
        aidlConfig.audioCapabilities = api2aidlAudioCapabilities(apiConfig.audioCapabilities);
        aidlConfig.data = Arrays.copyOf(apiConfig.getData(), apiConfig.getData().length);
        aidlConfig.audioCapabilities = api2aidlAudioCapabilities(apiConfig.getAudioCapabilities());
        return aidlConfig;
    }

+104 −54
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.UUID;
@@ -1513,50 +1514,56 @@ public class SoundTrigger {
     *  A RecognitionConfig is provided to
     *  {@link SoundTriggerModule#startRecognition(int, RecognitionConfig)} to configure the
     *  recognition request.
     *
     *  @hide
     */
    @TestApi
    @FlaggedApi(android.media.soundtrigger.Flags.FLAG_MANAGER_API)
    public static final class RecognitionConfig implements Parcelable {
        /** True if the DSP should capture the trigger sound and make it available for further
         * capture. */
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public final boolean captureRequested;
        /**
         * True if the service should restart listening after the DSP triggers.
         * Note: This config flag is currently used at the service layer rather than by the DSP.
         */
        public final boolean allowMultipleTriggers;
        /** List of all keyphrases in the sound model for which recognition should be performed with
         * options for each keyphrase. */
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        @NonNull
        @SuppressLint("ArrayReturn")
        public final KeyphraseRecognitionExtra keyphrases[];
        /** Opaque data for use by system applications who know about voice engine internals,
         * typically during enrollment. */
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        @NonNull
        public final byte[] data;
        private final boolean mCaptureRequested;
        private final boolean mAllowMultipleTriggers;
        private final KeyphraseRecognitionExtra mKeyphrases[];
        private final byte[] mData;
        @ModuleProperties.AudioCapabilities
        private final int mAudioCapabilities;

        /**
         * Bit field encoding of the AudioCapabilities
         * supported by the firmware.
         * Constructor for {@link RecognitionConfig} with {@code audioCapabilities} describes a
         * config that can be used by
         * {@link SoundTriggerModule#startRecognition(int, RecognitionConfig)}
         *
         * @param captureRequested Whether the DSP should capture the trigger sound.
         * @param allowMultipleTriggers Whether the service should restart listening after the DSP
         *                              triggers.
         * @param keyphrases List of keyphrases in the sound model.
         * @param data Opaque data for use by system applications who know about voice engine
         *             internals, typically during enrollment.
         * @param audioCapabilities Bit field encoding of the AudioCapabilities.
         *
         * @hide
         */
        @ModuleProperties.AudioCapabilities
        public final int audioCapabilities;

        @TestApi
        public RecognitionConfig(boolean captureRequested, boolean allowMultipleTriggers,
                @SuppressLint("ArrayReturn") @Nullable KeyphraseRecognitionExtra[] keyphrases,
                @Nullable byte[] data, int audioCapabilities) {
            this.captureRequested = captureRequested;
            this.allowMultipleTriggers = allowMultipleTriggers;
            this.keyphrases = keyphrases != null ? keyphrases : new KeyphraseRecognitionExtra[0];
            this.data = data != null ? data : new byte[0];
            this.audioCapabilities = audioCapabilities;
            this.mCaptureRequested = captureRequested;
            this.mAllowMultipleTriggers = allowMultipleTriggers;
            this.mKeyphrases = keyphrases != null ? keyphrases : new KeyphraseRecognitionExtra[0];
            this.mData = data != null ? data : new byte[0];
            this.mAudioCapabilities = audioCapabilities;
        }

        /**
         * Constructor for {@link RecognitionConfig} without audioCapabilities. The
         * audioCapabilities is set to 0.
         *
         * @param captureRequested Whether the DSP should capture the trigger sound.
         * @param allowMultipleTriggers Whether the service should restart listening after the DSP
         *                              triggers.
         * @param keyphrases List of keyphrases in the sound model.
         * @param data Opaque data for use by system applications.
         *
         * @hide
         */
        @UnsupportedAppUsage
        @TestApi
        public RecognitionConfig(boolean captureRequested, boolean allowMultipleTriggers,
                @SuppressLint("ArrayReturn") @Nullable KeyphraseRecognitionExtra[] keyphrases,
                @Nullable byte[] data) {
@@ -1574,9 +1581,52 @@ public class SoundTrigger {
            }
        };

        /**
         * Returns whether the DSP should capture the trigger sound and make it available for
         * further capture.
         */
        public boolean isCaptureRequested() {
            return mCaptureRequested;
        }

        /**
         * Returns whether the service should restart listening after the DSP triggers.
         *
         * <p><b>Note:</b> This config flag is currently used at the service layer rather than by
         * the DSP.
         */
        public boolean isAllowMultipleTriggers() {
            return mAllowMultipleTriggers;
        }

        /**
         * Gets all keyphrases in the sound model for which recognition should be performed with
         * options for each keyphrase.
         */
        @NonNull
        public List<KeyphraseRecognitionExtra> getKeyphrases() {
            return Arrays.asList(mKeyphrases);
        }

        /**
         * Opaque data.
         *
         * <p>For use by system applications who knows about voice engine internals, typically
         * during enrollment.
         */
        @NonNull
        public byte[] getData() {
            return mData;
        }

        /** Bit field encoding of the AudioCapabilities supported by the firmware. */
        public int getAudioCapabilities() {
            return mAudioCapabilities;
        }

        private static RecognitionConfig fromParcel(Parcel in) {
            boolean captureRequested = in.readByte() == 1;
            boolean allowMultipleTriggers = in.readByte() == 1;
            boolean captureRequested = in.readBoolean();
            boolean allowMultipleTriggers = in.readBoolean();
            KeyphraseRecognitionExtra[] keyphrases =
                    in.createTypedArray(KeyphraseRecognitionExtra.CREATOR);
            byte[] data = in.readBlob();
@@ -1587,11 +1637,11 @@ public class SoundTrigger {

        @Override
        public void writeToParcel(@NonNull Parcel dest, int flags) {
            dest.writeByte((byte) (captureRequested ? 1 : 0));
            dest.writeByte((byte) (allowMultipleTriggers ? 1 : 0));
            dest.writeTypedArray(keyphrases, flags);
            dest.writeBlob(data);
            dest.writeInt(audioCapabilities);
            dest.writeBoolean(mCaptureRequested);
            dest.writeBoolean(mAllowMultipleTriggers);
            dest.writeTypedArray(mKeyphrases, flags);
            dest.writeBlob(mData);
            dest.writeInt(mAudioCapabilities);
        }

        @Override
@@ -1601,10 +1651,10 @@ public class SoundTrigger {

        @Override
        public String toString() {
            return "RecognitionConfig [captureRequested=" + captureRequested
                    + ", allowMultipleTriggers=" + allowMultipleTriggers + ", keyphrases="
                    + Arrays.toString(keyphrases) + ", data=" + Arrays.toString(data)
                    + ", audioCapabilities=" + Integer.toHexString(audioCapabilities) + "]";
            return "RecognitionConfig [captureRequested=" + mCaptureRequested
                    + ", allowMultipleTriggers=" + mAllowMultipleTriggers + ", keyphrases="
                    + Arrays.toString(mKeyphrases) + ", data=" + Arrays.toString(mData)
                    + ", audioCapabilities=" + Integer.toHexString(mAudioCapabilities) + "]";
        }

        @Override
@@ -1616,19 +1666,19 @@ public class SoundTrigger {
            if (!(obj instanceof RecognitionConfig))
                return false;
            RecognitionConfig other = (RecognitionConfig) obj;
            if (captureRequested != other.captureRequested) {
            if (mCaptureRequested != other.mCaptureRequested) {
                return false;
            }
            if (allowMultipleTriggers != other.allowMultipleTriggers) {
            if (mAllowMultipleTriggers != other.mAllowMultipleTriggers) {
                return false;
            }
            if (!Arrays.equals(keyphrases, other.keyphrases)) {
            if (!Arrays.equals(mKeyphrases, other.mKeyphrases)) {
                return false;
            }
            if (!Arrays.equals(data, other.data)) {
            if (!Arrays.equals(mData, other.mData)) {
                return false;
            }
            if (audioCapabilities != other.audioCapabilities) {
            if (mAudioCapabilities != other.mAudioCapabilities) {
                return false;
            }
            return true;
@@ -1638,11 +1688,11 @@ public class SoundTrigger {
        public final int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + (captureRequested ? 1 : 0);
            result = prime * result + (allowMultipleTriggers ? 1 : 0);
            result = prime * result + Arrays.hashCode(keyphrases);
            result = prime * result + Arrays.hashCode(data);
            result = prime * result + audioCapabilities;
            result = prime * result + (mCaptureRequested ? 1 : 0);
            result = prime * result + (mAllowMultipleTriggers ? 1 : 0);
            result = prime * result + Arrays.hashCode(mKeyphrases);
            result = prime * result + Arrays.hashCode(mData);
            result = prime * result + mAudioCapabilities;
            return result;
        }
    }
+2 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.media.soundtrigger;

import android.annotation.CallbackExecutor;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -328,6 +329,7 @@ public final class SoundTriggerInstrumentation {
         * Get the recognition config used to start this recognition.
         * @return - The config passed to the HAL for startRecognition.
         */
        @FlaggedApi(Flags.FLAG_MANAGER_API)
        public @NonNull SoundTrigger.RecognitionConfig getRecognitionConfig() {
            return mRecognitionConfig;
        }
Loading