- add sources.
[platform/framework/web/crosswalk.git] / src / content / public / test / android / javatests / src / org / chromium / content / browser / test / util / TouchCommon.java
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.content.browser.test.util;
6
7 import android.os.SystemClock;
8 import android.view.MotionEvent;
9 import android.view.View;
10 import android.view.ViewConfiguration;
11 import android.test.ActivityInstrumentationTestCase2;
12
13 /**
14  * Touch-related functionality reused across test cases.
15  */
16 public class TouchCommon {
17     private ActivityInstrumentationTestCase2 mActivityTestCase;
18
19     // TODO(leandrogracia): This method should receive and use an activity
20     // instead of the ActivityInstrumentationTestCase2. However this is causing
21     // problems downstream. Any fix for this should be landed downstream first.
22     public TouchCommon(ActivityInstrumentationTestCase2 activityTestCase) {
23         mActivityTestCase = activityTestCase;
24     }
25
26     /**
27      * Starts (synchronously) a drag motion. Normally followed by dragTo() and dragEnd().
28      *
29      * @param x
30      * @param y
31      * @param downTime (in ms)
32      * @see TouchUtils
33      */
34     public void dragStart(float x, float y, long downTime) {
35         MotionEvent event = MotionEvent.obtain(downTime, downTime,
36                 MotionEvent.ACTION_DOWN, x, y, 0);
37         dispatchTouchEvent(event);
38     }
39
40     /**
41      * Drags / moves (synchronously) to the specified coordinates. Normally preceeded by
42      * dragStart() and followed by dragEnd()
43      *
44      * @param fromX
45      * @param toX
46      * @param fromY
47      * @param toY
48      * @param stepCount
49      * @param downTime (in ms)
50      * @see TouchUtils
51      */
52     public void dragTo(float fromX, float toX, float fromY,
53             float toY, int stepCount, long downTime) {
54         float x = fromX;
55         float y = fromY;
56         float yStep = (toY - fromY) / stepCount;
57         float xStep = (toX - fromX) / stepCount;
58         for (int i = 0; i < stepCount; ++i) {
59             y += yStep;
60             x += xStep;
61             long eventTime = SystemClock.uptimeMillis();
62             MotionEvent event = MotionEvent.obtain(downTime, eventTime,
63                     MotionEvent.ACTION_MOVE, x, y, 0);
64             dispatchTouchEvent(event);
65         }
66     }
67
68     /**
69      * Finishes (synchronously) a drag / move at the specified coordinate.
70      * Normally preceeded by dragStart() and dragTo().
71      *
72      * @param x
73      * @param y
74      * @param downTime (in ms)
75      * @see TouchUtils
76      */
77     public void dragEnd(float x, float y, long downTime) {
78         long eventTime = SystemClock.uptimeMillis();
79         MotionEvent event = MotionEvent.obtain(downTime, eventTime,
80                 MotionEvent.ACTION_UP, x, y, 0);
81         dispatchTouchEvent(event);
82     }
83
84     /**
85      * Sends (synchronously) a single click to an absolute screen coordinates.
86      *
87      * @param x screen absolute
88      * @param y screen absolute
89      * @see TouchUtils
90      */
91     public void singleClick(float x, float y) {
92
93         long downTime = SystemClock.uptimeMillis();
94         long eventTime = SystemClock.uptimeMillis();
95
96         MotionEvent event = MotionEvent.obtain(downTime, eventTime,
97                                                MotionEvent.ACTION_DOWN, x, y, 0);
98         dispatchTouchEvent(event);
99
100         eventTime = SystemClock.uptimeMillis();
101         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP,
102                                    x, y, 0);
103         dispatchTouchEvent(event);
104     }
105
106     /**
107      * Sends (synchronously) a single click to the View at the specified coordinates.
108      *
109      * @param v The view to be clicked.
110      * @param x Relative x location to v
111      * @param y Relative y location to v
112      */
113     public void singleClickView(View v, int x, int y) {
114         int location[] = getAbsoluteLocationFromRelative(v, x, y);
115         int absoluteX = location[0];
116         int absoluteY = location[1];
117         singleClick(absoluteX, absoluteY);
118     }
119
120     /**
121      * Sends (synchronously) a single click to the center of the View.
122      */
123     public void singleClickView(View v) {
124         singleClickView(v, v.getWidth() / 2, v.getHeight() / 2);
125     }
126
127     /**
128      * Sends (synchronously) a single click on the specified relative coordinates inside
129      * a given view.
130      *
131      * @param view The view to be clicked.
132      * @param x screen absolute
133      * @param y screen absolute
134      * @see TouchUtils
135      */
136     public void singleClickViewRelative(View view, int x, int y) {
137         long downTime = SystemClock.uptimeMillis();
138         long eventTime = SystemClock.uptimeMillis();
139
140         MotionEvent event = MotionEvent.obtain(downTime, eventTime,
141                                                MotionEvent.ACTION_DOWN, x, y, 0);
142         dispatchTouchEvent(view, event);
143
144         eventTime = SystemClock.uptimeMillis();
145         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP,
146                                    x, y, 0);
147         dispatchTouchEvent(view, event);
148     }
149
150     /**
151      * Sends (synchronously) a long press to an absolute screen coordinates.
152      *
153      * @param x screen absolute
154      * @param y screen absolute
155      * @see TouchUtils
156      */
157     public void longPress(float x, float y) {
158
159         long downTime = SystemClock.uptimeMillis();
160         long eventTime = SystemClock.uptimeMillis();
161
162         MotionEvent event = MotionEvent.obtain(downTime, eventTime,
163                                                MotionEvent.ACTION_DOWN, x, y, 0);
164         dispatchTouchEvent(event);
165
166         int longPressTimeout = ViewConfiguration.get(
167                 mActivityTestCase.getActivity()).getLongPressTimeout();
168
169         // Long press is flaky with just longPressTimeout. Doubling the time to be safe.
170         SystemClock.sleep(longPressTimeout * 2);
171
172         eventTime = SystemClock.uptimeMillis();
173         event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP,
174                                    x, y, 0);
175         dispatchTouchEvent(event);
176     }
177
178     /**
179      * Sends (synchronously) a long press to the View at the specified coordinates.
180      *
181      * @param v The view to be clicked.
182      * @param x Relative x location to v
183      * @param y Relative y location to v
184      */
185     public void longPressView(View v, int x, int y) {
186         int location[] = getAbsoluteLocationFromRelative(v, x, y);
187         int absoluteX = location[0];
188         int absoluteY = location[1];
189         longPress(absoluteX, absoluteY);
190     }
191
192     /**
193      * Send a MotionEvent to the root view of the activity.
194      * @param event
195      */
196     private void dispatchTouchEvent(final MotionEvent event) {
197         View view =
198                 mActivityTestCase.getActivity().findViewById(android.R.id.content).getRootView();
199         dispatchTouchEvent(view, event);
200     }
201
202     /**
203      * Send a MotionEvent to the specified view instead of the root view.
204      * For example AutofillPopup window that is above the root view.
205      * @param view The view that should receive the event.
206      * @param event The view to be dispatched.
207      */
208     private void dispatchTouchEvent(final View view, final MotionEvent event) {
209         try {
210             mActivityTestCase.runTestOnUiThread(new Runnable() {
211                 @Override
212                 public void run() {
213                     view.dispatchTouchEvent(event);
214                 }
215             });
216         } catch(Throwable e) {
217             throw new RuntimeException("Dispatching touch event failed", e);
218         }
219     }
220
221     /**
222      * Returns the absolute location in screen coordinates from location relative
223      * to view.
224      * @param v The view the coordinates are relative to.
225      * @param x Relative x location.
226      * @param y Relative y location.
227      * @return absolute x and y location in an array.
228      */
229     private static int[] getAbsoluteLocationFromRelative(View v, int x, int y) {
230         int location[] = new int[2];
231         v.getLocationOnScreen(location);
232         location[0] += x;
233         location[1] += y;
234         return location;
235     }
236 }