1 package com.xtremelabs.robolectric.shadows;
2 
3 import android.view.MotionEvent;
4 import com.xtremelabs.robolectric.Robolectric;
5 import com.xtremelabs.robolectric.internal.Implementation;
6 import com.xtremelabs.robolectric.internal.Implements;
7 import com.xtremelabs.robolectric.internal.RealObject;
8 
9 import java.lang.reflect.Constructor;
10 
11 /**
12  * Shadow for {@code MotionEvent} that uses reflection to create {@code MotionEvent} objects, which cannot otherwise
13  * be constructed.
14  */
15 @SuppressWarnings({"UnusedDeclaration"})
16 @Implements(MotionEvent.class)
17 public class ShadowMotionEvent {
18     @RealObject private MotionEvent realObject;
19 
20     private int action;
21     private float[] x = new float[2];
22     private float[] y = new float[2];
23     private int pointerCount = 1;
24     private long downTime;
25     private long eventTime;
26     private int[] pointerIds = new int[2];
27     private int pointerIndex;
28 
29     @Implementation
obtain(long downTime, long eventTime, int action, float x, float y, int metaState)30     public static MotionEvent obtain(long downTime, long eventTime, int action, float x, float y, int metaState) {
31         try {
32             Constructor<MotionEvent> constructor = MotionEvent.class.getDeclaredConstructor();
33             constructor.setAccessible(true);
34             MotionEvent motionEvent = constructor.newInstance();
35             ShadowMotionEvent shadowMotionEvent = (ShadowMotionEvent) Robolectric.shadowOf_(motionEvent);
36             shadowMotionEvent.x[0] = x;
37             shadowMotionEvent.y[0] = y;
38             shadowMotionEvent.action = action;
39             shadowMotionEvent.downTime = downTime;
40             shadowMotionEvent.eventTime = eventTime;
41             return motionEvent;
42         } catch (Exception e) {
43             throw new RuntimeException(e);
44         }
45     }
46 
47     @Implementation
obtain(MotionEvent motionEvent)48     public static MotionEvent obtain(MotionEvent motionEvent) {
49         return obtain(motionEvent.getDownTime(), motionEvent.getEventTime(), motionEvent.getAction(), motionEvent.getX(), motionEvent.getY(), motionEvent.getMetaState());
50     }
51 
52     @Implementation
getAction()53     public int getAction() {
54         return action | (pointerIndex << MotionEvent.ACTION_POINTER_ID_SHIFT);
55     }
56 
57     @Implementation
getRawX()58     public float getRawX() {
59         return getX();
60     }
61 
62     @Implementation
getRawY()63     public float getRawY() {
64         return getY();
65     }
66 
67     @Implementation
getX()68     public final float getX() {
69         return getX(0);
70     }
71 
72     @Implementation
getY()73     public final float getY() {
74         return getY(0);
75     }
76 
77     @Implementation
getX(int pointerIndex)78     public final float getX(int pointerIndex) {
79         return x[pointerIndex];
80     }
81 
82     @Implementation
getY(int pointerIndex)83     public final float getY(int pointerIndex) {
84         return y[pointerIndex];
85     }
86 
87     @Implementation
getPointerCount()88     public final int getPointerCount() {
89     	return pointerCount;
90     }
91 
92     @Implementation
getEventTime()93     public final long getEventTime() {
94         return eventTime;
95     }
96 
97     @Implementation
getDownTime()98     public final long getDownTime() {
99         return downTime;
100     }
101 
102     @Implementation
getPointerId(int index)103     public final int getPointerId(int index) {
104         return pointerIds[index];
105     }
106 
107     @Implementation
findPointerIndex(int id)108     public final int findPointerIndex(int id) {
109         for (int i = 0; i < pointerIds.length; i++) {
110             int pointerId = pointerIds[i];
111 
112             if (pointerId == id) {
113                 return i;
114             }
115         }
116         return -1;
117     }
118 
119     @Implementation
getActionMasked()120     public final int getActionMasked() {
121         return action;
122     }
123 
124     @Implementation
getActionIndex()125     public final int getActionIndex() {
126         return pointerIndex;
127     }
128 
129     @Implementation
getPressure(int pointerIndex)130     public final float getPressure(int pointerIndex) {
131         return 1.0f;
132     }
133 
134     @Implementation
setLocation(float x, float y)135     public final void setLocation(float x, float y) {
136         this.x[0] = x;
137         this.y[0] = y;
138     }
139 
setPointer2(float x, float y)140     public MotionEvent setPointer2(float x, float y) {
141         this.x[1] = x;
142         this.y[1] = y;
143         pointerCount = 2;
144         return realObject;
145     }
146 
setPointerIndex(int pointerIndex)147     public void setPointerIndex(int pointerIndex) {
148         this.pointerIndex = pointerIndex;
149     }
150 
setPointerIds(int index0PointerId, int index1PointerId)151     public void setPointerIds(int index0PointerId, int index1PointerId) {
152         pointerIds[0] = index0PointerId;
153         pointerIds[1] = index1PointerId;
154     }
155 }
156