Merge changes from topic "am-629d721311684d0894cb70223e57c879"
* changes:
[automerger skipped] Merge "[DO NOT MERGE] Bouncer - Intercept touch events when not visible" into tm-qpr-dev am: 030b7809d2 am: b2bec98532 -s ours
[automerger skipped] [DO NOT MERGE] Bouncer - Intercept touch events when not visible am: 96cdb8a262 am: 1734b48777 -s ours
diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java
index f843318..fc5cb4b 100644
--- a/core/java/com/android/internal/app/AssistUtils.java
+++ b/core/java/com/android/internal/app/AssistUtils.java
@@ -229,6 +229,35 @@
}
}
+ /**
+ * Enables visual detection service.
+ *
+ * @param listener to receive visual attention gained/lost events.
+ */
+ public void enableVisualQueryDetection(
+ IVisualQueryDetectionAttentionListener listener) {
+ try {
+ if (mVoiceInteractionManagerService != null) {
+ mVoiceInteractionManagerService.enableVisualQueryDetection(listener);
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to register visual query detection attention listener", e);
+ }
+ }
+
+ /**
+ * Disables visual query detection.
+ */
+ public void disableVisualQueryDetection() {
+ try {
+ if (mVoiceInteractionManagerService != null) {
+ mVoiceInteractionManagerService.disableVisualQueryDetection();
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to register visual query detection attention listener", e);
+ }
+ }
+
@UnsupportedAppUsage
public ComponentName getAssistComponentForUser(int userId) {
final String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
diff --git a/core/java/com/android/internal/app/IVisualQueryDetectionAttentionListener.aidl b/core/java/com/android/internal/app/IVisualQueryDetectionAttentionListener.aidl
new file mode 100644
index 0000000..3e48da7
--- /dev/null
+++ b/core/java/com/android/internal/app/IVisualQueryDetectionAttentionListener.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+/**
+ * Allows sysui to notify users the assistant is ready to take a query without notifying the
+ * assistant app.
+ */
+oneway interface IVisualQueryDetectionAttentionListener {
+ /**
+ * Called when attention signal is sent.
+ */
+ void onAttentionGained();
+
+ /**
+ * Called when a attention signal is lost.
+ */
+ void onAttentionLost();
+}
\ No newline at end of file
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index 88d6425..619b420 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -39,6 +39,7 @@
import com.android.internal.app.IVoiceInteractionSessionShowCallback;
import com.android.internal.app.IVoiceInteractionSoundTriggerSession;
import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.app.IVisualQueryDetectionAttentionListener;
interface IVoiceInteractionManagerService {
void showSession(in Bundle sessionArgs, int flags, String attributionTag);
@@ -300,6 +301,12 @@
*/
void shutdownHotwordDetectionService();
+ @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
+ void enableVisualQueryDetection(in IVisualQueryDetectionAttentionListener Listener);
+
+ @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
+ void disableVisualQueryDetection();
+
void startPerceiving(in IVisualQueryDetectionVoiceInteractionCallback callback);
void stopPerceiving();
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 445446e..03796de 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -66,6 +66,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IHotwordRecognitionStatusCallback;
+import com.android.internal.app.IVisualQueryDetectionAttentionListener;
import com.android.internal.infra.ServiceConnector;
import com.android.server.LocalServices;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
@@ -328,6 +329,15 @@
session.startListeningFromMicLocked(audioFormat, callback);
}
+ public void setVisualQueryDetectionAttentionListenerLocked(
+ @Nullable IVisualQueryDetectionAttentionListener listener) {
+ final VisualQueryDetectorSession session = getVisualQueryDetectorSessionLocked();
+ if (session == null) {
+ return;
+ }
+ session.setVisualQueryDetectionAttentionListenerLocked(listener);
+ }
+
/**
* This method is only used by VisualQueryDetector.
*/
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VisualQueryDetectorSession.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VisualQueryDetectorSession.java
index 621c3de..33150d8 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VisualQueryDetectorSession.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VisualQueryDetectorSession.java
@@ -33,6 +33,7 @@
import android.util.Slog;
import com.android.internal.app.IHotwordRecognitionStatusCallback;
+import com.android.internal.app.IVisualQueryDetectionAttentionListener;
import java.io.PrintWriter;
import java.util.Objects;
@@ -49,6 +50,7 @@
final class VisualQueryDetectorSession extends DetectorSession {
private static final String TAG = "VisualQueryDetectorSession";
+ private IVisualQueryDetectionAttentionListener mAttentionListener;
private boolean mEgressingData;
private boolean mQueryStreaming;
@@ -64,6 +66,7 @@
logging);
mEgressingData = false;
mQueryStreaming = false;
+ mAttentionListener = null;
}
@Override
@@ -74,6 +77,11 @@
//TODO(b/261783819): Starts detection in VisualQueryDetectionService.
}
+ void setVisualQueryDetectionAttentionListenerLocked(
+ @Nullable IVisualQueryDetectionAttentionListener listener) {
+ mAttentionListener = listener;
+ }
+
@SuppressWarnings("GuardedBy")
void startPerceivingLocked(IVisualQueryDetectionVoiceInteractionCallback callback) {
if (DEBUG) {
@@ -86,15 +94,31 @@
@Override
public void onAttentionGained() {
Slog.v(TAG, "BinderCallback#onAttentionGained");
- //TODO check to see if there is an active SysUI listener registered
mEgressingData = true;
+ if (mAttentionListener == null) {
+ return;
+ }
+ try {
+ mAttentionListener.onAttentionGained();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error delivering attention gained event.", e);
+ return;
+ }
}
@Override
public void onAttentionLost() {
Slog.v(TAG, "BinderCallback#onAttentionLost");
- //TODO check to see if there is an active SysUI listener registered
mEgressingData = false;
+ if (mAttentionListener == null) {
+ return;
+ }
+ try {
+ mAttentionListener.onAttentionLost();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error delivering attention lost event.", e);
+ return;
+ }
}
@Override
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 38bf9c2..0abed0b 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -87,6 +87,7 @@
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IHotwordRecognitionStatusCallback;
+import com.android.internal.app.IVisualQueryDetectionAttentionListener;
import com.android.internal.app.IVoiceActionCheckCallback;
import com.android.internal.app.IVoiceInteractionManagerService;
import com.android.internal.app.IVoiceInteractionSessionListener;
@@ -1338,6 +1339,39 @@
}
}
+ @android.annotation.EnforcePermission(
+ android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
+ @Override
+ public void enableVisualQueryDetection(
+ IVisualQueryDetectionAttentionListener listener) {
+ super.enableVisualQueryDetection_enforcePermission();
+ synchronized (this) {
+
+ if (mImpl == null) {
+ Slog.w(TAG,
+ "enableVisualQueryDetection without running voice interaction service");
+ return;
+ }
+ this.mImpl.setVisualQueryDetectionAttentionListenerLocked(listener);
+ }
+ }
+
+ @android.annotation.EnforcePermission(
+ android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
+ @Override
+ public void disableVisualQueryDetection() {
+ super.disableVisualQueryDetection_enforcePermission();
+ synchronized (this) {
+ if (mImpl == null) {
+ Slog.w(TAG,
+ "disableVisualQueryDetection without running voice interaction"
+ + " service");
+ return;
+ }
+ this.mImpl.setVisualQueryDetectionAttentionListenerLocked(null);
+ }
+ }
+
@Override
public void startPerceiving(
IVisualQueryDetectionVoiceInteractionCallback callback)
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 127195c..3dbd269 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -72,7 +72,9 @@
import android.util.Slog;
import android.view.IWindowManager;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IHotwordRecognitionStatusCallback;
+import com.android.internal.app.IVisualQueryDetectionAttentionListener;
import com.android.internal.app.IVoiceActionCheckCallback;
import com.android.internal.app.IVoiceInteractionSessionShowCallback;
import com.android.internal.app.IVoiceInteractor;
@@ -247,6 +249,7 @@
Context.RECEIVER_EXPORTED);
}
+ @GuardedBy("this")
public void grantImplicitAccessLocked(int grantRecipientUid, @Nullable Intent intent) {
final int grantRecipientAppId = UserHandle.getAppId(grantRecipientUid);
final int grantRecipientUserId = UserHandle.getUserId(grantRecipientUid);
@@ -256,6 +259,7 @@
/* direct= */ true);
}
+ @GuardedBy("this")
public boolean showSessionLocked(@Nullable Bundle args, int flags,
@Nullable String attributionTag,
@Nullable IVoiceInteractionSessionShowCallback showCallback,
@@ -328,6 +332,7 @@
}
}
+ @GuardedBy("this")
public boolean hideSessionLocked() {
if (mActiveSession != null) {
return mActiveSession.hideLocked();
@@ -335,6 +340,7 @@
return false;
}
+ @GuardedBy("this")
public boolean deliverNewSessionLocked(IBinder token,
IVoiceInteractionSession session, IVoiceInteractor interactor) {
if (mActiveSession == null || token != mActiveSession.mToken) {
@@ -345,6 +351,7 @@
return true;
}
+ @GuardedBy("this")
public int startVoiceActivityLocked(@Nullable String callingFeatureId, int callingPid,
int callingUid, IBinder token, Intent intent, String resolvedType) {
try {
@@ -367,6 +374,7 @@
}
}
+ @GuardedBy("this")
public int startAssistantActivityLocked(@Nullable String callingFeatureId, int callingPid,
int callingUid, IBinder token, Intent intent, String resolvedType) {
try {
@@ -389,6 +397,7 @@
}
}
+ @GuardedBy("this")
public void requestDirectActionsLocked(@NonNull IBinder token, int taskId,
@NonNull IBinder assistToken, @Nullable RemoteCallback cancellationCallback,
@NonNull RemoteCallback callback) {
@@ -444,6 +453,7 @@
}
}
+ @GuardedBy("this")
void performDirectActionLocked(@NonNull IBinder token, @NonNull String actionId,
@Nullable Bundle arguments, int taskId, IBinder assistToken,
@Nullable RemoteCallback cancellationCallback,
@@ -470,6 +480,7 @@
}
}
+ @GuardedBy("this")
public void setKeepAwakeLocked(IBinder token, boolean keepAwake) {
try {
if (mActiveSession == null || token != mActiveSession.mToken) {
@@ -482,6 +493,7 @@
}
}
+ @GuardedBy("this")
public void closeSystemDialogsLocked(IBinder token) {
try {
if (mActiveSession == null || token != mActiveSession.mToken) {
@@ -494,6 +506,7 @@
}
}
+ @GuardedBy("this")
public void finishLocked(IBinder token, boolean finishTask) {
if (mActiveSession == null || (!finishTask && token != mActiveSession.mToken)) {
Slog.w(TAG, "finish does not match active session");
@@ -503,6 +516,7 @@
mActiveSession = null;
}
+ @GuardedBy("this")
public void setDisabledShowContextLocked(int callingUid, int flags) {
int activeUid = mInfo.getServiceInfo().applicationInfo.uid;
if (callingUid != activeUid) {
@@ -512,6 +526,7 @@
mDisabledShowContext = flags;
}
+ @GuardedBy("this")
public int getDisabledShowContextLocked(int callingUid) {
int activeUid = mInfo.getServiceInfo().applicationInfo.uid;
if (callingUid != activeUid) {
@@ -521,6 +536,7 @@
return mDisabledShowContext;
}
+ @GuardedBy("this")
public int getUserDisabledShowContextLocked(int callingUid) {
int activeUid = mInfo.getServiceInfo().applicationInfo.uid;
if (callingUid != activeUid) {
@@ -534,6 +550,7 @@
return mInfo.getSupportsLocalInteraction();
}
+ @GuardedBy("this")
public void startListeningVisibleActivityChangedLocked(@NonNull IBinder token) {
if (DEBUG) {
Slog.d(TAG, "startListeningVisibleActivityChangedLocked: token=" + token);
@@ -546,6 +563,7 @@
mActiveSession.startListeningVisibleActivityChangedLocked();
}
+ @GuardedBy("this")
public void stopListeningVisibleActivityChangedLocked(@NonNull IBinder token) {
if (DEBUG) {
Slog.d(TAG, "stopListeningVisibleActivityChangedLocked: token=" + token);
@@ -558,6 +576,7 @@
mActiveSession.stopListeningVisibleActivityChangedLocked();
}
+ @GuardedBy("this")
public void notifyActivityDestroyedLocked(@NonNull IBinder activityToken) {
if (DEBUG) {
Slog.d(TAG, "notifyActivityDestroyedLocked activityToken=" + activityToken);
@@ -572,6 +591,7 @@
mActiveSession.notifyActivityDestroyedLocked(activityToken);
}
+ @GuardedBy("this")
public void notifyActivityEventChangedLocked(@NonNull IBinder activityToken, int type) {
if (DEBUG) {
Slog.d(TAG, "notifyActivityEventChangedLocked type=" + type);
@@ -586,6 +606,7 @@
mActiveSession.notifyActivityEventChangedLocked(activityToken, type);
}
+ @GuardedBy("this")
public void updateStateLocked(
@Nullable PersistableBundle options,
@Nullable SharedMemory sharedMemory,
@@ -606,6 +627,7 @@
}
}
+ @GuardedBy("this")
private void verifyDetectorForHotwordDetectionLocked(
@Nullable SharedMemory sharedMemory,
IHotwordRecognitionStatusCallback callback,
@@ -663,6 +685,7 @@
voiceInteractionServiceUid);
}
+ @GuardedBy("this")
private void verifyDetectorForVisualQueryDetectionLocked(@Nullable SharedMemory sharedMemory) {
Slog.v(TAG, "verifyDetectorForVisualQueryDetectionLocked");
@@ -701,6 +724,7 @@
}
}
+ @GuardedBy("this")
public void initAndVerifyDetectorLocked(
@NonNull Identity voiceInteractorIdentity,
@Nullable PersistableBundle options,
@@ -730,6 +754,7 @@
detectorType);
}
+ @GuardedBy("this")
public void destroyDetectorLocked(IBinder token) {
Slog.v(TAG, "destroyDetectorLocked");
@@ -748,6 +773,7 @@
}
}
+ @GuardedBy("this")
public void shutdownHotwordDetectionServiceLocked() {
if (DEBUG) {
Slog.d(TAG, "shutdownHotwordDetectionServiceLocked");
@@ -760,6 +786,16 @@
mHotwordDetectionConnection = null;
}
+ @GuardedBy("this")
+ public void setVisualQueryDetectionAttentionListenerLocked(
+ @Nullable IVisualQueryDetectionAttentionListener listener) {
+ if (mHotwordDetectionConnection == null) {
+ return;
+ }
+ mHotwordDetectionConnection.setVisualQueryDetectionAttentionListenerLocked(listener);
+ }
+
+ @GuardedBy("this")
public void startPerceivingLocked(IVisualQueryDetectionVoiceInteractionCallback callback) {
if (DEBUG) {
Slog.d(TAG, "startPerceivingLocked");
@@ -773,6 +809,7 @@
mHotwordDetectionConnection.startPerceivingLocked(callback);
}
+ @GuardedBy("this")
public void stopPerceivingLocked() {
if (DEBUG) {
Slog.d(TAG, "stopPerceivingLocked");
@@ -786,6 +823,7 @@
mHotwordDetectionConnection.stopPerceivingLocked();
}
+ @GuardedBy("this")
public void startListeningFromMicLocked(
AudioFormat audioFormat,
IMicrophoneHotwordDetectionVoiceInteractionCallback callback) {
@@ -801,6 +839,7 @@
mHotwordDetectionConnection.startListeningFromMicLocked(audioFormat, callback);
}
+ @GuardedBy("this")
public void startListeningFromExternalSourceLocked(
ParcelFileDescriptor audioStream,
AudioFormat audioFormat,
@@ -825,6 +864,7 @@
options, token, callback);
}
+ @GuardedBy("this")
public void stopListeningFromMicLocked() {
if (DEBUG) {
Slog.d(TAG, "stopListeningFromMicLocked");
@@ -838,6 +878,7 @@
mHotwordDetectionConnection.stopListeningFromMicLocked();
}
+ @GuardedBy("this")
public void triggerHardwareRecognitionEventForTestLocked(
SoundTrigger.KeyphraseRecognitionEvent event,
IHotwordRecognitionStatusCallback callback) {
@@ -852,6 +893,7 @@
mHotwordDetectionConnection.triggerHardwareRecognitionEventForTestLocked(event, callback);
}
+ @GuardedBy("this")
public IRecognitionStatusCallback createSoundTriggerCallbackLocked(
IHotwordRecognitionStatusCallback callback) {
if (DEBUG) {
@@ -876,6 +918,7 @@
return null;
}
+ @GuardedBy("this")
boolean isIsolatedProcessLocked(@NonNull ServiceInfo serviceInfo) {
return (serviceInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) != 0
&& (serviceInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) == 0;
@@ -889,6 +932,7 @@
mHotwordDetectionConnection.forceRestart();
}
+ @GuardedBy("this")
void setDebugHotwordLoggingLocked(boolean logging) {
if (mHotwordDetectionConnection == null) {
Slog.w(TAG, "Failed to set temporary debug logging: no hotword detection active");
@@ -897,6 +941,7 @@
mHotwordDetectionConnection.setDebugHotwordLoggingLocked(logging);
}
+ @GuardedBy("this")
void resetHotwordDetectionConnectionLocked() {
if (DEBUG) {
Slog.d(TAG, "resetHotwordDetectionConnectionLocked");
@@ -911,6 +956,7 @@
mHotwordDetectionConnection = null;
}
+ @GuardedBy("this")
public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!mValid) {
pw.print(" NOT VALID: ");
@@ -947,6 +993,7 @@
}
}
+ @GuardedBy("this")
void startLocked() {
Intent intent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
intent.setComponent(mComponent);
@@ -971,6 +1018,7 @@
}
}
+ @GuardedBy("this")
void shutdownLocked() {
// If there is an active session, cancel it to allow it to clean up its window and other
// state.
@@ -998,6 +1046,7 @@
}
}
+ @GuardedBy("this")
void notifySoundModelsChangedLocked() {
if (mService == null) {
Slog.w(TAG, "Not bound to voice interaction service " + mComponent);