1 /* 2 * Copyright (C) 2022 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.dreams.touch; 18 19 import static com.android.systemui.dreams.touch.dagger.DreamTouchModule.INPUT_SESSION_NAME; 20 import static com.android.systemui.dreams.touch.dagger.DreamTouchModule.PILFER_ON_GESTURE_CONSUME; 21 22 import android.os.Looper; 23 import android.view.Choreographer; 24 import android.view.GestureDetector; 25 import android.view.MotionEvent; 26 27 import com.android.systemui.settings.DisplayTracker; 28 import com.android.systemui.shared.system.InputChannelCompat; 29 import com.android.systemui.shared.system.InputMonitorCompat; 30 31 import javax.inject.Inject; 32 import javax.inject.Named; 33 34 /** 35 * {@link InputSession} encapsulates components behind input monitoring and handles their lifecycle. 36 * Sessions are meant to be disposable; actions such as exclusively capturing touch events is modal 37 * and destroying the sessions allows a reset. Additionally, {@link InputSession} is meant to have 38 * a single listener for input and gesture. Any broadcasting must be accomplished elsewhere. 39 */ 40 public class InputSession { 41 private final InputMonitorCompat mInputMonitor; 42 private final InputChannelCompat.InputEventReceiver mInputEventReceiver; 43 private final GestureDetector mGestureDetector; 44 45 /** 46 * Default session constructor. 47 * @param sessionName The session name that will be applied to the underlying 48 * {@link InputMonitorCompat}. 49 * @param inputEventListener A listener to receive input events. 50 * @param gestureListener A listener to receive gesture events. 51 * @param pilferOnGestureConsume Whether touch events should be pilfered after a gesture has 52 * been consumed. 53 */ 54 @Inject InputSession(@amedINPUT_SESSION_NAME) String sessionName, InputChannelCompat.InputEventListener inputEventListener, GestureDetector.OnGestureListener gestureListener, DisplayTracker displayTracker, @Named(PILFER_ON_GESTURE_CONSUME) boolean pilferOnGestureConsume)55 public InputSession(@Named(INPUT_SESSION_NAME) String sessionName, 56 InputChannelCompat.InputEventListener inputEventListener, 57 GestureDetector.OnGestureListener gestureListener, 58 DisplayTracker displayTracker, 59 @Named(PILFER_ON_GESTURE_CONSUME) boolean pilferOnGestureConsume) { 60 mInputMonitor = new InputMonitorCompat(sessionName, displayTracker.getDefaultDisplayId()); 61 mGestureDetector = new GestureDetector(gestureListener); 62 63 mInputEventReceiver = mInputMonitor.getInputReceiver(Looper.getMainLooper(), 64 Choreographer.getInstance(), 65 ev -> { 66 // Process event. Since sometimes input may be a prerequisite for some 67 // gesture logic, process input first. 68 inputEventListener.onInputEvent(ev); 69 70 if (ev instanceof MotionEvent 71 && mGestureDetector.onTouchEvent((MotionEvent) ev) 72 && pilferOnGestureConsume) { 73 mInputMonitor.pilferPointers(); 74 } 75 }); 76 } 77 78 /** 79 * Destroys the {@link InputSession}, removing any component from listening to future touch 80 * events. 81 */ dispose()82 public void dispose() { 83 if (mInputEventReceiver != null) { 84 mInputEventReceiver.dispose(); 85 } 86 87 if (mInputMonitor != null) { 88 mInputMonitor.dispose(); 89 } 90 } 91 } 92