Refactor InputSession dependencies.
This changelist moves InputSession dependencies into a submodule of the
current InputSession component.
Bug: 333596426
Test: atest InputSessionTest
Flag: N/A
Change-Id: I2769b0ad21f9ed765380033b97ca9b88cb0702b6
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/InputSession.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/InputSession.java
index e1d0339..e72839f 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/InputSession.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/InputSession.java
@@ -16,7 +16,6 @@
package com.android.systemui.dreams.touch;
-import static com.android.systemui.dreams.touch.dagger.DreamTouchModule.INPUT_SESSION_NAME;
import static com.android.systemui.dreams.touch.dagger.DreamTouchModule.PILFER_ON_GESTURE_CONSUME;
import android.os.Looper;
@@ -24,7 +23,7 @@
import android.view.GestureDetector;
import android.view.MotionEvent;
-import com.android.systemui.settings.DisplayTracker;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.shared.system.InputChannelCompat;
import com.android.systemui.shared.system.InputMonitorCompat;
@@ -44,24 +43,26 @@
/**
* Default session constructor.
- * @param sessionName The session name that will be applied to the underlying
- * {@link InputMonitorCompat}.
+ * @param inputMonitor Input monitor to track input events.
+ * @param gestureDetector Gesture detector for detecting gestures.
* @param inputEventListener A listener to receive input events.
- * @param gestureListener A listener to receive gesture events.
+ * @param choreographer Choreographer to use with the input receiver.
+ * @param looper Looper to use with the input receiver
* @param pilferOnGestureConsume Whether touch events should be pilfered after a gesture has
* been consumed.
*/
@Inject
- public InputSession(@Named(INPUT_SESSION_NAME) String sessionName,
+ public InputSession(
+ InputMonitorCompat inputMonitor,
+ GestureDetector gestureDetector,
InputChannelCompat.InputEventListener inputEventListener,
- GestureDetector.OnGestureListener gestureListener,
- DisplayTracker displayTracker,
+ Choreographer choreographer,
+ @Main Looper looper,
@Named(PILFER_ON_GESTURE_CONSUME) boolean pilferOnGestureConsume) {
- mInputMonitor = new InputMonitorCompat(sessionName, displayTracker.getDefaultDisplayId());
- mGestureDetector = new GestureDetector(gestureListener);
+ mInputMonitor = inputMonitor;
+ mGestureDetector = gestureDetector;
- mInputEventReceiver = mInputMonitor.getInputReceiver(Looper.getMainLooper(),
- Choreographer.getInstance(),
+ mInputEventReceiver = mInputMonitor.getInputReceiver(looper, choreographer,
ev -> {
// Process event. Since sometimes input may be a prerequisite for some
// gesture logic, process input first.
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/InputSessionComponent.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/InputSessionComponent.java
index ad59a2e..0b14521 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/InputSessionComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/InputSessionComponent.java
@@ -24,16 +24,18 @@
import com.android.systemui.dreams.touch.InputSession;
import com.android.systemui.shared.system.InputChannelCompat;
-import javax.inject.Named;
-
import dagger.BindsInstance;
import dagger.Subcomponent;
+import javax.inject.Named;
+
/**
* {@link InputSessionComponent} generates {@link InputSession} with specific instances bound for
* the session name and whether touches should be pilfered when consumed.
*/
-@Subcomponent
+@Subcomponent(
+ modules = { InputSessionModule.class }
+)
public interface InputSessionComponent {
/**
* Generates {@link InputSessionComponent}.
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/InputSessionModule.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/InputSessionModule.java
new file mode 100644
index 0000000..dfab666
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/InputSessionModule.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2024 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.systemui.dreams.touch.dagger;
+
+import static com.android.systemui.dreams.touch.dagger.DreamTouchModule.INPUT_SESSION_NAME;
+
+import android.view.GestureDetector;
+
+import com.android.systemui.settings.DisplayTracker;
+import com.android.systemui.shared.system.InputMonitorCompat;
+
+import dagger.Module;
+import dagger.Provides;
+
+import javax.inject.Named;
+
+
+/**
+ * Module for providing dependencies to {@link com.android.systemui.dreams.touch.InputSession}.
+ */
+@Module
+public interface InputSessionModule {
+ /** */
+ @Provides
+ static InputMonitorCompat providesInputMonitorCompat(@Named(INPUT_SESSION_NAME) String name,
+ DisplayTracker displayTracker) {
+ return new InputMonitorCompat(name, displayTracker.getDefaultDisplayId());
+ }
+
+ /** */
+ @Provides
+ static GestureDetector providesGestureDetector(
+ android.view.GestureDetector.OnGestureListener gestureListener) {
+ return new GestureDetector(gestureListener);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/InputSessionTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/InputSessionTest.java
new file mode 100644
index 0000000..3180e75
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/InputSessionTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2024 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.systemui.dreams.touch;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.Choreographer;
+import android.view.GestureDetector;
+import android.view.InputEvent;
+import android.view.MotionEvent;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.shared.system.InputChannelCompat;
+import com.android.systemui.shared.system.InputMonitorCompat;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * A test suite for exercising {@link InputSession}.
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper()
+public class InputSessionTest extends SysuiTestCase {
+ @Mock
+ InputMonitorCompat mInputMonitor;
+
+ @Mock
+ GestureDetector mGestureDetector;
+
+ @Mock
+ InputChannelCompat.InputEventListener mInputEventListener;
+
+ TestableLooper mLooper;
+
+ @Mock
+ Choreographer mChoreographer;
+
+ @Mock
+ InputChannelCompat.InputEventReceiver mInputEventReceiver;
+
+ InputSession mSession;
+
+ InputChannelCompat.InputEventListener mEventListener;
+
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mLooper = TestableLooper.get(this);
+ }
+
+ private void createSession(boolean pilfer) {
+ when(mInputMonitor.getInputReceiver(any(), any(), any()))
+ .thenReturn(mInputEventReceiver);
+ mSession = new InputSession(mInputMonitor, mGestureDetector,
+ mInputEventListener, mChoreographer, mLooper.getLooper(), pilfer);
+ final ArgumentCaptor<InputChannelCompat.InputEventListener> listenerCaptor =
+ ArgumentCaptor.forClass(InputChannelCompat.InputEventListener.class);
+ verify(mInputMonitor).getInputReceiver(any(), any(), listenerCaptor.capture());
+ mEventListener = listenerCaptor.getValue();
+ }
+
+ /**
+ * Ensures consumed motion events are pilfered when option is set.
+ */
+ @Test
+ public void testPilferOnMotionEventGestureConsume() {
+ createSession(true);
+ final MotionEvent event = Mockito.mock(MotionEvent.class);
+ when(mGestureDetector.onTouchEvent(event)).thenReturn(true);
+ mEventListener.onInputEvent(event);
+ verify(mInputEventListener).onInputEvent(eq(event));
+ verify(mInputMonitor).pilferPointers();
+ }
+
+ /**
+ * Ensures consumed motion events are not pilfered when option is not set.
+ */
+ @Test
+ public void testNoPilferOnMotionEventGestureConsume() {
+ createSession(false);
+ final MotionEvent event = Mockito.mock(MotionEvent.class);
+ when(mGestureDetector.onTouchEvent(event)).thenReturn(true);
+ mEventListener.onInputEvent(event);
+ verify(mInputEventListener).onInputEvent(eq(event));
+ verify(mInputMonitor, never()).pilferPointers();
+ }
+
+ /**
+ * Ensures input events are never pilfered.
+ */
+ @Test
+ public void testNoPilferOnInputEvent() {
+ createSession(true);
+ final InputEvent event = Mockito.mock(InputEvent.class);
+ mEventListener.onInputEvent(event);
+ verify(mInputEventListener).onInputEvent(eq(event));
+ verify(mInputMonitor, never()).pilferPointers();
+ }
+
+ /**
+ * Ensures components are properly disposed.
+ */
+ @Test
+ public void testDispose() {
+ createSession(true);
+ mSession.dispose();
+ verify(mInputMonitor).dispose();
+ verify(mInputEventReceiver).dispose();
+ }
+}