Hotword: Add HotwordAudioStream list in HotwordDetectedResult

- Create the new data class HotwordAudioStream
- Add HowordAudioStream list into HotwordDetectedResult
- Add @UnsupportedAppUsage and remove some codegen data

Test: atest CtsVoiceInteractionTestCases
Bug: 243766281
Bug: 243597982
Change-Id: I0953a93195699b17d4a69bba6c4140bc91eecb79
Merged-In: I0953a93195699b17d4a69bba6c4140bc91eecb79
diff --git a/core/java/android/service/voice/HotwordAudioStream.aidl b/core/java/android/service/voice/HotwordAudioStream.aidl
new file mode 100644
index 0000000..9550c83
--- /dev/null
+++ b/core/java/android/service/voice/HotwordAudioStream.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2022 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 HotwordAudioStream;
diff --git a/core/java/android/service/voice/HotwordAudioStream.java b/core/java/android/service/voice/HotwordAudioStream.java
new file mode 100644
index 0000000..c44542c
--- /dev/null
+++ b/core/java/android/service/voice/HotwordAudioStream.java
@@ -0,0 +1,434 @@
+/*
+ * Copyright (C) 2022 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.compat.annotation.UnsupportedAppUsage;
+import android.media.AudioFormat;
+import android.media.AudioRecord;
+import android.media.AudioTimestamp;
+import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
+import android.os.Parcelable;
+import android.os.PersistableBundle;
+
+import java.util.Objects;
+
+/**
+ * Represents an audio stream supporting the hotword detection.
+ *
+ * @hide
+ */
+public final class HotwordAudioStream implements Parcelable {
+
+    /**
+     * The {@link AudioFormat} of the audio stream.
+     */
+    @NonNull
+    @UnsupportedAppUsage
+    private final AudioFormat mAudioFormat;
+
+    /**
+     * This stream starts with the audio bytes used for hotword detection, but continues streaming
+     * the audio until the stream is shutdown by the {@link HotwordDetectionService}.
+     */
+    @NonNull
+    @UnsupportedAppUsage
+    private final ParcelFileDescriptor mAudioStreamParcelFileDescriptor;
+
+    /**
+     * The timestamp when the audio stream was captured by the Audio platform.
+     *
+     * <p>
+     * The {@link HotwordDetectionService} egressing the audio is the owner of the underlying
+     * AudioRecord. The {@link HotwordDetectionService} is expected to optionally populate this
+     * field by {@link AudioRecord#getTimestamp}.
+     * </p>
+     *
+     * <p>
+     * This timestamp can be used in conjunction with the
+     * {@link HotwordDetectedResult#getHotwordOffsetMillis()} and
+     * {@link HotwordDetectedResult#getHotwordDurationMillis()} to translate these durations to
+     * timestamps.
+     * </p>
+     *
+     * @see #getAudioStreamParcelFileDescriptor()
+     */
+    @Nullable
+    @UnsupportedAppUsage
+    private final AudioTimestamp mTimestamp;
+
+    private static AudioTimestamp defaultTimestamp() {
+        return null;
+    }
+
+    /**
+     * The metadata associated with the audio stream.
+     */
+    @NonNull
+    @UnsupportedAppUsage
+    private final PersistableBundle mMetadata;
+
+    private static PersistableBundle defaultMetadata() {
+        return new PersistableBundle();
+    }
+
+    private String timestampToString() {
+        if (mTimestamp == null) {
+            return "";
+        }
+        return "TimeStamp:"
+                + " framePos=" + mTimestamp.framePosition
+                + " nanoTime=" + mTimestamp.nanoTime;
+    }
+
+    private void parcelTimestamp(Parcel dest, int flags) {
+        if (mTimestamp != null) {
+            // mTimestamp is not null, we write it to the parcel, set true.
+            dest.writeBoolean(true);
+            dest.writeLong(mTimestamp.framePosition);
+            dest.writeLong(mTimestamp.nanoTime);
+        } else {
+            // mTimestamp is null, we don't write any value out, set false.
+            dest.writeBoolean(false);
+        }
+    }
+
+    @Nullable
+    private static AudioTimestamp unparcelTimestamp(Parcel in) {
+        // If it is true, it means we wrote the value to the parcel before, parse it.
+        // Otherwise, return null.
+        if (in.readBoolean()) {
+            final AudioTimestamp timeStamp = new AudioTimestamp();
+            timeStamp.framePosition = in.readLong();
+            timeStamp.nanoTime = in.readLong();
+            return timeStamp;
+        } else {
+            return null;
+        }
+    }
+
+    /* package-private */
+    HotwordAudioStream(
+            @NonNull AudioFormat audioFormat,
+            @NonNull ParcelFileDescriptor audioStreamParcelFileDescriptor,
+            @Nullable AudioTimestamp timestamp,
+            @NonNull PersistableBundle metadata) {
+        this.mAudioFormat = audioFormat;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mAudioFormat);
+        this.mAudioStreamParcelFileDescriptor = audioStreamParcelFileDescriptor;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mAudioStreamParcelFileDescriptor);
+        this.mTimestamp = timestamp;
+        this.mMetadata = metadata;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mMetadata);
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    /**
+     * The {@link AudioFormat} of the audio stream.
+     */
+    @UnsupportedAppUsage
+    @NonNull
+    public AudioFormat getAudioFormat() {
+        return mAudioFormat;
+    }
+
+    /**
+     * This stream starts with the audio bytes used for hotword detection, but continues streaming
+     * the audio until the stream is shutdown by the {@link HotwordDetectionService}.
+     */
+    @UnsupportedAppUsage
+    @NonNull
+    public ParcelFileDescriptor getAudioStreamParcelFileDescriptor() {
+        return mAudioStreamParcelFileDescriptor;
+    }
+
+    /**
+     * The timestamp when the audio stream was captured by the Audio platform.
+     *
+     * <p>
+     * The {@link HotwordDetectionService} egressing the audio is the owner of the underlying
+     * AudioRecord. The {@link HotwordDetectionService} is expected to optionally populate this
+     * field by {@link AudioRecord#getTimestamp}.
+     * </p>
+     *
+     * <p>
+     * This timestamp can be used in conjunction with the
+     * {@link HotwordDetectedResult#getHotwordOffsetMillis()} and
+     * {@link HotwordDetectedResult#getHotwordDurationMillis()} to translate these durations to
+     * timestamps.
+     * </p>
+     *
+     * @see #getAudioStreamParcelFileDescriptor()
+     */
+    @UnsupportedAppUsage
+    @Nullable
+    public AudioTimestamp getTimestamp() {
+        return mTimestamp;
+    }
+
+    /**
+     * The metadata associated with the audio stream.
+     */
+    @UnsupportedAppUsage
+    @NonNull
+    public PersistableBundle getMetadata() {
+        return mMetadata;
+    }
+
+    @Override
+    public String toString() {
+        // You can override field toString logic by defining methods like:
+        // String fieldNameToString() { ... }
+
+        return "HotwordAudioStream { "
+                + "audioFormat = " + mAudioFormat + ", "
+                + "audioStreamParcelFileDescriptor = " + mAudioStreamParcelFileDescriptor + ", "
+                + "timestamp = " + timestampToString() + ", "
+                + "metadata = " + mMetadata + " }";
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        // You can override field equality logic by defining either of the methods like:
+        // boolean fieldNameEquals(HotwordAudioStream other) { ... }
+        // boolean fieldNameEquals(FieldType otherValue) { ... }
+
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        @SuppressWarnings("unchecked")
+        HotwordAudioStream that = (HotwordAudioStream) o;
+        //noinspection PointlessBooleanExpression
+        return Objects.equals(mAudioFormat, that.mAudioFormat)
+                && Objects.equals(mAudioStreamParcelFileDescriptor,
+                that.mAudioStreamParcelFileDescriptor)
+                && Objects.equals(mTimestamp, that.mTimestamp)
+                && Objects.equals(mMetadata, that.mMetadata);
+    }
+
+    @Override
+    public int hashCode() {
+        // You can override field hashCode logic by defining methods like:
+        // int fieldNameHashCode() { ... }
+
+        int _hash = 1;
+        _hash = 31 * _hash + Objects.hashCode(mAudioFormat);
+        _hash = 31 * _hash + Objects.hashCode(mAudioStreamParcelFileDescriptor);
+        _hash = 31 * _hash + Objects.hashCode(mTimestamp);
+        _hash = 31 * _hash + Objects.hashCode(mMetadata);
+        return _hash;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
+
+        byte flg = 0;
+        if (mTimestamp != null) flg |= 0x4;
+        dest.writeByte(flg);
+        dest.writeTypedObject(mAudioFormat, flags);
+        dest.writeTypedObject(mAudioStreamParcelFileDescriptor, flags);
+        parcelTimestamp(dest, flags);
+        dest.writeTypedObject(mMetadata, flags);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    /* package-private */
+    HotwordAudioStream(@NonNull Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        byte flg = in.readByte();
+        AudioFormat audioFormat = (AudioFormat) in.readTypedObject(AudioFormat.CREATOR);
+        ParcelFileDescriptor audioStreamParcelFileDescriptor =
+                (ParcelFileDescriptor) in.readTypedObject(ParcelFileDescriptor.CREATOR);
+        AudioTimestamp timestamp = unparcelTimestamp(in);
+        PersistableBundle metadata = (PersistableBundle) in.readTypedObject(
+                PersistableBundle.CREATOR);
+
+        this.mAudioFormat = audioFormat;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mAudioFormat);
+        this.mAudioStreamParcelFileDescriptor = audioStreamParcelFileDescriptor;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mAudioStreamParcelFileDescriptor);
+        this.mTimestamp = timestamp;
+        this.mMetadata = metadata;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mMetadata);
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<HotwordAudioStream> CREATOR =
+            new Parcelable.Creator<HotwordAudioStream>() {
+                @Override
+                public HotwordAudioStream[] newArray(int size) {
+                    return new HotwordAudioStream[size];
+                }
+
+                @Override
+                public HotwordAudioStream createFromParcel(@NonNull Parcel in) {
+                    return new HotwordAudioStream(in);
+                }
+            };
+
+    /**
+     * A builder for {@link HotwordAudioStream}
+     */
+    @SuppressWarnings("WeakerAccess")
+    public static final class Builder {
+
+        @NonNull
+        private AudioFormat mAudioFormat;
+        @NonNull
+        private ParcelFileDescriptor mAudioStreamParcelFileDescriptor;
+        @Nullable
+        private AudioTimestamp mTimestamp;
+        @NonNull
+        private PersistableBundle mMetadata;
+
+        private long mBuilderFieldsSet = 0L;
+
+        /**
+         * Creates a new Builder.
+         *
+         * @param audioFormat                     The {@link AudioFormat} of the audio stream.
+         * @param audioStreamParcelFileDescriptor This stream starts with the audio bytes used for
+         *                                        hotword detection, but continues streaming
+         *                                        the audio until the stream is shutdown by the
+         *                                        {@link HotwordDetectionService}.
+         */
+        @UnsupportedAppUsage
+        public Builder(
+                @NonNull AudioFormat audioFormat,
+                @NonNull ParcelFileDescriptor audioStreamParcelFileDescriptor) {
+            mAudioFormat = audioFormat;
+            com.android.internal.util.AnnotationValidations.validate(
+                    NonNull.class, null, mAudioFormat);
+            mAudioStreamParcelFileDescriptor = audioStreamParcelFileDescriptor;
+            com.android.internal.util.AnnotationValidations.validate(
+                    NonNull.class, null, mAudioStreamParcelFileDescriptor);
+        }
+
+        /**
+         * The {@link AudioFormat} of the audio stream.
+         */
+        @UnsupportedAppUsage
+        @NonNull
+        public Builder setAudioFormat(@NonNull AudioFormat value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x1;
+            mAudioFormat = value;
+            return this;
+        }
+
+        /**
+         * This stream starts with the audio bytes used for hotword detection, but continues
+         * streaming
+         * the audio until the stream is shutdown by the {@link HotwordDetectionService}.
+         */
+        @UnsupportedAppUsage
+        @NonNull
+        public Builder setAudioStreamParcelFileDescriptor(@NonNull ParcelFileDescriptor value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x2;
+            mAudioStreamParcelFileDescriptor = value;
+            return this;
+        }
+
+        /**
+         * The timestamp when the audio stream was captured by the Audio platform.
+         *
+         * <p>
+         * The {@link HotwordDetectionService} egressing the audio is the owner of the underlying
+         * AudioRecord. The {@link HotwordDetectionService} is expected to optionally populate this
+         * field by {@link AudioRecord#getTimestamp}.
+         * </p>
+         *
+         * <p>
+         * This timestamp can be used in conjunction with the
+         * {@link HotwordDetectedResult#getHotwordOffsetMillis()} and
+         * {@link HotwordDetectedResult#getHotwordDurationMillis()} to translate these durations to
+         * timestamps.
+         * </p>
+         *
+         * @see #getAudioStreamParcelFileDescriptor()
+         */
+        @UnsupportedAppUsage
+        @NonNull
+        public Builder setTimestamp(@NonNull AudioTimestamp value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x4;
+            mTimestamp = value;
+            return this;
+        }
+
+        /**
+         * The metadata associated with the audio stream.
+         */
+        @UnsupportedAppUsage
+        @NonNull
+        public Builder setMetadata(@NonNull PersistableBundle value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x8;
+            mMetadata = value;
+            return this;
+        }
+
+        /** Builds the instance. This builder should not be touched after calling this! */
+        @UnsupportedAppUsage
+        @NonNull
+        public HotwordAudioStream build() {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x10; // Mark builder used
+
+            if ((mBuilderFieldsSet & 0x4) == 0) {
+                mTimestamp = defaultTimestamp();
+            }
+            if ((mBuilderFieldsSet & 0x8) == 0) {
+                mMetadata = defaultMetadata();
+            }
+            HotwordAudioStream o = new HotwordAudioStream(
+                    mAudioFormat,
+                    mAudioStreamParcelFileDescriptor,
+                    mTimestamp,
+                    mMetadata);
+            return o;
+        }
+
+        private void checkNotUsed() {
+            if ((mBuilderFieldsSet & 0x10) != 0) {
+                throw new IllegalStateException(
+                        "This Builder should not be reused. Use a new Builder instance instead");
+            }
+        }
+    }
+}
diff --git a/core/java/android/service/voice/HotwordDetectedResult.java b/core/java/android/service/voice/HotwordDetectedResult.java
index ab71459..0468a61 100644
--- a/core/java/android/service/voice/HotwordDetectedResult.java
+++ b/core/java/android/service/voice/HotwordDetectedResult.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.res.Resources;
 import android.media.AudioRecord;
 import android.media.MediaSyncEvent;
