blob: 97b0ec127b595b0c44e1dc7a24248475acca703a [file] [log] [blame]
Jeff Brown9f25b7f2012-04-10 14:30:49 -07001/*
2 * Copyright (C) 2010 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
Jeff Brown46b9ac02010-04-22 18:58:52 -070017#define LOG_TAG "Input"
Jeff Brown46b9ac02010-04-22 18:58:52 -070018//#define LOG_NDEBUG 0
19
Jeff Brown91c69ab2011-02-14 17:03:18 -080020#include <math.h>
Jeff Brown19c97d462011-06-01 12:33:19 -070021#include <limits.h>
Jeff Brown91c69ab2011-02-14 17:03:18 -080022
Jeff Brown8a90e6e2012-05-11 12:24:35 -070023#include <androidfw/Input.h>
24
Jeff Brown91c69ab2011-02-14 17:03:18 -080025#ifdef HAVE_ANDROID_OS
26#include <binder/Parcel.h>
27
28#include "SkPoint.h"
29#include "SkMatrix.h"
30#include "SkScalar.h"
31#endif
32
Jeff Brown46b9ac02010-04-22 18:58:52 -070033namespace android {
34
Jeff Brown47e6b1b2010-11-29 17:37:49 -080035// --- InputEvent ---
Jeff Brown46b9ac02010-04-22 18:58:52 -070036
Jeff Brownc5ed5912010-07-14 18:48:53 -070037void InputEvent::initialize(int32_t deviceId, int32_t source) {
Jeff Brown46b9ac02010-04-22 18:58:52 -070038 mDeviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -070039 mSource = source;
Jeff Brown46b9ac02010-04-22 18:58:52 -070040}
41
Dianne Hackborn2c6081c2010-07-15 17:44:53 -070042void InputEvent::initialize(const InputEvent& from) {
43 mDeviceId = from.mDeviceId;
44 mSource = from.mSource;
45}
46
Jeff Brown47e6b1b2010-11-29 17:37:49 -080047// --- KeyEvent ---
Jeff Brown46b9ac02010-04-22 18:58:52 -070048
Dianne Hackborn3c80a4a2010-06-29 19:20:40 -070049bool KeyEvent::hasDefaultAction(int32_t keyCode) {
50 switch (keyCode) {
Jeff Brownfd035822010-06-30 16:10:35 -070051 case AKEYCODE_HOME:
52 case AKEYCODE_BACK:
53 case AKEYCODE_CALL:
54 case AKEYCODE_ENDCALL:
55 case AKEYCODE_VOLUME_UP:
56 case AKEYCODE_VOLUME_DOWN:
Jeff Brownb0418da2010-11-01 15:24:01 -070057 case AKEYCODE_VOLUME_MUTE:
Jeff Brownfd035822010-06-30 16:10:35 -070058 case AKEYCODE_POWER:
59 case AKEYCODE_CAMERA:
60 case AKEYCODE_HEADSETHOOK:
61 case AKEYCODE_MENU:
62 case AKEYCODE_NOTIFICATION:
63 case AKEYCODE_FOCUS:
64 case AKEYCODE_SEARCH:
Jeff Brownb0418da2010-11-01 15:24:01 -070065 case AKEYCODE_MEDIA_PLAY:
66 case AKEYCODE_MEDIA_PAUSE:
Jeff Brownfd035822010-06-30 16:10:35 -070067 case AKEYCODE_MEDIA_PLAY_PAUSE:
68 case AKEYCODE_MEDIA_STOP:
69 case AKEYCODE_MEDIA_NEXT:
70 case AKEYCODE_MEDIA_PREVIOUS:
71 case AKEYCODE_MEDIA_REWIND:
Jeff Brownb0418da2010-11-01 15:24:01 -070072 case AKEYCODE_MEDIA_RECORD:
Jeff Brownfd035822010-06-30 16:10:35 -070073 case AKEYCODE_MEDIA_FAST_FORWARD:
74 case AKEYCODE_MUTE:
Dianne Hackborn3c80a4a2010-06-29 19:20:40 -070075 return true;
76 }
77
78 return false;
79}
80
81bool KeyEvent::hasDefaultAction() const {
82 return hasDefaultAction(getKeyCode());
83}
84
85bool KeyEvent::isSystemKey(int32_t keyCode) {
86 switch (keyCode) {
Jeff Brownfd035822010-06-30 16:10:35 -070087 case AKEYCODE_MENU:
88 case AKEYCODE_SOFT_RIGHT:
89 case AKEYCODE_HOME:
90 case AKEYCODE_BACK:
91 case AKEYCODE_CALL:
92 case AKEYCODE_ENDCALL:
93 case AKEYCODE_VOLUME_UP:
94 case AKEYCODE_VOLUME_DOWN:
Jeff Brownb0418da2010-11-01 15:24:01 -070095 case AKEYCODE_VOLUME_MUTE:
Jeff Brownfd035822010-06-30 16:10:35 -070096 case AKEYCODE_MUTE:
97 case AKEYCODE_POWER:
98 case AKEYCODE_HEADSETHOOK:
Jeff Brownb0418da2010-11-01 15:24:01 -070099 case AKEYCODE_MEDIA_PLAY:
100 case AKEYCODE_MEDIA_PAUSE:
Jeff Brownfd035822010-06-30 16:10:35 -0700101 case AKEYCODE_MEDIA_PLAY_PAUSE:
102 case AKEYCODE_MEDIA_STOP:
103 case AKEYCODE_MEDIA_NEXT:
104 case AKEYCODE_MEDIA_PREVIOUS:
105 case AKEYCODE_MEDIA_REWIND:
Jeff Brownb0418da2010-11-01 15:24:01 -0700106 case AKEYCODE_MEDIA_RECORD:
Jeff Brownfd035822010-06-30 16:10:35 -0700107 case AKEYCODE_MEDIA_FAST_FORWARD:
108 case AKEYCODE_CAMERA:
109 case AKEYCODE_FOCUS:
110 case AKEYCODE_SEARCH:
Dianne Hackborn3c80a4a2010-06-29 19:20:40 -0700111 return true;
112 }
113
114 return false;
115}
116
117bool KeyEvent::isSystemKey() const {
118 return isSystemKey(getKeyCode());
119}
120
Jeff Brown46b9ac02010-04-22 18:58:52 -0700121void KeyEvent::initialize(
122 int32_t deviceId,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700123 int32_t source,
Jeff Brown46b9ac02010-04-22 18:58:52 -0700124 int32_t action,
125 int32_t flags,
126 int32_t keyCode,
127 int32_t scanCode,
128 int32_t metaState,
129 int32_t repeatCount,
130 nsecs_t downTime,
131 nsecs_t eventTime) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700132 InputEvent::initialize(deviceId, source);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700133 mAction = action;
134 mFlags = flags;
135 mKeyCode = keyCode;
136 mScanCode = scanCode;
137 mMetaState = metaState;
138 mRepeatCount = repeatCount;
139 mDownTime = downTime;
140 mEventTime = eventTime;
141}
142
Dianne Hackborn2c6081c2010-07-15 17:44:53 -0700143void KeyEvent::initialize(const KeyEvent& from) {
144 InputEvent::initialize(from);
145 mAction = from.mAction;
146 mFlags = from.mFlags;
147 mKeyCode = from.mKeyCode;
148 mScanCode = from.mScanCode;
149 mMetaState = from.mMetaState;
150 mRepeatCount = from.mRepeatCount;
151 mDownTime = from.mDownTime;
152 mEventTime = from.mEventTime;
153}
154
Jeff Brown91c69ab2011-02-14 17:03:18 -0800155
156// --- PointerCoords ---
157
Jeff Brown6f2fba42011-02-19 01:08:02 -0800158float PointerCoords::getAxisValue(int32_t axis) const {
159 if (axis < 0 || axis > 63) {
160 return 0;
161 }
162
163 uint64_t axisBit = 1LL << axis;
164 if (!(bits & axisBit)) {
165 return 0;
166 }
167 uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
168 return values[index];
169}
170
171status_t PointerCoords::setAxisValue(int32_t axis, float value) {
172 if (axis < 0 || axis > 63) {
173 return NAME_NOT_FOUND;
174 }
175
176 uint64_t axisBit = 1LL << axis;
177 uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
178 if (!(bits & axisBit)) {
Jeff Brownbe1aa822011-07-27 16:04:54 -0700179 if (value == 0) {
180 return OK; // axes with value 0 do not need to be stored
181 }
Jeff Brown6f2fba42011-02-19 01:08:02 -0800182 uint32_t count = __builtin_popcountll(bits);
183 if (count >= MAX_AXES) {
184 tooManyAxes(axis);
185 return NO_MEMORY;
186 }
187 bits |= axisBit;
188 for (uint32_t i = count; i > index; i--) {
189 values[i] = values[i - 1];
190 }
191 }
192 values[index] = value;
193 return OK;
194}
195
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400196static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
Jeff Brownbe1aa822011-07-27 16:04:54 -0700197 float value = c.getAxisValue(axis);
198 if (value != 0) {
199 c.setAxisValue(axis, value * scaleFactor);
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400200 }
201}
202
203void PointerCoords::scale(float scaleFactor) {
204 // No need to scale pressure or size since they are normalized.
205 // No need to scale orientation since it is meaningless to do so.
206 scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, scaleFactor);
207 scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, scaleFactor);
208 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
209 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
210 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
211 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
212}
213
Jeff Brown91c69ab2011-02-14 17:03:18 -0800214#ifdef HAVE_ANDROID_OS
215status_t PointerCoords::readFromParcel(Parcel* parcel) {
Jeff Brown6f2fba42011-02-19 01:08:02 -0800216 bits = parcel->readInt64();
Jeff Brown91c69ab2011-02-14 17:03:18 -0800217
Jeff Brown6f2fba42011-02-19 01:08:02 -0800218 uint32_t count = __builtin_popcountll(bits);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800219 if (count > MAX_AXES) {
220 return BAD_VALUE;
221 }
222
223 for (uint32_t i = 0; i < count; i++) {
224 values[i] = parcel->readInt32();
225 }
226 return OK;
227}
228
229status_t PointerCoords::writeToParcel(Parcel* parcel) const {
Jeff Brown6f2fba42011-02-19 01:08:02 -0800230 parcel->writeInt64(bits);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800231
Jeff Brown6f2fba42011-02-19 01:08:02 -0800232 uint32_t count = __builtin_popcountll(bits);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800233 for (uint32_t i = 0; i < count; i++) {
234 parcel->writeInt32(values[i]);
235 }
236 return OK;
237}
238#endif
239
240void PointerCoords::tooManyAxes(int axis) {
Steve Block8564c8d2012-01-05 23:22:43 +0000241 ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
Jeff Brown91c69ab2011-02-14 17:03:18 -0800242 "cannot contain more than %d axis values.", axis, int(MAX_AXES));
243}
244
Jeff Brownace13b12011-03-09 17:39:48 -0800245bool PointerCoords::operator==(const PointerCoords& other) const {
246 if (bits != other.bits) {
247 return false;
248 }
249 uint32_t count = __builtin_popcountll(bits);
250 for (uint32_t i = 0; i < count; i++) {
251 if (values[i] != other.values[i]) {
252 return false;
253 }
254 }
255 return true;
256}
257
258void PointerCoords::copyFrom(const PointerCoords& other) {
259 bits = other.bits;
260 uint32_t count = __builtin_popcountll(bits);
261 for (uint32_t i = 0; i < count; i++) {
262 values[i] = other.values[i];
263 }
264}
265
Jeff Brown91c69ab2011-02-14 17:03:18 -0800266
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700267// --- PointerProperties ---
268
269bool PointerProperties::operator==(const PointerProperties& other) const {
270 return id == other.id
271 && toolType == other.toolType;
272}
273
274void PointerProperties::copyFrom(const PointerProperties& other) {
275 id = other.id;
276 toolType = other.toolType;
277}
278
279
Jeff Brown47e6b1b2010-11-29 17:37:49 -0800280// --- MotionEvent ---
Jeff Brown46b9ac02010-04-22 18:58:52 -0700281
282void MotionEvent::initialize(
283 int32_t deviceId,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700284 int32_t source,
Jeff Brown46b9ac02010-04-22 18:58:52 -0700285 int32_t action,
Jeff Brown85a31762010-09-01 17:01:00 -0700286 int32_t flags,
Jeff Brown46b9ac02010-04-22 18:58:52 -0700287 int32_t edgeFlags,
288 int32_t metaState,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700289 int32_t buttonState,
Jeff Brown5c225b12010-06-16 01:53:36 -0700290 float xOffset,
291 float yOffset,
Jeff Brown46b9ac02010-04-22 18:58:52 -0700292 float xPrecision,
293 float yPrecision,
294 nsecs_t downTime,
295 nsecs_t eventTime,
296 size_t pointerCount,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700297 const PointerProperties* pointerProperties,
Jeff Brown46b9ac02010-04-22 18:58:52 -0700298 const PointerCoords* pointerCoords) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700299 InputEvent::initialize(deviceId, source);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700300 mAction = action;
Jeff Brown85a31762010-09-01 17:01:00 -0700301 mFlags = flags;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700302 mEdgeFlags = edgeFlags;
303 mMetaState = metaState;
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700304 mButtonState = buttonState;
Jeff Brown5c225b12010-06-16 01:53:36 -0700305 mXOffset = xOffset;
306 mYOffset = yOffset;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700307 mXPrecision = xPrecision;
308 mYPrecision = yPrecision;
309 mDownTime = downTime;
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700310 mPointerProperties.clear();
311 mPointerProperties.appendArray(pointerProperties, pointerCount);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700312 mSampleEventTimes.clear();
313 mSamplePointerCoords.clear();
314 addSample(eventTime, pointerCoords);
315}
316
Jeff Brown91c69ab2011-02-14 17:03:18 -0800317void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
318 InputEvent::initialize(other->mDeviceId, other->mSource);
319 mAction = other->mAction;
320 mFlags = other->mFlags;
321 mEdgeFlags = other->mEdgeFlags;
322 mMetaState = other->mMetaState;
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700323 mButtonState = other->mButtonState;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800324 mXOffset = other->mXOffset;
325 mYOffset = other->mYOffset;
326 mXPrecision = other->mXPrecision;
327 mYPrecision = other->mYPrecision;
328 mDownTime = other->mDownTime;
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700329 mPointerProperties = other->mPointerProperties;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800330
331 if (keepHistory) {
332 mSampleEventTimes = other->mSampleEventTimes;
333 mSamplePointerCoords = other->mSamplePointerCoords;
334 } else {
335 mSampleEventTimes.clear();
336 mSampleEventTimes.push(other->getEventTime());
337 mSamplePointerCoords.clear();
338 size_t pointerCount = other->getPointerCount();
339 size_t historySize = other->getHistorySize();
340 mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
341 + (historySize * pointerCount), pointerCount);
342 }
343}
344
Jeff Brown46b9ac02010-04-22 18:58:52 -0700345void MotionEvent::addSample(
346 int64_t eventTime,
347 const PointerCoords* pointerCoords) {
348 mSampleEventTimes.push(eventTime);
349 mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
350}
351
Jeff Brown91c69ab2011-02-14 17:03:18 -0800352const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
353 return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
354}
355
356float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
357 return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
358}
359
360float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
361 float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
362 switch (axis) {
Jeff Brownebbd5d12011-02-17 13:01:34 -0800363 case AMOTION_EVENT_AXIS_X:
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400364 return value + mXOffset;
Jeff Brownebbd5d12011-02-17 13:01:34 -0800365 case AMOTION_EVENT_AXIS_Y:
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400366 return value + mYOffset;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800367 }
368 return value;
369}
370
371const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
372 size_t pointerIndex, size_t historicalIndex) const {
373 return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
374}
375
376float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
377 size_t historicalIndex) const {
378 return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
379}
380
381float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
382 size_t historicalIndex) const {
383 float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
384 switch (axis) {
Jeff Brownebbd5d12011-02-17 13:01:34 -0800385 case AMOTION_EVENT_AXIS_X:
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400386 return value + mXOffset;
Jeff Brownebbd5d12011-02-17 13:01:34 -0800387 case AMOTION_EVENT_AXIS_Y:
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400388 return value + mYOffset;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800389 }
390 return value;
391}
392
Jeff Brown2ed24622011-03-14 19:39:54 -0700393ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700394 size_t pointerCount = mPointerProperties.size();
Jeff Brown2ed24622011-03-14 19:39:54 -0700395 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700396 if (mPointerProperties.itemAt(i).id == pointerId) {
Jeff Brown2ed24622011-03-14 19:39:54 -0700397 return i;
398 }
399 }
400 return -1;
401}
402
Jeff Brown46b9ac02010-04-22 18:58:52 -0700403void MotionEvent::offsetLocation(float xOffset, float yOffset) {
Jeff Brown5c225b12010-06-16 01:53:36 -0700404 mXOffset += xOffset;
405 mYOffset += yOffset;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700406}
407
Jeff Brown91c69ab2011-02-14 17:03:18 -0800408void MotionEvent::scale(float scaleFactor) {
409 mXOffset *= scaleFactor;
410 mYOffset *= scaleFactor;
411 mXPrecision *= scaleFactor;
412 mYPrecision *= scaleFactor;
413
414 size_t numSamples = mSamplePointerCoords.size();
415 for (size_t i = 0; i < numSamples; i++) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400416 mSamplePointerCoords.editItemAt(i).scale(scaleFactor);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800417 }
418}
419
420#ifdef HAVE_ANDROID_OS
421static inline float transformAngle(const SkMatrix* matrix, float angleRadians) {
422 // Construct and transform a vector oriented at the specified clockwise angle from vertical.
423 // Coordinate system: down is increasing Y, right is increasing X.
424 SkPoint vector;
425 vector.fX = SkFloatToScalar(sinf(angleRadians));
426 vector.fY = SkFloatToScalar(-cosf(angleRadians));
427 matrix->mapVectors(& vector, 1);
428
429 // Derive the transformed vector's clockwise angle from vertical.
430 float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(-vector.fY));
431 if (result < - M_PI_2) {
432 result += M_PI;
433 } else if (result > M_PI_2) {
434 result -= M_PI;
435 }
436 return result;
437}
438
439void MotionEvent::transform(const SkMatrix* matrix) {
440 float oldXOffset = mXOffset;
441 float oldYOffset = mYOffset;
442
443 // The tricky part of this implementation is to preserve the value of
444 // rawX and rawY. So we apply the transformation to the first point
445 // then derive an appropriate new X/Y offset that will preserve rawX and rawY.
446 SkPoint point;
447 float rawX = getRawX(0);
448 float rawY = getRawY(0);
449 matrix->mapXY(SkFloatToScalar(rawX + oldXOffset), SkFloatToScalar(rawY + oldYOffset),
450 & point);
451 float newX = SkScalarToFloat(point.fX);
452 float newY = SkScalarToFloat(point.fY);
453 float newXOffset = newX - rawX;
454 float newYOffset = newY - rawY;
455
456 mXOffset = newXOffset;
457 mYOffset = newYOffset;
458
459 // Apply the transformation to all samples.
460 size_t numSamples = mSamplePointerCoords.size();
461 for (size_t i = 0; i < numSamples; i++) {
462 PointerCoords& c = mSamplePointerCoords.editItemAt(i);
Jeff Brownbe1aa822011-07-27 16:04:54 -0700463 float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
464 float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
465 matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), &point);
466 c.setAxisValue(AMOTION_EVENT_AXIS_X, SkScalarToFloat(point.fX) - newXOffset);
467 c.setAxisValue(AMOTION_EVENT_AXIS_Y, SkScalarToFloat(point.fY) - newYOffset);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800468
Jeff Brownbe1aa822011-07-27 16:04:54 -0700469 float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
470 c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(matrix, orientation));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800471 }
472}
473
474status_t MotionEvent::readFromParcel(Parcel* parcel) {
475 size_t pointerCount = parcel->readInt32();
476 size_t sampleCount = parcel->readInt32();
477 if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) {
478 return BAD_VALUE;
479 }
480
481 mDeviceId = parcel->readInt32();
482 mSource = parcel->readInt32();
483 mAction = parcel->readInt32();
484 mFlags = parcel->readInt32();
485 mEdgeFlags = parcel->readInt32();
486 mMetaState = parcel->readInt32();
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700487 mButtonState = parcel->readInt32();
Jeff Brown91c69ab2011-02-14 17:03:18 -0800488 mXOffset = parcel->readFloat();
489 mYOffset = parcel->readFloat();
490 mXPrecision = parcel->readFloat();
491 mYPrecision = parcel->readFloat();
492 mDownTime = parcel->readInt64();
493
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700494 mPointerProperties.clear();
495 mPointerProperties.setCapacity(pointerCount);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800496 mSampleEventTimes.clear();
497 mSampleEventTimes.setCapacity(sampleCount);
498 mSamplePointerCoords.clear();
499 mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
500
501 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700502 mPointerProperties.push();
503 PointerProperties& properties = mPointerProperties.editTop();
504 properties.id = parcel->readInt32();
505 properties.toolType = parcel->readInt32();
Jeff Brown91c69ab2011-02-14 17:03:18 -0800506 }
507
508 while (sampleCount-- > 0) {
509 mSampleEventTimes.push(parcel->readInt64());
510 for (size_t i = 0; i < pointerCount; i++) {
511 mSamplePointerCoords.push();
512 status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
Jeff Brownebbd5d12011-02-17 13:01:34 -0800513 if (status) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800514 return status;
515 }
516 }
517 }
518 return OK;
519}
520
521status_t MotionEvent::writeToParcel(Parcel* parcel) const {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700522 size_t pointerCount = mPointerProperties.size();
Jeff Brown91c69ab2011-02-14 17:03:18 -0800523 size_t sampleCount = mSampleEventTimes.size();
524
525 parcel->writeInt32(pointerCount);
526 parcel->writeInt32(sampleCount);
527
528 parcel->writeInt32(mDeviceId);
529 parcel->writeInt32(mSource);
530 parcel->writeInt32(mAction);
531 parcel->writeInt32(mFlags);
532 parcel->writeInt32(mEdgeFlags);
533 parcel->writeInt32(mMetaState);
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700534 parcel->writeInt32(mButtonState);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800535 parcel->writeFloat(mXOffset);
536 parcel->writeFloat(mYOffset);
537 parcel->writeFloat(mXPrecision);
538 parcel->writeFloat(mYPrecision);
539 parcel->writeInt64(mDownTime);
540
541 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700542 const PointerProperties& properties = mPointerProperties.itemAt(i);
543 parcel->writeInt32(properties.id);
544 parcel->writeInt32(properties.toolType);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800545 }
546
547 const PointerCoords* pc = mSamplePointerCoords.array();
548 for (size_t h = 0; h < sampleCount; h++) {
549 parcel->writeInt64(mSampleEventTimes.itemAt(h));
550 for (size_t i = 0; i < pointerCount; i++) {
551 status_t status = (pc++)->writeToParcel(parcel);
Jeff Brownebbd5d12011-02-17 13:01:34 -0800552 if (status) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800553 return status;
554 }
555 }
556 }
557 return OK;
558}
559#endif
560
Jeff Brown56194eb2011-03-02 19:23:13 -0800561bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
562 if (source & AINPUT_SOURCE_CLASS_POINTER) {
563 // Specifically excludes HOVER_MOVE and SCROLL.
564 switch (action & AMOTION_EVENT_ACTION_MASK) {
565 case AMOTION_EVENT_ACTION_DOWN:
566 case AMOTION_EVENT_ACTION_MOVE:
567 case AMOTION_EVENT_ACTION_UP:
568 case AMOTION_EVENT_ACTION_POINTER_DOWN:
569 case AMOTION_EVENT_ACTION_POINTER_UP:
570 case AMOTION_EVENT_ACTION_CANCEL:
571 case AMOTION_EVENT_ACTION_OUTSIDE:
572 return true;
573 }
574 }
575 return false;
576}
577
Jeff Brown91c69ab2011-02-14 17:03:18 -0800578
Jeff Brown2b6c32c2012-03-13 15:00:09 -0700579// --- PooledInputEventFactory ---
580
581PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
582 mMaxPoolSize(maxPoolSize) {
583}
584
585PooledInputEventFactory::~PooledInputEventFactory() {
586 for (size_t i = 0; i < mKeyEventPool.size(); i++) {
587 delete mKeyEventPool.itemAt(i);
588 }
589 for (size_t i = 0; i < mMotionEventPool.size(); i++) {
590 delete mMotionEventPool.itemAt(i);
591 }
592}
593
594KeyEvent* PooledInputEventFactory::createKeyEvent() {
595 if (!mKeyEventPool.isEmpty()) {
596 KeyEvent* event = mKeyEventPool.top();
597 mKeyEventPool.pop();
598 return event;
599 }
600 return new KeyEvent();
601}
602
603MotionEvent* PooledInputEventFactory::createMotionEvent() {
604 if (!mMotionEventPool.isEmpty()) {
605 MotionEvent* event = mMotionEventPool.top();
606 mMotionEventPool.pop();
607 return event;
608 }
609 return new MotionEvent();
610}
611
612void PooledInputEventFactory::recycle(InputEvent* event) {
613 switch (event->getType()) {
614 case AINPUT_EVENT_TYPE_KEY:
615 if (mKeyEventPool.size() < mMaxPoolSize) {
616 mKeyEventPool.push(static_cast<KeyEvent*>(event));
617 return;
618 }
619 break;
620 case AINPUT_EVENT_TYPE_MOTION:
621 if (mMotionEventPool.size() < mMaxPoolSize) {
622 mMotionEventPool.push(static_cast<MotionEvent*>(event));
623 return;
624 }
625 break;
626 }
627 delete event;
628}
629
Jeff Brown46b9ac02010-04-22 18:58:52 -0700630} // namespace android