1a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver/* 2a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * Copyright (C) 2015 The Android Open Source Project 3a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * 4a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * Licensed under the Apache License, Version 2.0 (the "License"); 5a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * you may not use this file except in compliance with the License. 6a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * You may obtain a copy of the License at 7a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * 8a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * http://www.apache.org/licenses/LICENSE-2.0 9a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * 10a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * Unless required by applicable law or agreed to in writing, software 11a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * distributed under the License is distributed on an "AS IS" BASIS, 12a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * See the License for the specific language governing permissions and 14a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * limitations under the License. 15a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver */ 16a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 17a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaverpackage com.android.server.accessibility; 18a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 19a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaverimport android.accessibilityservice.IAccessibilityServiceClient; 20a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaverimport android.os.Handler; 21a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaverimport android.os.Looper; 22a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaverimport android.os.Message; 23a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaverimport android.os.RemoteException; 24a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaverimport android.os.SystemClock; 25a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaverimport android.util.Slog; 26a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaverimport android.util.SparseArray; 27a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaverimport android.view.InputDevice; 28a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaverimport android.view.KeyEvent; 29a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaverimport android.view.MotionEvent; 30a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaverimport android.view.WindowManagerPolicy; 31a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaverimport android.view.accessibility.AccessibilityEvent; 32a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaverimport com.android.internal.os.SomeArgs; 33a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaverimport com.android.server.accessibility.AccessibilityManagerService.Service; 34a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 35a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaverimport java.util.List; 36a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 37a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver/** 38a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * Injects MotionEvents to permit {@code AccessibilityService}s to touch the screen on behalf of 39a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * users. 40a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * 41a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * All methods except {@code injectEvents} must be called only from the main thread. 42a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver */ 43a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaverpublic class MotionEventInjector implements EventStreamTransformation { 44a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver private static final String LOG_TAG = "MotionEventInjector"; 45a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver private static final int MESSAGE_SEND_MOTION_EVENT = 1; 46a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver private static final int MESSAGE_INJECT_EVENTS = 2; 47a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver private static final int MAX_POINTERS = 11; // Non-binding maximum 48a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 49a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver private final Handler mHandler; 50a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver private final SparseArray<Boolean> mOpenGesturesInProgress = new SparseArray<>(); 51a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 52a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver // These two arrays must be the same length 53a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver private MotionEvent.PointerProperties[] mPointerProperties = 54a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver new MotionEvent.PointerProperties[MAX_POINTERS]; 55a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver private MotionEvent.PointerCoords[] mPointerCoords = 56a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver new MotionEvent.PointerCoords[MAX_POINTERS]; 57a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver private EventStreamTransformation mNext; 58a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver private IAccessibilityServiceClient mServiceInterfaceForCurrentGesture; 59a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver private int mSequenceForCurrentGesture; 60a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver private int mSourceOfInjectedGesture = InputDevice.SOURCE_UNKNOWN; 61a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver private boolean mIsDestroyed = false; 62a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 63a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver /** 64a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * @param looper A looper on the main thread to use for dispatching new events 65a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver */ 66a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver public MotionEventInjector(Looper looper) { 67a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mHandler = new Handler(looper, new Callback()); 68a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 69a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 70a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver /** 71a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * Schedule a series of events for injection. These events must comprise a complete, valid 72a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * sequence. All gestures currently in progress will be cancelled, and all {@code downTime} 73a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * and {@code eventTime} fields will be offset by the current time. 74a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * 75a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * @param events The events to inject. Must all be from the same source. 76a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * @param serviceInterface The interface to call back with a result when the gesture is 77a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * either complete or cancelled. 78a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver */ 79a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver public void injectEvents(List<MotionEvent> events, 80a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver IAccessibilityServiceClient serviceInterface, int sequence) { 81a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver SomeArgs args = SomeArgs.obtain(); 82a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver args.arg1 = events; 83a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver args.arg2 = serviceInterface; 84a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver args.argi1 = sequence; 85a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_INJECT_EVENTS, args)); 86a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 87a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 88a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver @Override 89a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) { 90a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver cancelAnyPendingInjectedEvents(); 91a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver sendMotionEventToNext(event, rawEvent, policyFlags); 92a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 93a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 94a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver @Override 95a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver public void onKeyEvent(KeyEvent event, int policyFlags) { 96a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver if (mNext != null) { 97a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mNext.onKeyEvent(event, policyFlags); 98a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 99a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 100a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 101a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver @Override 102a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver public void onAccessibilityEvent(AccessibilityEvent event) { 103a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver if (mNext != null) { 104a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mNext.onAccessibilityEvent(event); 105a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 106a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 107a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 108a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver @Override 109a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver public void setNext(EventStreamTransformation next) { 110a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mNext = next; 111a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 112a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 113a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver @Override 114a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver public void clearEvents(int inputSource) { 115a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver /* 116a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * Reset state for motion events passing through so we won't send a cancel event for 117a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * them. 118a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver */ 119a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver if (!mHandler.hasMessages(MESSAGE_SEND_MOTION_EVENT)) { 120a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mOpenGesturesInProgress.put(inputSource, false); 121a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 122a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 123a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 124a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver @Override 125a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver public void onDestroy() { 126a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver cancelAnyPendingInjectedEvents(); 127a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mIsDestroyed = true; 128a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 129a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 130a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver private void injectEventsMainThread(List<MotionEvent> events, 131a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver IAccessibilityServiceClient serviceInterface, int sequence) { 132a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver if (mIsDestroyed) { 133a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver try { 134a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver serviceInterface.onPerformGestureResult(sequence, false); 135a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } catch (RemoteException re) { 136a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver Slog.e(LOG_TAG, "Error sending status with mIsDestroyed to " + serviceInterface, 137a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver re); 138a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 139a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver return; 140a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 141a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver cancelAnyPendingInjectedEvents(); 142a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mSourceOfInjectedGesture = events.get(0).getSource(); 143a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver cancelAnyGestureInProgress(mSourceOfInjectedGesture); 144a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mServiceInterfaceForCurrentGesture = serviceInterface; 145a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mSequenceForCurrentGesture = sequence; 146a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver if (mNext == null) { 147a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver notifyService(false); 148a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver return; 149a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 150a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 151a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver long startTime = SystemClock.uptimeMillis(); 152a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver for (int i = 0; i < events.size(); i++) { 153a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver MotionEvent event = events.get(i); 154a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver int numPointers = event.getPointerCount(); 155a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver if (numPointers > mPointerCoords.length) { 156a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mPointerCoords = new MotionEvent.PointerCoords[numPointers]; 157a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mPointerProperties = new MotionEvent.PointerProperties[numPointers]; 158a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 159a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver for (int j = 0; j < numPointers; j++) { 160a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver if (mPointerCoords[j] == null) { 161a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mPointerCoords[j] = new MotionEvent.PointerCoords(); 162a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mPointerProperties[j] = new MotionEvent.PointerProperties(); 163a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 164a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver event.getPointerCoords(j, mPointerCoords[j]); 165a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver event.getPointerProperties(j, mPointerProperties[j]); 166a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 167a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 168a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver /* 169a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * MotionEvent doesn't have a setEventTime() method (it carries around history data, 170a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver * which could become inconsistent), so we need to obtain a new one. 171a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver */ 172a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver MotionEvent offsetEvent = MotionEvent.obtain(startTime + event.getDownTime(), 173a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver startTime + event.getEventTime(), event.getAction(), numPointers, 174a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mPointerProperties, mPointerCoords, event.getMetaState(), 175a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver event.getButtonState(), event.getXPrecision(), event.getYPrecision(), 176a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver event.getDeviceId(), event.getEdgeFlags(), event.getSource(), 177a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver event.getFlags()); 178a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver Message message = mHandler.obtainMessage(MESSAGE_SEND_MOTION_EVENT, offsetEvent); 179a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mHandler.sendMessageDelayed(message, event.getEventTime()); 180a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 181a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 182a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 183a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver private void sendMotionEventToNext(MotionEvent event, MotionEvent rawEvent, 184a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver int policyFlags) { 185a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver if (mNext != null) { 186a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mNext.onMotionEvent(event, rawEvent, policyFlags); 187a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { 188a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mOpenGesturesInProgress.put(event.getSource(), true); 189a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 190a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver if ((event.getActionMasked() == MotionEvent.ACTION_UP) 191a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver || (event.getActionMasked() == MotionEvent.ACTION_CANCEL)) { 192a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mOpenGesturesInProgress.put(event.getSource(), false); 193a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 194a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 195a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 196a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 197a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver private void cancelAnyGestureInProgress(int source) { 198a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver if ((mNext != null) && mOpenGesturesInProgress.get(source, false)) { 199a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver long now = SystemClock.uptimeMillis(); 200a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver MotionEvent cancelEvent = 201a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver MotionEvent.obtain(now, now, MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0); 202a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver sendMotionEventToNext(cancelEvent, cancelEvent, 203a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver WindowManagerPolicy.FLAG_PASS_TO_USER); 204a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 205a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 206a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 207a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver private void cancelAnyPendingInjectedEvents() { 208a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver if (mHandler.hasMessages(MESSAGE_SEND_MOTION_EVENT)) { 209a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver cancelAnyGestureInProgress(mSourceOfInjectedGesture); 210a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mHandler.removeMessages(MESSAGE_SEND_MOTION_EVENT); 211a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver notifyService(false); 212a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 213a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 214a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 215a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 216a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver private void notifyService(boolean success) { 217a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver try { 218a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mServiceInterfaceForCurrentGesture.onPerformGestureResult( 219a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver mSequenceForCurrentGesture, success); 220a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } catch (RemoteException re) { 221a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver Slog.e(LOG_TAG, "Error sending motion event injection status to " 222a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver + mServiceInterfaceForCurrentGesture, re); 223a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 224a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 225a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver 226a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver private class Callback implements Handler.Callback { 227a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver @Override 228a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver public boolean handleMessage(Message message) { 229a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver if (message.what == MESSAGE_INJECT_EVENTS) { 230a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver SomeArgs args = (SomeArgs) message.obj; 231a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver injectEventsMainThread((List<MotionEvent>) args.arg1, 232a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver (IAccessibilityServiceClient) args.arg2, args.argi1); 233a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver args.recycle(); 234a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver return true; 235a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 236a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver if (message.what != MESSAGE_SEND_MOTION_EVENT) { 237a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver throw new IllegalArgumentException("Unknown message: " + message.what); 238a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 239a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver MotionEvent motionEvent = (MotionEvent) message.obj; 240a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver sendMotionEventToNext(motionEvent, motionEvent, 241a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver WindowManagerPolicy.FLAG_PASS_TO_USER); 242a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver // If the message queue is now empty, then this gesture is complete 243a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver if (!mHandler.hasMessages(MESSAGE_SEND_MOTION_EVENT)) { 244a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver notifyService(true); 245a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 246a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver return true; 247a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 248a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver } 249a6b64f5099b7be6e8384958d8bcddb97bb06ec93Phil Weaver} 250