@@ -31,6 +32,9 @@
 import com.android.internal.util.DataClass;
 import com.android.internal.util.Preconditions;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -196,6 +200,17 @@
     }
 
     /**
+     * The list of the audio streams containing audio bytes that were used for hotword detection.
+     *
+     * @hide
+     */
+    @NonNull
+    private final List<HotwordAudioStream> mAudioStreams;
+    private static List<HotwordAudioStream> defaultAudioStreams() {
+        return Collections.emptyList();
+    }
+
+    /**
      * App-specific extras to support trigger.
      *
      * <p>The size of this bundle will be limited to {@link #getMaxBundleSize}. Results will larger
@@ -353,6 +368,35 @@
         }
     }
 
+    /**
+     * The list of the audio streams containing audio bytes that were used for hotword detection.
+     *
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public @NonNull List<HotwordAudioStream> getAudioStreams() {
+        return List.copyOf(mAudioStreams);
+    }
+
+    @DataClass.Suppress("addAudioStreams")
+    abstract static class BaseBuilder {
+        /**
+         * The list of the audio streams containing audio bytes that were used for hotword
+         * detection.
+         *
+         * @hide
+         */
+        @UnsupportedAppUsage
+        public @NonNull Builder setAudioStreams(@NonNull List<HotwordAudioStream> value) {
+            Objects.requireNonNull(value, "value should not be null");
+            final Builder builder = (Builder) this;
+            // If the code gen flag in build() is changed, we must update the flag e.g. 0x200 here.
+            builder.mBuilderFieldsSet |= 0x200;
+            builder.mAudioStreams = List.copyOf(value);
+            return builder;
+        }
+    }
+
 
 
     // Code below generated by codegen v1.0.23.
