Merge "Follow HotwordDetector / DetectorFailure API feedback" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
1c00ee51b2
@@ -13033,6 +13033,7 @@ package android.service.voice {
|
||||
public abstract static class AlwaysOnHotwordDetector.Callback implements android.service.voice.HotwordDetector.Callback {
|
||||
ctor public AlwaysOnHotwordDetector.Callback();
|
||||
method public abstract void onAvailabilityChanged(int);
|
||||
method public void onFailure(@NonNull android.service.voice.SoundTriggerFailure);
|
||||
method public void onHotwordDetectionServiceInitialized(int);
|
||||
method public void onHotwordDetectionServiceRestarted();
|
||||
method public void onRejected(@NonNull android.service.voice.HotwordRejectedResult);
|
||||
@@ -13056,17 +13057,12 @@ 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<android.service.voice.DetectorFailure> 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 FailureSuggestedAction {
|
||||
field public static final int DISABLE_DETECTION = 2; // 0x2
|
||||
field public static final int NONE = 1; // 0x1
|
||||
field public static final int RECREATE_DETECTOR = 3; // 0x3
|
||||
field public static final int RESTART_RECOGNITION = 4; // 0x4
|
||||
field public static final int UNKNOWN = 0; // 0x0
|
||||
}
|
||||
|
||||
public final class HotwordAudioStream implements android.os.Parcelable {
|
||||
@@ -13163,9 +13159,12 @@ package android.service.voice {
|
||||
method public void onRejected(@NonNull android.service.voice.HotwordRejectedResult);
|
||||
}
|
||||
|
||||
public final class HotwordDetectionServiceFailure extends android.service.voice.DetectorFailure {
|
||||
public final class HotwordDetectionServiceFailure implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public int getErrorCode();
|
||||
method @NonNull public String getErrorMessage();
|
||||
method public int getSuggestedAction();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.service.voice.HotwordDetectionServiceFailure> CREATOR;
|
||||
field public static final int ERROR_CODE_BINDING_DIED = 2; // 0x2
|
||||
field public static final int ERROR_CODE_BIND_FAILURE = 1; // 0x1
|
||||
@@ -13188,12 +13187,13 @@ package android.service.voice {
|
||||
public static interface HotwordDetector.Callback {
|
||||
method public void onDetected(@NonNull android.service.voice.AlwaysOnHotwordDetector.EventPayload);
|
||||
method @Deprecated public void onError();
|
||||
method public default void onFailure(@NonNull android.service.voice.DetectorFailure);
|
||||
method public default void onFailure(@NonNull android.service.voice.HotwordDetectionServiceFailure);
|
||||
method public void onHotwordDetectionServiceInitialized(int);
|
||||
method public void onHotwordDetectionServiceRestarted();
|
||||
method public void onRecognitionPaused();
|
||||
method public void onRecognitionResumed();
|
||||
method public void onRejected(@NonNull android.service.voice.HotwordRejectedResult);
|
||||
method public default void onUnknownFailure(@NonNull String);
|
||||
}
|
||||
|
||||
public final class HotwordRejectedResult implements android.os.Parcelable {
|
||||
@@ -13220,9 +13220,12 @@ package android.service.voice {
|
||||
field public static final int INITIALIZATION_STATUS_UNKNOWN = 100; // 0x64
|
||||
}
|
||||
|
||||
public final class SoundTriggerFailure extends android.service.voice.DetectorFailure {
|
||||
public final class SoundTriggerFailure implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public int getErrorCode();
|
||||
method @NonNull public String getErrorMessage();
|
||||
method public int getSuggestedAction();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.service.voice.SoundTriggerFailure> CREATOR;
|
||||
field public static final int ERROR_CODE_MODULE_DIED = 1; // 0x1
|
||||
field public static final int ERROR_CODE_RECOGNITION_RESUME_FAILED = 2; // 0x2
|
||||
@@ -13230,11 +13233,6 @@ package android.service.voice {
|
||||
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<android.service.voice.UnknownFailure> CREATOR;
|
||||
}
|
||||
|
||||
public abstract class VisualQueryDetectionService extends android.app.Service implements android.service.voice.SandboxedDetectionInitializer {
|
||||
ctor public VisualQueryDetectionService();
|
||||
method public final void finishQuery() throws java.lang.IllegalStateException;
|
||||
@@ -13249,9 +13247,12 @@ package android.service.voice {
|
||||
field public static final String SERVICE_INTERFACE = "android.service.voice.VisualQueryDetectionService";
|
||||
}
|
||||
|
||||
public final class VisualQueryDetectionServiceFailure extends android.service.voice.DetectorFailure {
|
||||
public final class VisualQueryDetectionServiceFailure implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public int getErrorCode();
|
||||
method @NonNull public String getErrorMessage();
|
||||
method public int getSuggestedAction();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.service.voice.VisualQueryDetectionServiceFailure> CREATOR;
|
||||
field public static final int ERROR_CODE_BINDING_DIED = 2; // 0x2
|
||||
field public static final int ERROR_CODE_BIND_FAILURE = 1; // 0x1
|
||||
@@ -13269,10 +13270,11 @@ package android.service.voice {
|
||||
}
|
||||
|
||||
public static interface VisualQueryDetector.Callback {
|
||||
method public void onFailure(@NonNull android.service.voice.DetectorFailure);
|
||||
method public void onFailure(@NonNull android.service.voice.VisualQueryDetectionServiceFailure);
|
||||
method public void onQueryDetected(@NonNull String);
|
||||
method public void onQueryFinished();
|
||||
method public void onQueryRejected();
|
||||
method public void onUnknownFailure(@NonNull String);
|
||||
method public void onVisualQueryDetectionServiceInitialized(int);
|
||||
method public void onVisualQueryDetectionServiceRestarted();
|
||||
}
|
||||
|
||||
@@ -2897,23 +2897,19 @@ package android.service.voice {
|
||||
field public static final boolean ENABLE_PROXIMITY_RESULT = true;
|
||||
}
|
||||
|
||||
public final class HotwordDetectionServiceFailure extends android.service.voice.DetectorFailure {
|
||||
public final class HotwordDetectionServiceFailure implements android.os.Parcelable {
|
||||
ctor public HotwordDetectionServiceFailure(int, @NonNull String);
|
||||
}
|
||||
|
||||
public final class SoundTriggerFailure extends android.service.voice.DetectorFailure {
|
||||
public final class SoundTriggerFailure implements android.os.Parcelable {
|
||||
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 {
|
||||
public final class VisualQueryDetectionServiceFailure implements android.os.Parcelable {
|
||||
ctor public VisualQueryDetectionServiceFailure(int, @NonNull String);
|
||||
}
|
||||
|
||||
|
||||
@@ -228,11 +228,16 @@ abstract class AbstractDetector implements HotwordDetector {
|
||||
|
||||
/** Called when the detection fails due to an error. */
|
||||
@Override
|
||||
public void onError(DetectorFailure detectorFailure) {
|
||||
Slog.v(TAG, "BinderCallback#onError detectorFailure: " + detectorFailure);
|
||||
public void onHotwordDetectionServiceFailure(
|
||||
HotwordDetectionServiceFailure hotwordDetectionServiceFailure) {
|
||||
Slog.v(TAG, "BinderCallback#onHotwordDetectionServiceFailure: "
|
||||
+ hotwordDetectionServiceFailure);
|
||||
Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> {
|
||||
mCallback.onFailure(detectorFailure != null ? detectorFailure
|
||||
: new UnknownFailure("Error data is null"));
|
||||
if (hotwordDetectionServiceFailure != null) {
|
||||
mCallback.onFailure(hotwordDetectionServiceFailure);
|
||||
} else {
|
||||
mCallback.onUnknownFailure("Error data is null");
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@@ -280,6 +280,9 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
private static final int MSG_HOTWORD_REJECTED = 6;
|
||||
private static final int MSG_HOTWORD_STATUS_REPORTED = 7;
|
||||
private static final int MSG_PROCESS_RESTARTED = 8;
|
||||
private static final int MSG_DETECTION_HOTWORD_DETECTION_SERVICE_FAILURE = 9;
|
||||
private static final int MSG_DETECTION_SOUND_TRIGGER_FAILURE = 10;
|
||||
private static final int MSG_DETECTION_UNKNOWN_FAILURE = 11;
|
||||
|
||||
private final String mText;
|
||||
private final Locale mLocale;
|
||||
@@ -774,12 +777,28 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @deprecated Use {@link HotwordDetector.Callback#onError(DetectorFailure)} instead.
|
||||
* @deprecated On {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and above,
|
||||
* implement {@link HotwordDetector.Callback#onFailure(HotwordDetectionServiceFailure)},
|
||||
* {@link AlwaysOnHotwordDetector.Callback#onFailure(SoundTriggerFailure)},
|
||||
* {@link HotwordDetector.Callback#onUnknownFailure(String)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public abstract void onError();
|
||||
|
||||
/**
|
||||
* Called when the detection fails due to an error occurs in the
|
||||
* {@link com.android.server.soundtrigger.SoundTriggerService} and
|
||||
* {@link com.android.server.soundtrigger_middleware.SoundTriggerMiddlewareService},
|
||||
* {@link SoundTriggerFailure} will be reported to the detector.
|
||||
*
|
||||
* @param soundTriggerFailure It provides the error code, error message and suggested
|
||||
* action.
|
||||
*/
|
||||
public void onFailure(@NonNull SoundTriggerFailure soundTriggerFailure) {
|
||||
onError();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public abstract void onRecognitionPaused();
|
||||
|
||||
@@ -1556,18 +1575,43 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
@Override
|
||||
public void onError(int status) {
|
||||
Slog.i(TAG, "onError: " + status);
|
||||
// This is a workaround before the sound trigger uses the onDetectionFailure method.
|
||||
Message.obtain(mHandler, MSG_DETECTION_ERROR,
|
||||
new SoundTriggerFailure(status, "Sound trigger error")).sendToTarget();
|
||||
// TODO(b/271534248): This is a workaround before the sound trigger uses the new error
|
||||
// method.
|
||||
Message.obtain(mHandler, MSG_DETECTION_SOUND_TRIGGER_FAILURE,
|
||||
new SoundTriggerFailure(SoundTriggerFailure.ERROR_CODE_UNKNOWN,
|
||||
"Sound trigger error")).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetectionFailure(DetectorFailure detectorFailure) {
|
||||
Slog.v(TAG, "onDetectionFailure detectorFailure: " + detectorFailure);
|
||||
Message.obtain(mHandler, MSG_DETECTION_ERROR,
|
||||
detectorFailure != null ? detectorFailure
|
||||
: new UnknownFailure("Error data is null")).sendToTarget();
|
||||
public void onHotwordDetectionServiceFailure(
|
||||
HotwordDetectionServiceFailure hotwordDetectionServiceFailure) {
|
||||
Slog.v(TAG, "onHotwordDetectionServiceFailure: " + hotwordDetectionServiceFailure);
|
||||
if (hotwordDetectionServiceFailure != null) {
|
||||
Message.obtain(mHandler, MSG_DETECTION_HOTWORD_DETECTION_SERVICE_FAILURE,
|
||||
hotwordDetectionServiceFailure).sendToTarget();
|
||||
} else {
|
||||
Message.obtain(mHandler, MSG_DETECTION_UNKNOWN_FAILURE,
|
||||
"Error data is null").sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVisualQueryDetectionServiceFailure(
|
||||
VisualQueryDetectionServiceFailure visualQueryDetectionServiceFailure)
|
||||
throws RemoteException {
|
||||
// It should never be called here.
|
||||
Slog.w(TAG,
|
||||
"onVisualQueryDetectionServiceFailure: " + visualQueryDetectionServiceFailure);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnknownFailure(String errorMessage) throws RemoteException {
|
||||
Slog.v(TAG, "onUnknownFailure: " + errorMessage);
|
||||
Message.obtain(mHandler, MSG_DETECTION_UNKNOWN_FAILURE,
|
||||
!TextUtils.isEmpty(errorMessage) ? errorMessage
|
||||
: "Error data is null").sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecognitionPaused() {
|
||||
Slog.i(TAG, "onRecognitionPaused");
|
||||
@@ -1600,7 +1644,7 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
}
|
||||
|
||||
void onDetectorRemoteException() {
|
||||
Message.obtain(mHandler, MSG_DETECTION_ERROR,
|
||||
Message.obtain(mHandler, MSG_DETECTION_HOTWORD_DETECTION_SERVICE_FAILURE,
|
||||
new HotwordDetectionServiceFailure(
|
||||
HotwordDetectionServiceFailure.ERROR_CODE_REMOTE_EXCEPTION,
|
||||
"Detector remote exception occurs")).sendToTarget();
|
||||
@@ -1630,7 +1674,9 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
mExternalCallback.onDetected((EventPayload) message.obj);
|
||||
break;
|
||||
case MSG_DETECTION_ERROR:
|
||||
mExternalCallback.onFailure((DetectorFailure) message.obj);
|
||||
// TODO(b/271534248): After reverting the workaround, this logic is still
|
||||
// necessary.
|
||||
mExternalCallback.onError();
|
||||
break;
|
||||
case MSG_DETECTION_PAUSE:
|
||||
mExternalCallback.onRecognitionPaused();
|
||||
@@ -1647,6 +1693,15 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
case MSG_PROCESS_RESTARTED:
|
||||
mExternalCallback.onHotwordDetectionServiceRestarted();
|
||||
break;
|
||||
case MSG_DETECTION_HOTWORD_DETECTION_SERVICE_FAILURE:
|
||||
mExternalCallback.onFailure((HotwordDetectionServiceFailure) message.obj);
|
||||
break;
|
||||
case MSG_DETECTION_SOUND_TRIGGER_FAILURE:
|
||||
mExternalCallback.onFailure((SoundTriggerFailure) message.obj);
|
||||
break;
|
||||
case MSG_DETECTION_UNKNOWN_FAILURE:
|
||||
mExternalCallback.onUnknownFailure((String) message.obj);
|
||||
break;
|
||||
default:
|
||||
super.handleMessage(message);
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
@@ -1,218 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* <p>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<DetectorFailure> CREATOR =
|
||||
new Parcelable.Creator<DetectorFailure>() {
|
||||
@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);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
73
core/java/android/service/voice/FailureSuggestedAction.java
Normal file
73
core/java/android/service/voice/FailureSuggestedAction.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.SystemApi;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* This is used by the assistant application to know which action the application should take on a
|
||||
* failure callback. The detector can be a HotwordDector or a visual query detector.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public final class FailureSuggestedAction {
|
||||
|
||||
/**
|
||||
* A suggested action due to an unknown error occurs.
|
||||
*/
|
||||
public static final int 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 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.
|
||||
*/
|
||||
public static final int 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 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 RESTART_RECOGNITION = 4;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@IntDef({UNKNOWN, NONE, DISABLE_DETECTION, RECREATE_DETECTOR, RESTART_RECOGNITION})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface FailureSuggestedActionDef {}
|
||||
|
||||
private FailureSuggestedAction() {}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import android.annotation.SystemApi;
|
||||
import android.annotation.TestApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -36,7 +37,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public final class HotwordDetectionServiceFailure extends DetectorFailure {
|
||||
public final class HotwordDetectionServiceFailure implements Parcelable {
|
||||
|
||||
/**
|
||||
* An error code which means an unknown error occurs.
|
||||
@@ -94,12 +95,19 @@ public final class HotwordDetectionServiceFailure extends DetectorFailure {
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface HotwordDetectionServiceErrorCode {}
|
||||
|
||||
private int mErrorCode = ERROR_CODE_UNKNOWN;
|
||||
private String mErrorMessage = "Unknown";
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public HotwordDetectionServiceFailure(int errorCode, @NonNull String errorMessage) {
|
||||
super(ERROR_SOURCE_TYPE_HOTWORD_DETECTION, errorCode, errorMessage);
|
||||
if (TextUtils.isEmpty(errorMessage)) {
|
||||
throw new IllegalArgumentException("errorMessage is empty or null.");
|
||||
}
|
||||
mErrorCode = errorCode;
|
||||
mErrorMessage = errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,22 +115,33 @@ public final class HotwordDetectionServiceFailure extends DetectorFailure {
|
||||
*/
|
||||
@HotwordDetectionServiceErrorCode
|
||||
public int getErrorCode() {
|
||||
return super.getErrorCode();
|
||||
return mErrorCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Returns the error message.
|
||||
*/
|
||||
@NonNull
|
||||
public String getErrorMessage() {
|
||||
return mErrorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the suggested action.
|
||||
*/
|
||||
@FailureSuggestedAction.FailureSuggestedActionDef
|
||||
public int getSuggestedAction() {
|
||||
switch (getErrorCode()) {
|
||||
switch (mErrorCode) {
|
||||
case ERROR_CODE_BIND_FAILURE:
|
||||
case ERROR_CODE_BINDING_DIED:
|
||||
case ERROR_CODE_REMOTE_EXCEPTION:
|
||||
return SUGGESTED_ACTION_RECREATE_DETECTOR;
|
||||
return FailureSuggestedAction.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;
|
||||
return FailureSuggestedAction.RESTART_RECOGNITION;
|
||||
default:
|
||||
return SUGGESTED_ACTION_NONE;
|
||||
return FailureSuggestedAction.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +152,14 @@ public final class HotwordDetectionServiceFailure extends DetectorFailure {
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeInt(mErrorCode);
|
||||
dest.writeString8(mErrorMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "HotwordDetectionServiceFailure { errorCode = " + mErrorCode + ", errorMessage = "
|
||||
+ mErrorMessage + " }";
|
||||
}
|
||||
|
||||
public static final @NonNull Parcelable.Creator<HotwordDetectionServiceFailure> CREATOR =
|
||||
@@ -145,8 +171,7 @@ public final class HotwordDetectionServiceFailure extends DetectorFailure {
|
||||
|
||||
@Override
|
||||
public HotwordDetectionServiceFailure createFromParcel(@NonNull Parcel in) {
|
||||
DetectorFailure detectorFailure = DetectorFailure.CREATOR.createFromParcel(in);
|
||||
return (HotwordDetectionServiceFailure) detectorFailure;
|
||||
return new HotwordDetectionServiceFailure(in.readInt(), in.readString8());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -189,24 +189,34 @@ public interface HotwordDetector {
|
||||
/**
|
||||
* Called when the detection fails due to an error.
|
||||
*
|
||||
* @deprecated On Android 14 and above, implement {@link #onFailure(DetectorFailure)}
|
||||
* instead.
|
||||
* @deprecated On {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and above,
|
||||
* implement {@link HotwordDetector.Callback#onFailure(HotwordDetectionServiceFailure)},
|
||||
* {@link AlwaysOnHotwordDetector.Callback#onFailure(SoundTriggerFailure)},
|
||||
* {@link HotwordDetector.Callback#onUnknownFailure(String)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
void onError();
|
||||
|
||||
/**
|
||||
* Called when the detection fails due to an error, the subclasses of
|
||||
* {@link DetectorFailure} will be reported to the detector.
|
||||
* Called when the detection fails due to an error occurs in the
|
||||
* {@link HotwordDetectionService}, {@link HotwordDetectionServiceFailure} will be reported
|
||||
* to the detector.
|
||||
*
|
||||
* @see android.service.voice.HotwordDetectionServiceFailure
|
||||
* @see android.service.voice.SoundTriggerFailure
|
||||
* @see android.service.voice.UnknownFailure
|
||||
* @see android.service.voice.VisualQueryDetectionServiceFailure
|
||||
*
|
||||
* @param detectorFailure It provides the error code, error message and suggested action.
|
||||
* @param hotwordDetectionServiceFailure It provides the error code, error message and
|
||||
* suggested action.
|
||||
*/
|
||||
default void onFailure(@NonNull DetectorFailure detectorFailure) {
|
||||
default void onFailure(
|
||||
@NonNull HotwordDetectionServiceFailure hotwordDetectionServiceFailure) {
|
||||
onError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the detection fails due to an unknown error occurs, an error message
|
||||
* will be reported to the detector.
|
||||
*
|
||||
* @param errorMessage It provides the error message.
|
||||
*/
|
||||
default void onUnknownFailure(@NonNull String errorMessage) {
|
||||
onError();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
package android.service.voice;
|
||||
|
||||
import android.media.AudioFormat;
|
||||
import android.service.voice.DetectorFailure;
|
||||
import android.service.voice.HotwordDetectedResult;
|
||||
import android.service.voice.HotwordDetectionServiceFailure;
|
||||
import android.service.voice.HotwordRejectedResult;
|
||||
|
||||
/**
|
||||
@@ -39,7 +39,8 @@ oneway interface IMicrophoneHotwordDetectionVoiceInteractionCallback {
|
||||
/**
|
||||
* Called when the detection fails due to an error.
|
||||
*/
|
||||
void onError(in DetectorFailure detectorFailure);
|
||||
void onHotwordDetectionServiceFailure(
|
||||
in HotwordDetectionServiceFailure hotwordDetectionServiceFailure);
|
||||
|
||||
/**
|
||||
* Called when the detected result was not detected.
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package android.service.voice;
|
||||
|
||||
import android.service.voice.DetectorFailure;
|
||||
import android.service.voice.VisualQueryDetectionServiceFailure;
|
||||
|
||||
/**
|
||||
* Callback for returning the detected result from the VisualQueryDetectionService.
|
||||
@@ -43,5 +43,6 @@ oneway interface IVisualQueryDetectionVoiceInteractionCallback {
|
||||
/**
|
||||
* Called when the detection fails due to an error.
|
||||
*/
|
||||
void onDetectionFailure(in DetectorFailure detectorFailure);
|
||||
void onVisualQueryDetectionServiceFailure(
|
||||
in VisualQueryDetectionServiceFailure visualQueryDetectionServiceFailure);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.os.ParcelFileDescriptor;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SharedMemory;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
|
||||
@@ -176,11 +177,16 @@ class SoftwareHotwordDetector extends AbstractDetector {
|
||||
|
||||
/** Called when the detection fails due to an error. */
|
||||
@Override
|
||||
public void onError(DetectorFailure detectorFailure) {
|
||||
Slog.v(TAG, "BinderCallback#onError detectorFailure: " + detectorFailure);
|
||||
public void onHotwordDetectionServiceFailure(
|
||||
HotwordDetectionServiceFailure hotwordDetectionServiceFailure) {
|
||||
Slog.v(TAG, "BinderCallback#onHotwordDetectionServiceFailure:"
|
||||
+ hotwordDetectionServiceFailure);
|
||||
Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> {
|
||||
mCallback.onFailure(detectorFailure != null ? detectorFailure
|
||||
: new UnknownFailure("Error data is null"));
|
||||
if (hotwordDetectionServiceFailure != null) {
|
||||
mCallback.onFailure(hotwordDetectionServiceFailure);
|
||||
} else {
|
||||
mCallback.onUnknownFailure("Error data is null");
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -236,11 +242,34 @@ class SoftwareHotwordDetector extends AbstractDetector {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetectionFailure(DetectorFailure detectorFailure) throws RemoteException {
|
||||
Slog.v(TAG, "onDetectionFailure detectorFailure: " + detectorFailure);
|
||||
public void onHotwordDetectionServiceFailure(
|
||||
HotwordDetectionServiceFailure hotwordDetectionServiceFailure)
|
||||
throws RemoteException {
|
||||
Slog.v(TAG, "onHotwordDetectionServiceFailure: " + hotwordDetectionServiceFailure);
|
||||
Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> {
|
||||
mCallback.onFailure(detectorFailure != null ? detectorFailure
|
||||
: new UnknownFailure("Error data is null"));
|
||||
if (hotwordDetectionServiceFailure != null) {
|
||||
mCallback.onFailure(hotwordDetectionServiceFailure);
|
||||
} else {
|
||||
mCallback.onUnknownFailure("Error data is null");
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVisualQueryDetectionServiceFailure(
|
||||
VisualQueryDetectionServiceFailure visualQueryDetectionServiceFailure)
|
||||
throws RemoteException {
|
||||
// It should never be called here.
|
||||
Slog.w(TAG, "onVisualQueryDetectionServiceFailure: "
|
||||
+ visualQueryDetectionServiceFailure);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnknownFailure(String errorMessage) throws RemoteException {
|
||||
Slog.v(TAG, "onUnknownFailure: " + errorMessage);
|
||||
Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> {
|
||||
mCallback.onUnknownFailure(
|
||||
!TextUtils.isEmpty(errorMessage) ? errorMessage : "Error data is null");
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.annotation.SystemApi;
|
||||
import android.annotation.TestApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -35,7 +36,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public final class SoundTriggerFailure extends DetectorFailure {
|
||||
public final class SoundTriggerFailure implements Parcelable {
|
||||
|
||||
/**
|
||||
* An error code which means an unknown error occurs.
|
||||
@@ -72,12 +73,19 @@ public final class SoundTriggerFailure extends DetectorFailure {
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface SoundTriggerErrorCode {}
|
||||
|
||||
private int mErrorCode = ERROR_CODE_UNKNOWN;
|
||||
private String mErrorMessage = "Unknown";
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public SoundTriggerFailure(int errorCode, @NonNull String errorMessage) {
|
||||
super(ERROR_SOURCE_TYPE_SOUND_TRIGGER, errorCode, errorMessage);
|
||||
if (TextUtils.isEmpty(errorMessage)) {
|
||||
throw new IllegalArgumentException("errorMessage is empty or null.");
|
||||
}
|
||||
mErrorCode = errorCode;
|
||||
mErrorMessage = errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,19 +93,30 @@ public final class SoundTriggerFailure extends DetectorFailure {
|
||||
*/
|
||||
@SoundTriggerErrorCode
|
||||
public int getErrorCode() {
|
||||
return super.getErrorCode();
|
||||
return mErrorCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Returns the error message.
|
||||
*/
|
||||
@NonNull
|
||||
public String getErrorMessage() {
|
||||
return mErrorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the suggested action.
|
||||
*/
|
||||
@FailureSuggestedAction.FailureSuggestedActionDef
|
||||
public int getSuggestedAction() {
|
||||
switch (getErrorCode()) {
|
||||
switch (mErrorCode) {
|
||||
case ERROR_CODE_MODULE_DIED:
|
||||
case ERROR_CODE_UNEXPECTED_PREEMPTION:
|
||||
return SUGGESTED_ACTION_RECREATE_DETECTOR;
|
||||
return FailureSuggestedAction.RECREATE_DETECTOR;
|
||||
case ERROR_CODE_RECOGNITION_RESUME_FAILED:
|
||||
return SUGGESTED_ACTION_RESTART_RECOGNITION;
|
||||
return FailureSuggestedAction.RESTART_RECOGNITION;
|
||||
default:
|
||||
return SUGGESTED_ACTION_NONE;
|
||||
return FailureSuggestedAction.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +127,14 @@ public final class SoundTriggerFailure extends DetectorFailure {
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeInt(mErrorCode);
|
||||
dest.writeString8(mErrorMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SoundTriggerFailure { errorCode = " + mErrorCode + ", errorMessage = "
|
||||
+ mErrorMessage + " }";
|
||||
}
|
||||
|
||||
public static final @NonNull Parcelable.Creator<SoundTriggerFailure> CREATOR =
|
||||
@@ -120,7 +146,7 @@ public final class SoundTriggerFailure extends DetectorFailure {
|
||||
|
||||
@Override
|
||||
public SoundTriggerFailure createFromParcel(@NonNull Parcel in) {
|
||||
return (SoundTriggerFailure) DetectorFailure.CREATOR.createFromParcel(in);
|
||||
return new SoundTriggerFailure(in.readInt(), in.readString8());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* 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<UnknownFailure> CREATOR =
|
||||
new Parcelable.Creator<UnknownFailure>() {
|
||||
@Override
|
||||
public UnknownFailure[] newArray(int size) {
|
||||
return new UnknownFailure[size];
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnknownFailure createFromParcel(@NonNull Parcel in) {
|
||||
return (UnknownFailure) DetectorFailure.CREATOR.createFromParcel(in);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import android.annotation.SystemApi;
|
||||
import android.annotation.TestApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -33,7 +34,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public final class VisualQueryDetectionServiceFailure extends DetectorFailure {
|
||||
public final class VisualQueryDetectionServiceFailure implements Parcelable {
|
||||
|
||||
/**
|
||||
* An error code which means an unknown error occurs.
|
||||
@@ -79,12 +80,19 @@ public final class VisualQueryDetectionServiceFailure extends DetectorFailure {
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface VisualQueryDetectionServiceErrorCode {}
|
||||
|
||||
private int mErrorCode = ERROR_CODE_UNKNOWN;
|
||||
private String mErrorMessage = "Unknown";
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public VisualQueryDetectionServiceFailure(int errorCode, @NonNull String errorMessage) {
|
||||
super(ERROR_SOURCE_TYPE_VISUAL_QUERY_DETECTION, errorCode, errorMessage);
|
||||
if (TextUtils.isEmpty(errorMessage)) {
|
||||
throw new IllegalArgumentException("errorMessage is empty or null.");
|
||||
}
|
||||
mErrorCode = errorCode;
|
||||
mErrorMessage = errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,21 +100,32 @@ public final class VisualQueryDetectionServiceFailure extends DetectorFailure {
|
||||
*/
|
||||
@VisualQueryDetectionServiceErrorCode
|
||||
public int getErrorCode() {
|
||||
return super.getErrorCode();
|
||||
return mErrorCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Returns the error message.
|
||||
*/
|
||||
@NonNull
|
||||
public String getErrorMessage() {
|
||||
return mErrorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the suggested action.
|
||||
*/
|
||||
@FailureSuggestedAction.FailureSuggestedActionDef
|
||||
public int getSuggestedAction() {
|
||||
switch (getErrorCode()) {
|
||||
switch (mErrorCode) {
|
||||
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;
|
||||
return FailureSuggestedAction.RECREATE_DETECTOR;
|
||||
case ERROR_CODE_ILLEGAL_STREAMING_STATE:
|
||||
return SUGGESTED_ACTION_RESTART_RECOGNITION;
|
||||
return FailureSuggestedAction.RESTART_RECOGNITION;
|
||||
default:
|
||||
return SUGGESTED_ACTION_NONE;
|
||||
return FailureSuggestedAction.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +136,14 @@ public final class VisualQueryDetectionServiceFailure extends DetectorFailure {
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeInt(mErrorCode);
|
||||
dest.writeString8(mErrorMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VisualQueryDetectionServiceFailure { errorCode = " + mErrorCode
|
||||
+ ", errorMessage = " + mErrorMessage + " }";
|
||||
}
|
||||
|
||||
public static final @NonNull Parcelable.Creator<VisualQueryDetectionServiceFailure> CREATOR =
|
||||
@@ -129,8 +155,7 @@ public final class VisualQueryDetectionServiceFailure extends DetectorFailure {
|
||||
|
||||
@Override
|
||||
public VisualQueryDetectionServiceFailure createFromParcel(@NonNull Parcel in) {
|
||||
DetectorFailure detectorFailure = DetectorFailure.CREATOR.createFromParcel(in);
|
||||
return (VisualQueryDetectionServiceFailure) detectorFailure;
|
||||
return new VisualQueryDetectionServiceFailure(in.readInt(), in.readString8());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import android.os.ParcelFileDescriptor;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SharedMemory;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.app.IHotwordRecognitionStatusCallback;
|
||||
@@ -216,9 +217,23 @@ public class VisualQueryDetector {
|
||||
void onVisualQueryDetectionServiceRestarted();
|
||||
|
||||
/**
|
||||
* Called when the detection fails due to an error.
|
||||
* Called when the detection fails due to an error occurs in the
|
||||
* {@link VisualQueryDetectionService}, {@link VisualQueryDetectionServiceFailure} will be
|
||||
* reported to the detector.
|
||||
*
|
||||
* @param visualQueryDetectionServiceFailure It provides the error code, error message and
|
||||
* suggested action.
|
||||
*/
|
||||
void onFailure(@NonNull DetectorFailure detectorFailure);
|
||||
void onFailure(
|
||||
@NonNull VisualQueryDetectionServiceFailure visualQueryDetectionServiceFailure);
|
||||
|
||||
/**
|
||||
* Called when the detection fails due to an unknown error occurs, an error message
|
||||
* will be reported to the detector.
|
||||
*
|
||||
* @param errorMessage It provides the error message.
|
||||
*/
|
||||
void onUnknownFailure(@NonNull String errorMessage);
|
||||
}
|
||||
|
||||
private class VisualQueryDetectorInitializationDelegate extends AbstractDetector {
|
||||
@@ -295,10 +310,17 @@ public class VisualQueryDetector {
|
||||
|
||||
/** Called when the detection fails due to an error. */
|
||||
@Override
|
||||
public void onDetectionFailure(DetectorFailure detectorFailure) {
|
||||
Slog.v(TAG, "BinderCallback#onDetectionFailure");
|
||||
Binder.withCleanCallingIdentity(() -> mExecutor.execute(
|
||||
() -> mCallback.onFailure(detectorFailure)));
|
||||
public void onVisualQueryDetectionServiceFailure(
|
||||
VisualQueryDetectionServiceFailure visualQueryDetectionServiceFailure) {
|
||||
Slog.v(TAG, "BinderCallback#onVisualQueryDetectionServiceFailure: "
|
||||
+ visualQueryDetectionServiceFailure);
|
||||
Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> {
|
||||
if (visualQueryDetectionServiceFailure != null) {
|
||||
mCallback.onFailure(visualQueryDetectionServiceFailure);
|
||||
} else {
|
||||
mCallback.onUnknownFailure("Error data is null");
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,7 +397,35 @@ public class VisualQueryDetector {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetectionFailure(DetectorFailure detectorFailure) throws RemoteException {
|
||||
public void onHotwordDetectionServiceFailure(
|
||||
HotwordDetectionServiceFailure hotwordDetectionServiceFailure)
|
||||
throws RemoteException {
|
||||
// It should never be called here.
|
||||
Slog.w(TAG, "onHotwordDetectionServiceFailure: " + hotwordDetectionServiceFailure);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVisualQueryDetectionServiceFailure(
|
||||
VisualQueryDetectionServiceFailure visualQueryDetectionServiceFailure)
|
||||
throws RemoteException {
|
||||
Slog.v(TAG, "onVisualQueryDetectionServiceFailure: "
|
||||
+ visualQueryDetectionServiceFailure);
|
||||
Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> {
|
||||
if (visualQueryDetectionServiceFailure != null) {
|
||||
mCallback.onFailure(visualQueryDetectionServiceFailure);
|
||||
} else {
|
||||
mCallback.onUnknownFailure("Error data is null");
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnknownFailure(String errorMessage) throws RemoteException {
|
||||
Slog.v(TAG, "onUnknownFailure: " + errorMessage);
|
||||
Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> {
|
||||
mCallback.onUnknownFailure(
|
||||
!TextUtils.isEmpty(errorMessage) ? errorMessage : "Error data is null");
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
package com.android.internal.app;
|
||||
|
||||
import android.hardware.soundtrigger.SoundTrigger;
|
||||
import android.service.voice.DetectorFailure;
|
||||
import android.service.voice.HotwordDetectedResult;
|
||||
import android.service.voice.HotwordDetectionServiceFailure;
|
||||
import android.service.voice.HotwordRejectedResult;
|
||||
import android.service.voice.VisualQueryDetectionServiceFailure;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
@@ -63,11 +64,31 @@ oneway interface IHotwordRecognitionStatusCallback {
|
||||
void onError(int status);
|
||||
|
||||
/**
|
||||
* Called when the detection fails due to an error.
|
||||
* Called when the detection fails due to an error occurs in the
|
||||
* {@link HotwordDetectionService}.
|
||||
*
|
||||
* @param detectorFailure It provides the error code, error message and suggested action.
|
||||
* @param hotwordDetectionServiceFailure It provides the error code, error message and
|
||||
* suggested action.
|
||||
*/
|
||||
void onDetectionFailure(in DetectorFailure detectorFailure);
|
||||
void onHotwordDetectionServiceFailure(
|
||||
in HotwordDetectionServiceFailure hotwordDetectionServiceFailure);
|
||||
|
||||
/**
|
||||
* Called when the detection fails due to an error occurs in the
|
||||
* {@link VisualQueryDetectionService}.
|
||||
*
|
||||
* @param visualQueryDetectionServiceFailure It provides the error code, error message and
|
||||
* suggested action.
|
||||
*/
|
||||
void onVisualQueryDetectionServiceFailure(
|
||||
in VisualQueryDetectionServiceFailure visualQueryDetectionServiceFailure);
|
||||
|
||||
/**
|
||||
* Called when the detection fails due to an unknown error occurs.
|
||||
*
|
||||
* @param errorMessage It provides the error message.
|
||||
*/
|
||||
void onUnknownFailure(in String errorMessage);
|
||||
|
||||
/**
|
||||
* Called when the recognition is paused temporarily for some reason.
|
||||
|
||||
@@ -26,6 +26,7 @@ import static android.service.voice.HotwordDetectionService.ENABLE_PROXIMITY_RES
|
||||
import static android.service.voice.HotwordDetectionService.INITIALIZATION_STATUS_SUCCESS;
|
||||
import static android.service.voice.HotwordDetectionService.INITIALIZATION_STATUS_UNKNOWN;
|
||||
import static android.service.voice.HotwordDetectionService.KEY_INITIALIZATION_STATUS;
|
||||
import static android.service.voice.HotwordDetectionServiceFailure.ERROR_CODE_COPY_AUDIO_DATA_FAILURE;
|
||||
|
||||
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_ERROR;
|
||||
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_SUCCESS;
|
||||
@@ -68,7 +69,6 @@ import android.os.ParcelFileDescriptor;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SharedMemory;
|
||||
import android.service.voice.DetectorFailure;
|
||||
import android.service.voice.HotwordDetectedResult;
|
||||
import android.service.voice.HotwordDetectionService;
|
||||
import android.service.voice.HotwordDetectionServiceFailure;
|
||||
@@ -76,6 +76,7 @@ import android.service.voice.HotwordDetector;
|
||||
import android.service.voice.HotwordRejectedResult;
|
||||
import android.service.voice.IDspHotwordDetectionCallback;
|
||||
import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback;
|
||||
import android.service.voice.VisualQueryDetectionServiceFailure;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Pair;
|
||||
import android.util.Slog;
|
||||
@@ -124,17 +125,12 @@ abstract class DetectorSession {
|
||||
private static final String HOTWORD_DETECTION_OP_MESSAGE =
|
||||
"Providing hotword detection result to VoiceInteractionService";
|
||||
|
||||
// The error codes are used for onError callback
|
||||
static final int HOTWORD_DETECTION_SERVICE_DIED =
|
||||
HotwordDetectionServiceFailure.ERROR_CODE_BINDING_DIED;
|
||||
static final int CALLBACK_ONDETECTED_GOT_SECURITY_EXCEPTION =
|
||||
// The error codes are used for onHotwordDetectionServiceFailure callback.
|
||||
// Define these due to lines longer than 100 characters.
|
||||
static final int ONDETECTED_GOT_SECURITY_EXCEPTION =
|
||||
HotwordDetectionServiceFailure.ERROR_CODE_ON_DETECTED_SECURITY_EXCEPTION;
|
||||
static final int CALLBACK_DETECT_TIMEOUT =
|
||||
HotwordDetectionServiceFailure.ERROR_CODE_DETECT_TIMEOUT;
|
||||
static final int CALLBACK_ONDETECTED_STREAM_COPY_ERROR =
|
||||
static final int ONDETECTED_STREAM_COPY_ERROR =
|
||||
HotwordDetectionServiceFailure.ERROR_CODE_ON_DETECTED_STREAM_COPY_FAILURE;
|
||||
static final int CALLBACK_COPY_AUDIO_DATA_FAILURE =
|
||||
HotwordDetectionServiceFailure.ERROR_CODE_COPY_AUDIO_DATA_FAILURE;
|
||||
|
||||
// TODO: These constants need to be refined.
|
||||
private static final long MAX_UPDATE_TIMEOUT_MILLIS = 30000;
|
||||
@@ -449,11 +445,11 @@ abstract class DetectorSession {
|
||||
Slog.w(TAG, "Failed supplying audio data to validator", e);
|
||||
|
||||
try {
|
||||
callback.onError(
|
||||
new HotwordDetectionServiceFailure(CALLBACK_COPY_AUDIO_DATA_FAILURE,
|
||||
callback.onHotwordDetectionServiceFailure(
|
||||
new HotwordDetectionServiceFailure(ERROR_CODE_COPY_AUDIO_DATA_FAILURE,
|
||||
"Copy audio data failure for external source detection."));
|
||||
} catch (RemoteException ex) {
|
||||
Slog.w(TAG, "Failed to report onError status: " + ex);
|
||||
Slog.w(TAG, "Failed to report onHotwordDetectionServiceFailure status: " + ex);
|
||||
if (getDetectorType() != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) {
|
||||
HotwordMetricsLogger.writeDetectorEvent(getDetectorType(),
|
||||
HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_ERROR_EXCEPTION,
|
||||
@@ -538,10 +534,11 @@ abstract class DetectorSession {
|
||||
EXTERNAL_SOURCE_DETECT_SECURITY_EXCEPTION,
|
||||
mVoiceInteractionServiceUid);
|
||||
try {
|
||||
callback.onError(new HotwordDetectionServiceFailure(
|
||||
CALLBACK_ONDETECTED_GOT_SECURITY_EXCEPTION,
|
||||
"Security exception occurs in #onDetected"
|
||||
+ " method."));
|
||||
callback.onHotwordDetectionServiceFailure(
|
||||
new HotwordDetectionServiceFailure(
|
||||
ONDETECTED_GOT_SECURITY_EXCEPTION,
|
||||
"Security exception occurs in "
|
||||
+ "#onDetected method"));
|
||||
} catch (RemoteException e1) {
|
||||
notifyOnDetectorRemoteException();
|
||||
throw e1;
|
||||
@@ -557,9 +554,10 @@ abstract class DetectorSession {
|
||||
+ "IOException", e);
|
||||
// TODO: Write event
|
||||
try {
|
||||
callback.onError(new HotwordDetectionServiceFailure(
|
||||
CALLBACK_ONDETECTED_STREAM_COPY_ERROR,
|
||||
"Copy audio stream failure."));
|
||||
callback.onHotwordDetectionServiceFailure(
|
||||
new HotwordDetectionServiceFailure(
|
||||
ONDETECTED_STREAM_COPY_ERROR,
|
||||
"Copy audio stream failure."));
|
||||
} catch (RemoteException e1) {
|
||||
notifyOnDetectorRemoteException();
|
||||
throw e1;
|
||||
@@ -624,17 +622,40 @@ abstract class DetectorSession {
|
||||
mRemoteDetectionService = remoteDetectionService;
|
||||
}
|
||||
|
||||
void reportErrorLocked(@NonNull DetectorFailure detectorFailure) {
|
||||
private void reportErrorGetRemoteException() {
|
||||
if (getDetectorType() != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) {
|
||||
HotwordMetricsLogger.writeDetectorEvent(getDetectorType(),
|
||||
HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_ERROR_EXCEPTION,
|
||||
mVoiceInteractionServiceUid);
|
||||
}
|
||||
notifyOnDetectorRemoteException();
|
||||
}
|
||||
|
||||
void reportErrorLocked(@NonNull HotwordDetectionServiceFailure hotwordDetectionServiceFailure) {
|
||||
try {
|
||||
mCallback.onDetectionFailure(detectorFailure);
|
||||
mCallback.onHotwordDetectionServiceFailure(hotwordDetectionServiceFailure);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Failed to report onError status: " + e);
|
||||
if (getDetectorType() != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) {
|
||||
HotwordMetricsLogger.writeDetectorEvent(getDetectorType(),
|
||||
HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_ERROR_EXCEPTION,
|
||||
mVoiceInteractionServiceUid);
|
||||
}
|
||||
notifyOnDetectorRemoteException();
|
||||
Slog.w(TAG, "Failed to call onHotwordDetectionServiceFailure: " + e);
|
||||
reportErrorGetRemoteException();
|
||||
}
|
||||
}
|
||||
|
||||
void reportErrorLocked(
|
||||
@NonNull VisualQueryDetectionServiceFailure visualQueryDetectionServiceFailure) {
|
||||
try {
|
||||
mCallback.onVisualQueryDetectionServiceFailure(visualQueryDetectionServiceFailure);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Failed to call onVisualQueryDetectionServiceFailure: " + e);
|
||||
reportErrorGetRemoteException();
|
||||
}
|
||||
}
|
||||
|
||||
void reportErrorLocked(@NonNull String errorMessage) {
|
||||
try {
|
||||
mCallback.onUnknownFailure(errorMessage);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Failed to call onUnknownFailure: " + e);
|
||||
reportErrorGetRemoteException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
package com.android.server.voiceinteraction;
|
||||
|
||||
import static android.service.voice.HotwordDetectionServiceFailure.ERROR_CODE_DETECT_TIMEOUT;
|
||||
import static android.service.voice.HotwordDetectionServiceFailure.ERROR_CODE_ON_DETECTED_SECURITY_EXCEPTION;
|
||||
import static android.service.voice.HotwordDetectionServiceFailure.ERROR_CODE_ON_DETECTED_STREAM_COPY_FAILURE;
|
||||
|
||||
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_DETECTED_EXCEPTION;
|
||||
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_ERROR_EXCEPTION;
|
||||
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_PROCESS_RESTARTED_EXCEPTION;
|
||||
@@ -135,9 +139,10 @@ final class DspTrustedHotwordDetectorSession extends DetectorSession {
|
||||
METRICS_KEYPHRASE_TRIGGERED_DETECT_SECURITY_EXCEPTION,
|
||||
mVoiceInteractionServiceUid);
|
||||
try {
|
||||
externalCallback.onDetectionFailure(new HotwordDetectionServiceFailure(
|
||||
CALLBACK_ONDETECTED_GOT_SECURITY_EXCEPTION,
|
||||
"Security exception occurs in #onDetected method."));
|
||||
externalCallback.onHotwordDetectionServiceFailure(
|
||||
new HotwordDetectionServiceFailure(
|
||||
ERROR_CODE_ON_DETECTED_SECURITY_EXCEPTION,
|
||||
"Security exception occurs in #onDetected method."));
|
||||
} catch (RemoteException e1) {
|
||||
notifyOnDetectorRemoteException();
|
||||
HotwordMetricsLogger.writeDetectorEvent(
|
||||
@@ -155,9 +160,10 @@ final class DspTrustedHotwordDetectorSession extends DetectorSession {
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
Slog.w(TAG, "Ignoring #onDetected due to a IOException", e);
|
||||
externalCallback.onDetectionFailure(new HotwordDetectionServiceFailure(
|
||||
CALLBACK_ONDETECTED_STREAM_COPY_ERROR,
|
||||
"Copy audio stream failure."));
|
||||
externalCallback.onHotwordDetectionServiceFailure(
|
||||
new HotwordDetectionServiceFailure(
|
||||
ERROR_CODE_ON_DETECTED_STREAM_COPY_FAILURE,
|
||||
"Copy audio stream failure."));
|
||||
} catch (RemoteException e1) {
|
||||
notifyOnDetectorRemoteException();
|
||||
throw e1;
|
||||
@@ -242,8 +248,8 @@ final class DspTrustedHotwordDetectorSession extends DetectorSession {
|
||||
HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_TIMEOUT,
|
||||
mVoiceInteractionServiceUid);
|
||||
try {
|
||||
externalCallback.onDetectionFailure(
|
||||
new HotwordDetectionServiceFailure(CALLBACK_DETECT_TIMEOUT,
|
||||
externalCallback.onHotwordDetectionServiceFailure(
|
||||
new HotwordDetectionServiceFailure(ERROR_CODE_DETECT_TIMEOUT,
|
||||
"Timeout to response to the detection result."));
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Failed to report onError status: ", e);
|
||||
|
||||
@@ -56,7 +56,6 @@ import android.service.voice.HotwordDetector;
|
||||
import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback;
|
||||
import android.service.voice.ISandboxedDetectionService;
|
||||
import android.service.voice.IVisualQueryDetectionVoiceInteractionCallback;
|
||||
import android.service.voice.UnknownFailure;
|
||||
import android.service.voice.VisualQueryDetectionService;
|
||||
import android.service.voice.VisualQueryDetectionServiceFailure;
|
||||
import android.service.voice.VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity;
|
||||
@@ -786,8 +785,8 @@ final class HotwordDetectionConnection {
|
||||
VisualQueryDetectionServiceFailure.ERROR_CODE_BINDING_DIED,
|
||||
"Detection service is dead."));
|
||||
} else {
|
||||
detectorSession.reportErrorLocked(new UnknownFailure(
|
||||
"Detection service is dead with unknown detection service type."));
|
||||
detectorSession.reportErrorLocked(
|
||||
"Detection service is dead with unknown detection service type.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -804,8 +803,8 @@ final class HotwordDetectionConnection {
|
||||
VisualQueryDetectionServiceFailure.ERROR_CODE_BIND_FAILURE,
|
||||
"Bind detection service failure."));
|
||||
} else {
|
||||
detectorSession.reportErrorLocked(new UnknownFailure(
|
||||
"Bind detection service failure with unknown detection service type."));
|
||||
detectorSession.reportErrorLocked(
|
||||
"Bind detection service failure with unknown detection service type.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package com.android.server.voiceinteraction;
|
||||
|
||||
import static android.service.voice.HotwordDetectionService.AUDIO_SOURCE_MICROPHONE;
|
||||
import static android.service.voice.HotwordDetectionServiceFailure.ERROR_CODE_ON_DETECTED_SECURITY_EXCEPTION;
|
||||
import static android.service.voice.HotwordDetectionServiceFailure.ERROR_CODE_ON_DETECTED_STREAM_COPY_FAILURE;
|
||||
|
||||
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_DETECTED_EXCEPTION;
|
||||
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_ERROR_EXCEPTION;
|
||||
@@ -128,9 +130,10 @@ final class SoftwareTrustedHotwordDetectorSession extends DetectorSession {
|
||||
METRICS_KEYPHRASE_TRIGGERED_DETECT_SECURITY_EXCEPTION,
|
||||
mVoiceInteractionServiceUid);
|
||||
try {
|
||||
mSoftwareCallback.onError(new HotwordDetectionServiceFailure(
|
||||
CALLBACK_ONDETECTED_GOT_SECURITY_EXCEPTION,
|
||||
"Security exception occurs in #onDetected method."));
|
||||
mSoftwareCallback.onHotwordDetectionServiceFailure(
|
||||
new HotwordDetectionServiceFailure(
|
||||
ERROR_CODE_ON_DETECTED_SECURITY_EXCEPTION,
|
||||
"Security exception occurs in #onDetected method."));
|
||||
} catch (RemoteException e1) {
|
||||
notifyOnDetectorRemoteException();
|
||||
HotwordMetricsLogger.writeDetectorEvent(
|
||||
@@ -149,9 +152,10 @@ final class SoftwareTrustedHotwordDetectorSession extends DetectorSession {
|
||||
Slog.w(TAG, "Ignoring #onDetected due to a IOException", e);
|
||||
// TODO: Write event
|
||||
try {
|
||||
mSoftwareCallback.onError(new HotwordDetectionServiceFailure(
|
||||
CALLBACK_ONDETECTED_STREAM_COPY_ERROR,
|
||||
"Copy audio stream failure."));
|
||||
mSoftwareCallback.onHotwordDetectionServiceFailure(
|
||||
new HotwordDetectionServiceFailure(
|
||||
ERROR_CODE_ON_DETECTED_STREAM_COPY_FAILURE,
|
||||
"Copy audio stream failure."));
|
||||
} catch (RemoteException e1) {
|
||||
notifyOnDetectorRemoteException();
|
||||
HotwordMetricsLogger.writeDetectorEvent(
|
||||
|
||||
@@ -110,11 +110,12 @@ final class VisualQueryDetectorSession extends DetectorSession {
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Error delivering attention gained event.", e);
|
||||
try {
|
||||
callback.onDetectionFailure(new VisualQueryDetectionServiceFailure(
|
||||
ERROR_CODE_ILLEGAL_ATTENTION_STATE,
|
||||
"Attention listener failed to switch to GAINED state."));
|
||||
callback.onVisualQueryDetectionServiceFailure(
|
||||
new VisualQueryDetectionServiceFailure(
|
||||
ERROR_CODE_ILLEGAL_ATTENTION_STATE,
|
||||
"Attention listener failed to switch to GAINED state."));
|
||||
} catch (RemoteException ex) {
|
||||
Slog.v(TAG, "Fail to call onDetectionFailure");
|
||||
Slog.v(TAG, "Fail to call onVisualQueryDetectionServiceFailure");
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -132,11 +133,12 @@ final class VisualQueryDetectorSession extends DetectorSession {
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Error delivering attention lost event.", e);
|
||||
try {
|
||||
callback.onDetectionFailure(new VisualQueryDetectionServiceFailure(
|
||||
ERROR_CODE_ILLEGAL_ATTENTION_STATE,
|
||||
"Attention listener failed to switch to LOST state."));
|
||||
callback.onVisualQueryDetectionServiceFailure(
|
||||
new VisualQueryDetectionServiceFailure(
|
||||
ERROR_CODE_ILLEGAL_ATTENTION_STATE,
|
||||
"Attention listener failed to switch to LOST state."));
|
||||
} catch (RemoteException ex) {
|
||||
Slog.v(TAG, "Fail to call onDetectionFailure");
|
||||
Slog.v(TAG, "Fail to call onVisualQueryDetectionServiceFailure");
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -148,9 +150,10 @@ final class VisualQueryDetectorSession extends DetectorSession {
|
||||
Slog.v(TAG, "BinderCallback#onQueryDetected");
|
||||
if (!mEgressingData) {
|
||||
Slog.v(TAG, "Query should not be egressed within the unattention state.");
|
||||
callback.onDetectionFailure(new VisualQueryDetectionServiceFailure(
|
||||
ERROR_CODE_ILLEGAL_STREAMING_STATE,
|
||||
"Cannot stream queries without attention signals."));
|
||||
callback.onVisualQueryDetectionServiceFailure(
|
||||
new VisualQueryDetectionServiceFailure(
|
||||
ERROR_CODE_ILLEGAL_STREAMING_STATE,
|
||||
"Cannot stream queries without attention signals."));
|
||||
return;
|
||||
}
|
||||
mQueryStreaming = true;
|
||||
@@ -164,9 +167,10 @@ final class VisualQueryDetectorSession extends DetectorSession {
|
||||
if (!mQueryStreaming) {
|
||||
Slog.v(TAG, "Query streaming state signal FINISHED is block since there is"
|
||||
+ " no active query being streamed.");
|
||||
callback.onDetectionFailure(new VisualQueryDetectionServiceFailure(
|
||||
ERROR_CODE_ILLEGAL_STREAMING_STATE,
|
||||
"Cannot send FINISHED signal with no query streamed."));
|
||||
callback.onVisualQueryDetectionServiceFailure(
|
||||
new VisualQueryDetectionServiceFailure(
|
||||
ERROR_CODE_ILLEGAL_STREAMING_STATE,
|
||||
"Cannot send FINISHED signal with no query streamed."));
|
||||
return;
|
||||
}
|
||||
callback.onQueryFinished();
|
||||
@@ -179,9 +183,10 @@ final class VisualQueryDetectorSession extends DetectorSession {
|
||||
if (!mQueryStreaming) {
|
||||
Slog.v(TAG, "Query streaming state signal REJECTED is block since there is"
|
||||
+ " no active query being streamed.");
|
||||
callback.onDetectionFailure(new VisualQueryDetectionServiceFailure(
|
||||
ERROR_CODE_ILLEGAL_STREAMING_STATE,
|
||||
"Cannot send REJECTED signal with no query streamed."));
|
||||
callback.onVisualQueryDetectionServiceFailure(
|
||||
new VisualQueryDetectionServiceFailure(
|
||||
ERROR_CODE_ILLEGAL_STREAMING_STATE,
|
||||
"Cannot send REJECTED signal with no query streamed."));
|
||||
return;
|
||||
}
|
||||
callback.onQueryRejected();
|
||||
|
||||
Reference in New Issue
Block a user