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

Commit c94338c4 authored by Ajay Gopi's avatar Ajay Gopi
Browse files

Define HotwordTrainingData

This structure will be egressed from the active HotwordDetectionService
when it determines useful training events. We plan to extend the hotword
detection service callback to allow the egress of HotwordTrainingData
by adding  onTrainingData(HotwordTrainingData data) method to the callback.

Change-Id: I476fe9180a5fd58e56197d606fbdac04b9792af2
Test: atest --no-bazel-mode CtsVoiceInteractionTestCases:HotwordDetectionServiceBasicTest
Bug: 291599840
parent 1a7ed027
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -13254,6 +13254,48 @@ package android.service.voice {
    method @NonNull public android.service.voice.HotwordRejectedResult.Builder setConfidenceLevel(int);
  }
  public final class HotwordTrainingAudio implements android.os.Parcelable {
    method public int describeContents();
    method @NonNull public android.media.AudioFormat getAudioFormat();
    method @NonNull public int getAudioType();
    method @NonNull public byte[] getHotwordAudio();
    method public int getHotwordOffsetMillis();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.service.voice.HotwordTrainingAudio> CREATOR;
    field public static final int HOTWORD_OFFSET_UNSET = -1; // 0xffffffff
  }
  public static final class HotwordTrainingAudio.Builder {
    ctor public HotwordTrainingAudio.Builder(@NonNull byte[], @NonNull android.media.AudioFormat);
    method @NonNull public android.service.voice.HotwordTrainingAudio build();
    method @NonNull public android.service.voice.HotwordTrainingAudio.Builder setAudioFormat(@NonNull android.media.AudioFormat);
    method @NonNull public android.service.voice.HotwordTrainingAudio.Builder setAudioType(@NonNull int);
    method @NonNull public android.service.voice.HotwordTrainingAudio.Builder setHotwordAudio(@NonNull byte...);
    method @NonNull public android.service.voice.HotwordTrainingAudio.Builder setHotwordOffsetMillis(int);
  }
  public final class HotwordTrainingData implements android.os.Parcelable {
    method public int describeContents();
    method public static int getMaxTrainingDataSize();
    method public int getTimeoutStage();
    method @NonNull public java.util.List<android.service.voice.HotwordTrainingAudio> getTrainingAudios();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.service.voice.HotwordTrainingData> CREATOR;
    field public static final int TIMEOUT_STAGE_EARLY = 2; // 0x2
    field public static final int TIMEOUT_STAGE_LATE = 4; // 0x4
    field public static final int TIMEOUT_STAGE_MIDDLE = 3; // 0x3
    field public static final int TIMEOUT_STAGE_UNKNOWN = 0; // 0x0
    field public static final int TIMEOUT_STAGE_VERY_EARLY = 1; // 0x1
  }
  public static final class HotwordTrainingData.Builder {
    ctor public HotwordTrainingData.Builder();
    method @NonNull public android.service.voice.HotwordTrainingData.Builder addTrainingAudio(@NonNull android.service.voice.HotwordTrainingAudio);
    method @NonNull public android.service.voice.HotwordTrainingData build();
    method @NonNull public android.service.voice.HotwordTrainingData.Builder setTimeoutStage(int);
    method @NonNull public android.service.voice.HotwordTrainingData.Builder setTrainingAudios(@NonNull java.util.List<android.service.voice.HotwordTrainingAudio>);
  }
  public interface SandboxedDetectionInitializer {
    method public static int getMaxCustomInitializationStatus();
    method public void onUpdateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory, long, @Nullable java.util.function.IntConsumer);
+19 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.service.voice;

parcelable HotwordTrainingAudio;
 No newline at end of file
+367 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.service.voice;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.media.AudioFormat;
import android.os.Parcel;
import android.os.Parcelable;

import com.android.internal.util.DataClass;

/**
 * Represents audio supporting hotword model training.
 *
 * @hide
 */
@DataClass(
        genConstructor = false,
        genBuilder = true,
        genEqualsHashCode = true,
        genHiddenConstDefs = true,
        genParcelable = true,
        genToString = true
)
@SystemApi
public final class HotwordTrainingAudio implements Parcelable {
    /** Represents unset value for the hotword offset. */
    public static final int HOTWORD_OFFSET_UNSET = -1;

    /** Buffer of hotword audio data for training models. */
    @NonNull
    private final byte[] mHotwordAudio;

    private String hotwordAudioToString() {
        return "length=" + mHotwordAudio.length;
    }

    /**
     * The {@link AudioFormat} of the {@link HotwordTrainingAudio#mHotwordAudio}.
     */
    @NonNull
    private final AudioFormat mAudioFormat;

    /**
     * App-defined identifier to distinguish hotword training audio instances.
     */
    @NonNull
    private final int mAudioType;

    private static int defaultAudioType() {
        return 0;
    }

