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