@@ -436,6 +480,7 @@
             int score,
             int personalizedScore,
             int hotwordPhraseId,
+            @NonNull List<HotwordAudioStream> audioStreams,
             @NonNull PersistableBundle extras) {
         this.mConfidenceLevel = confidenceLevel;
         com.android.internal.util.AnnotationValidations.validate(
@@ -448,6 +493,9 @@
         this.mScore = score;
         this.mPersonalizedScore = personalizedScore;
         this.mHotwordPhraseId = hotwordPhraseId;
+        this.mAudioStreams = audioStreams;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mAudioStreams);
         this.mExtras = extras;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, mExtras);
@@ -578,6 +626,7 @@
                 "score = " + mScore + ", " +
                 "personalizedScore = " + mPersonalizedScore + ", " +
                 "hotwordPhraseId = " + mHotwordPhraseId + ", " +
+                "audioStreams = " + mAudioStreams + ", " +
                 "extras = " + mExtras +
         " }";
     }
@@ -604,6 +653,7 @@
                 && mScore == that.mScore
                 && mPersonalizedScore == that.mPersonalizedScore
                 && mHotwordPhraseId == that.mHotwordPhraseId
+                && Objects.equals(mAudioStreams, that.mAudioStreams)
                 && Objects.equals(mExtras, that.mExtras);
     }
 