    /**
     * App-defined offset in milliseconds relative to start of
     * {@link HotwordTrainingAudio#mHotwordAudio}. Default value is
     * {@link HotwordTrainingAudio#HOTWORD_OFFSET_UNSET}.
     */
    private int mHotwordOffsetMillis = HOTWORD_OFFSET_UNSET;



    // Code below generated by codegen v1.0.23.
    //
    // DO NOT MODIFY!
    // CHECKSTYLE:OFF Generated code
    //
    // To regenerate run:
    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/service/voice/HotwordTrainingAudio.java
    //
    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
    //   Settings > Editor > Code Style > Formatter Control
    //@formatter:off


    @DataClass.Generated.Member
    /* package-private */ HotwordTrainingAudio(
            @NonNull byte[] hotwordAudio,
            @NonNull AudioFormat audioFormat,
            @NonNull int audioType,
            int hotwordOffsetMillis) {
        this.mHotwordAudio = hotwordAudio;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mHotwordAudio);
        this.mAudioFormat = audioFormat;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mAudioFormat);
        this.mAudioType = audioType;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mAudioType);
        this.mHotwordOffsetMillis = hotwordOffsetMillis;

        // onConstructed(); // You can define this method to get a callback
    }

    /**
     * Buffer of hotword audio data for training models.
     */
    @DataClass.Generated.Member
    public @NonNull byte[] getHotwordAudio() {
        return mHotwordAudio;
    }

    /**
     * The {@link AudioFormat} of the {@link HotwordTrainingAudio#mHotwordAudio}.
     */
    @DataClass.Generated.Member
    public @NonNull AudioFormat getAudioFormat() {
        return mAudioFormat;
    }

    /**
     * App-defined identifier to distinguish hotword training audio instances.
     */
    @DataClass.Generated.Member
    public @NonNull int getAudioType() {
        return mAudioType;
    }

    /**
     * App-defined offset in milliseconds relative to start of
     * {@link HotwordTrainingAudio#mHotwordAudio}. Default value is
     * {@link HotwordTrainingAudio#HOTWORD_OFFSET_UNSET}.
     */
    @DataClass.Generated.Member
    public int getHotwordOffsetMillis() {
        return mHotwordOffsetMillis;
    }

    @Override
    @DataClass.Generated.Member
    public String toString() {
        // You can override field toString logic by defining methods like:
        // String fieldNameToString() { ... }

        return "HotwordTrainingAudio { " +
                "hotwordAudio = " + hotwordAudioToString() + ", " +
                "audioFormat = " + mAudioFormat + ", " +
                "audioType = " + mAudioType + ", " +
                "hotwordOffsetMillis = " + mHotwordOffsetMillis +
        " }";
    }

    @Override
    @DataClass.Generated.Member
    public boolean equals(@Nullable Object o) {
        // You can override field equality logic by defining either of the methods like:
        // boolean fieldNameEquals(HotwordTrainingAudio other) { ... }
        // boolean fieldNameEquals(FieldType otherValue) { ... }

        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        @SuppressWarnings("unchecked")
        HotwordTrainingAudio that = (HotwordTrainingAudio) o;
        //noinspection PointlessBooleanExpression
        return true
                && java.util.Arrays.equals(mHotwordAudio, that.mHotwordAudio)
                && java.util.Objects.equals(mAudioFormat, that.mAudioFormat)
                && mAudioType == that.mAudioType
                && mHotwordOffsetMillis == that.mHotwordOffsetMillis;
    }

    @Override
    @DataClass.Generated.Member
    public int hashCode() {
        // You can override field hashCode logic by defining methods like:
        // int fieldNameHashCode() { ... }

        int _hash = 1;
        _hash = 31 * _hash + java.util.Arrays.hashCode(mHotwordAudio);
        _hash = 31 * _hash + java.util.Objects.hashCode(mAudioFormat);
        _hash = 31 * _hash + mAudioType;
        _hash = 31 * _hash + mHotwordOffsetMillis;
        return _hash;
    }

    @Override
    @DataClass.Generated.Member
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        // You can override field parcelling by defining methods like:
        // void parcelFieldName(Parcel dest, int flags) { ... }

        dest.writeByteArray(mHotwordAudio);
        dest.writeTypedObject(mAudioFormat, flags);
        dest.writeInt(mAudioType);
        dest.writeInt(mHotwordOffsetMillis);
    }

    @Override
    @DataClass.Generated.Member
    public int describeContents() { return 0; }

    /** @hide */
    @SuppressWarnings({"unchecked", "RedundantCast"})
    @DataClass.Generated.Member
    /* package-private */ HotwordTrainingAudio(@NonNull Parcel in) {
        // You can override field unparcelling by defining methods like:
        // static FieldType unparcelFieldName(Parcel in) { ... }

        byte[] hotwordAudio = in.createByteArray();
        AudioFormat audioFormat = (AudioFormat) in.readTypedObject(AudioFormat.CREATOR);
        int audioType = in.readInt();
        int hotwordOffsetMillis = in.readInt();

        this.mHotwordAudio = hotwordAudio;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mHotwordAudio);
        this.mAudioFormat = audioFormat;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mAudioFormat);
        this.mAudioType = audioType;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mAudioType);
        this.mHotwordOffsetMillis = hotwordOffsetMillis;

        // onConstructed(); // You can define this method to get a callback
    }

    @DataClass.Generated.Member
    public static final @NonNull Parcelable.Creator<HotwordTrainingAudio> CREATOR
            = new Parcelable.Creator<HotwordTrainingAudio>() {
        @Override
        public HotwordTrainingAudio[] newArray(int size) {
            return new HotwordTrainingAudio[size];
        }

        @Override
        public HotwordTrainingAudio createFromParcel(@NonNull Parcel in) {
            return new HotwordTrainingAudio(in);
        }
    };

    /**
     * A builder for {@link HotwordTrainingAudio}
     */
    @SuppressWarnings("WeakerAccess")
    @DataClass.Generated.Member
    public static final class Builder {

        private @NonNull byte[] mHotwordAudio;
        private @NonNull AudioFormat mAudioFormat;
        private @NonNull int mAudioType;
        private int mHotwordOffsetMillis;

        private long mBuilderFieldsSet = 0L;

        /**
         * Creates a new Builder.
         *
         * @param hotwordAudio
         *   Buffer of hotword audio data for training models.
         * @param audioFormat
         *   The {@link AudioFormat} of the {@link HotwordTrainingAudio#mHotwordAudio}.
         */
        public Builder(
                @NonNull byte[] hotwordAudio,
                @NonNull AudioFormat audioFormat) {
            mHotwordAudio = hotwordAudio;
            com.android.internal.util.AnnotationValidations.validate(
                    NonNull.class, null, mHotwordAudio);
            mAudioFormat = audioFormat;
            com.android.internal.util.AnnotationValidations.validate(
                    NonNull.class, null, mAudioFormat);
        }

        /**
         * Buffer of hotword audio data for training models.
         */
        @DataClass.Generated.Member
        public @NonNull Builder setHotwordAudio(@NonNull byte... value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x1;
            mHotwordAudio = value;
            return this;
        }

        /**
         * The {@link AudioFormat} of the {@link HotwordTrainingAudio#mHotwordAudio}.
         */
        @DataClass.Generated.Member
        public @NonNull Builder setAudioFormat(@NonNull AudioFormat value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x2;
            mAudioFormat = value;
            return this;
        }

        /**
         * App-defined identifier to distinguish hotword training audio instances.
         */
        @DataClass.Generated.Member
        public @NonNull Builder setAudioType(@NonNull int value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x4;
            mAudioType = value;
            return this;
        }

        /**
         * App-defined offset in milliseconds relative to start of
         * {@link HotwordTrainingAudio#mHotwordAudio}. Default value is
         * {@link HotwordTrainingAudio#HOTWORD_OFFSET_UNSET}.
         */
        @DataClass.Generated.Member
        public @NonNull Builder setHotwordOffsetMillis(int value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x8;
            mHotwordOffsetMillis = value;
            return this;
        }

        /** Builds the instance. This builder should not be touched after calling this! */
        public @NonNull HotwordTrainingAudio build() {
            checkNotUsed();
            mBuilderFieldsSet |= 0x10; // Mark builder used

            if ((mBuilderFieldsSet & 0x4) == 0) {
                mAudioType = defaultAudioType();
            }
            if ((mBuilderFieldsSet & 0x8) == 0) {
                mHotwordOffsetMillis = HOTWORD_OFFSET_UNSET;
            }
            HotwordTrainingAudio o = new HotwordTrainingAudio(
                    mHotwordAudio,
                    mAudioFormat,
                    mAudioType,
                    mHotwordOffsetMillis);
            return o;
        }

        private void checkNotUsed() {
            if ((mBuilderFieldsSet & 0x10) != 0) {
                throw new IllegalStateException(
                        "This Builder should not be reused. Use a new Builder instance instead");
            }
        }
    }

    @DataClass.Generated(
            time = 1692837160437L,
            codegenVersion = "1.0.23",
            sourceFile = "frameworks/base/core/java/android/service/voice/HotwordTrainingAudio.java",
            inputSignatures = "public static final  int HOTWORD_OFFSET_UNSET\nprivate final @android.annotation.NonNull byte[] mHotwordAudio\nprivate final @android.annotation.NonNull android.media.AudioFormat mAudioFormat\nprivate final @android.annotation.NonNull int mAudioType\nprivate  int mHotwordOffsetMillis\nprivate  java.lang.String hotwordAudioToString()\nprivate static  int defaultAudioType()\nclass HotwordTrainingAudio extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=true, genEqualsHashCode=true, genHiddenConstDefs=true, genParcelable=true, genToString=true)")
    @Deprecated
    private void __metadata() {}


    //@formatter:on
    // End of generated code

}
+19 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.service.voice;

parcelable HotwordTrainingData;
+371 −0

File added.

Preview size limit exceeded, changes collapsed.