EMMA Coverage Report (generated Fri Aug 23 16:39:17 PDT 2013)
[all classes][org.chromium.content.browser]

COVERAGE SUMMARY FOR SOURCE FILE [GenericTouchGesture.java]

nameclass, %method, %block, %line, %
GenericTouchGesture.java0%   (0/5)0%   (0/25)0%   (0/700)0%   (0/109)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class GenericTouchGesture0%   (0/1)0%   (0/12)0%   (0/478)0%   (0/73)
<static initializer> 0%   (0/1)0%   (0/8)0%   (0/1)
GenericTouchGesture (ContentViewCore, int, int, int, int): void 0%   (0/1)0%   (0/75)0%   (0/16)
GenericTouchGesture (ContentViewCore, int, int, int, int, int, int, int, int)... 0%   (0/1)0%   (0/106)0%   (0/19)
access$000 (GenericTouchGesture): TimeAnimator 0%   (0/1)0%   (0/3)0%   (0/1)
access$002 (GenericTouchGesture, TimeAnimator): TimeAnimator 0%   (0/1)0%   (0/5)0%   (0/1)
access$100 (GenericTouchGesture): long 0%   (0/1)0%   (0/3)0%   (0/1)
access$200 (GenericTouchGesture): Handler 0%   (0/1)0%   (0/3)0%   (0/1)
createJBRunnable (): Runnable 0%   (0/1)0%   (0/5)0%   (0/1)
createPreJBRunnable (): Runnable 0%   (0/1)0%   (0/5)0%   (0/1)
havePointersArrived (): boolean 0%   (0/1)0%   (0/30)0%   (0/4)
sendEvent (long): boolean 0%   (0/1)0%   (0/208)0%   (0/31)
start (int): void 0%   (0/1)0%   (0/27)0%   (0/5)
     
class GenericTouchGesture$10%   (0/1)0%   (0/2)0%   (0/26)0%   (0/5)
GenericTouchGesture$1 (GenericTouchGesture): void 0%   (0/1)0%   (0/6)0%   (0/1)
run (): void 0%   (0/1)0%   (0/20)0%   (0/4)
     
class GenericTouchGesture$1$10%   (0/1)0%   (0/2)0%   (0/23)0%   (0/4)
GenericTouchGesture$1$1 (GenericTouchGesture$1): void 0%   (0/1)0%   (0/6)0%   (0/1)
onTimeUpdate (TimeAnimator, long, long): void 0%   (0/1)0%   (0/17)0%   (0/3)
     
class GenericTouchGesture$20%   (0/1)0%   (0/2)0%   (0/18)0%   (0/4)
GenericTouchGesture$2 (GenericTouchGesture): void 0%   (0/1)0%   (0/6)0%   (0/1)
run (): void 0%   (0/1)0%   (0/12)0%   (0/3)
     
class GenericTouchGesture$TouchPointer0%   (0/1)0%   (0/7)0%   (0/155)0%   (0/26)
GenericTouchGesture$TouchPointer (int, int, int, int, int, float): void 0%   (0/1)0%   (0/92)0%   (0/18)
getCoords (): MotionEvent$PointerCoords 0%   (0/1)0%   (0/3)0%   (0/1)
getCurrentX (): float 0%   (0/1)0%   (0/4)0%   (0/1)
getCurrentY (): float 0%   (0/1)0%   (0/4)0%   (0/1)
getProperties (): MotionEvent$PointerProperties 0%   (0/1)0%   (0/3)0%   (0/1)
hasArrived (): boolean 0%   (0/1)0%   (0/28)0%   (0/1)
moveBy (float): void 0%   (0/1)0%   (0/21)0%   (0/3)

