From 84cc4accd1846fc04bbfe27282abe5b4e7a6a3d8 Mon Sep 17 00:00:00 2001 From: lpeter Date: Sat, 22 Jan 2022 14:53:05 +0800 Subject: [PATCH] Indicate which detector triggered the HotwordDetectionService Currently we are adding the metrics to find why there is a significant drop in assistant successful queries for using trusted hotword. In the metrics, we need to know which detector is used. In this patch, we first provide the way to distinguish which detector triggered the HotwordDetectionService. Bug: 215633663 Test: atest CtsVoiceInteractionTestCases Test: atest CtsVoiceInteractionTestCases --instant Change-Id: I2fa904c5a52d714c9ecb545084ffb60e81ed1d8a --- .../voice/AbstractHotwordDetector.java | 12 ++++-- .../voice/AlwaysOnHotwordDetector.java | 7 +++- .../service/voice/HotwordDetector.java | 37 +++++++++++++++++++ .../voice/SoftwareHotwordDetector.java | 5 ++- .../app/IVoiceInteractionManagerService.aidl | 4 +- .../HotwordDetectionConnection.java | 8 +++- .../VoiceInteractionManagerService.java | 5 ++- .../VoiceInteractionManagerServiceImpl.java | 11 +++++- 8 files changed, 74 insertions(+), 15 deletions(-) diff --git a/core/java/android/service/voice/AbstractHotwordDetector.java b/core/java/android/service/voice/AbstractHotwordDetector.java index dbe1089746840..192260791a8b3 100644 --- a/core/java/android/service/voice/AbstractHotwordDetector.java +++ b/core/java/android/service/voice/AbstractHotwordDetector.java @@ -44,14 +44,17 @@ abstract class AbstractHotwordDetector implements HotwordDetector { private final IVoiceInteractionManagerService mManagerService; private final Handler mHandler; private final HotwordDetector.Callback mCallback; + private final int mDetectorType; AbstractHotwordDetector( IVoiceInteractionManagerService managerService, - HotwordDetector.Callback callback) { + HotwordDetector.Callback callback, + int detectorType) { mManagerService = managerService; // TODO: this needs to be supplied from above mHandler = new Handler(Looper.getMainLooper()); mCallback = callback; + mDetectorType = detectorType; } /** @@ -104,19 +107,20 @@ abstract class AbstractHotwordDetector implements HotwordDetector { Slog.d(TAG, "updateState()"); } synchronized (mLock) { - updateStateLocked(options, sharedMemory, null /* callback */); + updateStateLocked(options, sharedMemory, null /* callback */, mDetectorType); } } protected void updateStateLocked(@Nullable PersistableBundle options, - @Nullable SharedMemory sharedMemory, IHotwordRecognitionStatusCallback callback) { + @Nullable SharedMemory sharedMemory, IHotwordRecognitionStatusCallback callback, + int detectorType) { if (DEBUG) { Slog.d(TAG, "updateStateLocked()"); } Identity identity = new Identity(); identity.packageName = ActivityThread.currentOpPackageName(); try { - mManagerService.updateState(identity, options, sharedMemory, callback); + mManagerService.updateState(identity, options, sharedMemory, callback, detectorType); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java index face870ca1b43..c9daf52b56853 100644 --- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java +++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java @@ -578,7 +578,9 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector { IVoiceInteractionManagerService modelManagementService, int targetSdkVersion, boolean supportHotwordDetectionService, @Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory) { - super(modelManagementService, callback); + super(modelManagementService, callback, + supportHotwordDetectionService ? DETECTOR_TYPE_TRUSTED_HOTWORD_DSP + : DETECTOR_TYPE_NORMAL); mHandler = new MyHandler(); mText = text; @@ -590,7 +592,8 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector { mTargetSdkVersion = targetSdkVersion; mSupportHotwordDetectionService = supportHotwordDetectionService; if (mSupportHotwordDetectionService) { - updateStateLocked(options, sharedMemory, mInternalCallback); + updateStateLocked(options, sharedMemory, mInternalCallback, + DETECTOR_TYPE_TRUSTED_HOTWORD_DSP); } try { Identity identity = new Identity(); diff --git a/core/java/android/service/voice/HotwordDetector.java b/core/java/android/service/voice/HotwordDetector.java index e2478195bdde6..969ec22beb978 100644 --- a/core/java/android/service/voice/HotwordDetector.java +++ b/core/java/android/service/voice/HotwordDetector.java @@ -36,6 +36,27 @@ import android.os.SharedMemory; @SystemApi public interface HotwordDetector { + /** + * Indicates that it is a non-trusted hotword detector. + * + * @hide + */ + int DETECTOR_TYPE_NORMAL = 0; + + /** + * Indicates that it is a DSP trusted hotword detector. + * + * @hide + */ + int DETECTOR_TYPE_TRUSTED_HOTWORD_DSP = 1; + + /** + * Indicates that it is a software trusted hotword detector. + * + * @hide + */ + int DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE = 2; + /** * Starts hotword recognition. *

@@ -97,6 +118,22 @@ public interface HotwordDetector { */ void updateState(@Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory); + /** + * @hide + */ + static String detectorTypeToString(int detectorType) { + switch (detectorType) { + case DETECTOR_TYPE_NORMAL: + return "normal"; + case DETECTOR_TYPE_TRUSTED_HOTWORD_DSP: + return "trusted_hotword_dsp"; + case DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE: + return "trusted_hotword_software"; + default: + return Integer.toString(detectorType); + } + } + /** * The callback to notify of detection events. */ diff --git a/core/java/android/service/voice/SoftwareHotwordDetector.java b/core/java/android/service/voice/SoftwareHotwordDetector.java index f7a3415259fd5..512a654adbab7 100644 --- a/core/java/android/service/voice/SoftwareHotwordDetector.java +++ b/core/java/android/service/voice/SoftwareHotwordDetector.java @@ -60,14 +60,15 @@ class SoftwareHotwordDetector extends AbstractHotwordDetector { PersistableBundle options, SharedMemory sharedMemory, HotwordDetector.Callback callback) { - super(managerService, callback); + super(managerService, callback, DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE); mManagerService = managerService; mAudioFormat = audioFormat; mCallback = callback; mHandler = new Handler(Looper.getMainLooper()); updateStateLocked(options, sharedMemory, - new InitializationStateListener(mHandler, mCallback)); + new InitializationStateListener(mHandler, mCallback), + DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE); } @RequiresPermission(RECORD_AUDIO) diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl index 998526209c72d..52d54cd1f7176 100644 --- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl +++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl @@ -242,12 +242,14 @@ interface IVoiceInteractionManagerService { * {@link HotwordDetectionService}. Use this to provide the hotword models data or other * such data to the trusted process. * @param callback Use this to report {@link HotwordDetectionService} status. + * @param detectorType Indicate which detector is used. */ void updateState( in Identity originatorIdentity, in PersistableBundle options, in SharedMemory sharedMemory, - in IHotwordRecognitionStatusCallback callback); + in IHotwordRecognitionStatusCallback callback, + int detectorType); /** * Requests to shutdown hotword detection service. diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java index e19ea47df3bb5..8acd3c7c1c366 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java @@ -51,6 +51,7 @@ import android.os.ServiceManager; import android.os.SharedMemory; import android.service.voice.HotwordDetectedResult; import android.service.voice.HotwordDetectionService; +import android.service.voice.HotwordDetector; import android.service.voice.HotwordRejectedResult; import android.service.voice.IDspHotwordDetectionCallback; import android.service.voice.IHotwordDetectionService; @@ -132,12 +133,13 @@ final class HotwordDetectionConnection { private @NonNull ServiceConnection mRemoteHotwordDetectionService; private IBinder mAudioFlinger; private boolean mDebugHotwordLogging = false; + private final int mDetectorType; HotwordDetectionConnection(Object lock, Context context, int voiceInteractionServiceUid, Identity voiceInteractorIdentity, ComponentName serviceName, int userId, boolean bindInstantServiceAllowed, @Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory, - @NonNull IHotwordRecognitionStatusCallback callback) { + @NonNull IHotwordRecognitionStatusCallback callback, int detectorType) { if (callback == null) { Slog.w(TAG, "Callback is null while creating connection"); throw new IllegalArgumentException("Callback is null while creating connection"); @@ -149,6 +151,7 @@ final class HotwordDetectionConnection { mDetectionComponentName = serviceName; mUser = userId; mCallback = callback; + mDetectorType = detectorType; final Intent intent = new Intent(HotwordDetectionService.SERVICE_INTERFACE); intent.setComponent(mDetectionComponentName); initAudioFlingerLocked(); @@ -657,7 +660,8 @@ final class HotwordDetectionConnection { pw.print(", mValidatingDspTrigger=" + mValidatingDspTrigger); pw.print(", mPerformingSoftwareHotwordDetection=" + mPerformingSoftwareHotwordDetection); pw.print(", mRestartCount=" + mServiceConnectionFactory.mRestartCount); - pw.println(", mLastRestartInstant=" + mLastRestartInstant); + pw.print(", mLastRestartInstant=" + mLastRestartInstant); + pw.println(", mDetectorType=" + HotwordDetector.detectorTypeToString(mDetectorType)); } private void handleExternalSourceHotwordDetection( diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java index 8445ed4884e27..1285a84ea752c 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java @@ -1168,7 +1168,8 @@ public class VoiceInteractionManagerService extends SystemService { @NonNull Identity voiceInteractorIdentity, @Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory, - IHotwordRecognitionStatusCallback callback) { + IHotwordRecognitionStatusCallback callback, + int detectorType) { enforceCallingPermission(Manifest.permission.MANAGE_HOTWORD_DETECTION); synchronized (this) { enforceIsCurrentVoiceInteractionService(); @@ -1184,7 +1185,7 @@ public class VoiceInteractionManagerService extends SystemService { final long caller = Binder.clearCallingIdentity(); try { mImpl.updateStateLocked( - voiceInteractorIdentity, options, sharedMemory, callback); + voiceInteractorIdentity, options, sharedMemory, callback, detectorType); } finally { Binder.restoreCallingIdentity(caller); } diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java index 96c78bc2d0efe..fb4d73cf9d52f 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java @@ -53,6 +53,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.SharedMemory; import android.os.UserHandle; +import android.service.voice.HotwordDetector; import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback; import android.service.voice.IVoiceInteractionService; import android.service.voice.IVoiceInteractionSession; @@ -102,6 +103,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne VoiceInteractionSessionConnection mActiveSession; int mDisabledShowContext; + int mDetectorType; final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override @@ -457,7 +459,8 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne @NonNull Identity voiceInteractorIdentity, @Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory, - IHotwordRecognitionStatusCallback callback) { + IHotwordRecognitionStatusCallback callback, + int detectorType) { Slog.v(TAG, "updateStateLocked"); if (mHotwordDetectionComponentName == null) { Slog.w(TAG, "Hotword detection service name not found"); @@ -494,11 +497,13 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne throw new IllegalStateException("Can't set sharedMemory to be read-only"); } + mDetectorType = detectorType; + if (mHotwordDetectionConnection == null) { mHotwordDetectionConnection = new HotwordDetectionConnection(mServiceStub, mContext, mInfo.getServiceInfo().applicationInfo.uid, voiceInteractorIdentity, mHotwordDetectionComponentName, mUser, /* bindInstantServiceAllowed= */ false, - options, sharedMemory, callback); + options, sharedMemory, callback, detectorType); } else { mHotwordDetectionConnection.updateStateLocked(options, sharedMemory); } @@ -668,6 +673,8 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne pw.println(Integer.toHexString(mDisabledShowContext)); } pw.print(" mBound="); pw.print(mBound); pw.print(" mService="); pw.println(mService); + pw.print(" mDetectorType="); + pw.println(HotwordDetector.detectorTypeToString(mDetectorType)); if (mHotwordDetectionConnection != null) { pw.println(" Hotword detection connection:"); mHotwordDetectionConnection.dump(" ", pw);