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
This commit is contained in:
lpeter
2022-01-22 14:53:05 +08:00
parent 08d0c47646
commit 84cc4accd1
8 changed files with 74 additions and 15 deletions

View File

@@ -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();
}

View File

@@ -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();

View File

@@ -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.
* <p>
@@ -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.
*/

View File

@@ -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)

View File

@@ -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.

View File

@@ -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(

View File

@@ -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);
}

View File

@@ -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);