summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Coco Duan <cocod@google.com> 2024-02-08 18:15:25 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-02-08 18:15:25 +0000
commit43b8ccaa3427d2cde5f7c0b202006ce89270ec89 (patch)
treec0d3bdcac78402caa6761b71e19a09256c001214
parenta3c870d1d6f15719a9ef6edb6650c3867c2c6137 (diff)
parent0906c162a5b85fa9a535f2fdc5d2cfb7ea6b99e7 (diff)
Merge "Turn off glanceable hub touch handling on dream if disabled" into main
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/CommunalTouchHandlerTest.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/touch/CommunalTouchHandler.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java66
6 files changed, 160 insertions, 21 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/CommunalTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/CommunalTouchHandlerTest.java
index 2a9bc4a1d80e..8dcf9032759b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/CommunalTouchHandlerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/CommunalTouchHandlerTest.java
@@ -18,15 +18,20 @@ package com.android.systemui.dreams.touch;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.view.GestureDetector;
import android.view.MotionEvent;
+import androidx.lifecycle.Lifecycle;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.kosmos.KosmosJavaAdapter;
import com.android.systemui.shared.system.InputChannelCompat;
import com.android.systemui.statusbar.phone.CentralSurfaces;
@@ -39,28 +44,60 @@ import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.Optional;
+import java.util.concurrent.atomic.AtomicReference;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class CommunalTouchHandlerTest extends SysuiTestCase {
+ private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
+
@Mock
CentralSurfaces mCentralSurfaces;
@Mock
DreamTouchHandler.TouchSession mTouchSession;
CommunalTouchHandler mTouchHandler;
+ @Mock
+ Lifecycle mLifecycle;
private static final int INITIATION_WIDTH = 20;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
+ AtomicReference reference = new AtomicReference<>(null);
+ when(mLifecycle.getInternalScopeRef()).thenReturn(reference);
+ when(mLifecycle.getCurrentState()).thenReturn(Lifecycle.State.CREATED);
mTouchHandler = new CommunalTouchHandler(
Optional.of(mCentralSurfaces),
- INITIATION_WIDTH);
+ INITIATION_WIDTH,
+ mKosmos.getCommunalInteractor(),
+ mLifecycle
+ );
+ }
+
+ @Test
+ public void communalTouchHandler_disabledByDefault() {
+ assertThat(mTouchHandler.isEnabled()).isFalse();
+ }
+
+ @Test
+ public void communalTouchHandler_disabled_whenCommunalUnavailable() {
+ mTouchHandler.mIsCommunalAvailableCallback.accept(false);
+ assertThat(mTouchHandler.isEnabled()).isFalse();
+
+ mTouchHandler.onSessionStart(mTouchSession);
+ verify(mTouchSession, never()).registerGestureListener(any());
+ }
+
+ @Test
+ public void communalTouchHandler_enabled_whenCommunalAvailable() {
+ mTouchHandler.mIsCommunalAvailableCallback.accept(true);
+ assertThat(mTouchHandler.isEnabled()).isTrue();
}
@Test
public void testEventPropagation() {
+ mTouchHandler.mIsCommunalAvailableCallback.accept(true);
final MotionEvent motionEvent = Mockito.mock(MotionEvent.class);
final ArgumentCaptor<InputChannelCompat.InputEventListener>
@@ -75,6 +112,7 @@ public class CommunalTouchHandlerTest extends SysuiTestCase {
@Test
public void testTouchPilferingOnScroll() {
+ mTouchHandler.mIsCommunalAvailableCallback.accept(true);
final MotionEvent motionEvent1 = Mockito.mock(MotionEvent.class);
final MotionEvent motionEvent2 = Mockito.mock(MotionEvent.class);
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/CommunalTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/CommunalTouchHandler.java
index 05279fcdf51c..e5c705f608b9 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/CommunalTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/CommunalTouchHandler.java
@@ -17,15 +17,21 @@
package com.android.systemui.dreams.touch;
import static com.android.systemui.dreams.touch.dagger.ShadeModule.COMMUNAL_GESTURE_INITIATION_WIDTH;
+import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
import android.graphics.Rect;
import android.graphics.Region;
import android.view.GestureDetector;
import android.view.MotionEvent;
+import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.Lifecycle;
+
+import com.android.systemui.communal.domain.interactor.CommunalInteractor;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import java.util.Optional;
+import java.util.function.Consumer;
import javax.inject.Inject;
import javax.inject.Named;
@@ -34,17 +40,49 @@ import javax.inject.Named;
public class CommunalTouchHandler implements DreamTouchHandler {
private final int mInitiationWidth;
private final Optional<CentralSurfaces> mCentralSurfaces;
+ private final Lifecycle mLifecycle;
+ private final CommunalInteractor mCommunalInteractor;
+ private Boolean mIsEnabled = false;
+
+ @VisibleForTesting
+ final Consumer<Boolean> mIsCommunalAvailableCallback =
+ isAvailable -> {
+ setIsEnabled(isAvailable);
+ };
@Inject
public CommunalTouchHandler(
Optional<CentralSurfaces> centralSurfaces,
- @Named(COMMUNAL_GESTURE_INITIATION_WIDTH) int initiationWidth) {
+ @Named(COMMUNAL_GESTURE_INITIATION_WIDTH) int initiationWidth,
+ CommunalInteractor communalInteractor,
+ Lifecycle lifecycle) {
mInitiationWidth = initiationWidth;
mCentralSurfaces = centralSurfaces;
+ mLifecycle = lifecycle;
+ mCommunalInteractor = communalInteractor;
+
+ collectFlow(
+ mLifecycle,
+ mCommunalInteractor.isCommunalAvailable(),
+ mIsCommunalAvailableCallback
+ );
+ }
+
+ @Override
+ public Boolean isEnabled() {
+ return mIsEnabled;
+ }
+
+ @Override
+ public void setIsEnabled(Boolean enabled) {
+ mIsEnabled = enabled;
}
@Override
public void onSessionStart(TouchSession session) {
+ if (!mIsEnabled) {
+ return;
+ }
mCentralSurfaces.ifPresent(surfaces -> handleSessionStart(surfaces, session));
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java
index aca621bd9e55..55a9c0c4de99 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java
@@ -292,6 +292,9 @@ public class DreamOverlayTouchMonitor {
new HashMap<>();
for (DreamTouchHandler handler : mHandlers) {
+ if (!handler.isEnabled()) {
+ continue;
+ }
final Rect maxBounds = mDisplayHelper.getMaxBounds(ev.getDisplayId(),
TYPE_APPLICATION_OVERLAY);
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java
index b37010cfc07b..72ad45d1055c 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java
@@ -86,6 +86,20 @@ public interface DreamTouchHandler {
}
/**
+ * Returns whether the handler is enabled to handle touch on dream.
+ * @return isEnabled state. By default it's true.
+ */
+ default Boolean isEnabled() {
+ return true;
+ }
+
+ /**
+ * Sets whether to enable the handler to handle touch on dream.
+ * @param enabled new value to be set whether to enable the handler.
+ */
+ default void setIsEnabled(Boolean enabled){}
+
+ /**
* Returns the region the touch handler is interested in. By default, no region is specified,
* indicating the entire screen should be considered.
* @param region A {@link Region} that is passed in to the target entry touch region.
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt
index 0d0a6469d674..46ce5f2623de 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt
@@ -18,6 +18,7 @@ package com.android.systemui.util.kotlin
import android.view.View
import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.coroutineScope
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -76,6 +77,23 @@ fun <T> collectFlow(
}
}
+/**
+ * Collect information for the given [flow], calling [consumer] for each emitted event. Defaults to
+ * [LifeCycle.State.CREATED] which is mapped over from the equivalent definition for collecting the
+ * flow on a view.
+ */
+@JvmOverloads
+fun <T> collectFlow(
+ lifecycle: Lifecycle,
+ flow: Flow<T>,
+ consumer: Consumer<T>,
+ state: Lifecycle.State = Lifecycle.State.CREATED,
+) {
+ lifecycle.coroutineScope.launch {
+ lifecycle.repeatOnLifecycle(state) { flow.collect { consumer.accept(it) } }
+ }
+}
+
fun <A, B, R> combineFlows(flow1: Flow<A>, flow2: Flow<B>, bifunction: (A, B) -> R): Flow<R> {
return combine(flow1, flow2, bifunction)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java
index 21397d97b578..1c6f25147a1e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java
@@ -153,7 +153,7 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase {
@Test
public void testReportedDisplayBounds() {
- final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
+ final DreamTouchHandler touchHandler = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler)
.collect(Collectors.toCollection(HashSet::new)));
@@ -175,7 +175,7 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase {
@Test
public void testEntryTouchZone() {
- final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
+ final DreamTouchHandler touchHandler = createTouchHandler();
final Rect touchArea = new Rect(4, 4, 8 , 8);
doAnswer(invocation -> {
@@ -203,10 +203,10 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase {
@Test
public void testSessionCount() {
- final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
+ final DreamTouchHandler touchHandler = createTouchHandler();
final Rect touchArea = new Rect(4, 4, 8 , 8);
- final DreamTouchHandler unzonedTouchHandler = Mockito.mock(DreamTouchHandler.class);
+ final DreamTouchHandler unzonedTouchHandler = createTouchHandler();
doAnswer(invocation -> {
final Region region = (Region) invocation.getArguments()[1];
region.set(touchArea);
@@ -248,9 +248,28 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase {
}
}
+
@Test
- public void testInputEventPropagation() {
+ public void testNoActiveSessionWhenHandlerDisabled() {
final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
+ // disable the handler
+ when(touchHandler.isEnabled()).thenReturn(false);
+
+ final Environment environment = new Environment(Stream.of(touchHandler)
+ .collect(Collectors.toCollection(HashSet::new)));
+ final MotionEvent initialEvent = Mockito.mock(MotionEvent.class);
+ when(initialEvent.getX()).thenReturn(5.0f);
+ when(initialEvent.getY()).thenReturn(5.0f);
+ environment.publishInputEvent(initialEvent);
+
+ // Make sure there is no active session.
+ verify(touchHandler, never()).onSessionStart(any());
+ verify(touchHandler, never()).getTouchInitiationRegion(any(), any());
+ }
+
+ @Test
+ public void testInputEventPropagation() {
+ final DreamTouchHandler touchHandler = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler)
.collect(Collectors.toCollection(HashSet::new)));
@@ -270,7 +289,7 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase {
@Test
public void testInputEventPropagationAfterRemoval() {
- final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
+ final DreamTouchHandler touchHandler = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler)
.collect(Collectors.toCollection(HashSet::new)));
@@ -294,7 +313,7 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase {
@Test
public void testInputGesturePropagation() {
- final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
+ final DreamTouchHandler touchHandler = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler)
.collect(Collectors.toCollection(HashSet::new)));
@@ -313,7 +332,7 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase {
@Test
public void testGestureConsumption() {
- final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
+ final DreamTouchHandler touchHandler = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler)
.collect(Collectors.toCollection(HashSet::new)));
@@ -336,8 +355,9 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase {
@Test
public void testBroadcast() {
- final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
- final DreamTouchHandler touchHandler2 = Mockito.mock(DreamTouchHandler.class);
+ final DreamTouchHandler touchHandler = createTouchHandler();
+ final DreamTouchHandler touchHandler2 = createTouchHandler();
+ when(touchHandler2.isEnabled()).thenReturn(true);
final Environment environment = new Environment(Stream.of(touchHandler, touchHandler2)
.collect(Collectors.toCollection(HashSet::new)));
@@ -361,7 +381,7 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase {
@Test
public void testPush() throws InterruptedException, ExecutionException {
- final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
+ final DreamTouchHandler touchHandler = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler)
.collect(Collectors.toCollection(HashSet::new)));
@@ -404,7 +424,8 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase {
@Test
public void testPop() {
- final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
+ final DreamTouchHandler touchHandler = createTouchHandler();
+
final DreamTouchHandler.TouchSession.Callback callback =
Mockito.mock(DreamTouchHandler.TouchSession.Callback.class);
@@ -424,7 +445,7 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase {
@Test
public void testPauseWithNoActiveSessions() {
- final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
+ final DreamTouchHandler touchHandler = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler)
.collect(Collectors.toCollection(HashSet::new)));
@@ -438,7 +459,7 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase {
@Test
public void testDeferredPauseWithActiveSessions() {
- final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
+ final DreamTouchHandler touchHandler = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler)
.collect(Collectors.toCollection(HashSet::new)));
@@ -476,7 +497,7 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase {
@Test
public void testDestroyWithActiveSessions() {
- final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
+ final DreamTouchHandler touchHandler = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler)
.collect(Collectors.toCollection(HashSet::new)));
@@ -509,9 +530,8 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase {
@Test
public void testPilfering() {
- final DreamTouchHandler touchHandler1 = Mockito.mock(DreamTouchHandler.class);
- final DreamTouchHandler touchHandler2 = Mockito.mock(DreamTouchHandler.class);
-
+ final DreamTouchHandler touchHandler1 = createTouchHandler();
+ final DreamTouchHandler touchHandler2 = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler1, touchHandler2)
.collect(Collectors.toCollection(HashSet::new)));
@@ -543,7 +563,8 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase {
@Test
public void testOnRemovedCallbackOnStopMonitoring() {
- final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
+ final DreamTouchHandler touchHandler = createTouchHandler();
+
final DreamTouchHandler.TouchSession.Callback callback =
Mockito.mock(DreamTouchHandler.TouchSession.Callback.class);
@@ -607,4 +628,11 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase {
DreamTouchHandler handler) {
return registerInputEventListener(captureSession(handler));
}
+
+ private DreamTouchHandler createTouchHandler() {
+ final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
+ // enable the handler by default
+ when(touchHandler.isEnabled()).thenReturn(true);
+ return touchHandler;
+ }
}