Merge "Indicate which detector triggered the HotwordDetectionService"

This commit is contained in:
TreeHugger Robot
2022-01-27 08:36:32 +00:00
committed by Android (Google) Code Review
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);