| /* | |
| * Copyright (C) 2007 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 android.test; | |
| import static android.view.WindowInsets.Type.displayCutout; | |
| import static android.view.WindowInsets.Type.navigationBars; | |
| import android.app.Activity; | |
| import android.app.Instrumentation; | |
| import android.graphics.Insets; | |
| import android.graphics.Rect; | |
| import android.os.SystemClock; | |
| import android.util.Size; | |
| import android.view.Gravity; | |
| import android.view.MotionEvent; | |
| import android.view.View; | |
| import android.view.ViewConfiguration; | |
| import android.view.ViewGroup; | |
| import android.view.WindowInsets; | |
| import android.view.WindowManager; | |
| import android.view.WindowMetrics; | |
| /** | |
| * Reusable methods for generating touch events. These methods can be used with | |
| * InstrumentationTestCase or ActivityInstrumentationTestCase2 to simulate user interaction with | |
| * the application through a touch screen. | |
| * | |
| * @deprecated Use | |
| * <a href="{@docRoot}training/testing/ui-testing/espresso-testing.html">Espresso UI testing | |
| * framework</a> instead. New tests should be written using the | |
| * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>. | |
| */ | |
| @Deprecated | |
| public class TouchUtils { | |
| /** | |
| * Simulate touching in the center of the screen and dragging one quarter of the way down | |
| * @param test The test case that is being run | |
| * | |
| * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of | |
| * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for | |
| * configuring the Activity under test | |
| */ | |
| @Deprecated | |
| public static void dragQuarterScreenDown(ActivityInstrumentationTestCase test) { | |
| dragQuarterScreenDown(test, test.getActivity()); | |
| } | |
| /** | |
| * Simulate touching in the center of the screen and dragging one quarter of the way down | |
| * @param test The test case that is being run | |
| * @param activity The activity that is in the foreground of the test case | |
| */ | |
| public static void dragQuarterScreenDown(InstrumentationTestCase test, Activity activity) { | |
| WindowManager wm = activity.getWindowManager(); | |
| final Size size = getSizeExcludingNavigationBarAndCutout(wm.getCurrentWindowMetrics()); | |
| final float x = size.getWidth() / 2.0f; | |
| final float fromY = size.getHeight() * 0.5f; | |
| final float toY = size.getHeight() * 0.75f; | |
| drag(test, x, x, fromY, toY, 4); | |
| } | |
| /** | |
| * Simulate touching in the center of the screen and dragging one quarter of the way up | |
| * @param test The test case that is being run | |
| * | |
| * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of | |
| * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for | |
| * configuring the Activity under test | |
| */ | |
| @Deprecated | |
| public static void dragQuarterScreenUp(ActivityInstrumentationTestCase test) { | |
| dragQuarterScreenUp(test, test.getActivity()); | |
| } | |
| /** | |
| * Simulate touching in the center of the screen and dragging one quarter of the way up | |
| * @param test The test case that is being run | |
| * @param activity The activity that is in the foreground of the test case | |
| */ | |
| public static void dragQuarterScreenUp(InstrumentationTestCase test, Activity activity) { | |
| WindowManager wm = activity.getWindowManager(); | |
| final Size size = getSizeExcludingNavigationBarAndCutout(wm.getCurrentWindowMetrics()); | |
| final float x = size.getWidth() / 2.0f; | |
| final float fromY = size.getHeight() * 0.5f; | |
| final float toY = size.getHeight() * 0.25f; | |
| drag(test, x, x, fromY, toY, 4); | |
| } | |
| private static Size getSizeExcludingNavigationBarAndCutout(WindowMetrics windowMetrics) { | |
| WindowInsets windowInsets = windowMetrics.getWindowInsets(); | |
| final Insets insetsWithCutout = windowInsets | |
| .getInsetsIgnoringVisibility(navigationBars() | displayCutout()); | |
| final int insetsWidth = insetsWithCutout.left + insetsWithCutout.right; | |
| final int insetsHeight = insetsWithCutout.top + insetsWithCutout.bottom; | |
| Rect bounds = windowMetrics.getBounds(); | |
| return new Size(bounds.width() - insetsWidth, bounds.height() - insetsHeight); | |
| } | |
| /** | |
| * Scroll a ViewGroup to the bottom by repeatedly calling | |
| * {@link #dragQuarterScreenUp(InstrumentationTestCase, Activity)} | |
| * | |
| * @param test The test case that is being run | |
| * @param v The ViewGroup that should be dragged | |
| * | |
| * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of | |
| * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for | |
| * configuring the Activity under test | |
| */ | |
| @Deprecated | |
| public static void scrollToBottom(ActivityInstrumentationTestCase test, ViewGroup v) { | |
| scrollToBottom(test, test.getActivity(), v); | |
| } | |
| /** | |
| * Scroll a ViewGroup to the bottom by repeatedly calling | |
| * {@link #dragQuarterScreenUp(InstrumentationTestCase, Activity)} | |
| * | |
| * @param test The test case that is being run | |
| * @param activity The activity that is in the foreground of the test case | |
| * @param v The ViewGroup that should be dragged | |
| */ | |
| public static void scrollToBottom(InstrumentationTestCase test, Activity activity, | |
| ViewGroup v) { | |
| ViewStateSnapshot prev; | |
| ViewStateSnapshot next = new ViewStateSnapshot(v); | |
| do { | |
| prev = next; | |
| TouchUtils.dragQuarterScreenUp(test, activity); | |
| next = new ViewStateSnapshot(v); | |
| } while (!prev.equals(next)); | |
| } | |
| /** | |
| * Scroll a ViewGroup to the top by repeatedly calling | |
| * {@link #dragQuarterScreenDown(InstrumentationTestCase, Activity)} | |
| * | |
| * @param test The test case that is being run | |
| * @param v The ViewGroup that should be dragged | |
| * | |
| * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of | |
| * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for | |
| * configuring the Activity under test | |
| */ | |
| @Deprecated | |
| public static void scrollToTop(ActivityInstrumentationTestCase test, ViewGroup v) { | |
| scrollToTop(test, test.getActivity(), v); | |
| } | |
| /** | |
| * Scroll a ViewGroup to the top by repeatedly calling | |
| * {@link #dragQuarterScreenDown(InstrumentationTestCase, Activity)} | |
| * | |
| * @param test The test case that is being run | |
| * @param activity The activity that is in the foreground of the test case | |
| * @param v The ViewGroup that should be dragged | |
| */ | |
| public static void scrollToTop(InstrumentationTestCase test, Activity activity, ViewGroup v) { | |
| ViewStateSnapshot prev; | |
| ViewStateSnapshot next = new ViewStateSnapshot(v); | |
| do { | |
| prev = next; | |
| TouchUtils.dragQuarterScreenDown(test, activity); | |
| next = new ViewStateSnapshot(v); | |
| } while (!prev.equals(next)); | |
| } | |
| /** | |
| * Simulate touching the center of a view and dragging to the bottom of the screen. | |
| * | |
| * @param test The test case that is being run | |
| * @param v The view that should be dragged | |
| * | |
| * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of | |
| * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for | |
| * configuring the Activity under test | |
| */ | |
| @Deprecated | |
| public static void dragViewToBottom(ActivityInstrumentationTestCase test, View v) { | |
| dragViewToBottom(test, test.getActivity(), v, 4); | |
| } | |
| /** | |
| * Simulate touching the center of a view and dragging to the bottom of the screen. | |
| * | |
| * @param test The test case that is being run | |
| * @param activity The activity that is in the foreground of the test case | |
| * @param v The view that should be dragged | |
| */ | |
| public static void dragViewToBottom(InstrumentationTestCase test, Activity activity, View v) { | |
| dragViewToBottom(test, activity, v, 4); | |
| } | |
| /** | |
| * Simulate touching the center of a view and dragging to the bottom of the screen. | |
| * | |
| * @param test The test case that is being run | |
| * @param v The view that should be dragged | |
| * @param stepCount How many move steps to include in the drag | |
| * | |
| * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of | |
| * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for | |
| * configuring the Activity under test | |
| */ | |
| @Deprecated | |
| public static void dragViewToBottom(ActivityInstrumentationTestCase test, View v, | |
| int stepCount) { | |
| dragViewToBottom(test, test.getActivity(), v, stepCount); | |
| } | |
| /** | |
| * Simulate touching the center of a view and dragging to the bottom of the screen. | |
| * | |
| * @param test The test case that is being run | |
| * @param activity The activity that is in the foreground of the test case | |
| * @param v The view that should be dragged | |
| * @param stepCount How many move steps to include in the drag | |
| */ | |
| public static void dragViewToBottom(InstrumentationTestCase test, Activity activity, View v, | |
| int stepCount) { | |
| WindowManager wm = activity.getWindowManager(); | |
| final int screenHeight = getSizeExcludingNavigationBarAndCutout( | |
| wm.getCurrentWindowMetrics()).getHeight(); | |
| int[] xy = new int[2]; | |
| v.getLocationOnScreen(xy); | |
| final int viewWidth = v.getWidth(); | |
| final int viewHeight = v.getHeight(); | |
| final float x = xy[0] + (viewWidth / 2.0f); | |
| float fromY = xy[1] + (viewHeight / 2.0f); | |
| float toY = screenHeight - 1; | |
| drag(test, x, x, fromY, toY, stepCount); | |
| } | |
| /** | |
| * Simulate touching the center of a view and releasing quickly (before the tap timeout). | |
| * | |
| * @param test The test case that is being run | |
| * @param v The view that should be clicked | |
| */ | |
| public static void tapView(InstrumentationTestCase test, View v) { | |
| int[] xy = new int[2]; | |
| v.getLocationOnScreen(xy); | |
| final int viewWidth = v.getWidth(); | |
| final int viewHeight = v.getHeight(); | |
| final float x = xy[0] + (viewWidth / 2.0f); | |
| float y = xy[1] + (viewHeight / 2.0f); | |
| Instrumentation inst = test.getInstrumentation(); | |
| long downTime = SystemClock.uptimeMillis(); | |
| long eventTime = SystemClock.uptimeMillis(); | |
| MotionEvent event = MotionEvent.obtain(downTime, eventTime, | |
| MotionEvent.ACTION_DOWN, x, y, 0); | |
| inst.sendPointerSync(event); | |
| inst.waitForIdleSync(); | |
| eventTime = SystemClock.uptimeMillis(); | |
| final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop(); | |
| event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, | |
| x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0); | |
| inst.sendPointerSync(event); | |
| inst.waitForIdleSync(); | |
| eventTime = SystemClock.uptimeMillis(); | |
| event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0); | |
| inst.sendPointerSync(event); | |
| inst.waitForIdleSync(); | |
| } | |
| /** | |
| * Simulate touching the center of a view and cancelling (so no onClick should | |
| * fire, etc). | |
| * | |
| * @param test The test case that is being run | |
| * @param v The view that should be clicked | |
| */ | |
| public static void touchAndCancelView(InstrumentationTestCase test, View v) { | |
| int[] xy = new int[2]; | |
| v.getLocationOnScreen(xy); | |
| final int viewWidth = v.getWidth(); | |
| final int viewHeight = v.getHeight(); | |
| final float x = xy[0] + (viewWidth / 2.0f); | |
| float y = xy[1] + (viewHeight / 2.0f); | |
| Instrumentation inst = test.getInstrumentation(); | |
| long downTime = SystemClock.uptimeMillis(); | |
| long eventTime = SystemClock.uptimeMillis(); | |
| MotionEvent event = MotionEvent.obtain(downTime, eventTime, | |
| MotionEvent.ACTION_DOWN, x, y, 0); | |
| inst.sendPointerSync(event); | |
| inst.waitForIdleSync(); | |
| eventTime = SystemClock.uptimeMillis(); | |
| final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop(); | |
| event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_CANCEL, | |
| x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0); | |
| inst.sendPointerSync(event); | |
| inst.waitForIdleSync(); | |
| } | |
| /** | |
| * Simulate touching the center of a view and releasing. | |
| * | |
| * @param test The test case that is being run | |
| * @param v The view that should be clicked | |
| */ | |
| public static void clickView(InstrumentationTestCase test, View v) { | |
| int[] xy = new int[2]; | |
| v.getLocationOnScreen(xy); | |
| final int viewWidth = v.getWidth(); | |
| final int viewHeight = v.getHeight(); | |
| final float x = xy[0] + (viewWidth / 2.0f); | |
| float y = xy[1] + (viewHeight / 2.0f); | |
| Instrumentation inst = test.getInstrumentation(); | |
| long downTime = SystemClock.uptimeMillis(); | |
| long eventTime = SystemClock.uptimeMillis(); | |
| MotionEvent event = MotionEvent.obtain(downTime, eventTime, | |
| MotionEvent.ACTION_DOWN, x, y, 0); | |
| inst.sendPointerSync(event); | |
| inst.waitForIdleSync(); | |
| eventTime = SystemClock.uptimeMillis(); | |
| final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop(); | |
| event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, | |
| x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0); | |
| inst.sendPointerSync(event); | |
| inst.waitForIdleSync(); | |
| eventTime = SystemClock.uptimeMillis(); | |
| event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0); | |
| inst.sendPointerSync(event); | |
| inst.waitForIdleSync(); | |
| try { | |
| Thread.sleep(1000); | |
| } catch (InterruptedException e) { | |
| e.printStackTrace(); | |
| } | |
| } | |
| /** | |
| * Simulate touching the center of a view, holding until it is a long press, and then releasing. | |
| * | |
| * @param test The test case that is being run | |
| * @param v The view that should be clicked | |
| * | |
| * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of | |
| * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for | |
| * configuring the Activity under test | |
| */ | |
| @Deprecated | |
| public static void longClickView(ActivityInstrumentationTestCase test, View v) { | |
| longClickView((InstrumentationTestCase) test, v); | |
| } | |
| /** | |
| * Simulate touching the center of a view, holding until it is a long press, and then releasing. | |
| * | |
| * @param test The test case that is being run | |
| * @param v The view that should be clicked | |
| */ | |
| public static void longClickView(InstrumentationTestCase test, View v) { | |
| int[] xy = new int[2]; | |
| v.getLocationOnScreen(xy); | |
| final int viewWidth = v.getWidth(); | |
| final int viewHeight = v.getHeight(); | |
| final float x = xy[0] + (viewWidth / 2.0f); | |
| float y = xy[1] + (viewHeight / 2.0f); | |
| Instrumentation inst = test.getInstrumentation(); | |
| long downTime = SystemClock.uptimeMillis(); | |
| long eventTime = SystemClock.uptimeMillis(); | |
| MotionEvent event = MotionEvent.obtain(downTime, eventTime, | |
| MotionEvent.ACTION_DOWN, x, y, 0); | |
| inst.sendPointerSync(event); | |
| inst.waitForIdleSync(); | |
| eventTime = SystemClock.uptimeMillis(); | |
| final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop(); | |
| event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, | |
| x + touchSlop / 2, y + touchSlop / 2, 0); | |
| inst.sendPointerSync(event); | |
| inst.waitForIdleSync(); | |
| try { | |
| Thread.sleep((long)(ViewConfiguration.getLongPressTimeout() * 1.5f)); | |
| } catch (InterruptedException e) { | |
| e.printStackTrace(); | |
| } | |
| eventTime = SystemClock.uptimeMillis(); | |
| event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0); | |
| inst.sendPointerSync(event); | |
| inst.waitForIdleSync(); | |
| } | |
| /** | |
| * Simulate touching the center of a view and dragging to the top of the screen. | |
| * | |
| * @param test The test case that is being run | |
| * @param v The view that should be dragged | |
| * | |
| * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of | |
| * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for | |
| * configuring the Activity under test | |
| */ | |
| @Deprecated | |
| public static void dragViewToTop(ActivityInstrumentationTestCase test, View v) { | |
| dragViewToTop((InstrumentationTestCase) test, v, 4); | |
| } | |
| /** | |
| * Simulate touching the center of a view and dragging to the top of the screen. | |
| * | |
| * @param test The test case that is being run | |
| * @param v The view that should be dragged | |
| * @param stepCount How many move steps to include in the drag | |
| * | |
| * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of | |
| * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for | |
| * configuring the Activity under test | |
| */ | |
| @Deprecated | |
| public static void dragViewToTop(ActivityInstrumentationTestCase test, View v, int stepCount) { | |
| dragViewToTop((InstrumentationTestCase) test, v, stepCount); | |
| } | |
| /** | |
| * Simulate touching the center of a view and dragging to the top of the screen. | |
| * | |
| * @param test The test case that is being run | |
| * @param v The view that should be dragged | |
| */ | |
| public static void dragViewToTop(InstrumentationTestCase test, View v) { | |
| dragViewToTop(test, v, 4); | |
| } | |
| /** | |
| * Simulate touching the center of a view and dragging to the top of the screen. | |
| * | |
| * @param test The test case that is being run | |
| * @param v The view that should be dragged | |
| * @param stepCount How many move steps to include in the drag | |
| */ | |
| public static void dragViewToTop(InstrumentationTestCase test, View v, int stepCount) { | |
| int[] xy = new int[2]; | |
| v.getLocationOnScreen(xy); | |
| final int viewWidth = v.getWidth(); | |
| final int viewHeight = v.getHeight(); | |
| final float x = xy[0] + (viewWidth / 2.0f); | |
| float fromY = xy[1] + (viewHeight / 2.0f); | |
| float toY = 0; | |
| drag(test, x, x, fromY, toY, stepCount); | |
| } | |
| /** | |
| * Get the location of a view. Use the gravity param to specify which part of the view to | |
| * return. | |
| * | |
| * @param v View to find | |
| * @param gravity A combination of (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, | |
| * RIGHT) | |
| * @param xy Result | |
| */ | |
| private static void getStartLocation(View v, int gravity, int[] xy) { | |
| v.getLocationOnScreen(xy); | |
| final int viewWidth = v.getWidth(); | |
| final int viewHeight = v.getHeight(); | |
| switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) { | |
| case Gravity.TOP: | |
| break; | |
| case Gravity.CENTER_VERTICAL: | |
| xy[1] += viewHeight / 2; | |
| break; | |
| case Gravity.BOTTOM: | |
| xy[1] += viewHeight - 1; | |
| break; | |
| default: | |
| // Same as top -- do nothing | |
| } | |
| switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) { | |
| case Gravity.LEFT: | |
| break; | |
| case Gravity.CENTER_HORIZONTAL: | |
| xy[0] += viewWidth / 2; | |
| break; | |
| case Gravity.RIGHT: | |
| xy[0] += viewWidth - 1; | |
| break; | |
| default: | |
| // Same as left -- do nothing | |
| } | |
| } | |
| /** | |
| * Simulate touching a view and dragging it by the specified amount. | |
| * | |
| * @param test The test case that is being run | |
| * @param v The view that should be dragged | |
| * @param gravity Which part of the view to use for the initial down event. A combination of | |
| * (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT) | |
| * @param deltaX Amount to drag horizontally in pixels | |
| * @param deltaY Amount to drag vertically in pixels | |
| * | |
| * @return distance in pixels covered by the drag | |
| * | |
| * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of | |
| * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for | |
| * configuring the Activity under test | |
| */ | |
| @Deprecated | |
| public static int dragViewBy(ActivityInstrumentationTestCase test, View v, int gravity, | |
| int deltaX, int deltaY) { | |
| return dragViewBy((InstrumentationTestCase) test, v, gravity, deltaX, deltaY); | |
| } | |
| /** | |
| * Simulate touching a view and dragging it by the specified amount. | |
| * | |
| * @param test The test case that is being run | |
| * @param v The view that should be dragged | |
| * @param gravity Which part of the view to use for the initial down event. A combination of | |
| * (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT) | |
| * @param deltaX Amount to drag horizontally in pixels | |
| * @param deltaY Amount to drag vertically in pixels | |
| * | |
| * @return distance in pixels covered by the drag | |
| * | |
| * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of | |
| * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for | |
| * configuring the Activity under test | |
| */ | |
| @Deprecated | |
| public static int dragViewBy(InstrumentationTestCase test, View v, int gravity, int deltaX, | |
| int deltaY) { | |
| int[] xy = new int[2]; | |
| getStartLocation(v, gravity, xy); | |
| final int fromX = xy[0]; | |
| final int fromY = xy[1]; | |
| int distance = (int) Math.hypot(deltaX, deltaY); | |
| drag(test, fromX, fromX + deltaX, fromY, fromY + deltaY, distance); | |
| return distance; | |
| } | |
| /** | |
| * Simulate touching a view and dragging it to a specified location. | |
| * | |
| * @param test The test case that is being run | |
| * @param v The view that should be dragged | |
| * @param gravity Which part of the view to use for the initial down event. A combination of | |
| * (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT) | |
| * @param toX Final location of the view after dragging | |
| * @param toY Final location of the view after dragging | |
| * | |
| * @return distance in pixels covered by the drag | |
| * | |
| * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of | |
| * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for | |
| * configuring the Activity under test | |
| */ | |
| @Deprecated | |
| public static int dragViewTo(ActivityInstrumentationTestCase test, View v, int gravity, int toX, | |
| int toY) { | |
| return dragViewTo((InstrumentationTestCase) test, v, gravity, toX, toY); | |
| } | |
| /** | |
| * Simulate touching a view and dragging it to a specified location. | |
| * | |
| * @param test The test case that is being run | |
| * @param v The view that should be dragged | |
| * @param gravity Which part of the view to use for the initial down event. A combination of | |
| * (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT) | |
| * @param toX Final location of the view after dragging | |
| * @param toY Final location of the view after dragging | |
| * | |
| * @return distance in pixels covered by the drag | |
| */ | |
| public static int dragViewTo(InstrumentationTestCase test, View v, int gravity, int toX, | |
| int toY) { | |
| int[] xy = new int[2]; | |
| getStartLocation(v, gravity, xy); | |
| final int fromX = xy[0]; | |
| final int fromY = xy[1]; | |
| int deltaX = fromX - toX; | |
| int deltaY = fromY - toY; | |
| int distance = (int)Math.hypot(deltaX, deltaY); | |
| drag(test, fromX, toX, fromY, toY, distance); | |
| return distance; | |
| } | |
| /** | |
| * Simulate touching a view and dragging it to a specified location. Only moves horizontally. | |
| * | |
| * @param test The test case that is being run | |
| * @param v The view that should be dragged | |
| * @param gravity Which part of the view to use for the initial down event. A combination of | |
| * (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT) | |
| * @param toX Final location of the view after dragging | |
| * | |
| * @return distance in pixels covered by the drag | |
| * | |
| * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of | |
| * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for | |
| * configuring the Activity under test | |
| */ | |
| @Deprecated | |
| public static int dragViewToX(ActivityInstrumentationTestCase test, View v, int gravity, | |
| int toX) { | |
| return dragViewToX((InstrumentationTestCase) test, v, gravity, toX); | |
| } | |
| /** | |
| * Simulate touching a view and dragging it to a specified location. Only moves horizontally. | |
| * | |
| * @param test The test case that is being run | |
| * @param v The view that should be dragged | |
| * @param gravity Which part of the view to use for the initial down event. A combination of | |
| * (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT) | |
| * @param toX Final location of the view after dragging | |
| * | |
| * @return distance in pixels covered by the drag | |
| */ | |
| public static int dragViewToX(InstrumentationTestCase test, View v, int gravity, int toX) { | |
| int[] xy = new int[2]; | |
| getStartLocation(v, gravity, xy); | |
| final int fromX = xy[0]; | |
| final int fromY = xy[1]; | |
| int deltaX = fromX - toX; | |
| drag(test, fromX, toX, fromY, fromY, deltaX); | |
| return deltaX; | |
| } | |
| /** | |
| * Simulate touching a view and dragging it to a specified location. Only moves vertically. | |
| * | |
| * @param test The test case that is being run | |
| * @param v The view that should be dragged | |
| * @param gravity Which part of the view to use for the initial down event. A combination of | |
| * (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT) | |
| * @param toY Final location of the view after dragging | |
| * | |
| * @return distance in pixels covered by the drag | |
| * | |
| * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of | |
| * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for | |
| * configuring the Activity under test | |
| */ | |
| @Deprecated | |
| public static int dragViewToY(ActivityInstrumentationTestCase test, View v, int gravity, | |
| int toY) { | |
| return dragViewToY((InstrumentationTestCase) test, v, gravity, toY); | |
| } | |
| /** | |
| * Simulate touching a view and dragging it to a specified location. Only moves vertically. | |
| * | |
| * @param test The test case that is being run | |
| * @param v The view that should be dragged | |
| * @param gravity Which part of the view to use for the initial down event. A combination of | |
| * (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT) | |
| * @param toY Final location of the view after dragging | |
| * | |
| * @return distance in pixels covered by the drag | |
| */ | |
| public static int dragViewToY(InstrumentationTestCase test, View v, int gravity, int toY) { | |
| int[] xy = new int[2]; | |
| getStartLocation(v, gravity, xy); | |
| final int fromX = xy[0]; | |
| final int fromY = xy[1]; | |
| int deltaY = fromY - toY; | |
| drag(test, fromX, fromX, fromY, toY, deltaY); | |
| return deltaY; | |
| } | |
| /** | |
| * Simulate touching a specific location and dragging to a new location. | |
| * | |
| * @param test The test case that is being run | |
| * @param fromX X coordinate of the initial touch, in screen coordinates | |
| * @param toX Xcoordinate of the drag destination, in screen coordinates | |
| * @param fromY X coordinate of the initial touch, in screen coordinates | |
| * @param toY Y coordinate of the drag destination, in screen coordinates | |
| * @param stepCount How many move steps to include in the drag | |
| * | |
| * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of | |
| * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for | |
| * configuring the Activity under test | |
| */ | |
| @Deprecated | |
| public static void drag(ActivityInstrumentationTestCase test, float fromX, float toX, | |
| float fromY, float toY, int stepCount) { | |
| drag((InstrumentationTestCase) test, fromX, toX, fromY, toY, stepCount); | |
| } | |
| /** | |
| * Simulate touching a specific location and dragging to a new location. | |
| * | |
| * @param test The test case that is being run | |
| * @param fromX X coordinate of the initial touch, in screen coordinates | |
| * @param toX Xcoordinate of the drag destination, in screen coordinates | |
| * @param fromY X coordinate of the initial touch, in screen coordinates | |
| * @param toY Y coordinate of the drag destination, in screen coordinates | |
| * @param stepCount How many move steps to include in the drag | |
| */ | |
| public static void drag(InstrumentationTestCase test, float fromX, float toX, float fromY, | |
| float toY, int stepCount) { | |
| Instrumentation inst = test.getInstrumentation(); | |
| long downTime = SystemClock.uptimeMillis(); | |
| long eventTime = SystemClock.uptimeMillis(); | |
| float y = fromY; | |
| float x = fromX; | |
| float yStep = (toY - fromY) / stepCount; | |
| float xStep = (toX - fromX) / stepCount; | |
| MotionEvent event = MotionEvent.obtain(downTime, eventTime, | |
| MotionEvent.ACTION_DOWN, x, y, 0); | |
| inst.sendPointerSync(event); | |
| for (int i = 0; i < stepCount; ++i) { | |
| y += yStep; | |
| x += xStep; | |
| eventTime = SystemClock.uptimeMillis(); | |
| event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, x, y, 0); | |
| inst.sendPointerSync(event); | |
| } | |
| eventTime = SystemClock.uptimeMillis(); | |
| event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0); | |
| inst.sendPointerSync(event); | |
| inst.waitForIdleSync(); | |
| } | |
| private static class ViewStateSnapshot { | |
| final View mFirst; | |
| final View mLast; | |
| final int mFirstTop; | |
| final int mLastBottom; | |
| final int mChildCount; | |
| private ViewStateSnapshot(ViewGroup viewGroup) { | |
| mChildCount = viewGroup.getChildCount(); | |
| if (mChildCount == 0) { | |
| mFirst = mLast = null; | |
| mFirstTop = mLastBottom = Integer.MIN_VALUE; | |
| } else { | |
| mFirst = viewGroup.getChildAt(0); | |
| mLast = viewGroup.getChildAt(mChildCount - 1); | |
| mFirstTop = mFirst.getTop(); | |
| mLastBottom = mLast.getBottom(); | |
| } | |
| } | |
| @Override | |
| public boolean equals(Object o) { | |
| if (this == o) { | |
| return true; | |
| } | |
| if (o == null || getClass() != o.getClass()) { | |
| return false; | |
| } | |
| final ViewStateSnapshot that = (ViewStateSnapshot) o; | |
| return mFirstTop == that.mFirstTop && | |
| mLastBottom == that.mLastBottom && | |
| mFirst == that.mFirst && | |
| mLast == that.mLast && | |
| mChildCount == that.mChildCount; | |
| } | |
| @Override | |
| public int hashCode() { | |
| int result = mFirst != null ? mFirst.hashCode() : 0; | |
| result = 31 * result + (mLast != null ? mLast.hashCode() : 0); | |
| result = 31 * result + mFirstTop; | |
| result = 31 * result + mLastBottom; | |
| result = 31 * result + mChildCount; | |
| return result; | |
| } | |
| } | |
| } |