| /* |
| * Copyright (C) 2021 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.service.voice; |
| |
| import android.annotation.IntDef; |
| import android.annotation.NonNull; |
| import android.annotation.Nullable; |
| import android.annotation.SystemApi; |
| import android.content.res.Resources; |
| import android.media.AudioRecord; |
| import android.media.MediaSyncEvent; |
| import android.os.Parcel; |
| import android.os.Parcelable; |
| import android.os.PersistableBundle; |
| |
| import com.android.internal.R; |
| import com.android.internal.util.DataClass; |
| import com.android.internal.util.Preconditions; |
| |
| import java.util.Objects; |
| |
| /** |
| * Represents a result supporting the hotword detection. |
| * |
| * @hide |
| */ |
| @DataClass( |
| genConstructor = false, |
| genBuilder = true, |
| genEqualsHashCode = true, |
| genHiddenConstDefs = true, |
| genParcelable = true, |
| genToString = true |
| ) |
| @SystemApi |
| public final class HotwordDetectedResult implements Parcelable { |
| |
| /** No confidence in hotword detector result. */ |
| public static final int CONFIDENCE_LEVEL_NONE = 0; |
| |
| /** Low confidence in hotword detector result. */ |
| public static final int CONFIDENCE_LEVEL_LOW = 1; |
| |
| /** Low-to-medium confidence in hotword detector result. */ |
| public static final int CONFIDENCE_LEVEL_LOW_MEDIUM = 2; |
| |
| /** Medium confidence in hotword detector result. */ |
| public static final int CONFIDENCE_LEVEL_MEDIUM = 3; |
| |
| /** Medium-to-high confidence in hotword detector result. */ |
| public static final int CONFIDENCE_LEVEL_MEDIUM_HIGH = 4; |
| |
| /** High confidence in hotword detector result. */ |
| public static final int CONFIDENCE_LEVEL_HIGH = 5; |
| |
| /** Very high confidence in hotword detector result. */ |
| public static final int CONFIDENCE_LEVEL_VERY_HIGH = 6; |
| |
| /** @hide */ |
| @IntDef(prefix = {"CONFIDENCE_LEVEL_"}, value = { |
| CONFIDENCE_LEVEL_NONE, |
| CONFIDENCE_LEVEL_LOW, |
| CONFIDENCE_LEVEL_LOW_MEDIUM, |
| CONFIDENCE_LEVEL_MEDIUM, |
| CONFIDENCE_LEVEL_MEDIUM_HIGH, |
| CONFIDENCE_LEVEL_HIGH, |
| CONFIDENCE_LEVEL_VERY_HIGH |
| }) |
| @interface HotwordConfidenceLevelValue { |
| } |
| |
| /** Represents unset value for the hotword offset. */ |
| public static final int HOTWORD_OFFSET_UNSET = -1; |
| |
| /** Represents unset value for the triggered audio channel. */ |
| public static final int AUDIO_CHANNEL_UNSET = -1; |
| |
| /** Limits the max value for the hotword offset. */ |
| private static final int LIMIT_HOTWORD_OFFSET_MAX_VALUE = 60 * 60 * 1000; // 1 hour |
| |
| /** Limits the max value for the triggered audio channel. */ |
| private static final int LIMIT_AUDIO_CHANNEL_MAX_VALUE = 63; |
| |
| /** Confidence level in the trigger outcome. */ |
| @HotwordConfidenceLevelValue |
| private final int mConfidenceLevel; |
| private static int defaultConfidenceLevel() { |
| return CONFIDENCE_LEVEL_NONE; |
| } |
| |
| /** |
| * A {@code MediaSyncEvent} that allows the {@link HotwordDetector} to recapture the audio |
| * that contains the hotword trigger. This must be obtained using |
| * {@link android.media.AudioRecord#shareAudioHistory(String, long)}. |
| */ |
| @Nullable |
| private MediaSyncEvent mMediaSyncEvent = null; |
| |
| /** |
| * Offset in milliseconds the audio stream when the trigger event happened (end of hotword |
| * phrase). |
| * |
| * <p>Only value between 0 and 3600000 (inclusive) is accepted. |
| */ |
| private int mHotwordOffsetMillis = HOTWORD_OFFSET_UNSET; |
| |
| /** |
| * Duration in milliseconds of the hotword trigger phrase. |
| * |
| * <p>Only values between 0 and {@link android.media.AudioRecord#getMaxSharedAudioHistoryMillis} |
| * (inclusive) are accepted. |
| */ |
| private int mHotwordDurationMillis = 0; |
| |
| /** |
| * Audio channel containing the highest-confidence hotword signal. |
| * |
| * <p>Only value between 0 and 63 (inclusive) is accepted. |
| */ |
| private int mAudioChannel = AUDIO_CHANNEL_UNSET; |
| |
| /** |
| * Returns whether the trigger has happened due to model having been personalized to fit user's |
| * voice. |
| */ |
| private boolean mHotwordDetectionPersonalized = false; |
| |
| /** |
| * Score for the hotword trigger. |
| * |
| * <p>Only values between 0 and {@link #getMaxScore} (inclusive) are accepted. |
| */ |
| private final int mScore; |
| private static int defaultScore() { |
| return 0; |
| } |
| |
| /** |
| * Score for the hotword trigger for device user. |
| * |
| * <p>Only values between 0 and {@link #getMaxScore} (inclusive) are accepted. |
| */ |
| private final int mPersonalizedScore; |
| private static int defaultPersonalizedScore() { |
| return 0; |
| } |
| |
| /** |
| * Returns the maximum values of {@link #getScore} and {@link #getPersonalizedScore}. |
| * <p> |
| * The float value should be calculated as {@code getScore() / getMaxScore()}. |
| */ |
| public static int getMaxScore() { |
| return 255; |
| } |
| |
| /** |
| * An ID representing the keyphrase that triggered the successful detection. |
| * |
| * <p>Only values between 0 and {@link #getMaxHotwordPhraseId()} (inclusive) are accepted. |
| */ |
| private final int mHotwordPhraseId; |
| private static int defaultHotwordPhraseId() { |
| return 0; |
| } |
| |
| /** |
| * Returns the maximum value of {@link #getHotwordPhraseId()}. |
| */ |
| public static int getMaxHotwordPhraseId() { |
| return 63; |
| } |
| |
| /** |
| * App-specific extras to support trigger. |
| * |
| * <p>The size of this bundle will be limited to {@link #getMaxBundleSize}. Results will larger |
| * bundles will be rejected. |
| * |
| * <p>Only primitive types are supported in this bundle. Complex types will be removed from the |
| * bundle. |
| * |
| * <p>The use of this method is discouraged, and support for it will be removed in future |
| * versions of Android. |
| * |
| * <p>This is a PersistableBundle so it doesn't allow any remotable objects or other contents |
| * that can be used to communicate with other processes. |
| */ |
| @NonNull |
| private final PersistableBundle mExtras; |
| private static PersistableBundle defaultExtras() { |
| return new PersistableBundle(); |
| } |
| |
| private static int sMaxBundleSize = -1; |
| |
| /** |
| * Returns the maximum byte size of the information contained in the bundle. |
| * |
| * <p>The total size will be calculated by how much bundle data should be written into the |
| * Parcel. |
| */ |
| public static int getMaxBundleSize() { |
| if (sMaxBundleSize < 0) { |
| sMaxBundleSize = Resources.getSystem().getInteger( |
| R.integer.config_hotwordDetectedResultMaxBundleSize); |
| } |
| return sMaxBundleSize; |
| } |
| |
| /** |
| * A {@code MediaSyncEvent} that allows the {@link HotwordDetector} to recapture the audio |
| * that contains the hotword trigger. This must be obtained using |
| * {@link android.media.AudioRecord#shareAudioHistory(String, long)}. |
| * <p> |
| * This can be {@code null} if reprocessing the hotword trigger isn't required. |
| */ |
| // Suppress codegen to make javadoc consistent. Getter returns @Nullable, setter accepts |
| // @NonNull only, and by default codegen would use the same javadoc on both. |
| public @Nullable MediaSyncEvent getMediaSyncEvent() { |
| return mMediaSyncEvent; |
| } |
| |
| /** |
| * Returns how many bytes should be written into the Parcel |
| * |
| * @hide |
| */ |
| public static int getParcelableSize(@NonNull Parcelable parcelable) { |
| final Parcel p = Parcel.obtain(); |
| parcelable.writeToParcel(p, 0); |
| p.setDataPosition(0); |
| final int size = p.dataSize(); |
| p.recycle(); |
| return size; |
| } |
| |
| /** |
| * Returns how many bits have been written into the HotwordDetectedResult. |
| * |
| * @hide |
| */ |
| public static int getUsageSize(@NonNull HotwordDetectedResult hotwordDetectedResult) { |
| int totalBits = 0; |
| |
| if (hotwordDetectedResult.getConfidenceLevel() != defaultConfidenceLevel()) { |
| totalBits += bitCount(CONFIDENCE_LEVEL_VERY_HIGH); |
| } |
| if (hotwordDetectedResult.getHotwordOffsetMillis() != HOTWORD_OFFSET_UNSET) { |
| totalBits += bitCount(LIMIT_HOTWORD_OFFSET_MAX_VALUE); |
| } |
| if (hotwordDetectedResult.getHotwordDurationMillis() != 0) { |
| totalBits += bitCount(AudioRecord.getMaxSharedAudioHistoryMillis()); |
| } |
| if (hotwordDetectedResult.getAudioChannel() != AUDIO_CHANNEL_UNSET) { |
| totalBits += bitCount(LIMIT_AUDIO_CHANNEL_MAX_VALUE); |
| } |
| |
| // Add one bit for HotwordDetectionPersonalized |
| totalBits += 1; |
| |
| if (hotwordDetectedResult.getScore() != defaultScore()) { |
| totalBits += bitCount(HotwordDetectedResult.getMaxScore()); |
| } |
| if (hotwordDetectedResult.getPersonalizedScore() != defaultPersonalizedScore()) { |
| totalBits += bitCount(HotwordDetectedResult.getMaxScore()); |
| } |
| if (hotwordDetectedResult.getHotwordPhraseId() != defaultHotwordPhraseId()) { |
| totalBits += bitCount(HotwordDetectedResult.getMaxHotwordPhraseId()); |
| } |
| PersistableBundle persistableBundle = hotwordDetectedResult.getExtras(); |
| if (!persistableBundle.isEmpty()) { |
| totalBits += getParcelableSize(persistableBundle) * Byte.SIZE; |
| } |
| return totalBits; |
| } |
| |
| private static int bitCount(long value) { |
| int bits = 0; |
| while (value > 0) { |
| bits++; |
| value = value >> 1; |
| } |
| return bits; |
| } |
| |
| private void onConstructed() { |
| Preconditions.checkArgumentInRange(mScore, 0, getMaxScore(), "score"); |
| Preconditions.checkArgumentInRange(mPersonalizedScore, 0, getMaxScore(), |
| "personalizedScore"); |
| Preconditions.checkArgumentInRange(mHotwordPhraseId, 0, getMaxHotwordPhraseId(), |
| "hotwordPhraseId"); |
| Preconditions.checkArgumentInRange((long) mHotwordDurationMillis, 0, |
| AudioRecord.getMaxSharedAudioHistoryMillis(), "hotwordDurationMillis"); |
| if (mHotwordOffsetMillis != HOTWORD_OFFSET_UNSET) { |
| Preconditions.checkArgumentInRange(mHotwordOffsetMillis, 0, |
| LIMIT_HOTWORD_OFFSET_MAX_VALUE, "hotwordOffsetMillis"); |
| } |
| if (mAudioChannel != AUDIO_CHANNEL_UNSET) { |
| Preconditions.checkArgumentInRange(mAudioChannel, 0, LIMIT_AUDIO_CHANNEL_MAX_VALUE, |
| "audioChannel"); |
| } |
| if (!mExtras.isEmpty()) { |
| Preconditions.checkArgumentInRange(getParcelableSize(mExtras), 0, getMaxBundleSize(), |
| "extras"); |
| } |
| } |
| |
| |
| |
| // Code below generated by codegen v1.0.23. |
| // |
| // DO NOT MODIFY! |
| // CHECKSTYLE:OFF Generated code |
| // |
| // To regenerate run: |
| // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/service/voice/HotwordDetectedResult.java |
| // |
| // To exclude the generated code from IntelliJ auto-formatting enable (one-time): |
| // Settings > Editor > Code Style > Formatter Control |
| //@formatter:off |
| |
| |
| /** @hide */ |
| @IntDef(prefix = "CONFIDENCE_LEVEL_", value = { |
| CONFIDENCE_LEVEL_NONE, |
| CONFIDENCE_LEVEL_LOW, |
| CONFIDENCE_LEVEL_LOW_MEDIUM, |
| CONFIDENCE_LEVEL_MEDIUM, |
| CONFIDENCE_LEVEL_MEDIUM_HIGH, |
| CONFIDENCE_LEVEL_HIGH, |
| CONFIDENCE_LEVEL_VERY_HIGH |
| }) |
| @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) |
| @DataClass.Generated.Member |
| public @interface ConfidenceLevel {} |
| |
| /** @hide */ |
| @DataClass.Generated.Member |
| public static String confidenceLevelToString(@ConfidenceLevel int value) { |
| switch (value) { |
| case CONFIDENCE_LEVEL_NONE: |
| return "CONFIDENCE_LEVEL_NONE"; |
| case CONFIDENCE_LEVEL_LOW: |
| return "CONFIDENCE_LEVEL_LOW"; |
| case CONFIDENCE_LEVEL_LOW_MEDIUM: |
| return "CONFIDENCE_LEVEL_LOW_MEDIUM"; |
| case CONFIDENCE_LEVEL_MEDIUM: |
| return "CONFIDENCE_LEVEL_MEDIUM"; |
| case CONFIDENCE_LEVEL_MEDIUM_HIGH: |
| return "CONFIDENCE_LEVEL_MEDIUM_HIGH"; |
| case CONFIDENCE_LEVEL_HIGH: |
| return "CONFIDENCE_LEVEL_HIGH"; |
| case CONFIDENCE_LEVEL_VERY_HIGH: |
| return "CONFIDENCE_LEVEL_VERY_HIGH"; |
| default: return Integer.toHexString(value); |
| } |
| } |
| |
| /** @hide */ |
| @IntDef(prefix = "LIMIT_", value = { |
| LIMIT_HOTWORD_OFFSET_MAX_VALUE, |
| LIMIT_AUDIO_CHANNEL_MAX_VALUE |
| }) |
| @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) |
| @DataClass.Generated.Member |
| /* package-private */ @interface Limit {} |
| |
| /** @hide */ |
| @DataClass.Generated.Member |
| /* package-private */ static String limitToString(@Limit int value) { |
| switch (value) { |
| case LIMIT_HOTWORD_OFFSET_MAX_VALUE: |
| return "LIMIT_HOTWORD_OFFSET_MAX_VALUE"; |
| case LIMIT_AUDIO_CHANNEL_MAX_VALUE: |
| return "LIMIT_AUDIO_CHANNEL_MAX_VALUE"; |
| default: return Integer.toHexString(value); |
| } |
| } |
| |
| @DataClass.Generated.Member |
| /* package-private */ HotwordDetectedResult( |
| @HotwordConfidenceLevelValue int confidenceLevel, |
| @Nullable MediaSyncEvent mediaSyncEvent, |
| int hotwordOffsetMillis, |
| int hotwordDurationMillis, |
| int audioChannel, |
| boolean hotwordDetectionPersonalized, |
| int score, |
| int personalizedScore, |
| int hotwordPhraseId, |
| @NonNull PersistableBundle extras) { |
| this.mConfidenceLevel = confidenceLevel; |
| com.android.internal.util.AnnotationValidations.validate( |
| HotwordConfidenceLevelValue.class, null, mConfidenceLevel); |
| this.mMediaSyncEvent = mediaSyncEvent; |
| this.mHotwordOffsetMillis = hotwordOffsetMillis; |
| this.mHotwordDurationMillis = hotwordDurationMillis; |
| this.mAudioChannel = audioChannel; |
| this.mHotwordDetectionPersonalized = hotwordDetectionPersonalized; |
| this.mScore = score; |
| this.mPersonalizedScore = personalizedScore; |
| this.mHotwordPhraseId = hotwordPhraseId; |
| this.mExtras = extras; |
| com.android.internal.util.AnnotationValidations.validate( |
| NonNull.class, null, mExtras); |
| |
| onConstructed(); |
| } |
| |
| /** |
| * Confidence level in the trigger outcome. |
| */ |
| @DataClass.Generated.Member |
| public @HotwordConfidenceLevelValue int getConfidenceLevel() { |
| return mConfidenceLevel; |
| } |
| |
| /** |
| * Offset in milliseconds the audio stream when the trigger event happened (end of hotword |
| * phrase). |
| * |
| * <p>Only value between 0 and 3600000 (inclusive) is accepted. |
| */ |
| @DataClass.Generated.Member |
| public int getHotwordOffsetMillis() { |
| return mHotwordOffsetMillis; |
| } |
| |
| /** |
| * Duration in milliseconds of the hotword trigger phrase. |
| * |
| * <p>Only values between 0 and {@link android.media.AudioRecord#getMaxSharedAudioHistoryMillis} |
| * (inclusive) are accepted. |
| */ |
| @DataClass.Generated.Member |
| public int getHotwordDurationMillis() { |
| return mHotwordDurationMillis; |
| } |
| |
| /** |
| * Audio channel containing the highest-confidence hotword signal. |
| * |
| * <p>Only value between 0 and 63 (inclusive) is accepted. |
| */ |
| @DataClass.Generated.Member |
| public int getAudioChannel() { |
| return mAudioChannel; |
| } |
| |
| /** |
| * Returns whether the trigger has happened due to model having been personalized to fit user's |
| * voice. |
| */ |
| @DataClass.Generated.Member |
| public boolean isHotwordDetectionPersonalized() { |
| return mHotwordDetectionPersonalized; |
| } |
| |
| /** |
| * Score for the hotword trigger. |
| * |
| * <p>Only values between 0 and {@link #getMaxScore} (inclusive) are accepted. |
| */ |
| @DataClass.Generated.Member |
| public int getScore() { |
| return mScore; |
| } |
| |
| /** |
| * Score for the hotword trigger for device user. |
| * |
| * <p>Only values between 0 and {@link #getMaxScore} (inclusive) are accepted. |
| */ |
| @DataClass.Generated.Member |
| public int getPersonalizedScore() { |
| return mPersonalizedScore; |
| } |
| |
| /** |
| * An ID representing the keyphrase that triggered the successful detection. |
| * |
| * <p>Only values between 0 and {@link #getMaxHotwordPhraseId()} (inclusive) are accepted. |
| */ |
| @DataClass.Generated.Member |
| public int getHotwordPhraseId() { |
| return mHotwordPhraseId; |
| } |
| |
| /** |
| * App-specific extras to support trigger. |
| * |
| * <p>The size of this bundle will be limited to {@link #getMaxBundleSize}. Results will larger |
| * bundles will be rejected. |
| * |
| * <p>Only primitive types are supported in this bundle. Complex types will be removed from the |
| * bundle. |
| * |
| * <p>The use of this method is discouraged, and support for it will be removed in future |
| * versions of Android. |
| * |
| * <p>This is a PersistableBundle so it doesn't allow any remotable objects or other contents |
| * that can be used to communicate with other processes. |
| */ |
| @DataClass.Generated.Member |
| public @NonNull PersistableBundle getExtras() { |
| return mExtras; |
| } |
| |
| @Override |
| @DataClass.Generated.Member |
| public String toString() { |
| // You can override field toString logic by defining methods like: |
| // String fieldNameToString() { ... } |
| |
| return "HotwordDetectedResult { " + |
| "confidenceLevel = " + mConfidenceLevel + ", " + |
| "mediaSyncEvent = " + mMediaSyncEvent + ", " + |
| "hotwordOffsetMillis = " + mHotwordOffsetMillis + ", " + |
| "hotwordDurationMillis = " + mHotwordDurationMillis + ", " + |
| "audioChannel = " + mAudioChannel + ", " + |
| "hotwordDetectionPersonalized = " + mHotwordDetectionPersonalized + ", " + |
| "score = " + mScore + ", " + |
| "personalizedScore = " + mPersonalizedScore + ", " + |
| "hotwordPhraseId = " + mHotwordPhraseId + ", " + |
| "extras = " + mExtras + |
| " }"; |
| } |
| |
| @Override |
| @DataClass.Generated.Member |
| public boolean equals(@Nullable Object o) { |
| // You can override field equality logic by defining either of the methods like: |
| // boolean fieldNameEquals(HotwordDetectedResult other) { ... } |
| // boolean fieldNameEquals(FieldType otherValue) { ... } |
| |
| if (this == o) return true; |
| if (o == null || getClass() != o.getClass()) return false; |
| @SuppressWarnings("unchecked") |
| HotwordDetectedResult that = (HotwordDetectedResult) o; |
| //noinspection PointlessBooleanExpression |
| return true |
| && mConfidenceLevel == that.mConfidenceLevel |
| && Objects.equals(mMediaSyncEvent, that.mMediaSyncEvent) |
| && mHotwordOffsetMillis == that.mHotwordOffsetMillis |
| && mHotwordDurationMillis == that.mHotwordDurationMillis |
| && mAudioChannel == that.mAudioChannel |
| && mHotwordDetectionPersonalized == that.mHotwordDetectionPersonalized |
| && mScore == that.mScore |
| && mPersonalizedScore == that.mPersonalizedScore |
| && mHotwordPhraseId == that.mHotwordPhraseId |
| && Objects.equals(mExtras, that.mExtras); |
| } |
| |
| @Override |
| @DataClass.Generated.Member |
| public int hashCode() { |
| // You can override field hashCode logic by defining methods like: |
| // int fieldNameHashCode() { ... } |
| |
| int _hash = 1; |
| _hash = 31 * _hash + mConfidenceLevel; |
| _hash = 31 * _hash + Objects.hashCode(mMediaSyncEvent); |
| _hash = 31 * _hash + mHotwordOffsetMillis; |
| _hash = 31 * _hash + mHotwordDurationMillis; |
| _hash = 31 * _hash + mAudioChannel; |
| _hash = 31 * _hash + Boolean.hashCode(mHotwordDetectionPersonalized); |
| _hash = 31 * _hash + mScore; |
| _hash = 31 * _hash + mPersonalizedScore; |
| _hash = 31 * _hash + mHotwordPhraseId; |
| _hash = 31 * _hash + Objects.hashCode(mExtras); |
| return _hash; |
| } |
| |
| @Override |
| @DataClass.Generated.Member |
| public void writeToParcel(@NonNull Parcel dest, int flags) { |
| // You can override field parcelling by defining methods like: |
| // void parcelFieldName(Parcel dest, int flags) { ... } |
| |
| int flg = 0; |
| if (mHotwordDetectionPersonalized) flg |= 0x20; |
| if (mMediaSyncEvent != null) flg |= 0x2; |
| dest.writeInt(flg); |
| dest.writeInt(mConfidenceLevel); |
| if (mMediaSyncEvent != null) dest.writeTypedObject(mMediaSyncEvent, flags); |
| dest.writeInt(mHotwordOffsetMillis); |
| dest.writeInt(mHotwordDurationMillis); |
| dest.writeInt(mAudioChannel); |
| dest.writeInt(mScore); |
| dest.writeInt(mPersonalizedScore); |
| dest.writeInt(mHotwordPhraseId); |
| dest.writeTypedObject(mExtras, flags); |
| } |
| |
| @Override |
| @DataClass.Generated.Member |
| public int describeContents() { return 0; } |
| |
| /** @hide */ |
| @SuppressWarnings({"unchecked", "RedundantCast"}) |
| @DataClass.Generated.Member |
| /* package-private */ HotwordDetectedResult(@NonNull Parcel in) { |
| // You can override field unparcelling by defining methods like: |
| // static FieldType unparcelFieldName(Parcel in) { ... } |
| |
| int flg = in.readInt(); |
| boolean hotwordDetectionPersonalized = (flg & 0x20) != 0; |
| int confidenceLevel = in.readInt(); |
| MediaSyncEvent mediaSyncEvent = (flg & 0x2) == 0 ? null : (MediaSyncEvent) in.readTypedObject(MediaSyncEvent.CREATOR); |
| int hotwordOffsetMillis = in.readInt(); |
| int hotwordDurationMillis = in.readInt(); |
| int audioChannel = in.readInt(); |
| int score = in.readInt(); |
| int personalizedScore = in.readInt(); |
| int hotwordPhraseId = in.readInt(); |
| PersistableBundle extras = (PersistableBundle) in.readTypedObject(PersistableBundle.CREATOR); |
| |
| this.mConfidenceLevel = confidenceLevel; |
| com.android.internal.util.AnnotationValidations.validate( |
| HotwordConfidenceLevelValue.class, null, mConfidenceLevel); |
| this.mMediaSyncEvent = mediaSyncEvent; |
| this.mHotwordOffsetMillis = hotwordOffsetMillis; |
| this.mHotwordDurationMillis = hotwordDurationMillis; |
| this.mAudioChannel = audioChannel; |
| this.mHotwordDetectionPersonalized = hotwordDetectionPersonalized; |
| this.mScore = score; |
| this.mPersonalizedScore = personalizedScore; |
| this.mHotwordPhraseId = hotwordPhraseId; |
| this.mExtras = extras; |
| com.android.internal.util.AnnotationValidations.validate( |
| NonNull.class, null, mExtras); |
| |
| onConstructed(); |
| } |
| |
| @DataClass.Generated.Member |
| public static final @NonNull Parcelable.Creator<HotwordDetectedResult> CREATOR |
| = new Parcelable.Creator<HotwordDetectedResult>() { |
| @Override |
| public HotwordDetectedResult[] newArray(int size) { |
| return new HotwordDetectedResult[size]; |
| } |
| |
| @Override |
| public HotwordDetectedResult createFromParcel(@NonNull Parcel in) { |
| return new HotwordDetectedResult(in); |
| } |
| }; |
| |
| /** |
| * A builder for {@link HotwordDetectedResult} |
| */ |
| @SuppressWarnings("WeakerAccess") |
| @DataClass.Generated.Member |
| public static final class Builder { |
| |
| private @HotwordConfidenceLevelValue int mConfidenceLevel; |
| private @Nullable MediaSyncEvent mMediaSyncEvent; |
| private int mHotwordOffsetMillis; |
| private int mHotwordDurationMillis; |
| private int mAudioChannel; |
| private boolean mHotwordDetectionPersonalized; |
| private int mScore; |
| private int mPersonalizedScore; |
| private int mHotwordPhraseId; |
| private @NonNull PersistableBundle mExtras; |
| |
| private long mBuilderFieldsSet = 0L; |
| |
| public Builder() { |
| } |
| |
| /** |
| * Confidence level in the trigger outcome. |
| */ |
| @DataClass.Generated.Member |
| public @NonNull Builder setConfidenceLevel(@HotwordConfidenceLevelValue int value) { |
| checkNotUsed(); |
| mBuilderFieldsSet |= 0x1; |
| mConfidenceLevel = value; |
| return this; |
| } |
| |
| /** |
| * A {@code MediaSyncEvent} that allows the {@link HotwordDetector} to recapture the audio |
| * that contains the hotword trigger. This must be obtained using |
| * {@link android.media.AudioRecord#shareAudioHistory(String, long)}. |
| */ |
| @DataClass.Generated.Member |
| public @NonNull Builder setMediaSyncEvent(@NonNull MediaSyncEvent value) { |
| checkNotUsed(); |
| mBuilderFieldsSet |= 0x2; |
| mMediaSyncEvent = value; |
| return this; |
| } |
| |
| /** |
| * Offset in milliseconds the audio stream when the trigger event happened (end of hotword |
| * phrase). |
| * |
| * <p>Only value between 0 and 3600000 (inclusive) is accepted. |
| */ |
| @DataClass.Generated.Member |
| public @NonNull Builder setHotwordOffsetMillis(int value) { |
| checkNotUsed(); |
| mBuilderFieldsSet |= 0x4; |
| mHotwordOffsetMillis = value; |
| return this; |
| } |
| |
| /** |
| * Duration in milliseconds of the hotword trigger phrase. |
| * |
| * <p>Only values between 0 and {@link android.media.AudioRecord#getMaxSharedAudioHistoryMillis} |
| * (inclusive) are accepted. |
| */ |
| @DataClass.Generated.Member |
| public @NonNull Builder setHotwordDurationMillis(int value) { |
| checkNotUsed(); |
| mBuilderFieldsSet |= 0x8; |
| mHotwordDurationMillis = value; |
| return this; |
| } |
| |
| /** |
| * Audio channel containing the highest-confidence hotword signal. |
| * |
| * <p>Only value between 0 and 63 (inclusive) is accepted. |
| */ |
| @DataClass.Generated.Member |
| public @NonNull Builder setAudioChannel(int value) { |
| checkNotUsed(); |
| mBuilderFieldsSet |= 0x10; |
| mAudioChannel = value; |
| return this; |
| } |
| |
| /** |
| * Returns whether the trigger has happened due to model having been personalized to fit user's |
| * voice. |
| */ |
| @DataClass.Generated.Member |
| public @NonNull Builder setHotwordDetectionPersonalized(boolean value) { |
| checkNotUsed(); |
| mBuilderFieldsSet |= 0x20; |
| mHotwordDetectionPersonalized = value; |
| return this; |
| } |
| |
| /** |
| * Score for the hotword trigger. |
| * |
| * <p>Only values between 0 and {@link #getMaxScore} (inclusive) are accepted. |
| */ |
| @DataClass.Generated.Member |
| public @NonNull Builder setScore(int value) { |
| checkNotUsed(); |
| mBuilderFieldsSet |= 0x40; |
| mScore = value; |
| return this; |
| } |
| |
| /** |
| * Score for the hotword trigger for device user. |
| * |
| * <p>Only values between 0 and {@link #getMaxScore} (inclusive) are accepted. |
| */ |
| @DataClass.Generated.Member |
| public @NonNull Builder setPersonalizedScore(int value) { |
| checkNotUsed(); |
| mBuilderFieldsSet |= 0x80; |
| mPersonalizedScore = value; |
| return this; |
| } |
| |
| /** |
| * An ID representing the keyphrase that triggered the successful detection. |
| * |
| * <p>Only values between 0 and {@link #getMaxHotwordPhraseId()} (inclusive) are accepted. |
| */ |
| @DataClass.Generated.Member |
| public @NonNull Builder setHotwordPhraseId(int value) { |
| checkNotUsed(); |
| mBuilderFieldsSet |= 0x100; |
| mHotwordPhraseId = value; |
| return this; |
| } |
| |
| /** |
| * App-specific extras to support trigger. |
| * |
| * <p>The size of this bundle will be limited to {@link #getMaxBundleSize}. Results will larger |
| * bundles will be rejected. |
| * |
| * <p>Only primitive types are supported in this bundle. Complex types will be removed from the |
| * bundle. |
| * |
| * <p>The use of this method is discouraged, and support for it will be removed in future |
| * versions of Android. |
| * |
| * <p>This is a PersistableBundle so it doesn't allow any remotable objects or other contents |
| * that can be used to communicate with other processes. |
| */ |
| @DataClass.Generated.Member |
| public @NonNull Builder setExtras(@NonNull PersistableBundle value) { |
| checkNotUsed(); |
| mBuilderFieldsSet |= 0x200; |
| mExtras = value; |
| return this; |
| } |
| |
| /** Builds the instance. This builder should not be touched after calling this! */ |
| public @NonNull HotwordDetectedResult build() { |
| checkNotUsed(); |
| mBuilderFieldsSet |= 0x400; // Mark builder used |
| |
| if ((mBuilderFieldsSet & 0x1) == 0) { |
| mConfidenceLevel = defaultConfidenceLevel(); |
| } |
| if ((mBuilderFieldsSet & 0x2) == 0) { |
| mMediaSyncEvent = null; |
| } |
| if ((mBuilderFieldsSet & 0x4) == 0) { |
| mHotwordOffsetMillis = HOTWORD_OFFSET_UNSET; |
| } |
| if ((mBuilderFieldsSet & 0x8) == 0) { |
| mHotwordDurationMillis = 0; |
| } |
| if ((mBuilderFieldsSet & 0x10) == 0) { |
| mAudioChannel = AUDIO_CHANNEL_UNSET; |
| } |
| if ((mBuilderFieldsSet & 0x20) == 0) { |
| mHotwordDetectionPersonalized = false; |
| } |
| if ((mBuilderFieldsSet & 0x40) == 0) { |
| mScore = defaultScore(); |
| } |
| if ((mBuilderFieldsSet & 0x80) == 0) { |
| mPersonalizedScore = defaultPersonalizedScore(); |
| } |
| if ((mBuilderFieldsSet & 0x100) == 0) { |
| mHotwordPhraseId = defaultHotwordPhraseId(); |
| } |
| if ((mBuilderFieldsSet & 0x200) == 0) { |
| mExtras = defaultExtras(); |
| } |
| HotwordDetectedResult o = new HotwordDetectedResult( |
| mConfidenceLevel, |
| mMediaSyncEvent, |
| mHotwordOffsetMillis, |
| mHotwordDurationMillis, |
| mAudioChannel, |
| mHotwordDetectionPersonalized, |
| mScore, |
| mPersonalizedScore, |
| mHotwordPhraseId, |
| mExtras); |
| return o; |
| } |
| |
| private void checkNotUsed() { |
| if ((mBuilderFieldsSet & 0x400) != 0) { |
| throw new IllegalStateException( |
| "This Builder should not be reused. Use a new Builder instance instead"); |
| } |
| } |
| } |
| |
| @DataClass.Generated( |
| time = 1625541522353L, |
| codegenVersion = "1.0.23", |
| sourceFile = "frameworks/base/core/java/android/service/voice/HotwordDetectedResult.java", |
| inputSignatures = "public static final int CONFIDENCE_LEVEL_NONE\npublic static final int CONFIDENCE_LEVEL_LOW\npublic static final int CONFIDENCE_LEVEL_LOW_MEDIUM\npublic static final int CONFIDENCE_LEVEL_MEDIUM\npublic static final int CONFIDENCE_LEVEL_MEDIUM_HIGH\npublic static final int CONFIDENCE_LEVEL_HIGH\npublic static final int CONFIDENCE_LEVEL_VERY_HIGH\npublic static final int HOTWORD_OFFSET_UNSET\npublic static final int AUDIO_CHANNEL_UNSET\nprivate static final int LIMIT_HOTWORD_OFFSET_MAX_VALUE\nprivate static final int LIMIT_AUDIO_CHANNEL_MAX_VALUE\nprivate final @android.service.voice.HotwordDetectedResult.HotwordConfidenceLevelValue int mConfidenceLevel\nprivate @android.annotation.Nullable android.media.MediaSyncEvent mMediaSyncEvent\nprivate int mHotwordOffsetMillis\nprivate int mHotwordDurationMillis\nprivate int mAudioChannel\nprivate boolean mHotwordDetectionPersonalized\nprivate final int mScore\nprivate final int mPersonalizedScore\nprivate final int mHotwordPhraseId\nprivate final @android.annotation.NonNull android.os.PersistableBundle mExtras\nprivate static int sMaxBundleSize\nprivate static int defaultConfidenceLevel()\nprivate static int defaultScore()\nprivate static int defaultPersonalizedScore()\npublic static int getMaxScore()\nprivate static int defaultHotwordPhraseId()\npublic static int getMaxHotwordPhraseId()\nprivate static android.os.PersistableBundle defaultExtras()\npublic static int getMaxBundleSize()\npublic @android.annotation.Nullable android.media.MediaSyncEvent getMediaSyncEvent()\npublic static int getParcelableSize(android.os.Parcelable)\npublic static int getUsageSize(android.service.voice.HotwordDetectedResult)\nprivate static int bitCount(long)\nprivate void onConstructed()\nclass HotwordDetectedResult extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=true, genEqualsHashCode=true, genHiddenConstDefs=true, genParcelable=true, genToString=true)") |
| @Deprecated |
| private void __metadata() {} |
| |
| |
| //@formatter:on |
| // End of generated code |
| |
| } |