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