| /* |
| * Copyright (C) 2013 DroidDriver committers |
| * |
| * 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 io.appium.droiddriver.util; |
| |
| import android.annotation.TargetApi; |
| import android.os.Build; |
| import android.os.SystemClock; |
| import android.util.Log; |
| import android.view.InputDevice; |
| import android.view.InputEvent; |
| import android.view.KeyEvent; |
| import android.view.MotionEvent; |
| |
| import io.appium.droiddriver.actions.InputInjector; |
| import io.appium.droiddriver.exceptions.ActionException; |
| |
| /** |
| * Helper methods to create InputEvents. |
| */ |
| public class Events { |
| /** |
| * @return a touch down event at the specified coordinates |
| */ |
| @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1) |
| private static MotionEvent newTouchDownEvent(int x, int y) { |
| long downTime = SystemClock.uptimeMillis(); |
| MotionEvent event = MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_DOWN, x, y, 1); |
| // TODO: Fix this if 'source' is required on devices older than HONEYCOMB_MR1. |
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) { |
| event.setSource(InputDevice.SOURCE_TOUCHSCREEN); |
| } |
| return event; |
| } |
| |
| /** |
| * @return a touch up event at the specified coordinates |
| */ |
| @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1) |
| private static MotionEvent newTouchUpEvent(long downTime, int x, int y) { |
| long eventTime = SystemClock.uptimeMillis(); |
| MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 1); |
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) { |
| event.setSource(InputDevice.SOURCE_TOUCHSCREEN); |
| } |
| return event; |
| } |
| |
| /** |
| * @return a touch move event at the specified coordinates |
| */ |
| @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1) |
| private static MotionEvent newTouchMoveEvent(long downTime, int x, int y) { |
| long eventTime = SystemClock.uptimeMillis(); |
| MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, x, y, 1); |
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) { |
| event.setSource(InputDevice.SOURCE_TOUCHSCREEN); |
| } |
| return event; |
| } |
| |
| @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1) |
| private static KeyEvent newKeyEvent(long downTime, long eventTime, int action, int keyCode, |
| int metaState) { |
| KeyEvent event = new KeyEvent(downTime, eventTime, action, keyCode, 0 /* repeat */, metaState); |
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) { |
| event.setSource(InputDevice.SOURCE_KEYBOARD); |
| } |
| return event; |
| } |
| |
| /** |
| * Injects {@code event}. {@code event} is recycled and should not be used |
| * after. |
| * |
| * @throws ActionException if injection failed |
| */ |
| private static void injectEvent(InputInjector injector, InputEvent event) { |
| injectEvent(Log.DEBUG, injector, event); |
| } |
| |
| private static void injectEvent(int priority, InputInjector injector, InputEvent event) { |
| Logs.call(priority, injector, "injectInputEvent", event); |
| try { |
| if (!injector.injectInputEvent(event)) { |
| throw new ActionException("Failed to inject " + event); |
| } |
| } finally { |
| if (event instanceof MotionEvent) { |
| ((MotionEvent) event).recycle(); |
| } |
| } |
| } |
| |
| public static long touchDown(InputInjector injector, int x, int y) { |
| MotionEvent downEvent = newTouchDownEvent(x, y); |
| long downTime = downEvent.getDownTime(); |
| injectEvent(injector, downEvent); |
| return downTime; |
| } |
| |
| public static void touchUp(InputInjector injector, long downTime, int x, int y) { |
| injectEvent(injector, newTouchUpEvent(downTime, x, y)); |
| } |
| |
| public static void touchMove(InputInjector injector, long downTime, int x, int y) { |
| injectEvent(Log.VERBOSE, injector, newTouchMoveEvent(downTime, x, y)); |
| } |
| |
| public static long keyDown(InputInjector injector, int keyCode, int metaState) { |
| long downTime = SystemClock.uptimeMillis(); |
| KeyEvent downEvent = newKeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN, keyCode, metaState); |
| injectEvent(injector, downEvent); |
| return downTime; |
| } |
| |
| public static void keyUp(InputInjector injector, long downTime, int keyCode, int metaState) { |
| injectEvent(injector, |
| newKeyEvent(downTime, SystemClock.uptimeMillis(), KeyEvent.ACTION_UP, keyCode, metaState)); |
| } |
| |
| private Events() {} |
| } |