diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 6a4b66c1ecd3b..f544e40d4ff36 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -13040,6 +13040,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(); @@ -13130,6 +13143,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 8ff1a84e91787..3baf5a24e6833 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; + } + }; +}