@@ -623,6 +673,7 @@
         _hash = 31 * _hash + mScore;
         _hash = 31 * _hash + mPersonalizedScore;
         _hash = 31 * _hash + mHotwordPhraseId;
+        _hash = 31 * _hash + Objects.hashCode(mAudioStreams);
         _hash = 31 * _hash + Objects.hashCode(mExtras);
         return _hash;
     }
@@ -645,6 +696,7 @@
         dest.writeInt(mScore);
         dest.writeInt(mPersonalizedScore);
         dest.writeInt(mHotwordPhraseId);
+        dest.writeParcelableList(mAudioStreams, flags);
         dest.writeTypedObject(mExtras, flags);
     }
 
@@ -669,6 +721,8 @@
         int score = in.readInt();
         int personalizedScore = in.readInt();
         int hotwordPhraseId = in.readInt();
+        List<HotwordAudioStream> audioStreams = new ArrayList<>();
+        in.readParcelableList(audioStreams, HotwordAudioStream.class.getClassLoader());
         PersistableBundle extras = (PersistableBundle) in.readTypedObject(PersistableBundle.CREATOR);
 
         this.mConfidenceLevel = confidenceLevel;
@@ -682,6 +736,9 @@
         this.mScore = score;
         this.mPersonalizedScore = personalizedScore;
         this.mHotwordPhraseId = hotwordPhraseId;
