From add5a9336c3e0b5590fd18d2a1644ce13a000755 Mon Sep 17 00:00:00 2001 From: Charles Chen Date: Mon, 2 Jan 2023 06:38:05 +0000 Subject: [PATCH] Rename remote hotword detection service usages All hotword detection service usage are renamed based on their semantic meaning. Variable names with framework reference have their HotwordDetection removed, and names refering to the actual HotwordDetectionService are added. Bug: 261783492 Test: atest CtsVoiceInteractionTestCases Change-Id: Ifa9bec8be2f0892a219250b7d68a4fad88de251d --- ...ectorSession.java => DetectorSession.java} | 48 +++++----- .../DspTrustedHotwordDetectorSession.java | 5 +- .../HotwordDetectionConnection.java | 93 ++++++++++--------- ...SoftwareTrustedHotwordDetectorSession.java | 6 +- 4 files changed, 80 insertions(+), 72 deletions(-) rename services/voiceinteraction/java/com/android/server/voiceinteraction/{HotwordDetectorSession.java => DetectorSession.java} (95%) diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectorSession.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/DetectorSession.java similarity index 95% rename from services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectorSession.java rename to services/voiceinteraction/java/com/android/server/voiceinteraction/DetectorSession.java index 689423ad3e3ea..4d6d3205db402 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectorSession.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/DetectorSession.java @@ -93,21 +93,27 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; /** - * A class that provides trusted hotword detector to communicate with the {@link - * HotwordDetectionService}. + * A class that provides sandboxed detector to communicate with the {@link + * HotwordDetectionService} and {@link VisualQueryDetectionService}. * - * This class provides the methods to do initialization with the {@link HotwordDetectionService} - * and handle external source detection. It also provides the methods to check if we can egress - * the data from the {@link HotwordDetectionService}. + * Trusted hotword detectors such as {@link SoftwareHotwordDetector} and + * {@link AlwaysOnHotwordDetector} will leverage this class to communitcate with + * {@link HotwordDetectionService}; similarly, {@link VisualQueryDetector} will communicate with + * {@link VisualQueryDetectionService}. + * + * This class provides the methods to do initialization with the {@link HotwordDetectionService} and + * {@link VisualQueryDetectionService} handles external source detection for + * {@link HotwordDetectionService}. It also provides the methods to check if we can egress the data + * from the {@link HotwordDetectionService} and {@link VisualQueryDetectionService}. * * The subclass should override the {@link #informRestartProcessLocked()} to handle the trusted * process restart. */ -abstract class HotwordDetectorSession { - private static final String TAG = "HotwordDetectorSession"; +abstract class DetectorSession { + private static final String TAG = "DetectorSession"; static final boolean DEBUG = false; - private static final String OP_MESSAGE = + private static final String HOTWORD_DETECTION_OP_MESSAGE = "Providing hotword detection result to VoiceInteractionService"; // The error codes are used for onError callback @@ -173,7 +179,7 @@ abstract class HotwordDetectorSession { @GuardedBy("mLock") ParcelFileDescriptor mCurrentAudioSink; @GuardedBy("mLock") - @NonNull HotwordDetectionConnection.ServiceConnection mRemoteHotwordDetectionService; + @NonNull HotwordDetectionConnection.ServiceConnection mRemoteDetectionService; boolean mDebugHotwordLogging = false; @GuardedBy("mLock") private double mProximityMeters = PROXIMITY_UNKNOWN; @@ -185,13 +191,13 @@ abstract class HotwordDetectorSession { boolean mPerformingExternalSourceHotwordDetection; @NonNull final IBinder mToken; - HotwordDetectorSession( - @NonNull HotwordDetectionConnection.ServiceConnection remoteHotwordDetectionService, + DetectorSession( + @NonNull HotwordDetectionConnection.ServiceConnection remoteDetectionService, @NonNull Object lock, @NonNull Context context, @NonNull IBinder token, @NonNull IHotwordRecognitionStatusCallback callback, int voiceInteractionServiceUid, Identity voiceInteractorIdentity, @NonNull ScheduledExecutorService scheduledExecutorService, boolean logging) { - mRemoteHotwordDetectionService = remoteHotwordDetectionService; + mRemoteDetectionService = remoteDetectionService; mLock = lock; mContext = context; mToken = token; @@ -219,7 +225,7 @@ abstract class HotwordDetectorSession { if (DEBUG) { Slog.d(TAG, "updateStateAfterProcessStartLocked"); } - AndroidFuture voidFuture = mRemoteHotwordDetectionService.postAsync(service -> { + AndroidFuture voidFuture = mRemoteDetectionService.postAsync(service -> { AndroidFuture future = new AndroidFuture<>(); IRemoteCallback statusCallback = new IRemoteCallback.Stub() { @Override @@ -319,7 +325,7 @@ abstract class HotwordDetectorSession { Slog.v(TAG, "call updateStateAfterProcessStartLocked"); updateStateAfterProcessStartLocked(options, sharedMemory); } else { - mRemoteHotwordDetectionService.run( + mRemoteDetectionService.run( service -> service.updateState(options, sharedMemory, /* callback= */ null)); } } @@ -407,7 +413,7 @@ abstract class HotwordDetectorSession { // TODO: handle cancellations well // TODO: what if we cancelled and started a new one? - mRemoteHotwordDetectionService.run( + mRemoteDetectionService.run( service -> { service.detectFromMicrophoneSource( serviceAudioSource, @@ -512,7 +518,7 @@ abstract class HotwordDetectorSession { void destroyLocked() { mDestroyed = true; mDebugHotwordLogging = false; - mRemoteHotwordDetectionService = null; + mRemoteDetectionService = null; if (mAttentionManagerInternal != null) { mAttentionManagerInternal.onStopProximityUpdates(mProximityCallbackInternal); } @@ -524,9 +530,9 @@ abstract class HotwordDetectorSession { } @SuppressWarnings("GuardedBy") - void updateRemoteHotwordDetectionServiceLocked( - @NonNull HotwordDetectionConnection.ServiceConnection remoteHotwordDetectionService) { - mRemoteHotwordDetectionService = remoteHotwordDetectionService; + void updateRemoteSandboxedDetectionServiceLocked( + @NonNull HotwordDetectionConnection.ServiceConnection remoteDetectionService) { + mRemoteDetectionService = remoteDetectionService; } void reportErrorLocked(int status) { @@ -628,9 +634,9 @@ abstract class HotwordDetectorSession { int hotwordOp = AppOpsManager.strOpToOp(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD); mAppOpsManager.noteOpNoThrow(hotwordOp, mVoiceInteractorIdentity.uid, mVoiceInteractorIdentity.packageName, - mVoiceInteractorIdentity.attributionTag, OP_MESSAGE); + mVoiceInteractorIdentity.attributionTag, HOTWORD_DETECTION_OP_MESSAGE); enforcePermissionForDataDelivery(mContext, mVoiceInteractorIdentity, - CAPTURE_AUDIO_HOTWORD, OP_MESSAGE); + CAPTURE_AUDIO_HOTWORD, HOTWORD_DETECTION_OP_MESSAGE); } }); } diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/DspTrustedHotwordDetectorSession.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/DspTrustedHotwordDetectorSession.java index 84bd716016432..ad84f004e9663 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/DspTrustedHotwordDetectorSession.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/DspTrustedHotwordDetectorSession.java @@ -32,7 +32,6 @@ import android.os.IBinder; import android.os.PersistableBundle; import android.os.RemoteException; import android.os.SharedMemory; -import android.service.voice.AlwaysOnHotwordDetector; import android.service.voice.HotwordDetectedResult; import android.service.voice.HotwordDetectionService; import android.service.voice.HotwordDetector; @@ -59,7 +58,7 @@ import java.util.concurrent.atomic.AtomicBoolean; * {@link android.service.voice.VoiceInteractionService#createAlwaysOnHotwordDetector(String, * Locale, PersistableBundle, SharedMemory, AlwaysOnHotwordDetector.Callback)}. */ -final class DspTrustedHotwordDetectorSession extends HotwordDetectorSession { +final class DspTrustedHotwordDetectorSession extends DetectorSession { private static final String TAG = "DspTrustedHotwordDetectorSession"; // The validation timeout value is 3 seconds for onDetect of DSP trigger event. @@ -182,7 +181,7 @@ final class DspTrustedHotwordDetectorSession extends HotwordDetectorSession { }; mValidatingDspTrigger = true; - mRemoteHotwordDetectionService.run(service -> { + mRemoteDetectionService.run(service -> { // We use the VALIDATION_TIMEOUT_MILLIS to inform that the client needs to invoke // the callback before timeout value. In order to reduce the latency impact between // server side and client side, we need to use another timeout value diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java index 276bccdb9f230..d501af7d83bea 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java @@ -89,7 +89,7 @@ final class HotwordDetectionConnection { Executors.newSingleThreadScheduledExecutor(); @Nullable private final ScheduledFuture mCancellationTaskFuture; private final IBinder.DeathRecipient mAudioServerDeathRecipient = this::audioServerDied; - @NonNull private final ServiceConnectionFactory mServiceConnectionFactory; + @NonNull private final ServiceConnectionFactory mHotwordDetectionServiceConnectionFactory; private final int mDetectorType; /** * Time after which each HotwordDetectionService process is stopped and replaced by a new one. @@ -99,7 +99,7 @@ final class HotwordDetectionConnection { final Object mLock; final int mVoiceInteractionServiceUid; - final ComponentName mDetectionComponentName; + final ComponentName mHotwordDetectionComponentName; final int mUser; final Context mContext; volatile HotwordDetectionServiceIdentity mIdentity; @@ -122,27 +122,30 @@ final class HotwordDetectionConnection { * to record the detectors. */ @GuardedBy("mLock") - private final SparseArray mHotwordDetectorSessions = + private final SparseArray mDetectorSessions = new SparseArray<>(); HotwordDetectionConnection(Object lock, Context context, int voiceInteractionServiceUid, - Identity voiceInteractorIdentity, ComponentName serviceName, int userId, + Identity voiceInteractorIdentity, ComponentName hotwordDetectionServiceName, int userId, boolean bindInstantServiceAllowed, int detectorType) { mLock = lock; mContext = context; mVoiceInteractionServiceUid = voiceInteractionServiceUid; mVoiceInteractorIdentity = voiceInteractorIdentity; - mDetectionComponentName = serviceName; + mHotwordDetectionComponentName = hotwordDetectionServiceName; mUser = userId; mDetectorType = detectorType; mReStartPeriodSeconds = DeviceConfig.getInt(DeviceConfig.NAMESPACE_VOICE_INTERACTION, KEY_RESTART_PERIOD_IN_SECONDS, 0); - final Intent intent = new Intent(HotwordDetectionService.SERVICE_INTERFACE); - intent.setComponent(mDetectionComponentName); + final Intent hotwordDetectionServiceIntent = + new Intent(HotwordDetectionService.SERVICE_INTERFACE); + hotwordDetectionServiceIntent.setComponent(mHotwordDetectionComponentName); initAudioFlingerLocked(); - mServiceConnectionFactory = new ServiceConnectionFactory(intent, bindInstantServiceAllowed); - mRemoteHotwordDetectionService = mServiceConnectionFactory.createLocked(); + mHotwordDetectionServiceConnectionFactory = + new ServiceConnectionFactory(hotwordDetectionServiceIntent, + bindInstantServiceAllowed); + mRemoteHotwordDetectionService = mHotwordDetectionServiceConnectionFactory.createLocked(); mLastRestartInstant = Instant.now(); if (mReStartPeriodSeconds <= 0) { @@ -176,8 +179,8 @@ final class HotwordDetectionConnection { try { mAudioFlinger.linkToDeath(mAudioServerDeathRecipient, /* flags= */ 0); } catch (RemoteException e) { - Slog.w(TAG, "Audio server died before we registered a DeathRecipient; retrying init.", - e); + Slog.w(TAG, "Audio server died before we registered a DeathRecipient; " + + "retrying init.", e); initAudioFlingerLocked(); } } @@ -200,10 +203,10 @@ final class HotwordDetectionConnection { void cancelLocked() { Slog.v(TAG, "cancelLocked"); clearDebugHotwordLoggingTimeoutLocked(); - runForEachHotwordDetectorSessionLocked((session) -> { + runForEachDetectorSessionLocked((session) -> { session.destroyLocked(); }); - mHotwordDetectorSessions.clear(); + mDetectorSessions.clear(); mDebugHotwordLogging = false; mRemoteHotwordDetectionService.unbind(); LocalServices.getService(PermissionManagerServiceInternal.class) @@ -223,7 +226,7 @@ final class HotwordDetectionConnection { @SuppressWarnings("GuardedBy") void updateStateLocked(PersistableBundle options, SharedMemory sharedMemory, @NonNull IBinder token) { - final HotwordDetectorSession session = getDetectorSessionByTokenLocked(token); + final DetectorSession session = getDetectorSessionByTokenLocked(token); if (session == null) { Slog.v(TAG, "Not found the detector by token"); return; @@ -259,7 +262,7 @@ final class HotwordDetectionConnection { if (DEBUG) { Slog.d(TAG, "startListeningFromExternalSourceLocked"); } - final HotwordDetectorSession session = getDetectorSessionByTokenLocked(token); + final DetectorSession session = getDetectorSessionByTokenLocked(token); if (session == null) { Slog.v(TAG, "Not found the detector by token"); return; @@ -321,7 +324,7 @@ final class HotwordDetectionConnection { Slog.v(TAG, "setDebugHotwordLoggingLocked: " + logging); clearDebugHotwordLoggingTimeoutLocked(); mDebugHotwordLogging = logging; - runForEachHotwordDetectorSessionLocked((session) -> { + runForEachDetectorSessionLocked((session) -> { session.setDebugHotwordLoggingLocked(logging); }); @@ -331,7 +334,7 @@ final class HotwordDetectionConnection { Slog.v(TAG, "Timeout to reset mDebugHotwordLogging to false"); synchronized (mLock) { mDebugHotwordLogging = false; - runForEachHotwordDetectorSessionLocked((session) -> { + runForEachDetectorSessionLocked((session) -> { session.setDebugHotwordLoggingLocked(false); }); } @@ -350,24 +353,24 @@ final class HotwordDetectionConnection { private void restartProcessLocked() { // TODO(b/244598068): Check HotwordAudioStreamManager first Slog.v(TAG, "Restarting hotword detection process"); - ServiceConnection oldConnection = mRemoteHotwordDetectionService; + ServiceConnection oldHotwordConnection = mRemoteHotwordDetectionService; HotwordDetectionServiceIdentity previousIdentity = mIdentity; mLastRestartInstant = Instant.now(); // Recreate connection to reset the cache. - mRemoteHotwordDetectionService = mServiceConnectionFactory.createLocked(); + mRemoteHotwordDetectionService = mHotwordDetectionServiceConnectionFactory.createLocked(); Slog.v(TAG, "Started the new process, dispatching processRestarted to detector"); - runForEachHotwordDetectorSessionLocked((session) -> { - session.updateRemoteHotwordDetectionServiceLocked(mRemoteHotwordDetectionService); + runForEachDetectorSessionLocked((session) -> { + session.updateRemoteSandboxedDetectionServiceLocked(mRemoteHotwordDetectionService); session.informRestartProcessLocked(); }); if (DEBUG) { Slog.i(TAG, "processRestarted is dispatched done, unbinding from the old process"); } - oldConnection.ignoreConnectionStatusEvents(); - oldConnection.unbind(); + oldHotwordConnection.ignoreConnectionStatusEvents(); + oldHotwordConnection.unbind(); if (previousIdentity != null) { removeServiceUidForAudioPolicy(previousIdentity.getIsolatedUid()); } @@ -437,12 +440,12 @@ final class HotwordDetectionConnection { pw.print(prefix); pw.print("mBound="); pw.println(mRemoteHotwordDetectionService.isBound()); pw.print(prefix); pw.print("mRestartCount="); - pw.println(mServiceConnectionFactory.mRestartCount); + pw.println(mHotwordDetectionServiceConnectionFactory.mRestartCount); pw.print(prefix); pw.print("mLastRestartInstant="); pw.println(mLastRestartInstant); pw.print(prefix); pw.print("mDetectorType="); pw.println(HotwordDetector.detectorTypeToString(mDetectorType)); - pw.print(prefix); pw.println("HotwordDetectorSession(s)"); - runForEachHotwordDetectorSessionLocked((session) -> { + pw.print(prefix); pw.println("DetectorSession(s)"); + runForEachDetectorSessionLocked((session) -> { session.dumpLocked(prefix, pw); }); } @@ -537,9 +540,9 @@ final class HotwordDetectionConnection { } } synchronized (HotwordDetectionConnection.this.mLock) { - runForEachHotwordDetectorSessionLocked((session) -> { + runForEachDetectorSessionLocked((session) -> { session.reportErrorLocked( - HotwordDetectorSession.HOTWORD_DETECTION_SERVICE_DIED); + DetectorSession.HOTWORD_DETECTION_SERVICE_DIED); }); } // Can improve to log exit reason if needed @@ -599,12 +602,12 @@ final class HotwordDetectionConnection { int detectorType) { // We only support one Dsp trusted hotword detector and one software hotword detector at // the same time, remove existing one. - HotwordDetectorSession removeSession = mHotwordDetectorSessions.get(detectorType); + DetectorSession removeSession = mDetectorSessions.get(detectorType); if (removeSession != null) { removeSession.destroyLocked(); - mHotwordDetectorSessions.remove(detectorType); + mDetectorSessions.remove(detectorType); } - final HotwordDetectorSession session; + final DetectorSession session; if (detectorType == HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP) { session = new DspTrustedHotwordDetectorSession(mRemoteHotwordDetectionService, mLock, mContext, token, callback, mVoiceInteractionServiceUid, @@ -615,30 +618,30 @@ final class HotwordDetectionConnection { mVoiceInteractionServiceUid, mVoiceInteractorIdentity, mScheduledExecutorService, mDebugHotwordLogging); } - mHotwordDetectorSessions.put(detectorType, session); + mDetectorSessions.put(detectorType, session); session.initialize(options, sharedMemory); } @SuppressWarnings("GuardedBy") void destroyDetectorLocked(@NonNull IBinder token) { - final HotwordDetectorSession session = getDetectorSessionByTokenLocked(token); + final DetectorSession session = getDetectorSessionByTokenLocked(token); if (session != null) { session.destroyLocked(); - final int index = mHotwordDetectorSessions.indexOfValue(session); - if (index < 0 || index > mHotwordDetectorSessions.size() - 1) { + final int index = mDetectorSessions.indexOfValue(session); + if (index < 0 || index > mDetectorSessions.size() - 1) { return; } - mHotwordDetectorSessions.removeAt(index); + mDetectorSessions.removeAt(index); } } @SuppressWarnings("GuardedBy") - private HotwordDetectorSession getDetectorSessionByTokenLocked(IBinder token) { + private DetectorSession getDetectorSessionByTokenLocked(IBinder token) { if (token == null) { return null; } - for (int i = 0; i < mHotwordDetectorSessions.size(); i++) { - final HotwordDetectorSession session = mHotwordDetectorSessions.valueAt(i); + for (int i = 0; i < mDetectorSessions.size(); i++) { + final DetectorSession session = mDetectorSessions.valueAt(i); if (!session.isDestroyed() && session.isSameToken(token)) { return session; } @@ -648,7 +651,7 @@ final class HotwordDetectionConnection { @SuppressWarnings("GuardedBy") private DspTrustedHotwordDetectorSession getDspTrustedHotwordDetectorSessionLocked() { - final HotwordDetectorSession session = mHotwordDetectorSessions.get( + final DetectorSession session = mDetectorSessions.get( HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP); if (session == null || session.isDestroyed()) { Slog.v(TAG, "Not found the Dsp detector"); @@ -659,7 +662,7 @@ final class HotwordDetectionConnection { @SuppressWarnings("GuardedBy") private SoftwareTrustedHotwordDetectorSession getSoftwareTrustedHotwordDetectorSessionLocked() { - final HotwordDetectorSession session = mHotwordDetectorSessions.get( + final DetectorSession session = mDetectorSessions.get( HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE); if (session == null || session.isDestroyed()) { Slog.v(TAG, "Not found the software detector"); @@ -669,10 +672,10 @@ final class HotwordDetectionConnection { } @SuppressWarnings("GuardedBy") - private void runForEachHotwordDetectorSessionLocked( - @NonNull Consumer action) { - for (int i = 0; i < mHotwordDetectorSessions.size(); i++) { - HotwordDetectorSession session = mHotwordDetectorSessions.valueAt(i); + private void runForEachDetectorSessionLocked( + @NonNull Consumer action) { + for (int i = 0; i < mDetectorSessions.size(); i++) { + DetectorSession session = mDetectorSessions.valueAt(i); action.accept(session); } } diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoftwareTrustedHotwordDetectorSession.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoftwareTrustedHotwordDetectorSession.java index 4eb997a610a47..3ad963d219432 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoftwareTrustedHotwordDetectorSession.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoftwareTrustedHotwordDetectorSession.java @@ -55,7 +55,7 @@ import java.util.concurrent.ScheduledExecutorService; * {@link android.service.voice.VoiceInteractionService#createHotwordDetector(PersistableBundle, * SharedMemory, HotwordDetector.Callback)}. */ -final class SoftwareTrustedHotwordDetectorSession extends HotwordDetectorSession { +final class SoftwareTrustedHotwordDetectorSession extends DetectorSession { private static final String TAG = "SoftwareTrustedHotwordDetectorSession"; private IMicrophoneHotwordDetectionVoiceInteractionCallback mSoftwareCallback; @@ -155,7 +155,7 @@ final class SoftwareTrustedHotwordDetectorSession extends HotwordDetectorSession } }; - mRemoteHotwordDetectionService.run( + mRemoteDetectionService.run( service -> service.detectFromMicrophoneSource( null, AUDIO_SOURCE_MICROPHONE, @@ -179,7 +179,7 @@ final class SoftwareTrustedHotwordDetectorSession extends HotwordDetectorSession } mPerformingSoftwareHotwordDetection = false; - mRemoteHotwordDetectionService.run(ISandboxedDetectionService::stopDetection); + mRemoteDetectionService.run(ISandboxedDetectionService::stopDetection); closeExternalAudioStreamLocked("stopping requested"); }