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