1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.ambient.touch; 18 19 import static org.mockito.ArgumentMatchers.any; 20 import static org.mockito.ArgumentMatchers.eq; 21 import static org.mockito.Mockito.never; 22 import static org.mockito.Mockito.times; 23 import static org.mockito.Mockito.verify; 24 import static org.mockito.Mockito.when; 25 26 import android.platform.test.annotations.EnableFlags; 27 import android.testing.TestableLooper; 28 import android.view.Choreographer; 29 import android.view.GestureDetector; 30 import android.view.InputEvent; 31 import android.view.MotionEvent; 32 33 import androidx.test.ext.junit.runners.AndroidJUnit4; 34 import androidx.test.filters.SmallTest; 35 36 import com.android.systemui.Flags; 37 import com.android.systemui.SysuiTestCase; 38 import com.android.systemui.shared.system.InputChannelCompat; 39 import com.android.systemui.shared.system.InputMonitorCompat; 40 41 import org.junit.Before; 42 import org.junit.Test; 43 import org.junit.runner.RunWith; 44 import org.mockito.ArgumentCaptor; 45 import org.mockito.Mock; 46 import org.mockito.Mockito; 47 import org.mockito.MockitoAnnotations; 48 49 /** 50 * A test suite for exercising {@link InputSession}. 51 */ 52 @SmallTest 53 @RunWith(AndroidJUnit4.class) 54 @TestableLooper.RunWithLooper() 55 public class InputSessionTest extends SysuiTestCase { 56 @Mock 57 InputMonitorCompat mInputMonitor; 58 59 @Mock 60 GestureDetector mGestureDetector; 61 62 @Mock 63 InputChannelCompat.InputEventListener mInputEventListener; 64 65 TestableLooper mLooper; 66 67 @Mock 68 Choreographer mChoreographer; 69 70 @Mock 71 InputChannelCompat.InputEventReceiver mInputEventReceiver; 72 73 InputSession mSession; 74 75 InputChannelCompat.InputEventListener mEventListener; 76 77 78 @Before setup()79 public void setup() { 80 MockitoAnnotations.initMocks(this); 81 mLooper = TestableLooper.get(this); 82 } 83 createSession(boolean pilfer)84 private void createSession(boolean pilfer) { 85 when(mInputMonitor.getInputReceiver(any(), any(), any())) 86 .thenReturn(mInputEventReceiver); 87 mSession = new InputSession(mInputMonitor, mGestureDetector, 88 mInputEventListener, mChoreographer, mLooper.getLooper(), pilfer); 89 final ArgumentCaptor<InputChannelCompat.InputEventListener> listenerCaptor = 90 ArgumentCaptor.forClass(InputChannelCompat.InputEventListener.class); 91 verify(mInputMonitor).getInputReceiver(any(), any(), listenerCaptor.capture()); 92 mEventListener = listenerCaptor.getValue(); 93 } 94 95 /** 96 * Ensures consumed motion events are pilfered when option is set. 97 */ 98 @Test testPilferOnMotionEventGestureConsume()99 public void testPilferOnMotionEventGestureConsume() { 100 createSession(true); 101 final MotionEvent event = Mockito.mock(MotionEvent.class); 102 when(mGestureDetector.onTouchEvent(event)).thenReturn(true); 103 mEventListener.onInputEvent(event); 104 verify(mInputEventListener).onInputEvent(eq(event)); 105 verify(mInputMonitor).pilferPointers(); 106 } 107 108 /** 109 * Ensures consumed motion events are not pilfered when option is not set. 110 */ 111 @Test testNoPilferOnMotionEventGestureConsume()112 public void testNoPilferOnMotionEventGestureConsume() { 113 createSession(false); 114 final MotionEvent event = Mockito.mock(MotionEvent.class); 115 when(mGestureDetector.onTouchEvent(event)).thenReturn(true); 116 mEventListener.onInputEvent(event); 117 verify(mInputEventListener).onInputEvent(eq(event)); 118 verify(mInputMonitor, never()).pilferPointers(); 119 } 120 121 /** 122 * Ensures input events are never pilfered. 123 */ 124 @Test testNoPilferOnInputEvent()125 public void testNoPilferOnInputEvent() { 126 createSession(true); 127 final InputEvent event = Mockito.mock(InputEvent.class); 128 mEventListener.onInputEvent(event); 129 verify(mInputEventListener).onInputEvent(eq(event)); 130 verify(mInputMonitor, never()).pilferPointers(); 131 } 132 133 @Test 134 @EnableFlags(Flags.FLAG_DREAM_INPUT_SESSION_PILFER_ONCE) testPilferOnce()135 public void testPilferOnce() { 136 createSession(true); 137 final MotionEvent event = Mockito.mock(MotionEvent.class); 138 when(mGestureDetector.onTouchEvent(event)).thenReturn(true); 139 mEventListener.onInputEvent(event); 140 mEventListener.onInputEvent(event); 141 verify(mInputEventListener, times(2)).onInputEvent(eq(event)); 142 verify(mInputMonitor, times(1)).pilferPointers(); 143 } 144 145 /** 146 * Ensures components are properly disposed. 147 */ 148 @Test testDispose()149 public void testDispose() { 150 createSession(true); 151 mSession.dispose(); 152 verify(mInputMonitor).dispose(); 153 verify(mInputEventReceiver).dispose(); 154 } 155 } 156