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

Commit b2a5c297 authored by Nicholas Ambur's avatar Nicholas Ambur Committed by Android (Google) Code Review
Browse files

Merge "add parameter control to AlwaysOnHotwordDetector"

parents 9785b64c f94db1c8
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -42675,9 +42675,13 @@ package android.service.voice {
    method public android.content.Intent createEnrollIntent();
    method public android.content.Intent createReEnrollIntent();
    method public android.content.Intent createUnEnrollIntent();
    method public int getParameter(int);
    method public int getSupportedRecognitionModes();
    method @Nullable public android.service.voice.AlwaysOnHotwordDetector.ModelParamRange queryParameter(int);
    method public int setParameter(int, int);
    method public boolean startRecognition(int);
    method public boolean stopRecognition();
    field public static final int MODEL_PARAM_THRESHOLD_FACTOR = 0; // 0x0
    field public static final int RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS = 2; // 0x2
    field public static final int RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO = 1; // 0x1
    field public static final int RECOGNITION_MODE_USER_IDENTIFICATION = 2; // 0x2
@@ -42702,6 +42706,11 @@ package android.service.voice {
    method @Nullable public byte[] getTriggerAudio();
  }
  public static final class AlwaysOnHotwordDetector.ModelParamRange {
    method public int end();
    method public int start();
  }
  public class VoiceInteractionService extends android.app.Service {
    ctor public VoiceInteractionService();
    method public final android.service.voice.AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(String, java.util.Locale, android.service.voice.AlwaysOnHotwordDetector.Callback);
+2 −3
Original line number Diff line number Diff line
@@ -3546,7 +3546,6 @@ package android.hardware.soundtrigger {
  }
  public static final class SoundTrigger.ModelParamRange implements android.os.Parcelable {
    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.ModelParamRange> CREATOR;
    field public final int end;
@@ -4368,9 +4367,9 @@ package android.media.soundtrigger {
    method public int getDetectionServiceOperationsTimeout();
    method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public android.media.soundtrigger.SoundTriggerManager.Model getModel(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) throws java.lang.IllegalArgumentException, java.lang.UnsupportedOperationException;
    method @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public int getParameter(@NonNull java.util.UUID, int);
    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) throws java.lang.IllegalArgumentException, java.lang.UnsupportedOperationException;
    method @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public int setParameter(@Nullable java.util.UUID, int, int);
    method @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public void updateModel(android.media.soundtrigger.SoundTriggerManager.Model);
  }
+1 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.hardware.soundtrigger;

import android.annotation.Nullable;
import android.hardware.soundtrigger.ModelParams;
import android.media.AudioFormat;
import android.media.audio.common.AudioConfig;
@@ -32,8 +33,6 @@ import android.media.soundtrigger_middleware.SoundModel;
import android.media.soundtrigger_middleware.SoundTriggerModuleDescriptor;
import android.media.soundtrigger_middleware.SoundTriggerModuleProperties;

import android.annotation.Nullable;

import java.util.Arrays;
import java.util.UUID;

+51 −17
Original line number Diff line number Diff line
@@ -588,19 +588,19 @@ public class SoundTrigger {
        }
    }

    /*****************************************************************************
    /**
     * A ModelParamRange is a representation of supported parameter range for a
     * given loaded model.
     ****************************************************************************/
     */
    public static final class ModelParamRange implements Parcelable {

        /**
         * start of supported range inclusive
         * The inclusive start of supported range.
         */
        public final int start;

        /**
         * end of supported range inclusive
         * The inclusive end of supported range.
         */
        public final int end;

@@ -609,13 +609,15 @@ public class SoundTrigger {
            this.end = end;
        }

        /** @hide */
        private ModelParamRange(@NonNull Parcel in) {
            this.start = in.readInt();
            this.end = in.readInt();
        }

        @NonNull
        public static final Creator<ModelParamRange> CREATOR = new Creator<ModelParamRange>() {
        public static final Creator<ModelParamRange> CREATOR =
                new Creator<ModelParamRange>() {
                    @Override
                    @NonNull
                    public ModelParamRange createFromParcel(@NonNull Parcel in) {
@@ -629,11 +631,43 @@ public class SoundTrigger {
                    }
                };

        /** @hide */
        @Override
        public int describeContents() {
            return 0;
        }

        /** @hide */
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + (start);
            result = prime * result + (end);
            return result;
        }

        @Override
        public boolean equals(@Nullable Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            ModelParamRange other = (ModelParamRange) obj;
            if (start != other.start) {
                return false;
            }
            if (end != other.end) {
                return false;
            }
            return true;
        }

        @Override
        public void writeToParcel(@NonNull Parcel dest, int flags) {
            dest.writeInt(start);
+181 −0
Original line number Diff line number Diff line
@@ -168,6 +168,22 @@ public class AlwaysOnHotwordDetector {
    public static final int RECOGNITION_MODE_USER_IDENTIFICATION
            = SoundTrigger.RECOGNITION_MODE_USER_IDENTIFICATION;

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(flag = true, prefix = { "MODEL_PARAM_" }, value = {
            MODEL_PARAM_THRESHOLD_FACTOR,
    })
    public @interface ModelParams {}

    /**
     * Controls the sensitivity threshold adjustment factor for a given model.
     * Negative value corresponds to less sensitive model (high threshold) and
     * a positive value corresponds to a more sensitive model (low threshold).
     * Default value is 0.
     */
    public static final int MODEL_PARAM_THRESHOLD_FACTOR =
            android.hardware.soundtrigger.ModelParams.THRESHOLD_FACTOR;

    static final String TAG = "AlwaysOnHotwordDetector";
    static final boolean DBG = false;

@@ -197,6 +213,53 @@ public class AlwaysOnHotwordDetector {

    private int mAvailability = STATE_NOT_READY;

    /**
     *  A ModelParamRange is a representation of supported parameter range for a
     *  given loaded model.
     */
    public static final class ModelParamRange {
        private final SoundTrigger.ModelParamRange mModelParamRange;

        /** @hide */
        ModelParamRange(SoundTrigger.ModelParamRange modelParamRange) {
            mModelParamRange = modelParamRange;
        }

        /**
         * The inclusive start of supported range.
         *
         * @return start of range
         */
        public int start() {
            return mModelParamRange.start;
        }

        /**
         * The inclusive end of supported range.
         *
         * @return end of range
         */
        public int end() {
            return mModelParamRange.end;
        }

        @Override
        @NonNull
        public String toString() {
            return mModelParamRange.toString();
        }

        @Override
        public boolean equals(@Nullable Object obj) {
            return mModelParamRange.equals(obj);
        }

        @Override
        public int hashCode() {
            return mModelParamRange.hashCode();
        }
    }

    /**
     * Additional payload for {@link Callback#onDetected}.
     */
@@ -444,6 +507,83 @@ public class AlwaysOnHotwordDetector {
        }
    }

    /**
     * Set a model specific {@link ModelParams} with the given value. This
     * parameter will keep its value for the duration the model is loaded regardless of starting and
     * stopping recognition. Once the model is unloaded, the value will be lost.
     * {@link AlwaysOnHotwordDetector#queryParameter} should be checked first before calling this
     * method.
     *
     * @param modelParam   {@link ModelParams}
     * @param value        Value to set
     * @return - {@link SoundTrigger#STATUS_OK} in case of success
     *         - {@link SoundTrigger#STATUS_NO_INIT} if the native service cannot be reached
     *         - {@link SoundTrigger#STATUS_BAD_VALUE} invalid input parameter
     *         - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence or
     *           if API is not supported by HAL
     */
    public int setParameter(@ModelParams int modelParam, int value) {
        if (DBG) {
            Slog.d(TAG, "setParameter(" + modelParam + ", " + value + ")");
        }

        synchronized (mLock) {
            if (mAvailability == STATE_INVALID) {
                throw new IllegalStateException("setParameter called on an invalid detector");
            }

            return setParameterLocked(modelParam, value);
        }
    }

    /**
     * Get a model specific {@link ModelParams}. This parameter will keep its value
     * for the duration the model is loaded regardless of starting and stopping recognition.
     * Once the model is unloaded, the value will be lost. If the value is not set, a default
     * value is returned. See {@link ModelParams} for parameter default values.
     * {@link AlwaysOnHotwordDetector#queryParameter} should be checked first before
     * calling this method.
     *
     * @param modelParam   {@link ModelParams}
     * @return value of parameter
     */
    public int getParameter(@ModelParams int modelParam) {
        if (DBG) {
            Slog.d(TAG, "getParameter(" + modelParam + ")");
        }

        synchronized (mLock) {
            if (mAvailability == STATE_INVALID) {
                throw new IllegalStateException("getParameter called on an invalid detector");
            }

            return getParameterLocked(modelParam);
        }
    }

    /**
     * Determine if parameter control is supported for the given model handle.
     * This method should be checked prior to calling {@link AlwaysOnHotwordDetector#setParameter}
     * or {@link AlwaysOnHotwordDetector#getParameter}.
     *
     * @param modelParam {@link ModelParams}
     * @return supported range of parameter, null if not supported
     */
    @Nullable
    public ModelParamRange queryParameter(@ModelParams int modelParam) {
        if (DBG) {
            Slog.d(TAG, "queryParameter(" + modelParam + ")");
        }

        synchronized (mLock) {
            if (mAvailability == STATE_INVALID) {
                throw new IllegalStateException("queryParameter called on an invalid detector");
            }

            return queryParameterLocked(modelParam);
        }
    }

    /**
     * Creates an intent to start the enrollment for the associated keyphrase.
     * This intent must be invoked using {@link Context#startForegroundService(Intent)}.
@@ -601,6 +741,47 @@ public class AlwaysOnHotwordDetector {
        return code;
    }

    private int setParameterLocked(@ModelParams int modelParam, int value) {
        try {
            int code = mModelManagementService.setParameter(mVoiceInteractionService,
                    mKeyphraseMetadata.id, modelParam, value);

            if (code != STATUS_OK) {
                Slog.w(TAG, "setParameter failed with error code " + code);
            }

            return code;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    private int getParameterLocked(@ModelParams int modelParam) {
        try {
            return mModelManagementService.getParameter(mVoiceInteractionService,
                    mKeyphraseMetadata.id, modelParam);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    @Nullable
    private ModelParamRange queryParameterLocked(@ModelParams int modelParam) {
        try {
            SoundTrigger.ModelParamRange modelParamRange =
                    mModelManagementService.queryParameter(mVoiceInteractionService,
                            mKeyphraseMetadata.id, modelParam);

            if (modelParamRange == null) {
                return null;
            }

            return new ModelParamRange(modelParamRange);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    private void notifyStateChangedLocked() {
        Message message = Message.obtain(mHandler, MSG_AVAILABILITY_CHANGED);
        message.arg1 = mAvailability;
Loading