1// Copyright 2013 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 
5package org.chromium.content.browser;
6 
7import android.animation.TimeAnimator;
8import android.animation.TimeAnimator.TimeListener;
9import android.os.Build;
10import android.os.Handler;
11import android.os.Looper;
12import android.os.SystemClock;
13import android.view.MotionEvent;
14import android.view.MotionEvent.PointerProperties;
15import android.view.MotionEvent.PointerCoords;
16 
17import org.chromium.base.CalledByNative;
18import org.chromium.base.JNINamespace;
19 
20/**
21 * Provides a Java-side implementation for simulating touch gestures,
22 * such as scroll or pinch.
23 */
24@JNINamespace("content")
25public class GenericTouchGesture {
26    private final ContentViewCore mContentViewCore;
27 
28    private final Handler mHandler = new Handler(Looper.getMainLooper());
29 
30    private TimeAnimator mTimeAnimator;
31 
32    private int mNativePtr;
33    private long mDownTime;
34 
35    private final byte STATE_INITIAL = 0;
36    private final byte STATE_MOVING = 1;
37    private final byte STATE_PENDING_UP = 2;
38    private final byte STATE_FINAL = 3;
39    private byte state = STATE_INITIAL;
40 
41    private static class TouchPointer {
42        private final float mStartX;
43        private final float mStartY;
44        private final float mDeltaX;
45        private final float mDeltaY;
46        private final float mStepX;
47        private final float mStepY;
48 
49        private PointerProperties mProperties;
50        private PointerCoords mCoords;
51 
52 
53        // Class representing a single pointer being moved over the screen.
54        TouchPointer(int startX, int startY, int deltaX, int deltaY,
55                int id, float scale) {
56            mStartX = startX * scale;
57            mStartY = startY * scale;
58 
59            mDeltaX = deltaX * scale;
60            mDeltaY = deltaY * scale;
61 
62            if (deltaX != 0 || deltaY != 0) {
63                mStepX = mDeltaX / Math.abs(mDeltaX + mDeltaY);
64                mStepY = mDeltaY / Math.abs(mDeltaX + mDeltaY);
65            } else {
66                mStepX = 0;
67                mStepY = 0;
68            }
69 
70            mProperties = new PointerProperties();
71            mProperties.id = id;
72            mProperties.toolType = MotionEvent.TOOL_TYPE_FINGER;
73 
74            mCoords = new PointerCoords();
75            mCoords.x = mStartX;
76            mCoords.y = mStartY;
77            mCoords.pressure = 1.0f;
78        }
79 
80        PointerProperties getProperties() {
81            return mProperties;
82        }
83 
84        PointerCoords getCoords() {
85            return mCoords;
86        }
87 
88        float getCurrentX() {
89            return mCoords.x;
90        }
91 
92        float getCurrentY() {
93            return mCoords.y;
94        }
95 
96        void moveBy(float delta) {
97            mCoords.x += mStepX * delta;
98            mCoords.y += mStepY * delta;
99        }
100 
101        boolean hasArrived() {
102            return Math.abs(mCoords.x - mStartX) >= Math.abs(mDeltaX) &&
103                   Math.abs(mCoords.y - mStartY) >= Math.abs(mDeltaY);
104        }
105    }
106 
107    private TouchPointer[] mPointers;
108    private final PointerProperties[] mPointerProperties;
109    private final PointerCoords[] mPointerCoords;
110 
111 
112    GenericTouchGesture(ContentViewCore contentViewCore,
113            int startX, int startY, int deltaX, int deltaY) {
114        mContentViewCore = contentViewCore;
115 
116        float scale = mContentViewCore.getRenderCoordinates().getDeviceScaleFactor();
117 
118        mPointers = new TouchPointer[1];
119        mPointers[0] = new TouchPointer(startX, startY, deltaX, deltaY, 0, scale);
120 
121        mPointerProperties = new PointerProperties[1];
122        mPointerProperties[0] = mPointers[0].getProperties();
123 
124        mPointerCoords = new PointerCoords[1];
125        mPointerCoords[0] = mPointers[0].getCoords();
126    }
127 
128    GenericTouchGesture(ContentViewCore contentViewCore,
129            int startX0, int startY0, int deltaX0, int deltaY0,
130            int startX1, int startY1, int deltaX1, int deltaY1) {
131        mContentViewCore = contentViewCore;
132 
133        float scale = mContentViewCore.getRenderCoordinates().getDeviceScaleFactor();
134 
135        mPointers = new TouchPointer[2];
136        mPointers[0] = new TouchPointer(startX0, startY0, deltaX0, deltaY0, 0, scale);
137        mPointers[1] = new TouchPointer(startX1, startY1, deltaX1, deltaY1, 1, scale);
138 
139        mPointerProperties = new PointerProperties[2];
140        mPointerProperties[0] = mPointers[0].getProperties();
141        mPointerProperties[1] = mPointers[1].getProperties();
142 
143        mPointerCoords = new PointerCoords[2];
144        mPointerCoords[0] = mPointers[0].getCoords();
145        mPointerCoords[1] = mPointers[1].getCoords();
146    }
147 
148    @CalledByNative
149    void start(int nativePtr) {
150        assert mNativePtr == 0;
151        mNativePtr = nativePtr;
152 
153        Runnable runnable = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) ?
154            createJBRunnable() : createPreJBRunnable();
155        mHandler.post(runnable);
156    }
157 
158    boolean sendEvent(long time) {
159        switch (state) {
160            case STATE_INITIAL: {
161                mDownTime = SystemClock.uptimeMillis();
162 
163                // Touch the first pointer down. This initiates the gesture.
164                MotionEvent event = MotionEvent.obtain(mDownTime, time,
165                        MotionEvent.ACTION_DOWN,
166                        mPointers[0].getCurrentX(), mPointers[0].getCurrentY(), 0);
167                mContentViewCore.onTouchEvent(event);
168                event.recycle();
169 
170                // If there are more pointers, touch them down too.
171                if (mPointers.length > 1) {
172                    event = MotionEvent.obtain(mDownTime, time,
173                            MotionEvent.ACTION_POINTER_DOWN,
174                            mPointers.length, mPointerProperties, mPointerCoords,
175                            0, 0, 1, 1, 0, 0, 0, 0);
176                    mContentViewCore.onTouchEvent(event);
177                    event.recycle();
178                }
179                state = STATE_MOVING;
180                break;
181            }
182            case STATE_MOVING: {
183                float delta = nativeGetDelta(
184                    mNativePtr, mContentViewCore.getRenderCoordinates().getDeviceScaleFactor());
185                if (delta != 0) {
186                    for (TouchPointer pointer : mPointers) {
187                        pointer.moveBy((float)delta);
188                    }
189                    MotionEvent event = MotionEvent.obtain(mDownTime, time,
190                            MotionEvent.ACTION_MOVE,
191                            mPointers.length, mPointerProperties, mPointerCoords,
192                            0, 0, 1, 1, 0, 0, 0, 0);
193                    mContentViewCore.onTouchEvent(event);
194                    event.recycle();
195                }
196                if (havePointersArrived())
197                    state = STATE_PENDING_UP;
198                break;
199            }
200            case STATE_PENDING_UP: {
201                // If there are more than one pointers, lift them up first.
202                if (mPointers.length > 1) {
203                    MotionEvent event = MotionEvent.obtain(mDownTime, time,
204                            MotionEvent.ACTION_POINTER_UP,
205                            mPointers.length, mPointerProperties, mPointerCoords,
206                            0, 0, 1, 1, 0, 0, 0, 0);
207                    mContentViewCore.onTouchEvent(event);
208                    event.recycle();
209                }
210 
211                // Finally, lift the first pointer up to finish the gesture.
212                MotionEvent event = MotionEvent.obtain(mDownTime, time,
213                        MotionEvent.ACTION_UP,
214                        mPointers[0].getCurrentX(), mPointers[0].getCurrentY(), 0);
215                mContentViewCore.onTouchEvent(event);
216                event.recycle();
217 
218                nativeSetHasFinished(mNativePtr);
219                state = STATE_FINAL;
220                break;
221            }
222        }
223        return state != STATE_FINAL;
224    }
225 
226    private boolean havePointersArrived() {
227        boolean arrived = true;
228        for (TouchPointer pointer : mPointers) {
229            arrived = arrived && pointer.hasArrived();
230        }
231        return arrived;
232    }
233 
234    private Runnable createJBRunnable() {
235        // On JB, we rely on TimeAnimator to send events tied with vsync.
236        return new Runnable() {
237            @Override
238            public void run() {
239                mTimeAnimator = new TimeAnimator();
240                mTimeAnimator.setTimeListener(new TimeListener() {
241                    @Override
242                    public void onTimeUpdate(TimeAnimator animation, long totalTime,
243                            long deltaTime) {
244                        if (!sendEvent(mDownTime + totalTime)) {
245                            mTimeAnimator.end();
246                        }
247                    }
248                });
249                mTimeAnimator.start();
250            }
251        };
252    }
253 
254    private Runnable createPreJBRunnable() {
255        // Pre-JB there's no TimeAnimator, so we keep posting messages.
256        return new Runnable() {
257            @Override
258            public void run() {
259                if (sendEvent(SystemClock.uptimeMillis())) {
260                    mHandler.post(this);
261                }
262            }
263        };
264    }
265 
266    private native float nativeGetDelta(
267            int nativeGenericTouchGestureAndroid, float scale);
268    private native void nativeSetHasFinished(int nativeGenericTouchGestureAndroid);
269}

[all classes][org.chromium.content.browser]
EMMA 2.0.5312 (C) Vladimir Roubtsov