From 172d9a2aca15f1292302f7d21eba661a67bf5714 Mon Sep 17 00:00:00 2001 From: lpeter Date: Thu, 12 Jan 2023 05:27:16 +0800 Subject: [PATCH] Create the DetectorFailure class and its subclasses. Add the DetectorFailure class and its subclasses to let the assistant application know what went wrong during using the hotword detector. Subclasses as below: HotwordDetectionServiceFailure class SoundTriggerFailure class UnknownFailure class VisualQueryDetectionServiceFailure class Bug: 256780491 Bug: 261012843 Test: atest CtsVoiceInteractionTestCases Change-Id: I5a35a0098afb77898e49f8c28b66ccf058e5e8dd --- core/api/system-current.txt | 54 +++++ core/api/test-current.txt | 16 ++ .../service/voice/DetectorFailure.aidl | 19 ++ .../service/voice/DetectorFailure.java | 218 ++++++++++++++++++ .../voice/HotwordDetectionServiceFailure.aidl | 19 ++ .../voice/HotwordDetectionServiceFailure.java | 152 ++++++++++++ .../service/voice/SoundTriggerFailure.aidl | 19 ++ .../service/voice/SoundTriggerFailure.java | 126 ++++++++++ .../android/service/voice/UnknownFailure.aidl | 19 ++ .../android/service/voice/UnknownFailure.java | 77 +++++++ .../VisualQueryDetectionServiceFailure.aidl | 19 ++ .../VisualQueryDetectionServiceFailure.java | 136 +++++++++++ 12 files changed, 874 insertions(+) create mode 100644 core/java/android/service/voice/DetectorFailure.aidl create mode 100644 core/java/android/service/voice/DetectorFailure.java create mode 100644 core/java/android/service/voice/HotwordDetectionServiceFailure.aidl create mode 100644 core/java/android/service/voice/HotwordDetectionServiceFailure.java create mode 100644 core/java/android/service/voice/SoundTriggerFailure.aidl create mode 100644 core/java/android/service/voice/SoundTriggerFailure.java create mode 100644 core/java/android/service/voice/UnknownFailure.aidl create mode 100644 core/java/android/service/voice/UnknownFailure.java create mode 100644 core/java/android/service/voice/VisualQueryDetectionServiceFailure.aidl create mode 100644 core/java/android/service/voice/VisualQueryDetectionServiceFailure.java diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 6581c421f9705..f767bbc938845 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -13041,6 +13041,19 @@ package android.service.voice { method public int getStart(); } + public abstract class DetectorFailure implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public String getErrorMessage(); + method public abstract int getSuggestedAction(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + field public static final int SUGGESTED_ACTION_DISABLE_DETECTION = 2; // 0x2 + field public static final int SUGGESTED_ACTION_NONE = 1; // 0x1 + field public static final int SUGGESTED_ACTION_RECREATE_DETECTOR = 3; // 0x3 + field public static final int SUGGESTED_ACTION_RESTART_RECOGNITION = 4; // 0x4 + field public static final int SUGGESTED_ACTION_UNKNOWN = 0; // 0x0 + } + public final class HotwordAudioStream implements android.os.Parcelable { method public int describeContents(); method @NonNull public android.media.AudioFormat getAudioFormat(); @@ -13131,6 +13144,20 @@ package android.service.voice { method public void onRejected(@NonNull android.service.voice.HotwordRejectedResult); } + public final class HotwordDetectionServiceFailure extends android.service.voice.DetectorFailure { + method public int getErrorCode(); + method public int getSuggestedAction(); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + field public static final int ERROR_CODE_BINDING_DIED = 2; // 0x2 + field public static final int ERROR_CODE_BIND_FAILURE = 1; // 0x1 + field public static final int ERROR_CODE_COPY_AUDIO_DATA_FAILURE = 3; // 0x3 + field public static final int ERROR_CODE_DETECT_TIMEOUT = 4; // 0x4 + field public static final int ERROR_CODE_ON_DETECTED_SECURITY_EXCEPTION = 5; // 0x5 + field public static final int ERROR_CODE_ON_DETECTED_STREAM_COPY_FAILURE = 6; // 0x6 + field public static final int ERROR_CODE_REMOTE_EXCEPTION = 7; // 0x7 + field public static final int ERROR_CODE_UNKNOWN = 0; // 0x0 + } + public interface HotwordDetector { method public default void destroy(); method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition() throws android.service.voice.HotwordDetector.IllegalDetectorStateException; @@ -13176,6 +13203,21 @@ package android.service.voice { field public static final int INITIALIZATION_STATUS_UNKNOWN = 100; // 0x64 } + public final class SoundTriggerFailure extends android.service.voice.DetectorFailure { + method public int getErrorCode(); + method public int getSuggestedAction(); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + field public static final int ERROR_CODE_MODULE_DIED = 1; // 0x1 + field public static final int ERROR_CODE_RECOGNITION_RESUME_FAILED = 2; // 0x2 + field public static final int ERROR_CODE_UNEXPECTED_PREEMPTION = 3; // 0x3 + field public static final int ERROR_CODE_UNKNOWN = 0; // 0x0 + } + + public final class UnknownFailure extends android.service.voice.DetectorFailure { + method public int getSuggestedAction(); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + } + public abstract class VisualQueryDetectionService extends android.app.Service implements android.service.voice.SandboxedDetectionServiceBase { ctor public VisualQueryDetectionService(); method @Nullable public android.os.IBinder onBind(@NonNull android.content.Intent); @@ -13194,6 +13236,18 @@ package android.service.voice { method public void onQueryRejected() throws java.lang.IllegalStateException; } + public final class VisualQueryDetectionServiceFailure extends android.service.voice.DetectorFailure { + method public int getErrorCode(); + method public int getSuggestedAction(); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + field public static final int ERROR_CODE_BINDING_DIED = 2; // 0x2 + field public static final int ERROR_CODE_BIND_FAILURE = 1; // 0x1 + field public static final int ERROR_CODE_ILLEGAL_ATTENTION_STATE = 3; // 0x3 + field public static final int ERROR_CODE_ILLEGAL_STREAMING_STATE = 4; // 0x4 + field public static final int ERROR_CODE_REMOTE_EXCEPTION = 5; // 0x5 + field public static final int ERROR_CODE_UNKNOWN = 0; // 0x0 + } + public class VisualQueryDetector { method public void destroy(); method @RequiresPermission(allOf={android.Manifest.permission.CAMERA, android.Manifest.permission.RECORD_AUDIO}) public boolean startRecognition() throws android.service.voice.HotwordDetector.IllegalDetectorStateException; diff --git a/core/api/test-current.txt b/core/api/test-current.txt index c0cd6386aec2f..d3baadc82ec60 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -2796,10 +2796,26 @@ package android.service.voice { field public static final boolean ENABLE_PROXIMITY_RESULT = true; } + public final class HotwordDetectionServiceFailure extends android.service.voice.DetectorFailure { + ctor public HotwordDetectionServiceFailure(int, @NonNull String); + } + + public final class SoundTriggerFailure extends android.service.voice.DetectorFailure { + ctor public SoundTriggerFailure(int, @NonNull String); + } + + public final class UnknownFailure extends android.service.voice.DetectorFailure { + ctor public UnknownFailure(@NonNull String); + } + public final class VisibleActivityInfo implements android.os.Parcelable { ctor public VisibleActivityInfo(int, @NonNull android.os.IBinder); } + public final class VisualQueryDetectionServiceFailure extends android.service.voice.DetectorFailure { + ctor public VisualQueryDetectionServiceFailure(int, @NonNull String); + } + public class VoiceInteractionService extends android.app.Service { method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_HOTWORD_DETECTION) public final android.service.voice.AlwaysOnHotwordDetector createAlwaysOnHotwordDetectorForTest(@NonNull String, @NonNull java.util.Locale, @NonNull android.hardware.soundtrigger.SoundTrigger.ModuleProperties, @NonNull java.util.concurrent.Executor, @NonNull android.service.voice.AlwaysOnHotwordDetector.Callback); method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_HOTWORD_DETECTION) public final android.service.voice.AlwaysOnHotwordDetector createAlwaysOnHotwordDetectorForTest(@NonNull String, @NonNull java.util.Locale, @Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory, @NonNull android.hardware.soundtrigger.SoundTrigger.ModuleProperties, @NonNull java.util.concurrent.Executor, @NonNull android.service.voice.AlwaysOnHotwordDetector.Callback); diff --git a/core/java/android/service/voice/DetectorFailure.aidl b/core/java/android/service/voice/DetectorFailure.aidl new file mode 100644 index 0000000000000..3591329ac1114 --- /dev/null +++ b/core/java/android/service/voice/DetectorFailure.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2023 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; + +parcelable DetectorFailure; diff --git a/core/java/android/service/voice/DetectorFailure.java b/core/java/android/service/voice/DetectorFailure.java new file mode 100644 index 0000000000000..c6efdc3063e36 --- /dev/null +++ b/core/java/android/service/voice/DetectorFailure.java @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2023 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.SuppressLint; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; +import android.text.TextUtils; + +import com.android.internal.util.Preconditions; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * This is used by the assistant application to know what went wrong during using the detector + * and which action the application should take. The detector can be a HotwordDector or a visual + * query detector. + * + *

Any class that derives this class must only add an integer value of error source type, an + * integer value of error code and a string of error message passed into the constructor. Any other + * field will not be parceled through. If the derived class has custom parceling implementation, + * this class will not be able to unpack the parcel without having access to that implementation. + * + * @hide + */ +@SuppressLint("ParcelNotFinal") // Safe because the constructor is package-private +@SystemApi +public abstract class DetectorFailure implements Parcelable { + + /** + * A suggested action due to an unknown error occurs. + */ + public static final int SUGGESTED_ACTION_UNKNOWN = 0; + + /** + * Indicates that an error occurs, but no action is needed for the client. The error will be + * recovered from within the framework. + */ + public static final int SUGGESTED_ACTION_NONE = 1; + + /** + * Indicates that an error occurs, but no action is needed for the client due to the error can + * not be recovered. It means that the detection will not work even though the assistant + * application creates the detector again. + * + * Example: The detection service always crashes after assistant application creates the + * detector. The assistant application can stop re-creating the detector and show a suitable + * error dialog to notify the user. + */ + public static final int SUGGESTED_ACTION_DISABLE_DETECTION = 2; + + /** + * Indicates that the detection service is invalid, the client needs to destroy its detector + * first and recreate its detector later. + */ + public static final int SUGGESTED_ACTION_RECREATE_DETECTOR = 3; + + /** + * Indicates that the detection has stopped. The client needs to start recognition again. + * + * Example: The system server receives a Dsp trigger event. + */ + public static final int SUGGESTED_ACTION_RESTART_RECOGNITION = 4; + + /** + * @hide + */ + @IntDef(prefix = {"SUGGESTED_ACTION_"}, value = { + SUGGESTED_ACTION_UNKNOWN, + SUGGESTED_ACTION_NONE, + SUGGESTED_ACTION_DISABLE_DETECTION, + SUGGESTED_ACTION_RECREATE_DETECTOR, + SUGGESTED_ACTION_RESTART_RECOGNITION + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SuggestedAction {} + + /** + * Indicates that an error occurs from the unknown error source. + * + * @hide + */ + public static final int ERROR_SOURCE_TYPE_UNKNOWN = -1; + + /** + * Indicates that an error occurs from the hotword detection. + * + * @see HotwordDetectionServiceFailure#ERROR_CODE_BIND_FAILURE + * @see HotwordDetectionServiceFailure#ERROR_CODE_BINDING_DIED + * @see HotwordDetectionServiceFailure#ERROR_CODE_COPY_AUDIO_DATA_FAILURE + * @see HotwordDetectionServiceFailure#ERROR_CODE_DETECT_TIMEOUT + * @see HotwordDetectionServiceFailure#ERROR_CODE_ON_DETECTED_SECURITY_EXCEPTION + * @see HotwordDetectionServiceFailure#ERROR_CODE_ON_DETECTED_STREAM_COPY_FAILURE + * @see HotwordDetectionServiceFailure#ERROR_CODE_REMOTE_EXCEPTION + * + * @hide + */ + public static final int ERROR_SOURCE_TYPE_HOTWORD_DETECTION = 0; + + /** + * Indicates that an error occurs from the sound trigger system service + * {@link com.android.server.soundtrigger.SoundTriggerService} and + * {@link com.android.server.soundtrigger_middleware.SoundTriggerMiddlewareService}. + * + * @see SoundTriggerFailure#ERROR_CODE_MODULE_DIED + * @see SoundTriggerFailure#ERROR_CODE_RECOGNITION_RESUME_FAILED + * @see SoundTriggerFailure#ERROR_CODE_UNEXPECTED_PREEMPTION + * + * @hide + */ + public static final int ERROR_SOURCE_TYPE_SOUND_TRIGGER = 1; + + /** + * Indicates that an error occurs from {@link VisualQueryDetectionService}. + * + * @see VisualQueryDetectionServiceFailure#ERROR_CODE_BIND_FAILURE + * @see VisualQueryDetectionServiceFailure#ERROR_CODE_BINDING_DIED + * @see VisualQueryDetectionServiceFailure#ERROR_CODE_ILLEGAL_ATTENTION_STATE + * @see VisualQueryDetectionServiceFailure#ERROR_CODE_ILLEGAL_STREAMING_STATE + * @see VisualQueryDetectionServiceFailure#ERROR_CODE_REMOTE_EXCEPTION + * + * @hide + */ + public static final int ERROR_SOURCE_TYPE_VISUAL_QUERY_DETECTION = 2; + + private int mErrorSourceType = ERROR_SOURCE_TYPE_UNKNOWN; + private int mErrorCode = UnknownFailure.ERROR_CODE_UNKNOWN; + private String mErrorMessage = "Unknown"; + + DetectorFailure(int errorSourceType, int errorCode, @NonNull String errorMessage) { + Preconditions.checkArgumentInRange(errorSourceType, ERROR_SOURCE_TYPE_UNKNOWN, + ERROR_SOURCE_TYPE_VISUAL_QUERY_DETECTION, "errorSourceType"); + if (TextUtils.isEmpty(errorMessage)) { + throw new IllegalArgumentException("errorMessage is empty or null."); + } + mErrorSourceType = errorSourceType; + mErrorCode = errorCode; + mErrorMessage = errorMessage; + } + + /** + * Returns the suggested action. + */ + @SuggestedAction + public abstract int getSuggestedAction(); + + /** + * Returns the error code. + * + * @hide + */ + public int getErrorCode() { + return mErrorCode; + } + + /** + * Returns the error message. + */ + @NonNull + public String getErrorMessage() { + return mErrorMessage; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mErrorSourceType); + dest.writeInt(mErrorCode); + dest.writeString8(mErrorMessage); + } + + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public DetectorFailure[] newArray(int size) { + return new DetectorFailure[size]; + } + + @Override + public DetectorFailure createFromParcel(@NonNull Parcel in) { + final int errorSourceType = in.readInt(); + final int errorCode = in.readInt(); + final String errorMessage = in.readString8(); + switch (errorSourceType) { + case ERROR_SOURCE_TYPE_HOTWORD_DETECTION: + return new HotwordDetectionServiceFailure(errorCode, errorMessage); + case ERROR_SOURCE_TYPE_SOUND_TRIGGER: + return new SoundTriggerFailure(errorCode, errorMessage); + case ERROR_SOURCE_TYPE_VISUAL_QUERY_DETECTION: + return new VisualQueryDetectionServiceFailure(errorCode, errorMessage); + default: + return new UnknownFailure(errorMessage); + } + } + }; +} diff --git a/core/java/android/service/voice/HotwordDetectionServiceFailure.aidl b/core/java/android/service/voice/HotwordDetectionServiceFailure.aidl new file mode 100644 index 0000000000000..8d3cfc2de8504 --- /dev/null +++ b/core/java/android/service/voice/HotwordDetectionServiceFailure.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2023 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; + +parcelable HotwordDetectionServiceFailure; diff --git a/core/java/android/service/voice/HotwordDetectionServiceFailure.java b/core/java/android/service/voice/HotwordDetectionServiceFailure.java new file mode 100644 index 0000000000000..3d9f66b173d4e --- /dev/null +++ b/core/java/android/service/voice/HotwordDetectionServiceFailure.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2023 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.SystemApi; +import android.annotation.TestApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * This class is used by the assistant application to know what went wrong during using the + * {@link HotwordDetector} and which action that the application should take. When an error occurs + * from Dsp hotword detection, software hotword detection and {@link HotwordDetectionService}, the + * system will send {@link HotwordDetectionServiceFailure} which contains the error code, error + * message and the suggested action to help the assistant application to take the next action. + * + * @hide + */ +@SystemApi +public final class HotwordDetectionServiceFailure extends DetectorFailure { + + /** + * An error code which means an unknown error occurs. + */ + public static final int ERROR_CODE_UNKNOWN = 0; + + /** + * Indicates that the system server binds hotword detection service failure. + */ + public static final int ERROR_CODE_BIND_FAILURE = 1; + + /** + * Indicates that the hotword detection service is dead. + */ + public static final int ERROR_CODE_BINDING_DIED = 2; + + /** + * Indicates to copy audio data failure for external source detection. + */ + public static final int ERROR_CODE_COPY_AUDIO_DATA_FAILURE = 3; + + /** + * Indicates that the detection service doesn’t respond to the detection result before timeout. + */ + public static final int ERROR_CODE_DETECT_TIMEOUT = 4; + + /** + * Indicates that the security exception occurs in #onDetected method. + */ + public static final int ERROR_CODE_ON_DETECTED_SECURITY_EXCEPTION = 5; + + /** + * Indicates to copy the audio stream failure in #onDetected method. + */ + public static final int ERROR_CODE_ON_DETECTED_STREAM_COPY_FAILURE = 6; + + /** + * Indicates that the remote exception occurs when calling callback method. + */ + public static final int ERROR_CODE_REMOTE_EXCEPTION = 7; + + /** + * @hide + */ + @IntDef(prefix = {"ERROR_CODE_"}, value = { + ERROR_CODE_UNKNOWN, + ERROR_CODE_BIND_FAILURE, + ERROR_CODE_BINDING_DIED, + ERROR_CODE_COPY_AUDIO_DATA_FAILURE, + ERROR_CODE_DETECT_TIMEOUT, + ERROR_CODE_ON_DETECTED_SECURITY_EXCEPTION, + ERROR_CODE_ON_DETECTED_STREAM_COPY_FAILURE, + ERROR_CODE_REMOTE_EXCEPTION + }) + @Retention(RetentionPolicy.SOURCE) + public @interface HotwordDetectionServiceErrorCode {} + + /** + * @hide + */ + @TestApi + public HotwordDetectionServiceFailure(int errorCode, @NonNull String errorMessage) { + super(ERROR_SOURCE_TYPE_HOTWORD_DETECTION, errorCode, errorMessage); + } + + /** + * Returns the error code. + */ + @HotwordDetectionServiceErrorCode + public int getErrorCode() { + return super.getErrorCode(); + } + + @Override + public int getSuggestedAction() { + switch (getErrorCode()) { + case ERROR_CODE_BIND_FAILURE: + case ERROR_CODE_BINDING_DIED: + case ERROR_CODE_REMOTE_EXCEPTION: + return SUGGESTED_ACTION_RECREATE_DETECTOR; + case ERROR_CODE_DETECT_TIMEOUT: + case ERROR_CODE_ON_DETECTED_SECURITY_EXCEPTION: + case ERROR_CODE_ON_DETECTED_STREAM_COPY_FAILURE: + return SUGGESTED_ACTION_RESTART_RECOGNITION; + default: + return SUGGESTED_ACTION_NONE; + } + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + super.writeToParcel(dest, flags); + } + + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public HotwordDetectionServiceFailure[] newArray(int size) { + return new HotwordDetectionServiceFailure[size]; + } + + @Override + public HotwordDetectionServiceFailure createFromParcel(@NonNull Parcel in) { + DetectorFailure detectorFailure = DetectorFailure.CREATOR.createFromParcel(in); + return (HotwordDetectionServiceFailure) detectorFailure; + } + }; +} diff --git a/core/java/android/service/voice/SoundTriggerFailure.aidl b/core/java/android/service/voice/SoundTriggerFailure.aidl new file mode 100644 index 0000000000000..7ba1c7bf338e3 --- /dev/null +++ b/core/java/android/service/voice/SoundTriggerFailure.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2023 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; + +parcelable SoundTriggerFailure; diff --git a/core/java/android/service/voice/SoundTriggerFailure.java b/core/java/android/service/voice/SoundTriggerFailure.java new file mode 100644 index 0000000000000..a431fbc0fe1dd --- /dev/null +++ b/core/java/android/service/voice/SoundTriggerFailure.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2023 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.SystemApi; +import android.annotation.TestApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * This class is used by the assistant application to know what went wrong during using the + * sound trigger system service {@link com.android.server.soundtrigger.SoundTriggerService} and + * {@link com.android.server.soundtrigger_middleware.SoundTriggerMiddlewareService}, and which + * action that the application should take. + * + * @hide + */ +@SystemApi +public final class SoundTriggerFailure extends DetectorFailure { + + /** + * An error code which means an unknown error occurs. + */ + public static final int ERROR_CODE_UNKNOWN = 0; + + /** + * Indicates that the underlying sound trigger module has died and will be restarted. All + * session state has been invalidated. + */ + public static final int ERROR_CODE_MODULE_DIED = 1; + + /** + * Indicates that sound trigger service recognition resume has failed. The model is in the + * stopped state and will not be restarted by the framework. + */ + public static final int ERROR_CODE_RECOGNITION_RESUME_FAILED = 2; + + /** + * Indicates that the sound trigger service has been unexpectedly preempted by another user. + * The model is in the stopped state and will not be restarted by the framework. + */ + public static final int ERROR_CODE_UNEXPECTED_PREEMPTION = 3; + + /** + * @hide + */ + @IntDef(prefix = {"ERROR_CODE_"}, value = { + ERROR_CODE_UNKNOWN, + ERROR_CODE_MODULE_DIED, + ERROR_CODE_RECOGNITION_RESUME_FAILED, + ERROR_CODE_UNEXPECTED_PREEMPTION + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SoundTriggerErrorCode {} + + /** + * @hide + */ + @TestApi + public SoundTriggerFailure(int errorCode, @NonNull String errorMessage) { + super(ERROR_SOURCE_TYPE_SOUND_TRIGGER, errorCode, errorMessage); + } + + /** + * Returns the error code. + */ + @SoundTriggerErrorCode + public int getErrorCode() { + return super.getErrorCode(); + } + + @Override + public int getSuggestedAction() { + switch (getErrorCode()) { + case ERROR_CODE_MODULE_DIED: + case ERROR_CODE_UNEXPECTED_PREEMPTION: + return SUGGESTED_ACTION_RECREATE_DETECTOR; + case ERROR_CODE_RECOGNITION_RESUME_FAILED: + return SUGGESTED_ACTION_RESTART_RECOGNITION; + default: + return SUGGESTED_ACTION_NONE; + } + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + super.writeToParcel(dest, flags); + } + + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public SoundTriggerFailure[] newArray(int size) { + return new SoundTriggerFailure[size]; + } + + @Override + public SoundTriggerFailure createFromParcel(@NonNull Parcel in) { + return (SoundTriggerFailure) DetectorFailure.CREATOR.createFromParcel(in); + } + }; +} diff --git a/core/java/android/service/voice/UnknownFailure.aidl b/core/java/android/service/voice/UnknownFailure.aidl new file mode 100644 index 0000000000000..cf43cc2fad46c --- /dev/null +++ b/core/java/android/service/voice/UnknownFailure.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2023 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; + +parcelable UnknownFailure; diff --git a/core/java/android/service/voice/UnknownFailure.java b/core/java/android/service/voice/UnknownFailure.java new file mode 100644 index 0000000000000..2ef2d5f880fd0 --- /dev/null +++ b/core/java/android/service/voice/UnknownFailure.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2023 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.NonNull; +import android.annotation.SystemApi; +import android.annotation.TestApi; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * A class which indicates an unknown error occurs during the detector doing detection. The class + * is mainly used by the assistant application, the application still can get the suggested action + * for the unknown error. + * + * @hide + */ +@SystemApi +public final class UnknownFailure extends DetectorFailure { + + /** + * An error code which means an unknown error occurs. + * + * @hide + */ + public static final int ERROR_CODE_UNKNOWN = 0; + + /** + * @hide + */ + @TestApi + public UnknownFailure(@NonNull String errorMessage) { + super(ERROR_SOURCE_TYPE_UNKNOWN, ERROR_CODE_UNKNOWN, errorMessage); + } + + @Override + public int getSuggestedAction() { + return SUGGESTED_ACTION_UNKNOWN; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + super.writeToParcel(dest, flags); + } + + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public UnknownFailure[] newArray(int size) { + return new UnknownFailure[size]; + } + + @Override + public UnknownFailure createFromParcel(@NonNull Parcel in) { + return (UnknownFailure) DetectorFailure.CREATOR.createFromParcel(in); + } + }; +} diff --git a/core/java/android/service/voice/VisualQueryDetectionServiceFailure.aidl b/core/java/android/service/voice/VisualQueryDetectionServiceFailure.aidl new file mode 100644 index 0000000000000..877df2895357a --- /dev/null +++ b/core/java/android/service/voice/VisualQueryDetectionServiceFailure.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2023 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; + +parcelable VisualQueryDetectionServiceFailure; diff --git a/core/java/android/service/voice/VisualQueryDetectionServiceFailure.java b/core/java/android/service/voice/VisualQueryDetectionServiceFailure.java new file mode 100644 index 0000000000000..aa02299b2b287 --- /dev/null +++ b/core/java/android/service/voice/VisualQueryDetectionServiceFailure.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2023 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.SystemApi; +import android.annotation.TestApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * This class is used by the assistant application to know what went wrong during using + * {@link VisualQueryDetectionService} and which action that the application should take. + * + * @hide + */ +@SystemApi +public final class VisualQueryDetectionServiceFailure extends DetectorFailure { + + /** + * An error code which means an unknown error occurs. + */ + public static final int ERROR_CODE_UNKNOWN = 0; + + /** + * Indicates that the system server binds visual query detection service failure. + */ + public static final int ERROR_CODE_BIND_FAILURE = 1; + + /** + * Indicates that the visual query detection service is dead. + */ + public static final int ERROR_CODE_BINDING_DIED = 2; + + /** + * Indicates that the detection service has no attention listener registered. + */ + public static final int ERROR_CODE_ILLEGAL_ATTENTION_STATE = 3; + + /** + * Indicates that the detection service is not egressing and should not be streaming queries. + */ + public static final int ERROR_CODE_ILLEGAL_STREAMING_STATE = 4; + + /** + * Indicates that the remote exception occurs when calling callback method. + */ + public static final int ERROR_CODE_REMOTE_EXCEPTION = 5; + + /** + * @hide + */ + @IntDef(prefix = {"ERROR_CODE_"}, value = { + ERROR_CODE_UNKNOWN, + ERROR_CODE_BIND_FAILURE, + ERROR_CODE_BINDING_DIED, + ERROR_CODE_ILLEGAL_ATTENTION_STATE, + ERROR_CODE_ILLEGAL_STREAMING_STATE, + ERROR_CODE_REMOTE_EXCEPTION + }) + @Retention(RetentionPolicy.SOURCE) + public @interface VisualQueryDetectionServiceErrorCode {} + + /** + * @hide + */ + @TestApi + public VisualQueryDetectionServiceFailure(int errorCode, @NonNull String errorMessage) { + super(ERROR_SOURCE_TYPE_VISUAL_QUERY_DETECTION, errorCode, errorMessage); + } + + /** + * Returns the error code. + */ + @VisualQueryDetectionServiceErrorCode + public int getErrorCode() { + return super.getErrorCode(); + } + + @Override + public int getSuggestedAction() { + switch (getErrorCode()) { + case ERROR_CODE_BIND_FAILURE: + case ERROR_CODE_BINDING_DIED: + case ERROR_CODE_ILLEGAL_ATTENTION_STATE: + case ERROR_CODE_REMOTE_EXCEPTION: + return SUGGESTED_ACTION_RECREATE_DETECTOR; + case ERROR_CODE_ILLEGAL_STREAMING_STATE: + return SUGGESTED_ACTION_RESTART_RECOGNITION; + default: + return SUGGESTED_ACTION_NONE; + } + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + super.writeToParcel(dest, flags); + } + + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public VisualQueryDetectionServiceFailure[] newArray(int size) { + return new VisualQueryDetectionServiceFailure[size]; + } + + @Override + public VisualQueryDetectionServiceFailure createFromParcel(@NonNull Parcel in) { + DetectorFailure detectorFailure = DetectorFailure.CREATOR.createFromParcel(in); + return (VisualQueryDetectionServiceFailure) detectorFailure; + } + }; +}