• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.hardware.input;
18 
19 import android.annotation.FloatRange;
20 import android.annotation.IntDef;
21 import android.annotation.NonNull;
22 import android.annotation.SystemApi;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 import android.view.MotionEvent;
26 
27 import java.lang.annotation.Retention;
28 import java.lang.annotation.RetentionPolicy;
29 
30 /**
31  * An event describing a touchscreen interaction originating from a remote device.
32  *
33  * The pointer id, tool type, action, and location are required; pressure and main axis size are
34  * optional.
35  *
36  * @hide
37  */
38 @SystemApi
39 public final class VirtualTouchEvent implements Parcelable {
40 
41     /** @hide */
42     public static final int TOOL_TYPE_UNKNOWN = MotionEvent.TOOL_TYPE_UNKNOWN;
43     /** Tool type indicating that the user's finger is the origin of the event. */
44     public static final int TOOL_TYPE_FINGER = MotionEvent.TOOL_TYPE_FINGER;
45     /**
46      * Tool type indicating that a user's palm (or other input mechanism to be rejected) is the
47      * origin of the event.
48      */
49     public static final int TOOL_TYPE_PALM = MotionEvent.TOOL_TYPE_PALM;
50     /** @hide */
51     @IntDef(prefix = { "TOOL_TYPE_" }, value = {
52             TOOL_TYPE_UNKNOWN,
53             TOOL_TYPE_FINGER,
54             TOOL_TYPE_PALM,
55     })
56     @Retention(RetentionPolicy.SOURCE)
57     public @interface ToolType {}
58 
59     /** @hide */
60     public static final int ACTION_UNKNOWN = -1;
61     /** Action indicating the tool has been pressed down to the touchscreen. */
62     public static final int ACTION_DOWN = MotionEvent.ACTION_DOWN;
63     /** Action indicating the tool has been lifted from the touchscreen. */
64     public static final int ACTION_UP = MotionEvent.ACTION_UP;
65     /** Action indicating the tool has been moved along the face of the touchscreen. */
66     public static final int ACTION_MOVE = MotionEvent.ACTION_MOVE;
67     /** Action indicating the tool cancelled the current movement. */
68     public static final int ACTION_CANCEL = MotionEvent.ACTION_CANCEL;
69     /** @hide */
70     @IntDef(prefix = { "ACTION_" }, value = {
71             ACTION_UNKNOWN,
72             ACTION_DOWN,
73             ACTION_UP,
74             ACTION_MOVE,
75             ACTION_CANCEL,
76     })
77     @Retention(RetentionPolicy.SOURCE)
78     public @interface Action {}
79 
80     private final int mPointerId;
81     private final @ToolType int mToolType;
82     private final @Action int mAction;
83     private final float mX;
84     private final float mY;
85     private final float mPressure;
86     private final float mMajorAxisSize;
87 
VirtualTouchEvent(int pointerId, @ToolType int toolType, @Action int action, float x, float y, float pressure, float majorAxisSize)88     private VirtualTouchEvent(int pointerId, @ToolType int toolType, @Action int action,
89             float x, float y, float pressure, float majorAxisSize) {
90         mPointerId = pointerId;
91         mToolType = toolType;
92         mAction = action;
93         mX = x;
94         mY = y;
95         mPressure = pressure;
96         mMajorAxisSize = majorAxisSize;
97     }
98 
VirtualTouchEvent(@onNull Parcel parcel)99     private VirtualTouchEvent(@NonNull Parcel parcel) {
100         mPointerId = parcel.readInt();
101         mToolType = parcel.readInt();
102         mAction = parcel.readInt();
103         mX = parcel.readFloat();
104         mY = parcel.readFloat();
105         mPressure = parcel.readFloat();
106         mMajorAxisSize = parcel.readFloat();
107     }
108 
109     @Override
writeToParcel(@onNull Parcel dest, int flags)110     public void writeToParcel(@NonNull Parcel dest, int flags) {
111         dest.writeInt(mPointerId);
112         dest.writeInt(mToolType);
113         dest.writeInt(mAction);
114         dest.writeFloat(mX);
115         dest.writeFloat(mY);
116         dest.writeFloat(mPressure);
117         dest.writeFloat(mMajorAxisSize);
118     }
119 
120     @Override
describeContents()121     public int describeContents() {
122         return 0;
123     }
124 
125     /**
126      * Returns the pointer id associated with this event.
127      */
getPointerId()128     public int getPointerId() {
129         return mPointerId;
130     }
131 
132     /**
133      * Returns the tool type associated with this event.
134      */
getToolType()135     public @ToolType int getToolType() {
136         return mToolType;
137     }
138 
139     /**
140      * Returns the action associated with this event.
141      */
getAction()142     public @Action int getAction() {
143         return mAction;
144     }
145 
146     /**
147      * Returns the x-axis location associated with this event.
148      */
getX()149     public float getX() {
150         return mX;
151     }
152 
153     /**
154      * Returns the y-axis location associated with this event.
155      */
getY()156     public float getY() {
157         return mY;
158     }
159 
160     /**
161      * Returns the pressure associated with this event. Returns {@link Float#NaN} if omitted.
162      */
getPressure()163     public float getPressure() {
164         return mPressure;
165     }
166 
167     /**
168      * Returns the major axis size associated with this event. Returns {@link Float#NaN} if omitted.
169      */
getMajorAxisSize()170     public float getMajorAxisSize() {
171         return mMajorAxisSize;
172     }
173 
174     /**
175      * Builder for {@link VirtualTouchEvent}.
176      */
177     public static final class Builder {
178 
179         private @ToolType int mToolType = TOOL_TYPE_UNKNOWN;
180         private int mPointerId = MotionEvent.INVALID_POINTER_ID;
181         private @Action int mAction = ACTION_UNKNOWN;
182         private float mX = Float.NaN;
183         private float mY = Float.NaN;
184         private float mPressure = Float.NaN;
185         private float mMajorAxisSize = Float.NaN;
186 
187         /**
188          * Creates a {@link VirtualTouchEvent} object with the current builder configuration.
189          */
build()190         public @NonNull VirtualTouchEvent build() {
191             if (mToolType == TOOL_TYPE_UNKNOWN || mPointerId == MotionEvent.INVALID_POINTER_ID
192                     || mAction == ACTION_UNKNOWN || Float.isNaN(mX) || Float.isNaN(mY)) {
193                 throw new IllegalArgumentException(
194                         "Cannot build virtual touch event with unset required fields");
195             }
196             if ((mToolType == TOOL_TYPE_PALM && mAction != ACTION_CANCEL)
197                     || (mAction == ACTION_CANCEL && mToolType != TOOL_TYPE_PALM)) {
198                 throw new IllegalArgumentException(
199                         "ACTION_CANCEL and TOOL_TYPE_PALM must always appear together");
200             }
201             return new VirtualTouchEvent(mPointerId, mToolType, mAction, mX, mY, mPressure,
202                     mMajorAxisSize);
203         }
204 
205         /**
206          * Sets the pointer id of the event.
207          *
208          * @return this builder, to allow for chaining of calls
209          */
setPointerId(int pointerId)210         public @NonNull Builder setPointerId(int pointerId) {
211             mPointerId = pointerId;
212             return this;
213         }
214 
215         /**
216          * Sets the tool type of the event.
217          *
218          * @return this builder, to allow for chaining of calls
219          */
setToolType(@oolType int toolType)220         public @NonNull Builder setToolType(@ToolType int toolType) {
221             if (toolType != TOOL_TYPE_FINGER && toolType != TOOL_TYPE_PALM) {
222                 throw new IllegalArgumentException("Unsupported touch event tool type");
223             }
224             mToolType = toolType;
225             return this;
226         }
227 
228         /**
229          * Sets the action of the event.
230          *
231          * @return this builder, to allow for chaining of calls
232          */
setAction(@ction int action)233         public @NonNull Builder setAction(@Action int action) {
234             if (action != ACTION_DOWN && action != ACTION_UP && action != ACTION_MOVE
235                     && action != ACTION_CANCEL) {
236                 throw new IllegalArgumentException("Unsupported touch event action type");
237             }
238             mAction = action;
239             return this;
240         }
241 
242         /**
243          * Sets the x-axis location of the event.
244          *
245          * @return this builder, to allow for chaining of calls
246          */
setX(float absX)247         public @NonNull Builder setX(float absX) {
248             mX = absX;
249             return this;
250         }
251 
252         /**
253          * Sets the y-axis location of the event.
254          *
255          * @return this builder, to allow for chaining of calls
256          */
setY(float absY)257         public @NonNull Builder setY(float absY) {
258             mY = absY;
259             return this;
260         }
261 
262         /**
263          * Sets the pressure of the event. This field is optional and can be omitted.
264          *
265          * @return this builder, to allow for chaining of calls
266          */
setPressure(@loatRangefrom = 0f) float pressure)267         public @NonNull Builder setPressure(@FloatRange(from = 0f) float pressure) {
268             if (pressure < 0f) {
269                 throw new IllegalArgumentException("Touch event pressure cannot be negative");
270             }
271             mPressure = pressure;
272             return this;
273         }
274 
275         /**
276          * Sets the major axis size of the event. This field is optional and can be omitted.
277          *
278          * @return this builder, to allow for chaining of calls
279          */
setMajorAxisSize(@loatRangefrom = 0f) float majorAxisSize)280         public @NonNull Builder setMajorAxisSize(@FloatRange(from = 0f) float majorAxisSize) {
281             if (majorAxisSize < 0f) {
282                 throw new IllegalArgumentException(
283                         "Touch event major axis size cannot be negative");
284             }
285             mMajorAxisSize = majorAxisSize;
286             return this;
287         }
288     }
289 
290     public static final @NonNull Parcelable.Creator<VirtualTouchEvent> CREATOR =
291             new Parcelable.Creator<VirtualTouchEvent>() {
292         public VirtualTouchEvent createFromParcel(Parcel source) {
293             return new VirtualTouchEvent(source);
294         }
295         public VirtualTouchEvent[] newArray(int size) {
296             return new VirtualTouchEvent[size];
297         }
298     };
299 }
300