• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.service.voice;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.SystemApi;
23 import android.compat.annotation.UnsupportedAppUsage;
24 import android.content.res.Resources;
25 import android.media.AudioRecord;
26 import android.media.MediaSyncEvent;
27 import android.os.Parcel;
28 import android.os.Parcelable;
29 import android.os.PersistableBundle;
30 
31 import com.android.internal.R;
32 import com.android.internal.util.DataClass;
33 import com.android.internal.util.Preconditions;
34 
35 import java.lang.annotation.Retention;
36 import java.lang.annotation.RetentionPolicy;
37 import java.util.ArrayList;
38 import java.util.Collections;
39 import java.util.List;
40 import java.util.Objects;
41 
42 /**
43  * Represents a result supporting the hotword detection.
44  *
45  * @hide
46  */
47 @DataClass(
48         genConstructor = false,
49         genBuilder = true,
50         genEqualsHashCode = true,
51         genHiddenConstDefs = true,
52         genParcelable = true,
53         genToString = true
54 )
55 @SystemApi
56 public final class HotwordDetectedResult implements Parcelable {
57 
58     /** No confidence in hotword detector result. */
59     public static final int CONFIDENCE_LEVEL_NONE = 0;
60 
61     /** Low confidence in hotword detector result. */
62     public static final int CONFIDENCE_LEVEL_LOW = 1;
63 
64     /** Low-to-medium confidence in hotword detector result. */
65     public static final int CONFIDENCE_LEVEL_LOW_MEDIUM = 2;
66 
67     /** Medium confidence in hotword detector result. */
68     public static final int CONFIDENCE_LEVEL_MEDIUM = 3;
69 
70     /** Medium-to-high confidence in hotword detector result. */
71     public static final int CONFIDENCE_LEVEL_MEDIUM_HIGH = 4;
72 
73     /** High confidence in hotword detector result. */
74     public static final int CONFIDENCE_LEVEL_HIGH = 5;
75 
76     /** Very high confidence in hotword detector result. */
77     public static final int CONFIDENCE_LEVEL_VERY_HIGH = 6;
78 
79     /** @hide */
80     @IntDef(prefix = {"CONFIDENCE_LEVEL_"}, value = {
81             CONFIDENCE_LEVEL_NONE,
82             CONFIDENCE_LEVEL_LOW,
83             CONFIDENCE_LEVEL_LOW_MEDIUM,
84             CONFIDENCE_LEVEL_MEDIUM,
85             CONFIDENCE_LEVEL_MEDIUM_HIGH,
86             CONFIDENCE_LEVEL_HIGH,
87             CONFIDENCE_LEVEL_VERY_HIGH
88     })
89     @interface HotwordConfidenceLevelValue {
90     }
91 
92     /** Represents unset value for the hotword offset. */
93     public static final int HOTWORD_OFFSET_UNSET = -1;
94 
95     /** Represents unset value for the triggered audio channel. */
96     public static final int AUDIO_CHANNEL_UNSET = -1;
97 
98     /** Limits the max value for the hotword offset. */
99     private static final int LIMIT_HOTWORD_OFFSET_MAX_VALUE = 60 * 60 * 1000; // 1 hour
100 
101     /** Limits the max value for the triggered audio channel. */
102     private static final int LIMIT_AUDIO_CHANNEL_MAX_VALUE = 63;
103 
104     /**
105      * The bundle key for proximity
106      *
107      * TODO(b/238896013): Move the proximity logic out of bundle to proper API.
108      */
109     private static final String EXTRA_PROXIMITY =
110             "android.service.voice.extra.PROXIMITY";
111 
112     /**
113      * Users’ proximity is unknown (proximity sensing was inconclusive and is unsupported).
114      *
115      * @hide
116      */
117     public static final int PROXIMITY_UNKNOWN = -1;
118 
119     /**
120      * Proximity value that represents that the object is near.
121      *
122      * @hide
123      */
124     public static final int PROXIMITY_NEAR = 1;
125 
126     /**
127      * Proximity value that represents that the object is far.
128      *
129      * @hide
130      */
131     public static final int PROXIMITY_FAR = 2;
132 
133     /** @hide */
134     @IntDef(prefix = {"PROXIMITY"}, value = {
135             PROXIMITY_UNKNOWN,
136             PROXIMITY_NEAR,
137             PROXIMITY_FAR
138     })
139     @Retention(RetentionPolicy.SOURCE)
140     public @interface ProximityValue {}
141 
142     /** Confidence level in the trigger outcome. */
143     @HotwordConfidenceLevelValue
144     private final int mConfidenceLevel;
defaultConfidenceLevel()145     private static int defaultConfidenceLevel() {
146         return CONFIDENCE_LEVEL_NONE;
147     }
148 
149     /**
150      * A {@code MediaSyncEvent} that allows the {@link HotwordDetector} to recapture the audio
151      * that contains the hotword trigger. This must be obtained using
152      * {@link android.media.AudioRecord#shareAudioHistory(String, long)}.
153      */
154     @Nullable
155     private MediaSyncEvent mMediaSyncEvent = null;
156 
157     /**
158      * Offset in milliseconds the audio stream when the trigger event happened (end of hotword
159      * phrase).
160      *
161      * <p>Only value between 0 and 3600000 (inclusive) is accepted.
162      */
163     private int mHotwordOffsetMillis = HOTWORD_OFFSET_UNSET;
164 
165     /**
166      * Duration in milliseconds of the hotword trigger phrase.
167      *
168      * <p>Only values between 0 and {@link android.media.AudioRecord#getMaxSharedAudioHistoryMillis}
169      * (inclusive) are accepted.
170      */
171     private int mHotwordDurationMillis = 0;
172 
173     /**
174      * Audio channel containing the highest-confidence hotword signal.
175      *
176      * <p>Only value between 0 and 63 (inclusive) is accepted.
177      */
178     private int mAudioChannel = AUDIO_CHANNEL_UNSET;
179 
180     /**
181      * Returns whether the trigger has happened due to model having been personalized to fit user's
182      * voice.
183      */
184     private boolean mHotwordDetectionPersonalized = false;
185 
186     /**
187      * Score for the hotword trigger.
188      *
189      * <p>Only values between 0 and {@link #getMaxScore} (inclusive) are accepted.
190      */
191     private final int mScore;
defaultScore()192     private static int defaultScore() {
193         return 0;
194     }
195 
196     /**
197      * Score for the hotword trigger for device user.
198      *
199      * <p>Only values between 0 and {@link #getMaxScore} (inclusive) are accepted.
200      */
201     private final int mPersonalizedScore;
defaultPersonalizedScore()202     private static int defaultPersonalizedScore() {
203         return 0;
204     }
205 
206     /**
207      * Returns the maximum values of {@link #getScore} and {@link #getPersonalizedScore}.
208      * <p>
209      * The float value should be calculated as {@code getScore() / getMaxScore()}.
210      */
getMaxScore()211     public static int getMaxScore() {
212         return 255;
213     }
214 
215     /**
216      * An ID representing the keyphrase that triggered the successful detection.
217      *
218      * <p>Only values between 0 and {@link #getMaxHotwordPhraseId()} (inclusive) are accepted.
219      */
220     private final int mHotwordPhraseId;
defaultHotwordPhraseId()221     private static int defaultHotwordPhraseId() {
222         return 0;
223     }
224 
225     /**
226      * Returns the maximum value of {@link #getHotwordPhraseId()}.
227      */
getMaxHotwordPhraseId()228     public static int getMaxHotwordPhraseId() {
229         return 63;
230     }
231 
232     /**
233      * The list of the audio streams containing audio bytes that were used for hotword detection.
234      *
235      * @hide
236      */
237     @NonNull
238     private final List<HotwordAudioStream> mAudioStreams;
defaultAudioStreams()239     private static List<HotwordAudioStream> defaultAudioStreams() {
240         return Collections.emptyList();
241     }
242 
243     /**
244      * App-specific extras to support trigger.
245      *
246      * <p>The size of this bundle will be limited to {@link #getMaxBundleSize}. Results will larger
247      * bundles will be rejected.
248      *
249      * <p>Only primitive types are supported in this bundle. Complex types will be removed from the
250      * bundle.
251      *
252      * <p>The use of this method is discouraged, and support for it will be removed in future
253      * versions of Android.
254      *
255      * <p>After the trigger happens, a special case of proximity-related extra, with the key of
256      * 'android.service.voice.extra.PROXIMITY_VALUE' and the value of proximity value (integer)
257      * will be stored to enable proximity logic. {@link HotwordDetectedResult#PROXIMITY_NEAR} will
258      * indicate 'NEAR' proximity and {@link HotwordDetectedResult#PROXIMITY_FAR} will indicate 'FAR'
259      * proximity. The proximity value is provided by the system, on devices that support detecting
260      * proximity of nearby users, to help disambiguate which nearby device should respond. When the
261      * proximity is unknown, the proximity value will not be stored. This mapping will be excluded
262      * from the max bundle size calculation because this mapping is included after the result is
263      * returned from the hotword detector service.
264      *
265      * <p>This is a PersistableBundle so it doesn't allow any remotable objects or other contents
266      * that can be used to communicate with other processes.
267      */
268     @NonNull
269     private final PersistableBundle mExtras;
defaultExtras()270     private static PersistableBundle defaultExtras() {
271         return new PersistableBundle();
272     }
273 
274     private static int sMaxBundleSize = -1;
275 
276     /**
277      * Returns the maximum byte size of the information contained in the bundle.
278      *
279      * <p>The total size will be calculated by how much bundle data should be written into the
280      * Parcel.
281      */
getMaxBundleSize()282     public static int getMaxBundleSize() {
283         if (sMaxBundleSize < 0) {
284             sMaxBundleSize = Resources.getSystem().getInteger(
285                     R.integer.config_hotwordDetectedResultMaxBundleSize);
286         }
287         return sMaxBundleSize;
288     }
289 
290     /**
291      * A {@code MediaSyncEvent} that allows the {@link HotwordDetector} to recapture the audio
292      * that contains the hotword trigger. This must be obtained using
293      * {@link android.media.AudioRecord#shareAudioHistory(String, long)}.
294      * <p>
295      * This can be {@code null} if reprocessing the hotword trigger isn't required.
296      */
297     // Suppress codegen to make javadoc consistent. Getter returns @Nullable, setter accepts
298     // @NonNull only, and by default codegen would use the same javadoc on both.
getMediaSyncEvent()299     public @Nullable MediaSyncEvent getMediaSyncEvent() {
300         return mMediaSyncEvent;
301     }
302 
303     /**
304      * Returns how many bytes should be written into the Parcel
305      *
306      * @hide
307      */
getParcelableSize(@onNull Parcelable parcelable)308     public static int getParcelableSize(@NonNull Parcelable parcelable) {
309         final Parcel p = Parcel.obtain();
310         parcelable.writeToParcel(p, 0);
311         p.setDataPosition(0);
312         final int size = p.dataSize();
313         p.recycle();
314         return size;
315     }
316 
317     /**
318      * Returns how many bits have been written into the HotwordDetectedResult.
319      *
320      * @hide
321      */
getUsageSize(@onNull HotwordDetectedResult hotwordDetectedResult)322     public static int getUsageSize(@NonNull HotwordDetectedResult hotwordDetectedResult) {
323         int totalBits = 0;
324 
325         if (hotwordDetectedResult.getConfidenceLevel() != defaultConfidenceLevel()) {
326             totalBits += bitCount(CONFIDENCE_LEVEL_VERY_HIGH);
327         }
328         if (hotwordDetectedResult.getHotwordOffsetMillis() != HOTWORD_OFFSET_UNSET) {
329             totalBits += bitCount(LIMIT_HOTWORD_OFFSET_MAX_VALUE);
330         }
331         if (hotwordDetectedResult.getHotwordDurationMillis() != 0) {
332             totalBits += bitCount(AudioRecord.getMaxSharedAudioHistoryMillis());
333         }
334         if (hotwordDetectedResult.getAudioChannel() != AUDIO_CHANNEL_UNSET) {
335             totalBits += bitCount(LIMIT_AUDIO_CHANNEL_MAX_VALUE);
336         }
337 
338         // Add one bit for HotwordDetectionPersonalized
339         totalBits += 1;
340 
341         if (hotwordDetectedResult.getScore() != defaultScore()) {
342             totalBits += bitCount(HotwordDetectedResult.getMaxScore());
343         }
344         if (hotwordDetectedResult.getPersonalizedScore() != defaultPersonalizedScore()) {
345             totalBits += bitCount(HotwordDetectedResult.getMaxScore());
346         }
347         if (hotwordDetectedResult.getHotwordPhraseId() != defaultHotwordPhraseId()) {
348             totalBits += bitCount(HotwordDetectedResult.getMaxHotwordPhraseId());
349         }
350         PersistableBundle persistableBundle = hotwordDetectedResult.getExtras();
351         if (!persistableBundle.isEmpty()) {
352             totalBits += getParcelableSize(persistableBundle) * Byte.SIZE;
353         }
354         return totalBits;
355     }
356 
bitCount(long value)357     private static int bitCount(long value) {
358         int bits = 0;
359         while (value > 0) {
360             bits++;
361             value = value >> 1;
362         }
363         return bits;
364     }
365 
onConstructed()366     private void onConstructed() {
367         Preconditions.checkArgumentInRange(mScore, 0, getMaxScore(), "score");
368         Preconditions.checkArgumentInRange(mPersonalizedScore, 0, getMaxScore(),
369                 "personalizedScore");
370         Preconditions.checkArgumentInRange(mHotwordPhraseId, 0, getMaxHotwordPhraseId(),
371                 "hotwordPhraseId");
372         Preconditions.checkArgumentInRange((long) mHotwordDurationMillis, 0,
373                 AudioRecord.getMaxSharedAudioHistoryMillis(), "hotwordDurationMillis");
374         if (mHotwordOffsetMillis != HOTWORD_OFFSET_UNSET) {
375             Preconditions.checkArgumentInRange(mHotwordOffsetMillis, 0,
376                     LIMIT_HOTWORD_OFFSET_MAX_VALUE, "hotwordOffsetMillis");
377         }
378         if (mAudioChannel != AUDIO_CHANNEL_UNSET) {
379             Preconditions.checkArgumentInRange(mAudioChannel, 0, LIMIT_AUDIO_CHANNEL_MAX_VALUE,
380                     "audioChannel");
381         }
382         if (!mExtras.isEmpty()) {
383             // Remove the proximity key from the bundle before checking the bundle size. The
384             // proximity value is added after the privileged module and can avoid the
385             // maxBundleSize limitation.
386             if (mExtras.containsKey(EXTRA_PROXIMITY)) {
387                 int proximityValue = mExtras.getInt(EXTRA_PROXIMITY);
388                 mExtras.remove(EXTRA_PROXIMITY);
389                 // Skip checking parcelable size if the new bundle size is 0. Newly empty bundle
390                 // has parcelable size of 4, but the default bundle has parcelable size of 0.
391                 if (mExtras.size() > 0) {
392                     Preconditions.checkArgumentInRange(getParcelableSize(mExtras), 0,
393                             getMaxBundleSize(), "extras");
394                 }
395                 mExtras.putInt(EXTRA_PROXIMITY, proximityValue);
396             } else {
397                 Preconditions.checkArgumentInRange(getParcelableSize(mExtras), 0,
398                         getMaxBundleSize(), "extras");
399             }
400         }
401     }
402 
403     /**
404      * The list of the audio streams containing audio bytes that were used for hotword detection.
405      *
406      * @hide
407      */
408     @UnsupportedAppUsage
getAudioStreams()409     public @NonNull List<HotwordAudioStream> getAudioStreams() {
410         return List.copyOf(mAudioStreams);
411     }
412 
413     @DataClass.Suppress("addAudioStreams")
414     abstract static class BaseBuilder {
415         /**
416          * The list of the audio streams containing audio bytes that were used for hotword
417          * detection.
418          *
419          * @hide
420          */
421         @UnsupportedAppUsage
setAudioStreams(@onNull List<HotwordAudioStream> value)422         public @NonNull Builder setAudioStreams(@NonNull List<HotwordAudioStream> value) {
423             Objects.requireNonNull(value, "value should not be null");
424             final Builder builder = (Builder) this;
425             // If the code gen flag in build() is changed, we must update the flag e.g. 0x200 here.
426             builder.mBuilderFieldsSet |= 0x200;
427             builder.mAudioStreams = List.copyOf(value);
428             return builder;
429         }
430     }
431 
432     /**
433      * Provides an instance of {@link Builder} with state corresponding to this instance.
434      * @hide
435      */
buildUpon()436     public Builder buildUpon() {
437         return new Builder()
438             .setConfidenceLevel(mConfidenceLevel)
439             .setMediaSyncEvent(mMediaSyncEvent)
440             .setHotwordOffsetMillis(mHotwordOffsetMillis)
441             .setHotwordDurationMillis(mHotwordDurationMillis)
442             .setAudioChannel(mAudioChannel)
443             .setHotwordDetectionPersonalized(mHotwordDetectionPersonalized)
444             .setScore(mScore)
445             .setPersonalizedScore(mPersonalizedScore)
446             .setHotwordPhraseId(mHotwordPhraseId)
447             .setAudioStreams(mAudioStreams)
448             .setExtras(mExtras);
449     }
450 
451     /**
452      * Adds proximity level, either near or far, that is mapped for the given distance into
453      * the bundle. The proximity value is provided by the system, on devices that support detecting
454      * proximity of nearby users, to help disambiguate which nearby device should respond.
455      * This mapping will be excluded from the max bundle size calculation because this mapping is
456      * included after the result is returned from the hotword detector service. The value will not
457      * be included if the proximity was unknown.
458      *
459      * @hide
460      */
setProximity(double distance)461     public void setProximity(double distance) {
462         int proximityLevel = convertToProximityLevel(distance);
463         if (proximityLevel != PROXIMITY_UNKNOWN) {
464             mExtras.putInt(EXTRA_PROXIMITY, proximityLevel);
465         }
466     }
467 
468     /**
469      * Mapping of the proximity distance (meters) to proximity values, unknown, near, and far.
470      * Currently, this mapping is handled by HotwordDetectedResult because it handles just
471      * HotwordDetectionConnection which we know the mapping of. However, the mapping will need to
472      * move to a more centralized place once there are more clients.
473      *
474      * TODO(b/258531144): Move the proximity mapping to a central location
475      */
476     @ProximityValue
convertToProximityLevel(double distance)477     private int convertToProximityLevel(double distance) {
478         if (distance < 0) {
479             return PROXIMITY_UNKNOWN;
480         } else if (distance <= 3) {
481             return PROXIMITY_NEAR;
482         } else {
483             return PROXIMITY_FAR;
484         }
485     }
486 
487 
488 
489     // Code below generated by codegen v1.0.23.
490     //
491     // DO NOT MODIFY!
492     // CHECKSTYLE:OFF Generated code
493     //
494     // To regenerate run:
495     // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/service/voice/HotwordDetectedResult.java
496     //
497     // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
498     //   Settings > Editor > Code Style > Formatter Control
499     //@formatter:off
500 
501 
502     /** @hide */
503     @IntDef(prefix = "CONFIDENCE_LEVEL_", value = {
504         CONFIDENCE_LEVEL_NONE,
505         CONFIDENCE_LEVEL_LOW,
506         CONFIDENCE_LEVEL_LOW_MEDIUM,
507         CONFIDENCE_LEVEL_MEDIUM,
508         CONFIDENCE_LEVEL_MEDIUM_HIGH,
509         CONFIDENCE_LEVEL_HIGH,
510         CONFIDENCE_LEVEL_VERY_HIGH
511     })
512     @Retention(RetentionPolicy.SOURCE)
513     @DataClass.Generated.Member
514     public @interface ConfidenceLevel {}
515 
516     /** @hide */
517     @DataClass.Generated.Member
confidenceLevelToString(@onfidenceLevel int value)518     public static String confidenceLevelToString(@ConfidenceLevel int value) {
519         switch (value) {
520             case CONFIDENCE_LEVEL_NONE:
521                     return "CONFIDENCE_LEVEL_NONE";
522             case CONFIDENCE_LEVEL_LOW:
523                     return "CONFIDENCE_LEVEL_LOW";
524             case CONFIDENCE_LEVEL_LOW_MEDIUM:
525                     return "CONFIDENCE_LEVEL_LOW_MEDIUM";
526             case CONFIDENCE_LEVEL_MEDIUM:
527                     return "CONFIDENCE_LEVEL_MEDIUM";
528             case CONFIDENCE_LEVEL_MEDIUM_HIGH:
529                     return "CONFIDENCE_LEVEL_MEDIUM_HIGH";
530             case CONFIDENCE_LEVEL_HIGH:
531                     return "CONFIDENCE_LEVEL_HIGH";
532             case CONFIDENCE_LEVEL_VERY_HIGH:
533                     return "CONFIDENCE_LEVEL_VERY_HIGH";
534             default: return Integer.toHexString(value);
535         }
536     }
537 
538     /** @hide */
539     @IntDef(prefix = "LIMIT_", value = {
540         LIMIT_HOTWORD_OFFSET_MAX_VALUE,
541         LIMIT_AUDIO_CHANNEL_MAX_VALUE
542     })
543     @Retention(RetentionPolicy.SOURCE)
544     @DataClass.Generated.Member
545     /* package-private */ @interface Limit {}
546 
547     /** @hide */
548     @DataClass.Generated.Member
limitToString(@imit int value)549     /* package-private */ static String limitToString(@Limit int value) {
550         switch (value) {
551             case LIMIT_HOTWORD_OFFSET_MAX_VALUE:
552                     return "LIMIT_HOTWORD_OFFSET_MAX_VALUE";
553             case LIMIT_AUDIO_CHANNEL_MAX_VALUE:
554                     return "LIMIT_AUDIO_CHANNEL_MAX_VALUE";
555             default: return Integer.toHexString(value);
556         }
557     }
558 
559     /** @hide */
560     @IntDef(prefix = "PROXIMITY_", value = {
561         PROXIMITY_UNKNOWN,
562         PROXIMITY_NEAR,
563         PROXIMITY_FAR
564     })
565     @Retention(RetentionPolicy.SOURCE)
566     @DataClass.Generated.Member
567     public @interface Proximity {}
568 
569     /** @hide */
570     @DataClass.Generated.Member
proximityToString(@roximity int value)571     public static String proximityToString(@Proximity int value) {
572         switch (value) {
573             case PROXIMITY_UNKNOWN:
574                     return "PROXIMITY_UNKNOWN";
575             case PROXIMITY_NEAR:
576                     return "PROXIMITY_NEAR";
577             case PROXIMITY_FAR:
578                     return "PROXIMITY_FAR";
579             default: return Integer.toHexString(value);
580         }
581     }
582 
583     @DataClass.Generated.Member
HotwordDetectedResult( @otwordConfidenceLevelValue int confidenceLevel, @Nullable MediaSyncEvent mediaSyncEvent, int hotwordOffsetMillis, int hotwordDurationMillis, int audioChannel, boolean hotwordDetectionPersonalized, int score, int personalizedScore, int hotwordPhraseId, @NonNull List<HotwordAudioStream> audioStreams, @NonNull PersistableBundle extras)584     /* package-private */ HotwordDetectedResult(
585             @HotwordConfidenceLevelValue int confidenceLevel,
586             @Nullable MediaSyncEvent mediaSyncEvent,
587             int hotwordOffsetMillis,
588             int hotwordDurationMillis,
589             int audioChannel,
590             boolean hotwordDetectionPersonalized,
591             int score,
592             int personalizedScore,
593             int hotwordPhraseId,
594             @NonNull List<HotwordAudioStream> audioStreams,
595             @NonNull PersistableBundle extras) {
596         this.mConfidenceLevel = confidenceLevel;
597         com.android.internal.util.AnnotationValidations.validate(
598                 HotwordConfidenceLevelValue.class, null, mConfidenceLevel);
599         this.mMediaSyncEvent = mediaSyncEvent;
600         this.mHotwordOffsetMillis = hotwordOffsetMillis;
601         this.mHotwordDurationMillis = hotwordDurationMillis;
602         this.mAudioChannel = audioChannel;
603         this.mHotwordDetectionPersonalized = hotwordDetectionPersonalized;
604         this.mScore = score;
605         this.mPersonalizedScore = personalizedScore;
606         this.mHotwordPhraseId = hotwordPhraseId;
607         this.mAudioStreams = audioStreams;
608         com.android.internal.util.AnnotationValidations.validate(
609                 NonNull.class, null, mAudioStreams);
610         this.mExtras = extras;
611         com.android.internal.util.AnnotationValidations.validate(
612                 NonNull.class, null, mExtras);
613 
614         onConstructed();
615     }
616 
617     /**
618      * Confidence level in the trigger outcome.
619      */
620     @DataClass.Generated.Member
getConfidenceLevel()621     public @HotwordConfidenceLevelValue int getConfidenceLevel() {
622         return mConfidenceLevel;
623     }
624 
625     /**
626      * Offset in milliseconds the audio stream when the trigger event happened (end of hotword
627      * phrase).
628      *
629      * <p>Only value between 0 and 3600000 (inclusive) is accepted.
630      */
631     @DataClass.Generated.Member
getHotwordOffsetMillis()632     public int getHotwordOffsetMillis() {
633         return mHotwordOffsetMillis;
634     }
635 
636     /**
637      * Duration in milliseconds of the hotword trigger phrase.
638      *
639      * <p>Only values between 0 and {@link android.media.AudioRecord#getMaxSharedAudioHistoryMillis}
640      * (inclusive) are accepted.
641      */
642     @DataClass.Generated.Member
getHotwordDurationMillis()643     public int getHotwordDurationMillis() {
644         return mHotwordDurationMillis;
645     }
646 
647     /**
648      * Audio channel containing the highest-confidence hotword signal.
649      *
650      * <p>Only value between 0 and 63 (inclusive) is accepted.
651      */
652     @DataClass.Generated.Member
getAudioChannel()653     public int getAudioChannel() {
654         return mAudioChannel;
655     }
656 
657     /**
658      * Returns whether the trigger has happened due to model having been personalized to fit user's
659      * voice.
660      */
661     @DataClass.Generated.Member
isHotwordDetectionPersonalized()662     public boolean isHotwordDetectionPersonalized() {
663         return mHotwordDetectionPersonalized;
664     }
665 
666     /**
667      * Score for the hotword trigger.
668      *
669      * <p>Only values between 0 and {@link #getMaxScore} (inclusive) are accepted.
670      */
671     @DataClass.Generated.Member
getScore()672     public int getScore() {
673         return mScore;
674     }
675 
676     /**
677      * Score for the hotword trigger for device user.
678      *
679      * <p>Only values between 0 and {@link #getMaxScore} (inclusive) are accepted.
680      */
681     @DataClass.Generated.Member
getPersonalizedScore()682     public int getPersonalizedScore() {
683         return mPersonalizedScore;
684     }
685 
686     /**
687      * An ID representing the keyphrase that triggered the successful detection.
688      *
689      * <p>Only values between 0 and {@link #getMaxHotwordPhraseId()} (inclusive) are accepted.
690      */
691     @DataClass.Generated.Member
getHotwordPhraseId()692     public int getHotwordPhraseId() {
693         return mHotwordPhraseId;
694     }
695 
696     /**
697      * App-specific extras to support trigger.
698      *
699      * <p>The size of this bundle will be limited to {@link #getMaxBundleSize}. Results will larger
700      * bundles will be rejected.
701      *
702      * <p>Only primitive types are supported in this bundle. Complex types will be removed from the
703      * bundle.
704      *
705      * <p>The use of this method is discouraged, and support for it will be removed in future
706      * versions of Android.
707      *
708      * <p>After the trigger happens, a special case of proximity-related extra, with the key of
709      * 'android.service.voice.extra.PROXIMITY_VALUE' and the value of proximity value (integer)
710      * will be stored to enable proximity logic. {@link HotwordDetectedResult#PROXIMITY_NEAR} will
711      * indicate 'NEAR' proximity and {@link HotwordDetectedResult#PROXIMITY_FAR} will indicate 'FAR'
712      * proximity. The proximity value is provided by the system, on devices that support detecting
713      * proximity of nearby users, to help disambiguate which nearby device should respond. When the
714      * proximity is unknown, the proximity value will not be stored. This mapping will be excluded
715      * from the max bundle size calculation because this mapping is included after the result is
716      * returned from the hotword detector service.
717      *
718      * <p>This is a PersistableBundle so it doesn't allow any remotable objects or other contents
719      * that can be used to communicate with other processes.
720      */
721     @DataClass.Generated.Member
getExtras()722     public @NonNull PersistableBundle getExtras() {
723         return mExtras;
724     }
725 
726     @Override
727     @DataClass.Generated.Member
toString()728     public String toString() {
729         // You can override field toString logic by defining methods like:
730         // String fieldNameToString() { ... }
731 
732         return "HotwordDetectedResult { " +
733                 "confidenceLevel = " + mConfidenceLevel + ", " +
734                 "mediaSyncEvent = " + mMediaSyncEvent + ", " +
735                 "hotwordOffsetMillis = " + mHotwordOffsetMillis + ", " +
736                 "hotwordDurationMillis = " + mHotwordDurationMillis + ", " +
737                 "audioChannel = " + mAudioChannel + ", " +
738                 "hotwordDetectionPersonalized = " + mHotwordDetectionPersonalized + ", " +
739                 "score = " + mScore + ", " +
740                 "personalizedScore = " + mPersonalizedScore + ", " +
741                 "hotwordPhraseId = " + mHotwordPhraseId + ", " +
742                 "audioStreams = " + mAudioStreams + ", " +
743                 "extras = " + mExtras +
744         " }";
745     }
746 
747     @Override
748     @DataClass.Generated.Member
equals(@ullable Object o)749     public boolean equals(@Nullable Object o) {
750         // You can override field equality logic by defining either of the methods like:
751         // boolean fieldNameEquals(HotwordDetectedResult other) { ... }
752         // boolean fieldNameEquals(FieldType otherValue) { ... }
753 
754         if (this == o) return true;
755         if (o == null || getClass() != o.getClass()) return false;
756         @SuppressWarnings("unchecked")
757         HotwordDetectedResult that = (HotwordDetectedResult) o;
758         //noinspection PointlessBooleanExpression
759         return true
760                 && mConfidenceLevel == that.mConfidenceLevel
761                 && Objects.equals(mMediaSyncEvent, that.mMediaSyncEvent)
762                 && mHotwordOffsetMillis == that.mHotwordOffsetMillis
763                 && mHotwordDurationMillis == that.mHotwordDurationMillis
764                 && mAudioChannel == that.mAudioChannel
765                 && mHotwordDetectionPersonalized == that.mHotwordDetectionPersonalized
766                 && mScore == that.mScore
767                 && mPersonalizedScore == that.mPersonalizedScore
768                 && mHotwordPhraseId == that.mHotwordPhraseId
769                 && Objects.equals(mAudioStreams, that.mAudioStreams)
770                 && Objects.equals(mExtras, that.mExtras);
771     }
772 
773     @Override
774     @DataClass.Generated.Member
hashCode()775     public int hashCode() {
776         // You can override field hashCode logic by defining methods like:
777         // int fieldNameHashCode() { ... }
778 
779         int _hash = 1;
780         _hash = 31 * _hash + mConfidenceLevel;
781         _hash = 31 * _hash + Objects.hashCode(mMediaSyncEvent);
782         _hash = 31 * _hash + mHotwordOffsetMillis;
783         _hash = 31 * _hash + mHotwordDurationMillis;
784         _hash = 31 * _hash + mAudioChannel;
785         _hash = 31 * _hash + Boolean.hashCode(mHotwordDetectionPersonalized);
786         _hash = 31 * _hash + mScore;
787         _hash = 31 * _hash + mPersonalizedScore;
788         _hash = 31 * _hash + mHotwordPhraseId;
789         _hash = 31 * _hash + Objects.hashCode(mAudioStreams);
790         _hash = 31 * _hash + Objects.hashCode(mExtras);
791         return _hash;
792     }
793 
794     @Override
795     @DataClass.Generated.Member
writeToParcel(@onNull Parcel dest, int flags)796     public void writeToParcel(@NonNull Parcel dest, int flags) {
797         // You can override field parcelling by defining methods like:
798         // void parcelFieldName(Parcel dest, int flags) { ... }
799 
800         int flg = 0;
801         if (mHotwordDetectionPersonalized) flg |= 0x20;
802         if (mMediaSyncEvent != null) flg |= 0x2;
803         dest.writeInt(flg);
804         dest.writeInt(mConfidenceLevel);
805         if (mMediaSyncEvent != null) dest.writeTypedObject(mMediaSyncEvent, flags);
806         dest.writeInt(mHotwordOffsetMillis);
807         dest.writeInt(mHotwordDurationMillis);
808         dest.writeInt(mAudioChannel);
809         dest.writeInt(mScore);
810         dest.writeInt(mPersonalizedScore);
811         dest.writeInt(mHotwordPhraseId);
812         dest.writeParcelableList(mAudioStreams, flags);
813         dest.writeTypedObject(mExtras, flags);
814     }
815 
816     @Override
817     @DataClass.Generated.Member
describeContents()818     public int describeContents() { return 0; }
819 
820     /** @hide */
821     @SuppressWarnings({"unchecked", "RedundantCast"})
822     @DataClass.Generated.Member
HotwordDetectedResult(@onNull Parcel in)823     /* package-private */ HotwordDetectedResult(@NonNull Parcel in) {
824         // You can override field unparcelling by defining methods like:
825         // static FieldType unparcelFieldName(Parcel in) { ... }
826 
827         int flg = in.readInt();
828         boolean hotwordDetectionPersonalized = (flg & 0x20) != 0;
829         int confidenceLevel = in.readInt();
830         MediaSyncEvent mediaSyncEvent = (flg & 0x2) == 0 ? null : (MediaSyncEvent) in.readTypedObject(MediaSyncEvent.CREATOR);
831         int hotwordOffsetMillis = in.readInt();
832         int hotwordDurationMillis = in.readInt();
833         int audioChannel = in.readInt();
834         int score = in.readInt();
835         int personalizedScore = in.readInt();
836         int hotwordPhraseId = in.readInt();
837         List<HotwordAudioStream> audioStreams = new ArrayList<>();
838         in.readParcelableList(audioStreams, HotwordAudioStream.class.getClassLoader());
839         PersistableBundle extras = (PersistableBundle) in.readTypedObject(PersistableBundle.CREATOR);
840 
841         this.mConfidenceLevel = confidenceLevel;
842         com.android.internal.util.AnnotationValidations.validate(
843                 HotwordConfidenceLevelValue.class, null, mConfidenceLevel);
844         this.mMediaSyncEvent = mediaSyncEvent;
845         this.mHotwordOffsetMillis = hotwordOffsetMillis;
846         this.mHotwordDurationMillis = hotwordDurationMillis;
847         this.mAudioChannel = audioChannel;
848         this.mHotwordDetectionPersonalized = hotwordDetectionPersonalized;
849         this.mScore = score;
850         this.mPersonalizedScore = personalizedScore;
851         this.mHotwordPhraseId = hotwordPhraseId;
852         this.mAudioStreams = audioStreams;
853         com.android.internal.util.AnnotationValidations.validate(
854                 NonNull.class, null, mAudioStreams);
855         this.mExtras = extras;
856         com.android.internal.util.AnnotationValidations.validate(
857                 NonNull.class, null, mExtras);
858 
859         onConstructed();
860     }
861 
862     @DataClass.Generated.Member
863     public static final @NonNull Parcelable.Creator<HotwordDetectedResult> CREATOR
864             = new Parcelable.Creator<HotwordDetectedResult>() {
865         @Override
866         public HotwordDetectedResult[] newArray(int size) {
867             return new HotwordDetectedResult[size];
868         }
869 
870         @Override
871         public HotwordDetectedResult createFromParcel(@NonNull Parcel in) {
872             return new HotwordDetectedResult(in);
873         }
874     };
875 
876     /**
877      * A builder for {@link HotwordDetectedResult}
878      */
879     @SuppressWarnings("WeakerAccess")
880     @DataClass.Generated.Member
881     public static final class Builder extends BaseBuilder {
882 
883         private @HotwordConfidenceLevelValue int mConfidenceLevel;
884         private @Nullable MediaSyncEvent mMediaSyncEvent;
885         private int mHotwordOffsetMillis;
886         private int mHotwordDurationMillis;
887         private int mAudioChannel;
888         private boolean mHotwordDetectionPersonalized;
889         private int mScore;
890         private int mPersonalizedScore;
891         private int mHotwordPhraseId;
892         private @NonNull List<HotwordAudioStream> mAudioStreams;
893         private @NonNull PersistableBundle mExtras;
894 
895         private long mBuilderFieldsSet = 0L;
896 
Builder()897         public Builder() {
898         }
899 
900         /**
901          * Confidence level in the trigger outcome.
902          */
903         @DataClass.Generated.Member
setConfidenceLevel(@otwordConfidenceLevelValue int value)904         public @NonNull Builder setConfidenceLevel(@HotwordConfidenceLevelValue int value) {
905             checkNotUsed();
906             mBuilderFieldsSet |= 0x1;
907             mConfidenceLevel = value;
908             return this;
909         }
910 
911         /**
912          * A {@code MediaSyncEvent} that allows the {@link HotwordDetector} to recapture the audio
913          * that contains the hotword trigger. This must be obtained using
914          * {@link android.media.AudioRecord#shareAudioHistory(String, long)}.
915          */
916         @DataClass.Generated.Member
setMediaSyncEvent(@onNull MediaSyncEvent value)917         public @NonNull Builder setMediaSyncEvent(@NonNull MediaSyncEvent value) {
918             checkNotUsed();
919             mBuilderFieldsSet |= 0x2;
920             mMediaSyncEvent = value;
921             return this;
922         }
923 
924         /**
925          * Offset in milliseconds the audio stream when the trigger event happened (end of hotword
926          * phrase).
927          *
928          * <p>Only value between 0 and 3600000 (inclusive) is accepted.
929          */
930         @DataClass.Generated.Member
setHotwordOffsetMillis(int value)931         public @NonNull Builder setHotwordOffsetMillis(int value) {
932             checkNotUsed();
933             mBuilderFieldsSet |= 0x4;
934             mHotwordOffsetMillis = value;
935             return this;
936         }
937 
938         /**
939          * Duration in milliseconds of the hotword trigger phrase.
940          *
941          * <p>Only values between 0 and {@link android.media.AudioRecord#getMaxSharedAudioHistoryMillis}
942          * (inclusive) are accepted.
943          */
944         @DataClass.Generated.Member
setHotwordDurationMillis(int value)945         public @NonNull Builder setHotwordDurationMillis(int value) {
946             checkNotUsed();
947             mBuilderFieldsSet |= 0x8;
948             mHotwordDurationMillis = value;
949             return this;
950         }
951 
952         /**
953          * Audio channel containing the highest-confidence hotword signal.
954          *
955          * <p>Only value between 0 and 63 (inclusive) is accepted.
956          */
957         @DataClass.Generated.Member
setAudioChannel(int value)958         public @NonNull Builder setAudioChannel(int value) {
959             checkNotUsed();
960             mBuilderFieldsSet |= 0x10;
961             mAudioChannel = value;
962             return this;
963         }
964 
965         /**
966          * Returns whether the trigger has happened due to model having been personalized to fit user's
967          * voice.
968          */
969         @DataClass.Generated.Member
setHotwordDetectionPersonalized(boolean value)970         public @NonNull Builder setHotwordDetectionPersonalized(boolean value) {
971             checkNotUsed();
972             mBuilderFieldsSet |= 0x20;
973             mHotwordDetectionPersonalized = value;
974             return this;
975         }
976 
977         /**
978          * Score for the hotword trigger.
979          *
980          * <p>Only values between 0 and {@link #getMaxScore} (inclusive) are accepted.
981          */
982         @DataClass.Generated.Member
setScore(int value)983         public @NonNull Builder setScore(int value) {
984             checkNotUsed();
985             mBuilderFieldsSet |= 0x40;
986             mScore = value;
987             return this;
988         }
989 
990         /**
991          * Score for the hotword trigger for device user.
992          *
993          * <p>Only values between 0 and {@link #getMaxScore} (inclusive) are accepted.
994          */
995         @DataClass.Generated.Member
setPersonalizedScore(int value)996         public @NonNull Builder setPersonalizedScore(int value) {
997             checkNotUsed();
998             mBuilderFieldsSet |= 0x80;
999             mPersonalizedScore = value;
1000             return this;
1001         }
1002 
1003         /**
1004          * An ID representing the keyphrase that triggered the successful detection.
1005          *
1006          * <p>Only values between 0 and {@link #getMaxHotwordPhraseId()} (inclusive) are accepted.
1007          */
1008         @DataClass.Generated.Member
setHotwordPhraseId(int value)1009         public @NonNull Builder setHotwordPhraseId(int value) {
1010             checkNotUsed();
1011             mBuilderFieldsSet |= 0x100;
1012             mHotwordPhraseId = value;
1013             return this;
1014         }
1015 
1016         /**
1017          * App-specific extras to support trigger.
1018          *
1019          * <p>The size of this bundle will be limited to {@link #getMaxBundleSize}. Results will larger
1020          * bundles will be rejected.
1021          *
1022          * <p>Only primitive types are supported in this bundle. Complex types will be removed from the
1023          * bundle.
1024          *
1025          * <p>The use of this method is discouraged, and support for it will be removed in future
1026          * versions of Android.
1027          *
1028          * <p>After the trigger happens, a special case of proximity-related extra, with the key of
1029          * 'android.service.voice.extra.PROXIMITY_VALUE' and the value of proximity value (integer)
1030          * will be stored to enable proximity logic. {@link HotwordDetectedResult#PROXIMITY_NEAR} will
1031          * indicate 'NEAR' proximity and {@link HotwordDetectedResult#PROXIMITY_FAR} will indicate 'FAR'
1032          * proximity. The proximity value is provided by the system, on devices that support detecting
1033          * proximity of nearby users, to help disambiguate which nearby device should respond. When the
1034          * proximity is unknown, the proximity value will not be stored. This mapping will be excluded
1035          * from the max bundle size calculation because this mapping is included after the result is
1036          * returned from the hotword detector service.
1037          *
1038          * <p>This is a PersistableBundle so it doesn't allow any remotable objects or other contents
1039          * that can be used to communicate with other processes.
1040          */
1041         @DataClass.Generated.Member
setExtras(@onNull PersistableBundle value)1042         public @NonNull Builder setExtras(@NonNull PersistableBundle value) {
1043             checkNotUsed();
1044             mBuilderFieldsSet |= 0x400;
1045             mExtras = value;
1046             return this;
1047         }
1048 
1049         /** Builds the instance. This builder should not be touched after calling this! */
build()1050         public @NonNull HotwordDetectedResult build() {
1051             checkNotUsed();
1052             mBuilderFieldsSet |= 0x800; // Mark builder used
1053 
1054             if ((mBuilderFieldsSet & 0x1) == 0) {
1055                 mConfidenceLevel = defaultConfidenceLevel();
1056             }
1057             if ((mBuilderFieldsSet & 0x2) == 0) {
1058                 mMediaSyncEvent = null;
1059             }
1060             if ((mBuilderFieldsSet & 0x4) == 0) {
1061                 mHotwordOffsetMillis = HOTWORD_OFFSET_UNSET;
1062             }
1063             if ((mBuilderFieldsSet & 0x8) == 0) {
1064                 mHotwordDurationMillis = 0;
1065             }
1066             if ((mBuilderFieldsSet & 0x10) == 0) {
1067                 mAudioChannel = AUDIO_CHANNEL_UNSET;
1068             }
1069             if ((mBuilderFieldsSet & 0x20) == 0) {
1070                 mHotwordDetectionPersonalized = false;
1071             }
1072             if ((mBuilderFieldsSet & 0x40) == 0) {
1073                 mScore = defaultScore();
1074             }
1075             if ((mBuilderFieldsSet & 0x80) == 0) {
1076                 mPersonalizedScore = defaultPersonalizedScore();
1077             }
1078             if ((mBuilderFieldsSet & 0x100) == 0) {
1079                 mHotwordPhraseId = defaultHotwordPhraseId();
1080             }
1081             if ((mBuilderFieldsSet & 0x200) == 0) {
1082                 mAudioStreams = defaultAudioStreams();
1083             }
1084             if ((mBuilderFieldsSet & 0x400) == 0) {
1085                 mExtras = defaultExtras();
1086             }
1087             HotwordDetectedResult o = new HotwordDetectedResult(
1088                     mConfidenceLevel,
1089                     mMediaSyncEvent,
1090                     mHotwordOffsetMillis,
1091                     mHotwordDurationMillis,
1092                     mAudioChannel,
1093                     mHotwordDetectionPersonalized,
1094                     mScore,
1095                     mPersonalizedScore,
1096                     mHotwordPhraseId,
1097                     mAudioStreams,
1098                     mExtras);
1099             return o;
1100         }
1101 
checkNotUsed()1102         private void checkNotUsed() {
1103             if ((mBuilderFieldsSet & 0x800) != 0) {
1104                 throw new IllegalStateException(
1105                         "This Builder should not be reused. Use a new Builder instance instead");
1106             }
1107         }
1108     }
1109 
1110     @DataClass.Generated(
1111             time = 1668528946960L,
1112             codegenVersion = "1.0.23",
1113             sourceFile = "frameworks/base/core/java/android/service/voice/HotwordDetectedResult.java",
1114             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\nprivate static final  java.lang.String EXTRA_PROXIMITY\npublic static final  int PROXIMITY_UNKNOWN\npublic static final  int PROXIMITY_NEAR\npublic static final  int PROXIMITY_FAR\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()\npublic  android.service.voice.HotwordDetectedResult.Builder buildUpon()\npublic  void setProximity(double)\nprivate @android.service.voice.HotwordDetectedResult.ProximityValue int convertToProximityLevel(double)\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 []")
1115     @Deprecated
__metadata()1116     private void __metadata() {}
1117 
1118 
1119     //@formatter:on
1120     // End of generated code
1121 
1122 }
1123