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