From f79009a5d75404e25dedfc40646f98dc24393a44 Mon Sep 17 00:00:00 2001 From: lpeter Date: Tue, 11 May 2021 21:04:15 +0800 Subject: [PATCH] API review : use a range of numbers for OEM errors By API review feedback, it would be better to use a range of numbers for OEM errors instead of just defining CUSTOM_ERROR_1 / CUSTOM_ERROR_2 in HotwordDetectionService. Bug: 184962614 Test: atest CtsVoiceInteractionTestCases Test: atest CtsVoiceInteractionTestCases --instant Change-Id: Id1e3a29e37ef566a1d8e30c703b7f2c4ae138f82 --- core/api/system-current.txt | 3 +- .../voice/AlwaysOnHotwordDetector.java | 8 +-- .../voice/HotwordDetectionService.java | 51 ++++++++++--------- .../service/voice/HotwordDetector.java | 8 +-- .../HotwordDetectionConnection.java | 5 ++ 5 files changed, 44 insertions(+), 31 deletions(-) diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 96a23b2a25ec3..dc8aa5a46819f 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -10544,6 +10544,7 @@ package android.service.voice { public abstract class HotwordDetectionService extends android.app.Service { ctor public HotwordDetectionService(); + method public static int getMaxCustomInitializationStatus(); method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent); method @Deprecated public void onDetect(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, long, @NonNull android.service.voice.HotwordDetectionService.Callback); method public void onDetect(@NonNull android.service.voice.AlwaysOnHotwordDetector.EventPayload, long, @NonNull android.service.voice.HotwordDetectionService.Callback); @@ -10551,8 +10552,6 @@ package android.service.voice { method public void onDetect(@NonNull android.service.voice.HotwordDetectionService.Callback); method public void onDetect(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @Nullable android.os.PersistableBundle, @NonNull android.service.voice.HotwordDetectionService.Callback); method public void onUpdateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory, long, @Nullable java.util.function.IntConsumer); - field public static final int INITIALIZATION_STATUS_CUSTOM_ERROR_1 = 1; // 0x1 - field public static final int INITIALIZATION_STATUS_CUSTOM_ERROR_2 = 2; // 0x2 field public static final int INITIALIZATION_STATUS_SUCCESS = 0; // 0x0 field public static final int INITIALIZATION_STATUS_UNKNOWN = 100; // 0x64 field public static final String SERVICE_INTERFACE = "android.service.voice.HotwordDetectionService"; diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java index bacc6ec2227b1..4f324385b1d5a 100644 --- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java +++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java @@ -49,7 +49,6 @@ import android.os.ParcelFileDescriptor; import android.os.PersistableBundle; import android.os.RemoteException; import android.os.SharedMemory; -import android.service.voice.HotwordDetectionService.InitializationStatus; import android.util.Log; import android.util.Slog; @@ -531,9 +530,12 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector { * Called when the {@link HotwordDetectionService} is created by the system and given a * short amount of time to report it's initialization state. * - * @param status Info about initialization state of {@link HotwordDetectionService}. + * @param status Info about initialization state of {@link HotwordDetectionService}; the + * allowed values are {@link HotwordDetectionService#INITIALIZATION_STATUS_SUCCESS}, + * 1<->{@link HotwordDetectionService#getMaxCustomInitializationStatus()}, + * {@link HotwordDetectionService#INITIALIZATION_STATUS_UNKNOWN}. */ - public void onHotwordDetectionServiceInitialized(@InitializationStatus int status) { + public void onHotwordDetectionServiceInitialized(int status) { } /** diff --git a/core/java/android/service/voice/HotwordDetectionService.java b/core/java/android/service/voice/HotwordDetectionService.java index 473e7ae76cc98..f64905103f7cf 100644 --- a/core/java/android/service/voice/HotwordDetectionService.java +++ b/core/java/android/service/voice/HotwordDetectionService.java @@ -76,31 +76,18 @@ public abstract class HotwordDetectionService extends Service { /** @hide */ public static final String KEY_INITIALIZATION_STATUS = "initialization_status"; - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(flag = true, prefix = { "INITIALIZATION_STATUS_" }, value = { - INITIALIZATION_STATUS_SUCCESS, - INITIALIZATION_STATUS_CUSTOM_ERROR_1, - INITIALIZATION_STATUS_CUSTOM_ERROR_2, - INITIALIZATION_STATUS_UNKNOWN, - }) - public @interface InitializationStatus {} + /** + * The maximum number of initialization status for some application specific failed reasons. + * + * @hide + */ + public static final int MAXIMUM_NUMBER_OF_INITIALIZATION_STATUS_CUSTOM_ERROR = 2; /** * Indicates that the updated status is successful. */ public static final int INITIALIZATION_STATUS_SUCCESS = 0; - /** - * Indicates that the updated status is failure for some application specific reasons. - */ - public static final int INITIALIZATION_STATUS_CUSTOM_ERROR_1 = 1; - - /** - * Indicates that the updated status is failure for some application specific reasons. - */ - public static final int INITIALIZATION_STATUS_CUSTOM_ERROR_2 = 2; - /** * Indicates that the callback wasn’t invoked within the timeout. * This is used by system. @@ -226,6 +213,19 @@ public abstract class HotwordDetectionService extends Service { } } + /** + * Returns the maximum number of initialization status for some application specific failed + * reasons. + * + * Note: The value 0 is reserved for success. + * + * @hide + */ + @SystemApi + public static int getMaxCustomInitializationStatus() { + return MAXIMUM_NUMBER_OF_INITIALIZATION_STATUS_CUSTOM_ERROR; + } + /** * Called when the device hardware (such as a DSP) detected the hotword, to request second stage * validation before handing over the audio to the {@link AlwaysOnHotwordDetector}. @@ -296,9 +296,10 @@ public abstract class HotwordDetectionService extends Service { * such data to the trusted process. * @param callbackTimeoutMillis Timeout in milliseconds for the operation to invoke the * statusCallback. - * @param statusCallback Use this to return the updated result. This is non-null only when the - * {@link HotwordDetectionService} is being initialized; and it is null if the state is updated - * after that. + * @param statusCallback Use this to return the updated result; the allowed values are + * {@link #INITIALIZATION_STATUS_SUCCESS}, 1<->{@link #getMaxCustomInitializationStatus()}. + * This is non-null only when the {@link HotwordDetectionService} is being initialized; and it + * is null if the state is updated after that. * * @hide */ @@ -307,7 +308,7 @@ public abstract class HotwordDetectionService extends Service { @Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory, @DurationMillisLong long callbackTimeoutMillis, - @Nullable @InitializationStatus IntConsumer statusCallback) { + @Nullable IntConsumer statusCallback) { // TODO: Handle the unimplemented case by throwing? } @@ -387,6 +388,10 @@ public abstract class HotwordDetectionService extends Service { if (callback != null) { intConsumer = value -> { + if (value > getMaxCustomInitializationStatus()) { + throw new IllegalArgumentException( + "The initialization status is invalid for " + value); + } try { Bundle status = new Bundle(); status.putInt(KEY_INITIALIZATION_STATUS, value); diff --git a/core/java/android/service/voice/HotwordDetector.java b/core/java/android/service/voice/HotwordDetector.java index 2fb4dbc835edf..3464ae544c8d8 100644 --- a/core/java/android/service/voice/HotwordDetector.java +++ b/core/java/android/service/voice/HotwordDetector.java @@ -28,7 +28,6 @@ import android.media.AudioFormat; import android.os.ParcelFileDescriptor; import android.os.PersistableBundle; import android.os.SharedMemory; -import android.service.voice.HotwordDetectionService.InitializationStatus; /** * Basic functionality for hotword detectors. @@ -166,9 +165,12 @@ public interface HotwordDetector { * Called when the {@link HotwordDetectionService} is created by the system and given a * short amount of time to report it's initialization state. * - * @param status Info about initialization state of {@link HotwordDetectionService}. + * @param status Info about initialization state of {@link HotwordDetectionService}; the + * allowed values are {@link HotwordDetectionService#INITIALIZATION_STATUS_SUCCESS}, + * 1<->{@link HotwordDetectionService#getMaxCustomInitializationStatus()}, + * {@link HotwordDetectionService#INITIALIZATION_STATUS_UNKNOWN}. */ - void onHotwordDetectionServiceInitialized(@InitializationStatus int status); + void onHotwordDetectionServiceInitialized(int status); /** * Called with the {@link HotwordDetectionService} is restarted. diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java index d1bd159ee7ff5..71ef38040d98b 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java @@ -164,6 +164,11 @@ final class HotwordDetectionConnection { KEY_INITIALIZATION_STATUS, INITIALIZATION_STATUS_UNKNOWN) : INITIALIZATION_STATUS_UNKNOWN; + // Add the protection to avoid unexpected status + if (status > HotwordDetectionService.getMaxCustomInitializationStatus() + && status != INITIALIZATION_STATUS_UNKNOWN) { + status = INITIALIZATION_STATUS_UNKNOWN; + } callback.onStatusReported(status); } catch (RemoteException e) { Slog.w(TAG, "Failed to report initialization status: " + e);