blob: eca692a4b547c6c93c0fe6b8d2cfe080d397e32b [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:
Michael Wright1df477a2013-01-31 16:19:18 -080075 case AKEYCODE_BRIGHTNESS_DOWN:
76 case AKEYCODE_BRIGHTNESS_UP:
Dianne Hackborn3c80a4a2010-06-29 19:20:40 -070077 return true;
78 }
79
80 return false;
81}
82
83bool KeyEvent::hasDefaultAction() const {
84 return hasDefaultAction(getKeyCode());
85}
86
87bool KeyEvent::isSystemKey(int32_t keyCode) {
88 switch (keyCode) {
Jeff Brownfd035822010-06-30 16:10:35 -070089 case AKEYCODE_MENU:
90 case AKEYCODE_SOFT_RIGHT:
91 case AKEYCODE_HOME:
92 case AKEYCODE_BACK:
93 case AKEYCODE_CALL:
94 case AKEYCODE_ENDCALL:
95 case AKEYCODE_VOLUME_UP:
96 case AKEYCODE_VOLUME_DOWN:
Jeff Brownb0418da2010-11-01 15:24:01 -070097 case AKEYCODE_VOLUME_MUTE:
Jeff Brownfd035822010-06-30 16:10:35 -070098 case AKEYCODE_MUTE:
99 case AKEYCODE_POWER:
100 case AKEYCODE_HEADSETHOOK:
Jeff Brownb0418da2010-11-01 15:24:01 -0700101 case AKEYCODE_MEDIA_PLAY:
102 case AKEYCODE_MEDIA_PAUSE:
Jeff Brownfd035822010-06-30 16:10:35 -0700103 case AKEYCODE_MEDIA_PLAY_PAUSE:
104 case AKEYCODE_MEDIA_STOP:
105 case AKEYCODE_MEDIA_NEXT:
106 case AKEYCODE_MEDIA_PREVIOUS:
107 case AKEYCODE_MEDIA_REWIND:
Jeff Brownb0418da2010-11-01 15:24:01 -0700108 case AKEYCODE_MEDIA_RECORD:
Jeff Brownfd035822010-06-30 16:10:35 -0700109 case AKEYCODE_MEDIA_FAST_FORWARD:
110 case AKEYCODE_CAMERA:
111 case AKEYCODE_FOCUS:
112 case AKEYCODE_SEARCH:
Michael Wright1df477a2013-01-31 16:19:18 -0800113 case AKEYCODE_BRIGHTNESS_DOWN:
114 case AKEYCODE_BRIGHTNESS_UP:
Dianne Hackborn3c80a4a2010-06-29 19:20:40 -0700115 return true;
116 }
117
118 return false;
119}
120
121bool KeyEvent::isSystemKey() const {
122 return isSystemKey(getKeyCode());
123}
124
Jeff Brown46b9ac02010-04-22 18:58:52 -0700125void KeyEvent::initialize(
126 int32_t deviceId,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700127 int32_t source,
Jeff Brown46b9ac02010-04-22 18:58:52 -0700128 int32_t action,
129 int32_t flags,
130 int32_t keyCode,
131 int32_t scanCode,
132 int32_t metaState,
133 int32_t repeatCount,
134 nsecs_t downTime,
135 nsecs_t eventTime) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700136 InputEvent::initialize(deviceId, source);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700137 mAction = action;
138 mFlags = flags;
139 mKeyCode = keyCode;
140 mScanCode = scanCode;
141 mMetaState = metaState;
142 mRepeatCount = repeatCount;
143 mDownTime = downTime;
144 mEventTime = eventTime;
145}
146
Dianne Hackborn2c6081c2010-07-15 17:44:53 -0700147void KeyEvent::initialize(const KeyEvent& from) {
148 InputEvent::initialize(from);
149 mAction = from.mAction;
150 mFlags = from.mFlags;
151 mKeyCode = from.mKeyCode;
152 mScanCode = from.mScanCode;
153 mMetaState = from.mMetaState;
154 mRepeatCount = from.mRepeatCount;
155 mDownTime = from.mDownTime;
156 mEventTime = from.mEventTime;
157}
158
Jeff Brown91c69ab2011-02-14 17:03:18 -0800159
160// --- PointerCoords ---
161
Jeff Brown6f2fba42011-02-19 01:08:02 -0800162float PointerCoords::getAxisValue(int32_t axis) const {
163 if (axis < 0 || axis > 63) {
164 return 0;
165 }
166
167 uint64_t axisBit = 1LL << axis;
168 if (!(bits & axisBit)) {
169 return 0;
170 }
171 uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
172 return values[index];
173}
174
175status_t PointerCoords::setAxisValue(int32_t axis, float value) {
176 if (axis < 0 || axis > 63) {
177 return NAME_NOT_FOUND;
178 }
179
180 uint64_t axisBit = 1LL << axis;
181 uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
182 if (!(bits & axisBit)) {
Jeff Brownbe1aa822011-07-27 16:04:54 -0700183 if (value == 0) {
184 return OK; // axes with value 0 do not need to be stored
185 }
Jeff Brown6f2fba42011-02-19 01:08:02 -0800186 uint32_t count = __builtin_popcountll(bits);
187 if (count >= MAX_AXES) {
188 tooManyAxes(axis);
189 return NO_MEMORY;
190 }
191 bits |= axisBit;
192 for (uint32_t i = count; i > index; i--) {
193 values[i] = values[i - 1];
194 }
195 }
196 values[index] = value;
197 return OK;
198}
199
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400200static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
Jeff Brownbe1aa822011-07-27 16:04:54 -0700201 float value = c.getAxisValue(axis);
202 if (value != 0) {
203 c.setAxisValue(axis, value * scaleFactor);
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400204 }
205}
206
207void PointerCoords::scale(float scaleFactor) {
208 // No need to scale pressure or size since they are normalized.
209 // No need to scale orientation since it is meaningless to do so.
210 scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, scaleFactor);
211 scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, scaleFactor);
212 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
213 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
214 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
215 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
216}
217
Jeff Brown91c69ab2011-02-14 17:03:18 -0800218#ifdef HAVE_ANDROID_OS
219status_t PointerCoords::readFromParcel(Parcel* parcel) {
Jeff Brown6f2fba42011-02-19 01:08:02 -0800220 bits = parcel->readInt64();
Jeff Brown91c69ab2011-02-14 17:03:18 -0800221
Jeff Brown6f2fba42011-02-19 01:08:02 -0800222 uint32_t count = __builtin_popcountll(bits);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800223 if (count > MAX_AXES) {
224 return BAD_VALUE;
225 }
226
227 for (uint32_t i = 0; i < count; i++) {
Ilya Polenov716f7b32012-12-10 10:19:58 +0400228 values[i] = parcel->readFloat();
Jeff Brown91c69ab2011-02-14 17:03:18 -0800229 }
230 return OK;
231}
232
233status_t PointerCoords::writeToParcel(Parcel* parcel) const {
Jeff Brown6f2fba42011-02-19 01:08:02 -0800234 parcel->writeInt64(bits);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800235
Jeff Brown6f2fba42011-02-19 01:08:02 -0800236 uint32_t count = __builtin_popcountll(bits);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800237 for (uint32_t i = 0; i < count; i++) {
Ilya Polenov716f7b32012-12-10 10:19:58 +0400238 parcel->writeFloat(values[i]);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800239 }
240 return OK;
241}
242#endif
243
244void PointerCoords::tooManyAxes(int axis) {
Steve Block8564c8d2012-01-05 23:22:43 +0000245 ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
Jeff Brown91c69ab2011-02-14 17:03:18 -0800246 "cannot contain more than %d axis values.", axis, int(MAX_AXES));
247}
248
Jeff Brownace13b12011-03-09 17:39:48 -0800249bool PointerCoords::operator==(const PointerCoords& other) const {
250 if (bits != other.bits) {
251 return false;
252 }
253 uint32_t count = __builtin_popcountll(bits);
254 for (uint32_t i = 0; i < count; i++) {
255 if (values[i] != other.values[i]) {
256 return false;
257 }
258 }
259 return true;
260}
261
262void PointerCoords::copyFrom(const PointerCoords& other) {
263 bits = other.bits;
264 uint32_t count = __builtin_popcountll(bits);
265 for (uint32_t i = 0; i < count; i++) {
266 values[i] = other.values[i];
267 }
268}
269
Jeff Brown91c69ab2011-02-14 17:03:18 -0800270
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700271// --- PointerProperties ---
272
273bool PointerProperties::operator==(const PointerProperties& other) const {
274 return id == other.id
275 && toolType == other.toolType;
276}
277
278void PointerProperties::copyFrom(const PointerProperties& other) {
279 id = other.id;
280 toolType = other.toolType;
281}
282
283
Jeff Brown47e6b1b2010-11-29 17:37:49 -0800284// --- MotionEvent ---
Jeff Brown46b9ac02010-04-22 18:58:52 -0700285
286void MotionEvent::initialize(
287 int32_t deviceId,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700288 int32_t source,
Jeff Brown46b9ac02010-04-22 18:58:52 -0700289 int32_t action,
Jeff Brown85a31762010-09-01 17:01:00 -0700290 int32_t flags,
Jeff Brown46b9ac02010-04-22 18:58:52 -0700291 int32_t edgeFlags,
292 int32_t metaState,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700293 int32_t buttonState,
Jeff Brown5c225b12010-06-16 01:53:36 -0700294 float xOffset,
295 float yOffset,
Jeff Brown46b9ac02010-04-22 18:58:52 -0700296 float xPrecision,
297 float yPrecision,
298 nsecs_t downTime,
299 nsecs_t eventTime,
300 size_t pointerCount,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700301 const PointerProperties* pointerProperties,
Jeff Brown46b9ac02010-04-22 18:58:52 -0700302 const PointerCoords* pointerCoords) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700303 InputEvent::initialize(deviceId, source);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700304 mAction = action;
Jeff Brown85a31762010-09-01 17:01:00 -0700305 mFlags = flags;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700306 mEdgeFlags = edgeFlags;
307 mMetaState = metaState;
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700308 mButtonState = buttonState;
Jeff Brown5c225b12010-06-16 01:53:36 -0700309 mXOffset = xOffset;
310 mYOffset = yOffset;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700311 mXPrecision = xPrecision;
312 mYPrecision = yPrecision;
313 mDownTime = downTime;
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700314 mPointerProperties.clear();
315 mPointerProperties.appendArray(pointerProperties, pointerCount);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700316 mSampleEventTimes.clear();
317 mSamplePointerCoords.clear();
318 addSample(eventTime, pointerCoords);
319}
320
Jeff Brown91c69ab2011-02-14 17:03:18 -0800321void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
322 InputEvent::initialize(other->mDeviceId, other->mSource);
323 mAction = other->mAction;
324 mFlags = other->mFlags;
325 mEdgeFlags = other->mEdgeFlags;
326 mMetaState = other->mMetaState;
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700327 mButtonState = other->mButtonState;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800328 mXOffset = other->mXOffset;
329 mYOffset = other->mYOffset;
330 mXPrecision = other->mXPrecision;
331 mYPrecision = other->mYPrecision;
332 mDownTime = other->mDownTime;
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700333 mPointerProperties = other->mPointerProperties;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800334
335 if (keepHistory) {
336 mSampleEventTimes = other->mSampleEventTimes;
337 mSamplePointerCoords = other->mSamplePointerCoords;
338 } else {
339 mSampleEventTimes.clear();
340 mSampleEventTimes.push(other->getEventTime());
341 mSamplePointerCoords.clear();
342 size_t pointerCount = other->getPointerCount();
343 size_t historySize = other->getHistorySize();
344 mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
345 + (historySize * pointerCount), pointerCount);
346 }
347}
348
Jeff Brown46b9ac02010-04-22 18:58:52 -0700349void MotionEvent::addSample(
350 int64_t eventTime,
351 const PointerCoords* pointerCoords) {
352 mSampleEventTimes.push(eventTime);
353 mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
354}
355
Jeff Brown91c69ab2011-02-14 17:03:18 -0800356const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
357 return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
358}
359
360float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
361 return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
362}
363
364float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
365 float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
366 switch (axis) {
Jeff Brownebbd5d12011-02-17 13:01:34 -0800367 case AMOTION_EVENT_AXIS_X:
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400368 return value + mXOffset;
Jeff Brownebbd5d12011-02-17 13:01:34 -0800369 case AMOTION_EVENT_AXIS_Y:
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400370 return value + mYOffset;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800371 }
372 return value;
373}
374
375const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
376 size_t pointerIndex, size_t historicalIndex) const {
377 return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
378}
379
380float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
381 size_t historicalIndex) const {
382 return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
383}
384
385float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
386 size_t historicalIndex) const {
387 float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
388 switch (axis) {
Jeff Brownebbd5d12011-02-17 13:01:34 -0800389 case AMOTION_EVENT_AXIS_X:
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400390 return value + mXOffset;
Jeff Brownebbd5d12011-02-17 13:01:34 -0800391 case AMOTION_EVENT_AXIS_Y:
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400392 return value + mYOffset;
Jeff Brown91c69ab2011-02-14 17:03:18 -0800393 }
394 return value;
395}
396
Jeff Brown2ed24622011-03-14 19:39:54 -0700397ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700398 size_t pointerCount = mPointerProperties.size();
Jeff Brown2ed24622011-03-14 19:39:54 -0700399 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700400 if (mPointerProperties.itemAt(i).id == pointerId) {
Jeff Brown2ed24622011-03-14 19:39:54 -0700401 return i;
402 }
403 }
404 return -1;
405}
406
Jeff Brown46b9ac02010-04-22 18:58:52 -0700407void MotionEvent::offsetLocation(float xOffset, float yOffset) {
Jeff Brown5c225b12010-06-16 01:53:36 -0700408 mXOffset += xOffset;
409 mYOffset += yOffset;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700410}
411
Jeff Brown91c69ab2011-02-14 17:03:18 -0800412void MotionEvent::scale(float scaleFactor) {
413 mXOffset *= scaleFactor;
414 mYOffset *= scaleFactor;
415 mXPrecision *= scaleFactor;
416 mYPrecision *= scaleFactor;
417
418 size_t numSamples = mSamplePointerCoords.size();
419 for (size_t i = 0; i < numSamples; i++) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400420 mSamplePointerCoords.editItemAt(i).scale(scaleFactor);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800421 }
422}
423
424#ifdef HAVE_ANDROID_OS
425static inline float transformAngle(const SkMatrix* matrix, float angleRadians) {
426 // Construct and transform a vector oriented at the specified clockwise angle from vertical.
427 // Coordinate system: down is increasing Y, right is increasing X.
428 SkPoint vector;
429 vector.fX = SkFloatToScalar(sinf(angleRadians));
430 vector.fY = SkFloatToScalar(-cosf(angleRadians));
431 matrix->mapVectors(& vector, 1);
432
433 // Derive the transformed vector's clockwise angle from vertical.
434 float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(-vector.fY));
435 if (result < - M_PI_2) {
436 result += M_PI;
437 } else if (result > M_PI_2) {
438 result -= M_PI;
439 }
440 return result;
441}
442
443void MotionEvent::transform(const SkMatrix* matrix) {
444 float oldXOffset = mXOffset;
445 float oldYOffset = mYOffset;
446
447 // The tricky part of this implementation is to preserve the value of
448 // rawX and rawY. So we apply the transformation to the first point
449 // then derive an appropriate new X/Y offset that will preserve rawX and rawY.
450 SkPoint point;
451 float rawX = getRawX(0);
452 float rawY = getRawY(0);
453 matrix->mapXY(SkFloatToScalar(rawX + oldXOffset), SkFloatToScalar(rawY + oldYOffset),
454 & point);
455 float newX = SkScalarToFloat(point.fX);
456 float newY = SkScalarToFloat(point.fY);
457 float newXOffset = newX - rawX;
458 float newYOffset = newY - rawY;
459
460 mXOffset = newXOffset;
461 mYOffset = newYOffset;
462
463 // Apply the transformation to all samples.
464 size_t numSamples = mSamplePointerCoords.size();
465 for (size_t i = 0; i < numSamples; i++) {
466 PointerCoords& c = mSamplePointerCoords.editItemAt(i);
Jeff Brownbe1aa822011-07-27 16:04:54 -0700467 float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
468 float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
469 matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), &point);
470 c.setAxisValue(AMOTION_EVENT_AXIS_X, SkScalarToFloat(point.fX) - newXOffset);
471 c.setAxisValue(AMOTION_EVENT_AXIS_Y, SkScalarToFloat(point.fY) - newYOffset);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800472
Jeff Brownbe1aa822011-07-27 16:04:54 -0700473 float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
474 c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(matrix, orientation));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800475 }
476}
477
478status_t MotionEvent::readFromParcel(Parcel* parcel) {
479 size_t pointerCount = parcel->readInt32();
480 size_t sampleCount = parcel->readInt32();
481 if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) {
482 return BAD_VALUE;
483 }
484
485 mDeviceId = parcel->readInt32();
486 mSource = parcel->readInt32();
487 mAction = parcel->readInt32();
488 mFlags = parcel->readInt32();
489 mEdgeFlags = parcel->readInt32();
490 mMetaState = parcel->readInt32();
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700491 mButtonState = parcel->readInt32();
Jeff Brown91c69ab2011-02-14 17:03:18 -0800492 mXOffset = parcel->readFloat();
493 mYOffset = parcel->readFloat();
494 mXPrecision = parcel->readFloat();
495 mYPrecision = parcel->readFloat();
496 mDownTime = parcel->readInt64();
497
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700498 mPointerProperties.clear();
499 mPointerProperties.setCapacity(pointerCount);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800500 mSampleEventTimes.clear();
501 mSampleEventTimes.setCapacity(sampleCount);
502 mSamplePointerCoords.clear();
503 mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
504
505 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700506 mPointerProperties.push();
507 PointerProperties& properties = mPointerProperties.editTop();
508 properties.id = parcel->readInt32();
509 properties.toolType = parcel->readInt32();
Jeff Brown91c69ab2011-02-14 17:03:18 -0800510 }
511
512 while (sampleCount-- > 0) {
513 mSampleEventTimes.push(parcel->readInt64());
514 for (size_t i = 0; i < pointerCount; i++) {
515 mSamplePointerCoords.push();
516 status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
Jeff Brownebbd5d12011-02-17 13:01:34 -0800517 if (status) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800518 return status;
519 }
520 }
521 }
522 return OK;
523}
524
525status_t MotionEvent::writeToParcel(Parcel* parcel) const {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700526 size_t pointerCount = mPointerProperties.size();
Jeff Brown91c69ab2011-02-14 17:03:18 -0800527 size_t sampleCount = mSampleEventTimes.size();
528
529 parcel->writeInt32(pointerCount);
530 parcel->writeInt32(sampleCount);
531
532 parcel->writeInt32(mDeviceId);
533 parcel->writeInt32(mSource);
534 parcel->writeInt32(mAction);
535 parcel->writeInt32(mFlags);
536 parcel->writeInt32(mEdgeFlags);
537 parcel->writeInt32(mMetaState);
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700538 parcel->writeInt32(mButtonState);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800539 parcel->writeFloat(mXOffset);
540 parcel->writeFloat(mYOffset);
541 parcel->writeFloat(mXPrecision);
542 parcel->writeFloat(mYPrecision);
543 parcel->writeInt64(mDownTime);
544
545 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700546 const PointerProperties& properties = mPointerProperties.itemAt(i);
547 parcel->writeInt32(properties.id);
548 parcel->writeInt32(properties.toolType);
Jeff Brown91c69ab2011-02-14 17:03:18 -0800549 }
550
551 const PointerCoords* pc = mSamplePointerCoords.array();
552 for (size_t h = 0; h < sampleCount; h++) {
553 parcel->writeInt64(mSampleEventTimes.itemAt(h));
554 for (size_t i = 0; i < pointerCount; i++) {
555 status_t status = (pc++)->writeToParcel(parcel);
Jeff Brownebbd5d12011-02-17 13:01:34 -0800556 if (status) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800557 return status;
558 }
559 }
560 }
561 return OK;
562}
563#endif
564
Jeff Brown56194eb2011-03-02 19:23:13 -0800565bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
566 if (source & AINPUT_SOURCE_CLASS_POINTER) {
567 // Specifically excludes HOVER_MOVE and SCROLL.
568 switch (action & AMOTION_EVENT_ACTION_MASK) {
569 case AMOTION_EVENT_ACTION_DOWN:
570 case AMOTION_EVENT_ACTION_MOVE:
571 case AMOTION_EVENT_ACTION_UP:
572 case AMOTION_EVENT_ACTION_POINTER_DOWN:
573 case AMOTION_EVENT_ACTION_POINTER_UP:
574 case AMOTION_EVENT_ACTION_CANCEL:
575 case AMOTION_EVENT_ACTION_OUTSIDE:
576 return true;
577 }
578 }
579 return false;
580}
581
Jeff Brown91c69ab2011-02-14 17:03:18 -0800582
Jeff Brown2b6c32c2012-03-13 15:00:09 -0700583// --- PooledInputEventFactory ---
584
585PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
586 mMaxPoolSize(maxPoolSize) {
587}
588
589PooledInputEventFactory::~PooledInputEventFactory() {
590 for (size_t i = 0; i < mKeyEventPool.size(); i++) {
591 delete mKeyEventPool.itemAt(i);
592 }
593 for (size_t i = 0; i < mMotionEventPool.size(); i++) {
594 delete mMotionEventPool.itemAt(i);
595 }
596}
597
598KeyEvent* PooledInputEventFactory::createKeyEvent() {
599 if (!mKeyEventPool.isEmpty()) {
600 KeyEvent* event = mKeyEventPool.top();
601 mKeyEventPool.pop();
602 return event;
603 }
604 return new KeyEvent();
605}
606
607MotionEvent* PooledInputEventFactory::createMotionEvent() {
608 if (!mMotionEventPool.isEmpty()) {
609 MotionEvent* event = mMotionEventPool.top();
610 mMotionEventPool.pop();
611 return event;
612 }
613 return new MotionEvent();
614}
615
616void PooledInputEventFactory::recycle(InputEvent* event) {
617 switch (event->getType()) {
618 case AINPUT_EVENT_TYPE_KEY:
619 if (mKeyEventPool.size() < mMaxPoolSize) {
620 mKeyEventPool.push(static_cast<KeyEvent*>(event));
621 return;
622 }
623 break;
624 case AINPUT_EVENT_TYPE_MOTION:
625 if (mMotionEventPool.size() < mMaxPoolSize) {
626 mMotionEventPool.push(static_cast<MotionEvent*>(event));
627 return;
628 }
629 break;
630 }
631 delete event;
632}
633
Jeff Brown46b9ac02010-04-22 18:58:52 -0700634} // namespace android