summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/res/values/config.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistManager.java78
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.java54
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java56
4 files changed, 103 insertions, 88 deletions
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index b6ef5947bcaf..d43f9f766b2c 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -914,4 +914,7 @@
"$packageName" part that will be replaced by the code with the package name of the target app.
-->
<string name="config_appStoreAppLinkTemplate" translatable="false"></string>
+
+ <!-- Flag controlling whether visual query attention detection has been enabled. -->
+ <bool name="config_enableVisualQueryAttentionDetection">false</bool>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index 2b83e6b05bbc..590056f2f8c2 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -23,6 +23,8 @@ import android.service.voice.VoiceInteractionSession;
import android.util.Log;
import com.android.internal.app.AssistUtils;
+import com.android.internal.app.IVisualQueryDetectionAttentionListener;
+import com.android.internal.app.IVisualQueryRecognitionStatusListener;
import com.android.internal.app.IVoiceInteractionSessionListener;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -39,10 +41,13 @@ import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.util.settings.SecureSettings;
-import javax.inject.Inject;
-
import dagger.Lazy;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
/**
* Class to manage everything related to assist in SystemUI.
*/
@@ -78,6 +83,18 @@ public class AssistManager {
void hide();
}
+ /**
+ * An interface for a listener that receives notification that visual query attention has
+ * either been gained or lost.
+ */
+ public interface VisualQueryAttentionListener {
+ /** Called when visual query attention has been gained. */
+ void onAttentionGained();
+
+ /** Called when visual query attention has been lost. */
+ void onAttentionLost();
+ }
+
private static final String TAG = "AssistManager";
// Note that VERBOSE logging may leak PII (e.g. transcription contents).
@@ -127,6 +144,23 @@ public class AssistManager {
private final SecureSettings mSecureSettings;
private final DeviceProvisionedController mDeviceProvisionedController;
+
+ private final List<VisualQueryAttentionListener> mVisualQueryAttentionListeners =
+ new ArrayList<>();
+
+ private final IVisualQueryDetectionAttentionListener mVisualQueryDetectionAttentionListener =
+ new IVisualQueryDetectionAttentionListener.Stub() {
+ @Override
+ public void onAttentionGained() {
+ mVisualQueryAttentionListeners.forEach(VisualQueryAttentionListener::onAttentionGained);
+ }
+
+ @Override
+ public void onAttentionLost() {
+ mVisualQueryAttentionListeners.forEach(VisualQueryAttentionListener::onAttentionLost);
+ }
+ };
+
private final CommandQueue mCommandQueue;
protected final AssistUtils mAssistUtils;
@@ -157,6 +191,7 @@ public class AssistManager {
mSecureSettings = secureSettings;
registerVoiceInteractionSessionListener();
+ registerVisualQueryRecognitionStatusListener();
mUiController = defaultUiController;
@@ -266,6 +301,24 @@ public class AssistManager {
mAssistUtils.hideCurrentSession();
}
+ /**
+ * Add the given {@link VisualQueryAttentionListener} to the list of listeners awaiting
+ * notification of gaining/losing visual query attention.
+ */
+ public void addVisualQueryAttentionListener(VisualQueryAttentionListener listener) {
+ if (!mVisualQueryAttentionListeners.contains(listener)) {
+ mVisualQueryAttentionListeners.add(listener);
+ }
+ }
+
+ /**
+ * Remove the given {@link VisualQueryAttentionListener} from the list of listeners awaiting
+ * notification of gaining/losing visual query attention.
+ */
+ public void removeVisualQueryAttentionListener(VisualQueryAttentionListener listener) {
+ mVisualQueryAttentionListeners.remove(listener);
+ }
+
private void startAssistInternal(Bundle args, @NonNull ComponentName assistComponent,
boolean isService) {
if (isService) {
@@ -326,6 +379,27 @@ public class AssistManager {
null, null);
}
+ private void registerVisualQueryRecognitionStatusListener() {
+ if (!mContext.getResources()
+ .getBoolean(R.bool.config_enableVisualQueryAttentionDetection)) {
+ return;
+ }
+
+ mAssistUtils.subscribeVisualQueryRecognitionStatus(
+ new IVisualQueryRecognitionStatusListener.Stub() {
+ @Override
+ public void onStartPerceiving() {
+ mAssistUtils.enableVisualQueryDetection(
+ mVisualQueryDetectionAttentionListener);
+ }
+
+ @Override
+ public void onStopPerceiving() {
+ mAssistUtils.disableVisualQueryDetection();
+ }
+ });
+ }
+
public void launchVoiceAssistFromKeyguard() {
mAssistUtils.launchVoiceAssistFromKeyguard();
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.java b/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.java
index c889ac214cda..4dd97d557b30 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.java
@@ -16,10 +16,9 @@
package com.android.systemui.dreams.conditions;
-import com.android.internal.app.AssistUtils;
-import com.android.internal.app.IVisualQueryDetectionAttentionListener;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.assist.AssistManager.VisualQueryAttentionListener;
import com.android.systemui.dagger.qualifiers.Application;
-import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.shared.condition.Condition;
import javax.inject.Inject;
@@ -30,12 +29,10 @@ import kotlinx.coroutines.CoroutineScope;
* {@link AssistantAttentionCondition} provides a signal when assistant has the user's attention.
*/
public class AssistantAttentionCondition extends Condition {
- private final DreamOverlayStateController mDreamOverlayStateController;
- private final AssistUtils mAssistUtils;
- private boolean mEnabled;
+ private final AssistManager mAssistManager;
- private final IVisualQueryDetectionAttentionListener mVisualQueryDetectionAttentionListener =
- new IVisualQueryDetectionAttentionListener.Stub() {
+ private final VisualQueryAttentionListener mVisualQueryAttentionListener =
+ new VisualQueryAttentionListener() {
@Override
public void onAttentionGained() {
updateCondition(true);
@@ -47,59 +44,26 @@ public class AssistantAttentionCondition extends Condition {
}
};
- private final DreamOverlayStateController.Callback mCallback =
- new DreamOverlayStateController.Callback() {
- @Override
- public void onStateChanged() {
- if (mDreamOverlayStateController.isDreamOverlayStatusBarVisible()) {
- enableVisualQueryDetection();
- } else {
- disableVisualQueryDetection();
- }
- }
- };
-
@Inject
public AssistantAttentionCondition(
@Application CoroutineScope scope,
- DreamOverlayStateController dreamOverlayStateController,
- AssistUtils assistUtils) {
+ AssistManager assistManager) {
super(scope);
- mDreamOverlayStateController = dreamOverlayStateController;
- mAssistUtils = assistUtils;
+ mAssistManager = assistManager;
}
@Override
protected void start() {
- mDreamOverlayStateController.addCallback(mCallback);
+ mAssistManager.addVisualQueryAttentionListener(mVisualQueryAttentionListener);
}
@Override
protected void stop() {
- disableVisualQueryDetection();
- mDreamOverlayStateController.removeCallback(mCallback);
+ mAssistManager.removeVisualQueryAttentionListener(mVisualQueryAttentionListener);
}
@Override
protected int getStartStrategy() {
return START_EAGERLY;
}
-
- private void enableVisualQueryDetection() {
- if (mEnabled) {
- return;
- }
- mEnabled = true;
- mAssistUtils.enableVisualQueryDetection(mVisualQueryDetectionAttentionListener);
- }
-
- private void disableVisualQueryDetection() {
- if (!mEnabled) {
- return;
- }
- mEnabled = false;
- mAssistUtils.disableVisualQueryDetection();
- // Make sure the condition is set to false as well.
- updateCondition(false);
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java
index 07cb5d88a515..6a178895839b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java
@@ -22,17 +22,14 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import android.os.RemoteException;
import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;
-import com.android.internal.app.AssistUtils;
-import com.android.internal.app.IVisualQueryDetectionAttentionListener;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.dreams.DreamOverlayStateController;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.assist.AssistManager.VisualQueryAttentionListener;
import com.android.systemui.shared.condition.Condition;
import org.junit.Before;
@@ -50,9 +47,7 @@ public class AssistantAttentionConditionTest extends SysuiTestCase {
@Mock
Condition.Callback mCallback;
@Mock
- AssistUtils mAssistUtils;
- @Mock
- DreamOverlayStateController mDreamOverlayStateController;
+ AssistManager mAssistManager;
@Mock
CoroutineScope mScope;
@@ -62,55 +57,34 @@ public class AssistantAttentionConditionTest extends SysuiTestCase {
public void setup() {
MockitoAnnotations.initMocks(this);
- mAssistantAttentionCondition =
- new AssistantAttentionCondition(mScope, mDreamOverlayStateController, mAssistUtils);
+ mAssistantAttentionCondition = new AssistantAttentionCondition(mScope, mAssistManager);
// Adding a callback also starts the condition.
mAssistantAttentionCondition.addCallback(mCallback);
}
@Test
public void testEnableVisualQueryDetection() {
- final ArgumentCaptor<DreamOverlayStateController.Callback> argumentCaptor =
- ArgumentCaptor.forClass(DreamOverlayStateController.Callback.class);
- verify(mDreamOverlayStateController).addCallback(argumentCaptor.capture());
-
- when(mDreamOverlayStateController.isDreamOverlayStatusBarVisible()).thenReturn(true);
- argumentCaptor.getValue().onStateChanged();
-
- verify(mAssistUtils).enableVisualQueryDetection(any());
+ verify(mAssistManager).addVisualQueryAttentionListener(
+ any(VisualQueryAttentionListener.class));
}
@Test
public void testDisableVisualQueryDetection() {
- final ArgumentCaptor<DreamOverlayStateController.Callback> argumentCaptor =
- ArgumentCaptor.forClass(DreamOverlayStateController.Callback.class);
- verify(mDreamOverlayStateController).addCallback(argumentCaptor.capture());
-
- when(mDreamOverlayStateController.isDreamOverlayStatusBarVisible()).thenReturn(true);
- argumentCaptor.getValue().onStateChanged();
- when(mDreamOverlayStateController.isDreamOverlayStatusBarVisible()).thenReturn(false);
- argumentCaptor.getValue().onStateChanged();
-
- verify(mAssistUtils).disableVisualQueryDetection();
+ mAssistantAttentionCondition.stop();
+ verify(mAssistManager).removeVisualQueryAttentionListener(
+ any(VisualQueryAttentionListener.class));
}
@Test
- public void testAttentionChangedTriggersCondition() throws RemoteException {
- final ArgumentCaptor<DreamOverlayStateController.Callback> callbackCaptor =
- ArgumentCaptor.forClass(DreamOverlayStateController.Callback.class);
- verify(mDreamOverlayStateController).addCallback(callbackCaptor.capture());
-
- when(mDreamOverlayStateController.isDreamOverlayStatusBarVisible()).thenReturn(true);
- callbackCaptor.getValue().onStateChanged();
-
- final ArgumentCaptor<IVisualQueryDetectionAttentionListener> listenerCaptor =
- ArgumentCaptor.forClass(IVisualQueryDetectionAttentionListener.class);
- verify(mAssistUtils).enableVisualQueryDetection(listenerCaptor.capture());
+ public void testAttentionChangedTriggersCondition() {
+ final ArgumentCaptor<VisualQueryAttentionListener> argumentCaptor =
+ ArgumentCaptor.forClass(VisualQueryAttentionListener.class);
+ verify(mAssistManager).addVisualQueryAttentionListener(argumentCaptor.capture());
- listenerCaptor.getValue().onAttentionGained();
+ argumentCaptor.getValue().onAttentionGained();
assertThat(mAssistantAttentionCondition.isConditionMet()).isTrue();
- listenerCaptor.getValue().onAttentionLost();
+ argumentCaptor.getValue().onAttentionLost();
assertThat(mAssistantAttentionCondition.isConditionMet()).isFalse();
verify(mCallback, times(2)).onConditionChanged(eq(mAssistantAttentionCondition));