diff --git a/core/java/android/service/voice/HotwordDetectionService.java b/core/java/android/service/voice/HotwordDetectionService.java index 23b2103ce5fd9..ea854e8c92834 100644 --- a/core/java/android/service/voice/HotwordDetectionService.java +++ b/core/java/android/service/voice/HotwordDetectionService.java @@ -24,8 +24,11 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SdkConstant; +import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.app.Service; +import android.content.ContentCaptureOptions; +import android.content.Context; import android.content.Intent; import android.media.AudioFormat; import android.os.Bundle; @@ -38,6 +41,8 @@ import android.os.PersistableBundle; import android.os.RemoteException; import android.os.SharedMemory; import android.util.Log; +import android.view.contentcapture.ContentCaptureManager; +import android.view.contentcapture.IContentCaptureManager; import java.lang.annotation.Documented; import java.lang.annotation.Retention; @@ -122,6 +127,9 @@ public abstract class HotwordDetectionService extends Service { private Handler mHandler; + @Nullable + private ContentCaptureManager mContentCaptureManager; + private final IHotwordDetectionService mInterface = new IHotwordDetectionService.Stub() { @Override public void detectFromDspSource( @@ -187,6 +195,13 @@ public abstract class HotwordDetectionService extends Service { Log.i(TAG, "Unsupported audio source " + audioSource); } } + + @Override + public void updateContentCaptureManager(IContentCaptureManager manager, + ContentCaptureOptions options) { + mContentCaptureManager = new ContentCaptureManager( + HotwordDetectionService.this, manager, options); + } }; @CallSuper @@ -207,6 +222,16 @@ public abstract class HotwordDetectionService extends Service { return null; } + @Override + @SuppressLint("OnNameExpected") + public @Nullable Object getSystemService(@ServiceName @NonNull String name) { + if (Context.CONTENT_CAPTURE_MANAGER_SERVICE.equals(name)) { + return mContentCaptureManager; + } else { + return super.getSystemService(name); + } + } + /** * Called when the device hardware (such as a DSP) detected the hotword, to request second stage * validation before handing over the audio to the {@link AlwaysOnHotwordDetector}. diff --git a/core/java/android/service/voice/IHotwordDetectionService.aidl b/core/java/android/service/voice/IHotwordDetectionService.aidl index d2421603e5544..2ffe787e895af 100644 --- a/core/java/android/service/voice/IHotwordDetectionService.aidl +++ b/core/java/android/service/voice/IHotwordDetectionService.aidl @@ -22,6 +22,8 @@ import android.os.ParcelFileDescriptor; import android.os.PersistableBundle; import android.os.SharedMemory; import android.service.voice.IDspHotwordDetectionCallback; +import android.view.contentcapture.IContentCaptureManager; +import android.content.ContentCaptureOptions; /** * Provide the interface to communicate with hotword detection service. @@ -42,6 +44,12 @@ oneway interface IHotwordDetectionService { in PersistableBundle options, in IDspHotwordDetectionCallback callback); - void updateState(in PersistableBundle options, in SharedMemory sharedMemory, - in IRemoteCallback callback); + void updateState( + in PersistableBundle options, + in SharedMemory sharedMemory, + in IRemoteCallback callback); + + void updateContentCaptureManager( + in IContentCaptureManager contentCaptureManager, + in ContentCaptureOptions options); } diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java index 6f701f7e3a36e..ba7aaab31de63 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java @@ -24,6 +24,7 @@ import static android.service.voice.HotwordDetectionService.KEY_INITIALIZATION_S import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; +import android.content.ContentCaptureOptions; import android.content.Context; import android.content.Intent; import android.hardware.soundtrigger.IRecognitionStatusCallback; @@ -34,10 +35,12 @@ import android.media.AudioManager; import android.media.AudioRecord; import android.media.MediaRecorder; import android.os.Bundle; +import android.os.IBinder; import android.os.IRemoteCallback; import android.os.ParcelFileDescriptor; import android.os.PersistableBundle; import android.os.RemoteException; +import android.os.ServiceManager; import android.os.SharedMemory; import android.service.voice.HotwordDetectedResult; import android.service.voice.HotwordDetectionService; @@ -47,6 +50,7 @@ import android.service.voice.IHotwordDetectionService; import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback; import android.util.Pair; import android.util.Slog; +import android.view.contentcapture.IContentCaptureManager; import com.android.internal.annotations.GuardedBy; import com.android.internal.app.IHotwordRecognitionStatusCallback; @@ -135,6 +139,7 @@ final class HotwordDetectionConnection { return; } updateStateWithCallbackLocked(options, sharedMemory, callback); + updateContentCaptureManager(); } private void updateStateWithCallbackLocked(PersistableBundle options, @@ -193,6 +198,15 @@ final class HotwordDetectionConnection { }); } + private void updateContentCaptureManager() { + IBinder b = ServiceManager + .getService(Context.CONTENT_CAPTURE_MANAGER_SERVICE); + IContentCaptureManager binderService = IContentCaptureManager.Stub.asInterface(b); + mRemoteHotwordDetectionService.post( + service -> service.updateContentCaptureManager(binderService, + new ContentCaptureOptions(null))); + } + private boolean isBound() { synchronized (mLock) { return mBound;