summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorPeter Li <lpeter@google.com>2021-03-29 11:43:29 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2021-03-29 11:43:29 +0000
commit378b540fa1721fb63000715ceb225df407bbdb7c (patch)
tree267e6a06ec621de9ec83d904116a0fd09ec7dae3 /core/java/android
parentd4a142719ea698fb8b4908dc992f2d6ee8798a21 (diff)
parent6f2a2638105c2af9d8f8a215b0cd9e2ed257e2b5 (diff)
Merge "Add callback to report HotwordDetectionService status" into sc-dev
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/service/voice/AlwaysOnHotwordDetector.java52
-rw-r--r--core/java/android/service/voice/HotwordDetectionService.java74
-rw-r--r--core/java/android/service/voice/HotwordDetector.java9
-rw-r--r--core/java/android/service/voice/IHotwordDetectionService.aidl5
-rw-r--r--core/java/android/service/voice/SoftwareHotwordDetector.java2
5 files changed, 128 insertions, 14 deletions
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index 73e0da16e049..8ca0e7ccff37 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -48,6 +48,7 @@ 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.Slog;
import com.android.internal.app.IHotwordRecognitionStatusCallback;
@@ -260,6 +261,7 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector {
private static final int MSG_DETECTION_PAUSE = 4;
private static final int MSG_DETECTION_RESUME = 5;
private static final int MSG_HOTWORD_REJECTED = 6;
+ private static final int MSG_HOTWORD_STATUS_REPORTED = 7;
private final String mText;
private final Locale mLocale;
@@ -523,6 +525,15 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector {
*/
public void onRejected(@Nullable HotwordRejectedResult result) {
}
+
+ /**
+ * 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}.
+ */
+ public void onHotwordDetectionServiceInitialized(@InitializationStatus int status) {
+ }
}
/**
@@ -559,7 +570,7 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector {
mTargetSdkVersion = targetSdkVersion;
mSupportHotwordDetectionService = supportHotwordDetectionService;
if (mSupportHotwordDetectionService) {
- updateState(options, sharedMemory);
+ updateStateLocked(options, sharedMemory, mInternalCallback);
}
try {
Identity identity = new Identity();
@@ -583,20 +594,34 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector {
* such data to the trusted process.
*
* @throws IllegalStateException if this AlwaysOnHotwordDetector wasn't specified to use a
- * {@link HotwordDetectionService} when it was created.
+ * {@link HotwordDetectionService} when it was created. In addition, if this
+ * AlwaysOnHotwordDetector is in an invalid or error state.
*/
public final void updateState(@Nullable PersistableBundle options,
@Nullable SharedMemory sharedMemory) {
if (DBG) {
Slog.d(TAG, "updateState()");
}
- if (!mSupportHotwordDetectionService) {
- throw new IllegalStateException(
- "updateState called, but it doesn't support hotword detection service");
+ synchronized (mLock) {
+ if (!mSupportHotwordDetectionService) {
+ throw new IllegalStateException(
+ "updateState called, but it doesn't support hotword detection service");
+ }
+ if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
+ throw new IllegalStateException(
+ "updateState called on an invalid detector or error state");
+ }
+ updateStateLocked(options, sharedMemory, null /* callback */);
}
+ }
+ private void updateStateLocked(@Nullable PersistableBundle options,
+ @Nullable SharedMemory sharedMemory, IHotwordRecognitionStatusCallback callback) {
+ if (DBG) {
+ Slog.d(TAG, "updateStateLocked()");
+ }
try {
- mModelManagementService.updateState(options, sharedMemory);
+ mModelManagementService.updateState(options, sharedMemory, callback);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1147,6 +1172,18 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector {
Slog.i(TAG, "onRecognitionResumed");
mHandler.sendEmptyMessage(MSG_DETECTION_RESUME);
}
+
+ @Override
+ public void onStatusReported(int status) {
+ if (DBG) {
+ Slog.d(TAG, "onStatusReported(" + status + ")");
+ } else {
+ Slog.i(TAG, "onStatusReported");
+ }
+ Message message = Message.obtain(mHandler, MSG_HOTWORD_STATUS_REPORTED);
+ message.arg1 = status;
+ message.sendToTarget();
+ }
}
class MyHandler extends Handler {
@@ -1178,6 +1215,9 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector {
case MSG_HOTWORD_REJECTED:
mExternalCallback.onRejected((HotwordRejectedResult) msg.obj);
break;
+ case MSG_HOTWORD_STATUS_REPORTED:
+ mExternalCallback.onHotwordDetectionServiceInitialized(msg.arg1);
+ break;
default:
super.handleMessage(msg);
}
diff --git a/core/java/android/service/voice/HotwordDetectionService.java b/core/java/android/service/voice/HotwordDetectionService.java
index fb731a094f90..7c14c2e19eb1 100644
--- a/core/java/android/service/voice/HotwordDetectionService.java
+++ b/core/java/android/service/voice/HotwordDetectionService.java
@@ -37,10 +37,13 @@ import android.os.RemoteException;
import android.os.SharedMemory;
import android.util.Log;
+import com.android.internal.app.IHotwordRecognitionStatusCallback;
+
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Locale;
+import java.util.function.IntConsumer;
/**
* Implemented by an application that wants to offer detection for hotword. The system will
@@ -54,6 +57,39 @@ public abstract class HotwordDetectionService extends Service {
// TODO (b/177502877): Set the Debug flag to false before shipping.
private static final boolean DBG = true;
+ private static final long UPDATE_TIMEOUT_MILLIS = 5000;
+
+ /** @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 {}
+
+ /**
+ * 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.
+ */
+ public static final int INITIALIZATION_STATUS_UNKNOWN = 100;
+
/**
* Source for the given audio stream.
*
@@ -104,15 +140,16 @@ public abstract class HotwordDetectionService extends Service {
}
@Override
- public void updateState(PersistableBundle options, SharedMemory sharedMemory)
- throws RemoteException {
+ public void updateState(PersistableBundle options, SharedMemory sharedMemory,
+ IHotwordRecognitionStatusCallback callback) throws RemoteException {
if (DBG) {
Log.d(TAG, "#updateState");
}
- mHandler.sendMessage(obtainMessage(HotwordDetectionService::onUpdateState,
+ mHandler.sendMessage(obtainMessage(HotwordDetectionService::onUpdateStateInternal,
HotwordDetectionService.this,
options,
- sharedMemory));
+ sharedMemory,
+ callback));
}
@Override
@@ -207,12 +244,20 @@ public abstract class HotwordDetectionService extends Service {
* @param sharedMemory The unrestricted data blob to provide to the
* {@link HotwordDetectionService}. Use this to provide the hotword models data or other
* 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.
*
* @hide
*/
@SystemApi
- public void onUpdateState(@Nullable PersistableBundle options,
- @Nullable SharedMemory sharedMemory) {
+ public void onUpdateState(
+ @Nullable PersistableBundle options,
+ @Nullable SharedMemory sharedMemory,
+ @DurationMillisLong long callbackTimeoutMillis,
+ @Nullable @InitializationStatus IntConsumer statusCallback) {
// TODO: Handle the unimplemented case by throwing?
}
@@ -268,6 +313,23 @@ public abstract class HotwordDetectionService extends Service {
throw new UnsupportedOperationException();
}
+ private void onUpdateStateInternal(@Nullable PersistableBundle options,
+ @Nullable SharedMemory sharedMemory, IHotwordRecognitionStatusCallback callback) {
+ // TODO (b/183684347): Implement timeout case.
+ IntConsumer intConsumer = null;
+ if (callback != null) {
+ intConsumer =
+ value -> {
+ try {
+ callback.onStatusReported(value);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ };
+ }
+ onUpdateState(options, sharedMemory, UPDATE_TIMEOUT_MILLIS, intConsumer);
+ }
+
/**
* Callback for returning the detection result.
*
diff --git a/core/java/android/service/voice/HotwordDetector.java b/core/java/android/service/voice/HotwordDetector.java
index 26491245914f..f4e5ddaa31a6 100644
--- a/core/java/android/service/voice/HotwordDetector.java
+++ b/core/java/android/service/voice/HotwordDetector.java
@@ -27,6 +27,7 @@ import android.annotation.SystemApi;
import android.media.AudioFormat;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
+import android.service.voice.HotwordDetectionService.InitializationStatus;
/**
* Basic functionality for hotword detectors.
@@ -144,5 +145,13 @@ public interface HotwordDetector {
* {@link HotwordDetectionService}.
*/
void onRejected(@Nullable HotwordRejectedResult result);
+
+ /**
+ * 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}.
+ */
+ void onHotwordDetectionServiceInitialized(@InitializationStatus int status);
}
}
diff --git a/core/java/android/service/voice/IHotwordDetectionService.aidl b/core/java/android/service/voice/IHotwordDetectionService.aidl
index cb140f9346fa..cac8333a5855 100644
--- a/core/java/android/service/voice/IHotwordDetectionService.aidl
+++ b/core/java/android/service/voice/IHotwordDetectionService.aidl
@@ -22,6 +22,8 @@ import android.os.PersistableBundle;
import android.os.SharedMemory;
import android.service.voice.IDspHotwordDetectionCallback;
+import com.android.internal.app.IHotwordRecognitionStatusCallback;
+
/**
* Provide the interface to communicate with hotword detection service.
*
@@ -41,5 +43,6 @@ oneway interface IHotwordDetectionService {
in PersistableBundle options,
in IDspHotwordDetectionCallback callback);
- void updateState(in PersistableBundle options, in SharedMemory sharedMemory);
+ void updateState(in PersistableBundle options, in SharedMemory sharedMemory,
+ in IHotwordRecognitionStatusCallback callback);
}
diff --git a/core/java/android/service/voice/SoftwareHotwordDetector.java b/core/java/android/service/voice/SoftwareHotwordDetector.java
index f49a9d45ae06..376596b9b0d0 100644
--- a/core/java/android/service/voice/SoftwareHotwordDetector.java
+++ b/core/java/android/service/voice/SoftwareHotwordDetector.java
@@ -67,7 +67,7 @@ class SoftwareHotwordDetector extends AbstractHotwordDetector {
mHandler = new Handler(Looper.getMainLooper());
try {
- mManagerService.updateState(options, sharedMemory);
+ mManagerService.updateState(options, sharedMemory, null /* callback */);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}