+        this.mAudioStreams = audioStreams;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mAudioStreams);
         this.mExtras = extras;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, mExtras);
@@ -708,7 +765,7 @@
      */
     @SuppressWarnings("WeakerAccess")
     @DataClass.Generated.Member
-    public static final class Builder {
+    public static final class Builder extends BaseBuilder {
 
         private @HotwordConfidenceLevelValue int mConfidenceLevel;
         private @Nullable MediaSyncEvent mMediaSyncEvent;
@@ -719,6 +776,7 @@
         private int mScore;
         private int mPersonalizedScore;
         private int mHotwordPhraseId;
+        private @NonNull List<HotwordAudioStream> mAudioStreams;
         private @NonNull PersistableBundle mExtras;
 
         private long mBuilderFieldsSet = 0L;
@@ -868,7 +926,7 @@
         @DataClass.Generated.Member
         public @NonNull Builder setExtras(@NonNull PersistableBundle value) {
             checkNotUsed();
-            mBuilderFieldsSet |= 0x200;
+            mBuilderFieldsSet |= 0x400;
             mExtras = value;
             return this;
         }
@@ -876,7 +934,7 @@
         /** Builds the instance. This builder should not be touched after calling this! */
         public @NonNull HotwordDetectedResult build() {
             checkNotUsed();
-            mBuilderFieldsSet |= 0x400; // Mark builder used
+            mBuilderFieldsSet |= 0x800; // Mark builder used
 
             if ((mBuilderFieldsSet & 0x1) == 0) {
                 mConfidenceLevel = defaultConfidenceLevel();
@@ -906,6 +964,9 @@
                 mHotwordPhraseId = defaultHotwordPhraseId();
             }
             if ((mBuilderFieldsSet & 0x200) == 0) {
+                mAudioStreams = defaultAudioStreams();
+            }
+            if ((mBuilderFieldsSet & 0x400) == 0) {
                 mExtras = defaultExtras();
             }
             HotwordDetectedResult o = new HotwordDetectedResult(
@@ -918,12 +979,13 @@
                     mScore,
                     mPersonalizedScore,
                     mHotwordPhraseId,
+                    mAudioStreams,
                     mExtras);
             return o;
         }
 
         private void checkNotUsed() {
-            if ((mBuilderFieldsSet & 0x400) != 0) {
+            if ((mBuilderFieldsSet & 0x800) != 0) {
                 throw new IllegalStateException(
                         "This Builder should not be reused. Use a new Builder instance instead");
             }
@@ -931,10 +993,10 @@
     }
 
     @DataClass.Generated(
-            time = 1658357814396L,
+            time = 1668405106028L,
             codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/core/java/android/service/voice/HotwordDetectedResult.java",
-            inputSignatures = "public static final  int CONFIDENCE_LEVEL_NONE\npublic static final  int CONFIDENCE_LEVEL_LOW\npublic static final  int CONFIDENCE_LEVEL_LOW_MEDIUM\npublic static final  int CONFIDENCE_LEVEL_MEDIUM\npublic static final  int CONFIDENCE_LEVEL_MEDIUM_HIGH\npublic static final  int CONFIDENCE_LEVEL_HIGH\npublic static final  int CONFIDENCE_LEVEL_VERY_HIGH\npublic static final  int HOTWORD_OFFSET_UNSET\npublic static final  int AUDIO_CHANNEL_UNSET\nprivate static final  int LIMIT_HOTWORD_OFFSET_MAX_VALUE\nprivate static final  int LIMIT_AUDIO_CHANNEL_MAX_VALUE\npublic static final  java.lang.String EXTRA_PROXIMITY_METERS\nprivate final @android.service.voice.HotwordDetectedResult.HotwordConfidenceLevelValue int mConfidenceLevel\nprivate @android.annotation.Nullable android.media.MediaSyncEvent mMediaSyncEvent\nprivate  int mHotwordOffsetMillis\nprivate  int mHotwordDurationMillis\nprivate  int mAudioChannel\nprivate  boolean mHotwordDetectionPersonalized\nprivate final  int mScore\nprivate final  int mPersonalizedScore\nprivate final  int mHotwordPhraseId\nprivate final @android.annotation.NonNull android.os.PersistableBundle mExtras\nprivate static  int sMaxBundleSize\nprivate static  int defaultConfidenceLevel()\nprivate static  int defaultScore()\nprivate static  int defaultPersonalizedScore()\npublic static  int getMaxScore()\nprivate static  int defaultHotwordPhraseId()\npublic static  int getMaxHotwordPhraseId()\nprivate static  android.os.PersistableBundle defaultExtras()\npublic static  int getMaxBundleSize()\npublic @android.annotation.Nullable android.media.MediaSyncEvent getMediaSyncEvent()\npublic static  int getParcelableSize(android.os.Parcelable)\npublic static  int getUsageSize(android.service.voice.HotwordDetectedResult)\nprivate static  int bitCount(long)\nprivate  void onConstructed()\nclass HotwordDetectedResult 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)")
+            inputSignatures = "public static final  int CONFIDENCE_LEVEL_NONE\npublic static final  int CONFIDENCE_LEVEL_LOW\npublic static final  int CONFIDENCE_LEVEL_LOW_MEDIUM\npublic static final  int CONFIDENCE_LEVEL_MEDIUM\npublic static final  int CONFIDENCE_LEVEL_MEDIUM_HIGH\npublic static final  int CONFIDENCE_LEVEL_HIGH\npublic static final  int CONFIDENCE_LEVEL_VERY_HIGH\npublic static final  int HOTWORD_OFFSET_UNSET\npublic static final  int AUDIO_CHANNEL_UNSET\nprivate static final  int LIMIT_HOTWORD_OFFSET_MAX_VALUE\nprivate static final  int LIMIT_AUDIO_CHANNEL_MAX_VALUE\npublic static final  java.lang.String EXTRA_PROXIMITY_METERS\nprivate final @android.service.voice.HotwordDetectedResult.HotwordConfidenceLevelValue int mConfidenceLevel\nprivate @android.annotation.Nullable android.media.MediaSyncEvent mMediaSyncEvent\nprivate  int mHotwordOffsetMillis\nprivate  int mHotwordDurationMillis\nprivate  int mAudioChannel\nprivate  boolean mHotwordDetectionPersonalized\nprivate final  int mScore\nprivate final  int mPersonalizedScore\nprivate final  int mHotwordPhraseId\nprivate final @android.annotation.NonNull java.util.List<android.service.voice.HotwordAudioStream> mAudioStreams\nprivate final @android.annotation.NonNull android.os.PersistableBundle mExtras\nprivate static  int sMaxBundleSize\nprivate static  int defaultConfidenceLevel()\nprivate static  int defaultScore()\nprivate static  int defaultPersonalizedScore()\npublic static  int getMaxScore()\nprivate static  int defaultHotwordPhraseId()\npublic static  int getMaxHotwordPhraseId()\nprivate static  java.util.List<android.service.voice.HotwordAudioStream> defaultAudioStreams()\nprivate static  android.os.PersistableBundle defaultExtras()\npublic static  int getMaxBundleSize()\npublic @android.annotation.Nullable android.media.MediaSyncEvent getMediaSyncEvent()\npublic static  int getParcelableSize(android.os.Parcelable)\npublic static  int getUsageSize(android.service.voice.HotwordDetectedResult)\nprivate static  int bitCount(long)\nprivate  void onConstructed()\npublic @android.compat.annotation.UnsupportedAppUsage @android.annotation.NonNull java.util.List<android.service.voice.HotwordAudioStream> getAudioStreams()\nclass HotwordDetectedResult extends java.lang.Object implements [android.os.Parcelable]\npublic @android.compat.annotation.UnsupportedAppUsage @android.annotation.NonNull android.service.voice.HotwordDetectedResult.Builder setAudioStreams(java.util.List<android.service.voice.HotwordAudioStream>)\nclass BaseBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=true, genEqualsHashCode=true, genHiddenConstDefs=true, genParcelable=true, genToString=true)\npublic @android.compat.annotation.UnsupportedAppUsage @android.annotation.NonNull android.service.voice.HotwordDetectedResult.Builder setAudioStreams(java.util.List<android.service.voice.HotwordAudioStream>)\nclass BaseBuilder extends java.lang.Object implements []")
     @Deprecated
     private void __metadata() {}