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

Commit ef84fc48 authored by Nicholas Ambur's avatar Nicholas Ambur
Browse files

add KeyphraseModelManager

Exposes a set of @SystemApi's allowing the active VoiceInteractionService
to enroll voice models.

Bug: 147159435
Test: manual tested enrollment and unenrollment via bundled
hotwordenrollment application and test app.

Change-Id: I94ef3550df236486401a0a6f9de9d874b9bf9b46
parent 4ec0be1f
Loading
Loading
Loading
Loading
+53 −0
Original line number Original line Diff line number Diff line
@@ -3566,9 +3566,34 @@ package android.hardware.radio {
package android.hardware.soundtrigger {
package android.hardware.soundtrigger {
  public class SoundTrigger {
  public class SoundTrigger {
    field public static final int RECOGNITION_MODE_GENERIC = 8; // 0x8
    field public static final int RECOGNITION_MODE_USER_AUTHENTICATION = 4; // 0x4
    field public static final int RECOGNITION_MODE_USER_IDENTIFICATION = 2; // 0x2
    field public static final int RECOGNITION_MODE_VOICE_TRIGGER = 1; // 0x1
    field public static final int STATUS_OK = 0; // 0x0
    field public static final int STATUS_OK = 0; // 0x0
  }
  }
  public static final class SoundTrigger.Keyphrase implements android.os.Parcelable {
    ctor public SoundTrigger.Keyphrase(int, int, @NonNull java.util.Locale, @NonNull String, @Nullable int[]);
    method @NonNull public static android.hardware.soundtrigger.SoundTrigger.Keyphrase readFromParcel(@NonNull android.os.Parcel);
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.soundtrigger.SoundTrigger.Keyphrase> CREATOR;
    field public final int id;
    field @NonNull public final java.util.Locale locale;
    field public final int recognitionModes;
    field @NonNull public final String text;
    field @NonNull public final int[] users;
  }
  public static final class SoundTrigger.KeyphraseSoundModel extends android.hardware.soundtrigger.SoundTrigger.SoundModel implements android.os.Parcelable {
    ctor public SoundTrigger.KeyphraseSoundModel(@NonNull java.util.UUID, @NonNull java.util.UUID, @Nullable byte[], @Nullable android.hardware.soundtrigger.SoundTrigger.Keyphrase[], int);
    ctor public SoundTrigger.KeyphraseSoundModel(@NonNull java.util.UUID, @NonNull java.util.UUID, @Nullable byte[], @Nullable android.hardware.soundtrigger.SoundTrigger.Keyphrase[]);
    method @NonNull public static android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel readFromParcel(@NonNull android.os.Parcel);
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel> CREATOR;
    field @NonNull public final android.hardware.soundtrigger.SoundTrigger.Keyphrase[] keyphrases;
  }
  public static final class SoundTrigger.ModelParamRange implements android.os.Parcelable {
  public static final class SoundTrigger.ModelParamRange implements android.os.Parcelable {
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    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 @NonNull public static final android.os.Parcelable.Creator<android.hardware.soundtrigger.SoundTrigger.ModelParamRange> CREATOR;
@@ -3607,6 +3632,16 @@ package android.hardware.soundtrigger {
    method public boolean isCaptureAvailable();
    method public boolean isCaptureAvailable();
  }
  }
  public static class SoundTrigger.SoundModel {
    field public static final int TYPE_GENERIC_SOUND = 1; // 0x1
    field public static final int TYPE_KEYPHRASE = 0; // 0x0
    field @NonNull public final byte[] data;
    field public final int type;
    field @NonNull public final java.util.UUID uuid;
    field @NonNull public final java.util.UUID vendorUuid;
    field public final int version;
  }
}
}
package android.hardware.usb {
package android.hardware.usb {
@@ -4739,6 +4774,16 @@ package android.media.tv.tuner.filter {
}
}
package android.media.voice {
  public final class KeyphraseModelManager {
    method @RequiresPermission("android.permission.MANAGE_VOICE_KEYPHRASES") public void deleteKeyphraseSoundModel(int, @NonNull java.util.Locale);
    method @Nullable @RequiresPermission("android.permission.MANAGE_VOICE_KEYPHRASES") public android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel getKeyphraseSoundModel(int, @NonNull java.util.Locale);
    method @RequiresPermission("android.permission.MANAGE_VOICE_KEYPHRASES") public void updateKeyphraseSoundModel(@NonNull android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel);
  }
}
package android.metrics {
package android.metrics {
  public class LogMaker {
  public class LogMaker {
@@ -9128,6 +9173,14 @@ package android.service.trust {
}
}
package android.service.voice {
  public class VoiceInteractionService extends android.app.Service {
    method @NonNull @RequiresPermission("android.permission.MANAGE_VOICE_KEYPHRASES") public final android.media.voice.KeyphraseModelManager createKeyphraseModelManager();
  }
}
package android.service.wallpaper {
package android.service.wallpaper {
  public class WallpaperService.Engine {
  public class WallpaperService.Engine {
+1 −1
Original line number Original line Diff line number Diff line
@@ -130,7 +130,7 @@ class ConversionUtil {
        aidlPhrase.id = apiPhrase.id;
        aidlPhrase.id = apiPhrase.id;
        aidlPhrase.recognitionModes = api2aidlRecognitionModes(apiPhrase.recognitionModes);
        aidlPhrase.recognitionModes = api2aidlRecognitionModes(apiPhrase.recognitionModes);
        aidlPhrase.users = Arrays.copyOf(apiPhrase.users, apiPhrase.users.length);
        aidlPhrase.users = Arrays.copyOf(apiPhrase.users, apiPhrase.users.length);
        aidlPhrase.locale = apiPhrase.locale;
        aidlPhrase.locale = apiPhrase.locale.toLanguageTag();
        aidlPhrase.text = apiPhrase.text;
        aidlPhrase.text = apiPhrase.text;
        return aidlPhrase;
        return aidlPhrase;
    }
    }
+34 −8
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
package android.hardware.soundtrigger;
package android.hardware.soundtrigger;


import android.Manifest;
import android.Manifest;
import android.annotation.IntDef;
import android.content.Intent;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
@@ -24,7 +25,6 @@ import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.content.res.XmlResourceParser;
import android.service.voice.AlwaysOnHotwordDetector;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.AttributeSet;
@@ -35,6 +35,8 @@ import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserException;


import java.io.IOException;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collections;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.LinkedList;
@@ -66,9 +68,10 @@ public class KeyphraseEnrollmentInfo {
            "com.android.intent.action.MANAGE_VOICE_KEYPHRASES";
            "com.android.intent.action.MANAGE_VOICE_KEYPHRASES";
    /**
    /**
     * Intent extra: The intent extra for the specific manage action that needs to be performed.
     * Intent extra: The intent extra for the specific manage action that needs to be performed.
     * Possible values are {@link AlwaysOnHotwordDetector#MANAGE_ACTION_ENROLL},
     *
     * {@link AlwaysOnHotwordDetector#MANAGE_ACTION_RE_ENROLL}
     * @see #MANAGE_ACTION_ENROLL
     * or {@link AlwaysOnHotwordDetector#MANAGE_ACTION_UN_ENROLL}.
     * @see #MANAGE_ACTION_RE_ENROLL
     * @see #MANAGE_ACTION_UN_ENROLL
     */
     */
    public static final String EXTRA_VOICE_KEYPHRASE_ACTION =
    public static final String EXTRA_VOICE_KEYPHRASE_ACTION =
            "com.android.intent.extra.VOICE_KEYPHRASE_ACTION";
            "com.android.intent.extra.VOICE_KEYPHRASE_ACTION";
@@ -85,6 +88,31 @@ public class KeyphraseEnrollmentInfo {
    public static final String EXTRA_VOICE_KEYPHRASE_LOCALE =
    public static final String EXTRA_VOICE_KEYPHRASE_LOCALE =
            "com.android.intent.extra.VOICE_KEYPHRASE_LOCALE";
            "com.android.intent.extra.VOICE_KEYPHRASE_LOCALE";


    /**
     * Keyphrase management actions used with the {@link #EXTRA_VOICE_KEYPHRASE_ACTION} intent extra
     * @hide
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = { "MANAGE_ACTION_" }, value = {
            MANAGE_ACTION_ENROLL,
            MANAGE_ACTION_RE_ENROLL,
            MANAGE_ACTION_UN_ENROLL
    })
    public @interface ManageActions {}

    /**
     * Indicates desired action to enroll keyphrase model
     */
    public static final int MANAGE_ACTION_ENROLL = 0;
    /**
     * Indicates desired action to re-enroll keyphrase model
     */
    public static final int MANAGE_ACTION_RE_ENROLL = 1;
    /**
     * Indicates desired action to un-enroll keyphrase model
     */
    public static final int MANAGE_ACTION_UN_ENROLL = 2;

    /**
    /**
     * List of available keyphrases.
     * List of available keyphrases.
     */
     */
@@ -294,15 +322,13 @@ public class KeyphraseEnrollmentInfo {
     * for the locale.
     * for the locale.
     *
     *
     * @param action The enrollment related action that this intent is supposed to perform.
     * @param action The enrollment related action that this intent is supposed to perform.
     *        This can be one of {@link AlwaysOnHotwordDetector#MANAGE_ACTION_ENROLL},
     *        {@link AlwaysOnHotwordDetector#MANAGE_ACTION_RE_ENROLL}
     *        or {@link AlwaysOnHotwordDetector#MANAGE_ACTION_UN_ENROLL}
     * @param keyphrase The keyphrase that the user needs to be enrolled to.
     * @param keyphrase The keyphrase that the user needs to be enrolled to.
     * @param locale The locale for which the enrollment needs to be performed.
     * @param locale The locale for which the enrollment needs to be performed.
     * @return An {@link Intent} to manage the keyphrase. This can be null if managing the
     * @return An {@link Intent} to manage the keyphrase. This can be null if managing the
     *         given keyphrase/locale combination isn't possible.
     *         given keyphrase/locale combination isn't possible.
     */
     */
    public Intent getManageKeyphraseIntent(int action, String keyphrase, Locale locale) {
    public Intent getManageKeyphraseIntent(@ManageActions int action, String keyphrase,
            Locale locale) {
        if (mKeyphrasePackageMap == null || mKeyphrasePackageMap.isEmpty()) {
        if (mKeyphrasePackageMap == null || mKeyphrasePackageMap.isEmpty()) {
            Slog.w(TAG, "No enrollment application exists");
            Slog.w(TAG, "No enrollment application exists");
            return null;
            return null;
+148 −87
Original line number Original line Diff line number Diff line
@@ -49,6 +49,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.Locale;
import java.util.UUID;
import java.util.UUID;


/**
/**
@@ -148,6 +149,7 @@ public class SoundTrigger {
        public final int maxUsers;
        public final int maxUsers;


        /** Supported recognition modes (bit field, RECOGNITION_MODE_VOICE_TRIGGER ...) */
        /** Supported recognition modes (bit field, RECOGNITION_MODE_VOICE_TRIGGER ...) */
        @RecognitionModes
        public final int recognitionModes;
        public final int recognitionModes;


        /** Supports seamless transition to capture mode after recognition */
        /** Supports seamless transition to capture mode after recognition */
@@ -175,9 +177,9 @@ public class SoundTrigger {


        ModuleProperties(int id, @NonNull String implementor, @NonNull String description,
        ModuleProperties(int id, @NonNull String implementor, @NonNull String description,
                @NonNull String uuid, int version, @NonNull String supportedModelArch,
                @NonNull String uuid, int version, @NonNull String supportedModelArch,
                int maxSoundModels, int maxKeyphrases, int maxUsers, int recognitionModes,
                int maxSoundModels, int maxKeyphrases, int maxUsers,
                boolean supportsCaptureTransition, int maxBufferMs,
                @RecognitionModes int recognitionModes, boolean supportsCaptureTransition,
                boolean supportsConcurrentCapture, int powerConsumptionMw,
                int maxBufferMs, boolean supportsConcurrentCapture, int powerConsumptionMw,
                boolean returnsTriggerInEvent, int audioCapabilities) {
                boolean returnsTriggerInEvent, int audioCapabilities) {
            this.id = id;
            this.id = id;
            this.implementor = requireNonNull(implementor);
            this.implementor = requireNonNull(implementor);
@@ -271,16 +273,27 @@ public class SoundTrigger {
        }
        }
    }
    }


    /*****************************************************************************
    /**
     * A SoundModel describes the attributes and contains the binary data used by the hardware
     * A SoundModel describes the attributes and contains the binary data used by the hardware
     * implementation to detect a particular sound pattern.
     * implementation to detect a particular sound pattern.
     * A specialized version {@link KeyphraseSoundModel} is defined for key phrase
     * A specialized version {@link KeyphraseSoundModel} is defined for key phrase
     * sound models.
     * sound models.
     *
     */
     * @hide
     ****************************************************************************/
    public static class SoundModel {
    public static class SoundModel {
        /** Undefined sound model type */

        /** @hide */
        @Retention(RetentionPolicy.SOURCE)
        @IntDef({
                TYPE_GENERIC_SOUND,
                TYPE_KEYPHRASE,
                TYPE_UNKNOWN,
        })
        public @interface SoundModelType {}

        /**
         * Undefined sound model type
         * @hide
         */
        public static final int TYPE_UNKNOWN = -1;
        public static final int TYPE_UNKNOWN = -1;


        /** Keyphrase sound model */
        /** Keyphrase sound model */
@@ -293,15 +306,14 @@ public class SoundTrigger {
        public static final int TYPE_GENERIC_SOUND = 1;
        public static final int TYPE_GENERIC_SOUND = 1;


        /** Unique sound model identifier */
        /** Unique sound model identifier */
        @UnsupportedAppUsage
        @NonNull
        @NonNull
        public final UUID uuid;
        public final UUID uuid;


        /** Sound model type (e.g. TYPE_KEYPHRASE); */
        /** Sound model type (e.g. TYPE_KEYPHRASE); */
        @SoundModelType
        public final int type;
        public final int type;


        /** Unique sound model vendor identifier */
        /** Unique sound model vendor identifier */
        @UnsupportedAppUsage
        @NonNull
        @NonNull
        public final UUID vendorUuid;
        public final UUID vendorUuid;


@@ -309,11 +321,11 @@ public class SoundTrigger {
        public final int version;
        public final int version;


        /** Opaque data. For use by vendor implementation and enrollment application */
        /** Opaque data. For use by vendor implementation and enrollment application */
        @UnsupportedAppUsage
        @NonNull
        @NonNull
        public final byte[] data;
        public final byte[] data;


        public SoundModel(@NonNull UUID uuid, @Nullable UUID vendorUuid, int type,
        /** @hide */
        public SoundModel(@NonNull UUID uuid, @Nullable UUID vendorUuid, @SoundModelType int type,
                @Nullable byte[] data, int version) {
                @Nullable byte[] data, int version) {
            this.uuid = requireNonNull(uuid);
            this.uuid = requireNonNull(uuid);
            this.vendorUuid = vendorUuid != null ? vendorUuid : new UUID(0, 0);
            this.vendorUuid = vendorUuid != null ? vendorUuid : new UUID(0, 0);
@@ -336,67 +348,90 @@ public class SoundTrigger {


        @Override
        @Override
        public boolean equals(Object obj) {
        public boolean equals(Object obj) {
            if (this == obj)
            if (this == obj) {
                return true;
                return true;
            if (obj == null)
            }
            if (obj == null) {
                return false;
                return false;
            if (!(obj instanceof SoundModel))
            }
            if (!(obj instanceof SoundModel)) {
                return false;
                return false;
            }
            SoundModel other = (SoundModel) obj;
            SoundModel other = (SoundModel) obj;
            if (type != other.type)
            if (type != other.type) {
                return false;
                return false;
            }
            if (uuid == null) {
            if (uuid == null) {
                if (other.uuid != null)
                if (other.uuid != null) {
                    return false;
                    return false;
            } else if (!uuid.equals(other.uuid))
                }
            } else if (!uuid.equals(other.uuid)) {
                return false;
                return false;
            }
            if (vendorUuid == null) {
            if (vendorUuid == null) {
                if (other.vendorUuid != null)
                if (other.vendorUuid != null) {
                    return false;
                    return false;
            } else if (!vendorUuid.equals(other.vendorUuid))
                }
            } else if (!vendorUuid.equals(other.vendorUuid)) {
                return false;
                return false;
            if (!Arrays.equals(data, other.data))
            }
            if (!Arrays.equals(data, other.data)) {
                return false;
                return false;
            if (version != other.version)
            }
            if (version != other.version) {
                return false;
                return false;
            }
            return true;
            return true;
        }
        }
    }
    }


    /*****************************************************************************
    /**
     * A Keyphrase describes a key phrase that can be detected by a
     * A Keyphrase describes a key phrase that can be detected by a
     * {@link KeyphraseSoundModel}
     * {@link KeyphraseSoundModel}
     *
     */
     * @hide
    public static final class Keyphrase implements Parcelable {
     ****************************************************************************/
    public static class Keyphrase implements Parcelable {
        /** Unique identifier for this keyphrase */
        /** Unique identifier for this keyphrase */
        @UnsupportedAppUsage
        public final int id;
        public final int id;


        /** Recognition modes supported for this key phrase in the model */
        /**
        @UnsupportedAppUsage
         * Recognition modes supported for this key phrase in the model
         *
         * @see #RECOGNITION_MODE_VOICE_TRIGGER
         * @see #RECOGNITION_MODE_USER_IDENTIFICATION
         * @see #RECOGNITION_MODE_USER_AUTHENTICATION
         * @see #RECOGNITION_MODE_GENERIC
         */
        @RecognitionModes
        public final int recognitionModes;
        public final int recognitionModes;


        /** Locale of the keyphrase. JAVA Locale string e.g en_US */
        /** Locale of the keyphrase. */
        @UnsupportedAppUsage
        @NonNull
        @NonNull
        public final String locale;
        public final Locale locale;


        /** Key phrase text */
        /** Key phrase text */
        @UnsupportedAppUsage
        @NonNull
        @NonNull
        public final String text;
        public final String text;


        /** Users this key phrase has been trained for. countains sound trigger specific user IDs
        /**
         * derived from system user IDs {@link android.os.UserHandle#getIdentifier()}. */
         * Users this key phrase has been trained for. countains sound trigger specific user IDs
        @UnsupportedAppUsage
         * derived from system user IDs {@link android.os.UserHandle#getIdentifier()}.
         */
        @NonNull
        @NonNull
        public final int[] users;
        public final int[] users;


        @UnsupportedAppUsage
        /**
        public Keyphrase(int id, int recognitionModes, @NonNull String locale, @NonNull String text,
         * Constructor for Keyphrase describes a key phrase that can be detected by a
                @Nullable int[] users) {
         * {@link KeyphraseSoundModel}
         *
         * @param id Unique keyphrase identifier for this keyphrase
         * @param recognitionModes Bit field representation of recognition modes this keyphrase
         *                         supports
         * @param locale Locale of the keyphrase
         * @param text Key phrase text
         * @param users Users this key phrase has been trained for.
         */
        public Keyphrase(int id, @RecognitionModes int recognitionModes, @NonNull Locale locale,
                @NonNull String text, @Nullable int[] users) {
            this.id = id;
            this.id = id;
            this.recognitionModes = recognitionModes;
            this.recognitionModes = recognitionModes;
            this.locale = requireNonNull(locale);
            this.locale = requireNonNull(locale);
@@ -404,21 +439,27 @@ public class SoundTrigger {
            this.users = users != null ? users : new int[0];
            this.users = users != null ? users : new int[0];
        }
        }


        public static final @android.annotation.NonNull Parcelable.Creator<Keyphrase> CREATOR
        public static final @NonNull Parcelable.Creator<Keyphrase> CREATOR =
                = new Parcelable.Creator<Keyphrase>() {
                new Parcelable.Creator<Keyphrase>() {
            public Keyphrase createFromParcel(Parcel in) {
            @NonNull
                return Keyphrase.fromParcel(in);
            public Keyphrase createFromParcel(@NonNull Parcel in) {
                return Keyphrase.readFromParcel(in);
            }
            }


            @NonNull
            public Keyphrase[] newArray(int size) {
            public Keyphrase[] newArray(int size) {
                return new Keyphrase[size];
                return new Keyphrase[size];
            }
            }
        };
        };


        private static Keyphrase fromParcel(Parcel in) {
        /**
         * Read from Parcel to generate keyphrase
         */
        @NonNull
        public static Keyphrase readFromParcel(@NonNull Parcel in) {
            int id = in.readInt();
            int id = in.readInt();
            int recognitionModes = in.readInt();
            int recognitionModes = in.readInt();
            String locale = in.readString();
            Locale locale = Locale.forLanguageTag(in.readString());
            String text = in.readString();
            String text = in.readString();
            int[] users = null;
            int[] users = null;
            int numUsers = in.readInt();
            int numUsers = in.readInt();
@@ -430,10 +471,10 @@ public class SoundTrigger {
        }
        }


        @Override
        @Override
        public void writeToParcel(Parcel dest, int flags) {
        public void writeToParcel(@NonNull Parcel dest, int flags) {
            dest.writeInt(id);
            dest.writeInt(id);
            dest.writeInt(recognitionModes);
            dest.writeInt(recognitionModes);
            dest.writeString(locale);
            dest.writeString(locale.toLanguageTag());
            dest.writeString(text);
            dest.writeString(text);
            if (users != null) {
            if (users != null) {
                dest.writeInt(users.length);
                dest.writeInt(users.length);
@@ -443,6 +484,7 @@ public class SoundTrigger {
            }
            }
        }
        }


        /** @hide */
        @Override
        @Override
        public int describeContents() {
        public int describeContents() {
            return 0;
            return 0;
@@ -462,49 +504,57 @@ public class SoundTrigger {


        @Override
        @Override
        public boolean equals(Object obj) {
        public boolean equals(Object obj) {
            if (this == obj)
            if (this == obj) {
                return true;
                return true;
            if (obj == null)
            }
            if (obj == null) {
                return false;
                return false;
            if (getClass() != obj.getClass())
            }
            if (getClass() != obj.getClass()) {
                return false;
                return false;
            }
            Keyphrase other = (Keyphrase) obj;
            Keyphrase other = (Keyphrase) obj;
            if (text == null) {
            if (text == null) {
                if (other.text != null)
                if (other.text != null) {
                    return false;
                    return false;
            } else if (!text.equals(other.text))
                }
            } else if (!text.equals(other.text)) {
                return false;
                return false;
            if (id != other.id)
            }
            if (id != other.id) {
                return false;
                return false;
            }
            if (locale == null) {
            if (locale == null) {
                if (other.locale != null)
                if (other.locale != null) {
                    return false;
                    return false;
            } else if (!locale.equals(other.locale))
                }
            } else if (!locale.equals(other.locale)) {
                return false;
                return false;
            if (recognitionModes != other.recognitionModes)
            }
            if (recognitionModes != other.recognitionModes) {
                return false;
                return false;
            if (!Arrays.equals(users, other.users))
            }
            if (!Arrays.equals(users, other.users)) {
                return false;
                return false;
            }
            return true;
            return true;
        }
        }


        @Override
        @Override
        public String toString() {
        public String toString() {
            return "Keyphrase [id=" + id + ", recognitionModes=" + recognitionModes + ", locale="
            return "Keyphrase [id=" + id + ", recognitionModes=" + recognitionModes
                    + locale + ", text=" + text + ", users=" + Arrays.toString(users) + "]";
                    + ", locale=" + locale.toLanguageTag() + ", text=" + text
                    + ", users=" + Arrays.toString(users) + "]";
        }
        }
    }
    }


    /*****************************************************************************
    /**
     * A KeyphraseSoundModel is a specialized {@link SoundModel} for key phrases.
     * A KeyphraseSoundModel is a specialized {@link SoundModel} for key phrases.
     * It contains data needed by the hardware to detect a certain number of key phrases
     * It contains data needed by the hardware to detect a certain number of key phrases
     * and the list of corresponding {@link Keyphrase} descriptors.
     * and the list of corresponding {@link Keyphrase} descriptors.
     *
     */
     * @hide
    public static final class KeyphraseSoundModel extends SoundModel implements Parcelable {
     ****************************************************************************/
    public static class KeyphraseSoundModel extends SoundModel implements Parcelable {
        /** Key phrases in this sound model */
        /** Key phrases in this sound model */
        @UnsupportedAppUsage
        @NonNull
        @NonNull
        public final Keyphrase[] keyphrases; // keyword phrases in model
        public final Keyphrase[] keyphrases; // keyword phrases in model


@@ -515,24 +565,29 @@ public class SoundTrigger {
            this.keyphrases = keyphrases != null ? keyphrases : new Keyphrase[0];
            this.keyphrases = keyphrases != null ? keyphrases : new Keyphrase[0];
        }
        }


        @UnsupportedAppUsage
        public KeyphraseSoundModel(@NonNull UUID uuid, @NonNull UUID vendorUuid,
        public KeyphraseSoundModel(@NonNull UUID uuid, @NonNull UUID vendorUuid,
                @Nullable byte[] data, @Nullable Keyphrase[] keyphrases) {
                @Nullable byte[] data, @Nullable Keyphrase[] keyphrases) {
            this(uuid, vendorUuid, data, keyphrases, -1);
            this(uuid, vendorUuid, data, keyphrases, -1);
        }
        }


        public static final @android.annotation.NonNull Parcelable.Creator<KeyphraseSoundModel> CREATOR
        public static final @NonNull Parcelable.Creator<KeyphraseSoundModel> CREATOR =
                = new Parcelable.Creator<KeyphraseSoundModel>() {
                new Parcelable.Creator<KeyphraseSoundModel>() {
            public KeyphraseSoundModel createFromParcel(Parcel in) {
            @NonNull
                return KeyphraseSoundModel.fromParcel(in);
            public KeyphraseSoundModel createFromParcel(@NonNull Parcel in) {
                return KeyphraseSoundModel.readFromParcel(in);
            }
            }


            @NonNull
            public KeyphraseSoundModel[] newArray(int size) {
            public KeyphraseSoundModel[] newArray(int size) {
                return new KeyphraseSoundModel[size];
                return new KeyphraseSoundModel[size];
            }
            }
        };
        };


        private static KeyphraseSoundModel fromParcel(Parcel in) {
        /**
         * Read from Parcel to generate KeyphraseSoundModel
         */
        @NonNull
        public static KeyphraseSoundModel readFromParcel(@NonNull Parcel in) {
            UUID uuid = UUID.fromString(in.readString());
            UUID uuid = UUID.fromString(in.readString());
            UUID vendorUuid = null;
            UUID vendorUuid = null;
            int length = in.readInt();
            int length = in.readInt();
@@ -545,13 +600,14 @@ public class SoundTrigger {
            return new KeyphraseSoundModel(uuid, vendorUuid, data, keyphrases, version);
            return new KeyphraseSoundModel(uuid, vendorUuid, data, keyphrases, version);
        }
        }


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


        @Override
        @Override
        public void writeToParcel(Parcel dest, int flags) {
        public void writeToParcel(@NonNull Parcel dest, int flags) {
            dest.writeString(uuid.toString());
            dest.writeString(uuid.toString());
            if (vendorUuid == null) {
            if (vendorUuid == null) {
                dest.writeInt(-1);
                dest.writeInt(-1);
@@ -583,15 +639,19 @@ public class SoundTrigger {


        @Override
        @Override
        public boolean equals(Object obj) {
        public boolean equals(Object obj) {
            if (this == obj)
            if (this == obj) {
                return true;
                return true;
            if (!super.equals(obj))
            }
            if (!super.equals(obj)) {
                return false;
                return false;
            if (!(obj instanceof KeyphraseSoundModel))
            }
            if (!(obj instanceof KeyphraseSoundModel)) {
                return false;
                return false;
            }
            KeyphraseSoundModel other = (KeyphraseSoundModel) obj;
            KeyphraseSoundModel other = (KeyphraseSoundModel) obj;
            if (!Arrays.equals(keyphrases, other.keyphrases))
            if (!Arrays.equals(keyphrases, other.keyphrases)) {
                return false;
                return false;
            }
            return true;
            return true;
        }
        }
    }
    }
@@ -761,30 +821,31 @@ public class SoundTrigger {


    /**
    /**
     * Modes for key phrase recognition
     * Modes for key phrase recognition
     * @hide
     */
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(flag = true, prefix = { "RECOGNITION_MODE_" }, value = {
            RECOGNITION_MODE_VOICE_TRIGGER,
            RECOGNITION_MODE_USER_IDENTIFICATION,
            RECOGNITION_MODE_USER_AUTHENTICATION,
            RECOGNITION_MODE_GENERIC
    })
    public @interface RecognitionModes {}


    /**
    /**
     * Simple recognition of the key phrase
     * Trigger on recognition of a key phrase
     *
     * @hide
     */
     */
    public static final int RECOGNITION_MODE_VOICE_TRIGGER = 0x1;
    public static final int RECOGNITION_MODE_VOICE_TRIGGER = 0x1;
    /**
    /**
     * Trigger only if one user is identified
     * Trigger only if one user is identified
     *
     * @hide
     */
     */
    public static final int RECOGNITION_MODE_USER_IDENTIFICATION = 0x2;
    public static final int RECOGNITION_MODE_USER_IDENTIFICATION = 0x2;
    /**
    /**
     * Trigger only if one user is authenticated
     * Trigger only if one user is authenticated
     *
     * @hide
     */
     */
    public static final int RECOGNITION_MODE_USER_AUTHENTICATION = 0x4;
    public static final int RECOGNITION_MODE_USER_AUTHENTICATION = 0x4;
    /**
    /**
     * Generic (non-speech) recognition.
     * Generic (non-speech) recognition.
     *
     * @hide
     */
     */
    public static final int RECOGNITION_MODE_GENERIC = 0x8;
    public static final int RECOGNITION_MODE_GENERIC = 0x8;


+4 −32

File changed.

Preview size limit exceeded, changes collapsed.

Loading