Home | History | Annotate | Download | only in input
      1 /*
      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 
     17 #define LOG_TAG "Input"
     18 //#define LOG_NDEBUG 0
     19 
     20 #include <math.h>
     21 #include <limits.h>
     22 
     23 #include <input/Input.h>
     24 #include <input/InputEventLabels.h>
     25 
     26 #ifdef HAVE_ANDROID_OS
     27 #include <binder/Parcel.h>
     28 #endif
     29 
     30 namespace android {
     31 
     32 // --- InputEvent ---
     33 
     34 void InputEvent::initialize(int32_t deviceId, int32_t source) {
     35     mDeviceId = deviceId;
     36     mSource = source;
     37 }
     38 
     39 void InputEvent::initialize(const InputEvent& from) {
     40     mDeviceId = from.mDeviceId;
     41     mSource = from.mSource;
     42 }
     43 
     44 // --- KeyEvent ---
     45 
     46 const char* KeyEvent::getLabel(int32_t keyCode) {
     47     return getLabelByKeyCode(keyCode);
     48 }
     49 
     50 int32_t KeyEvent::getKeyCodeFromLabel(const char* label) {
     51     return getKeyCodeByLabel(label);
     52 }
     53 
     54 void KeyEvent::initialize(
     55         int32_t deviceId,
     56         int32_t source,
     57         int32_t action,
     58         int32_t flags,
     59         int32_t keyCode,
     60         int32_t scanCode,
     61         int32_t metaState,
     62         int32_t repeatCount,
     63         nsecs_t downTime,
     64         nsecs_t eventTime) {
     65     InputEvent::initialize(deviceId, source);
     66     mAction = action;
     67     mFlags = flags;
     68     mKeyCode = keyCode;
     69     mScanCode = scanCode;
     70     mMetaState = metaState;
     71     mRepeatCount = repeatCount;
     72     mDownTime = downTime;
     73     mEventTime = eventTime;
     74 }
     75 
     76 void KeyEvent::initialize(const KeyEvent& from) {
     77     InputEvent::initialize(from);
     78     mAction = from.mAction;
     79     mFlags = from.mFlags;
     80     mKeyCode = from.mKeyCode;
     81     mScanCode = from.mScanCode;
     82     mMetaState = from.mMetaState;
     83     mRepeatCount = from.mRepeatCount;
     84     mDownTime = from.mDownTime;
     85     mEventTime = from.mEventTime;
     86 }
     87 
     88 
     89 // --- PointerCoords ---
     90 
     91 float PointerCoords::getAxisValue(int32_t axis) const {
     92     if (axis < 0 || axis > 63 || !BitSet64::hasBit(bits, axis)){
     93         return 0;
     94     }
     95     return values[BitSet64::getIndexOfBit(bits, axis)];
     96 }
     97 
     98 status_t PointerCoords::setAxisValue(int32_t axis, float value) {
     99     if (axis < 0 || axis > 63) {
    100         return NAME_NOT_FOUND;
    101     }
    102 
    103     uint32_t index = BitSet64::getIndexOfBit(bits, axis);
    104     if (!BitSet64::hasBit(bits, axis)) {
    105         if (value == 0) {
    106             return OK; // axes with value 0 do not need to be stored
    107         }
    108 
    109         uint32_t count = BitSet64::count(bits);
    110         if (count >= MAX_AXES) {
    111             tooManyAxes(axis);
    112             return NO_MEMORY;
    113         }
    114         BitSet64::markBit(bits, axis);
    115         for (uint32_t i = count; i > index; i--) {
    116             values[i] = values[i - 1];
    117         }
    118     }
    119 
    120     values[index] = value;
    121     return OK;
    122 }
    123 
    124 static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
    125     float value = c.getAxisValue(axis);
    126     if (value != 0) {
    127         c.setAxisValue(axis, value * scaleFactor);
    128     }
    129 }
    130 
    131 void PointerCoords::scale(float scaleFactor) {
    132     // No need to scale pressure or size since they are normalized.
    133     // No need to scale orientation since it is meaningless to do so.
    134     scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, scaleFactor);
    135     scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, scaleFactor);
    136     scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
    137     scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
    138     scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
    139     scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
    140 }
    141 
    142 void PointerCoords::applyOffset(float xOffset, float yOffset) {
    143     setAxisValue(AMOTION_EVENT_AXIS_X, getX() + xOffset);
    144     setAxisValue(AMOTION_EVENT_AXIS_Y, getY() + yOffset);
    145 }
    146 
    147 #ifdef HAVE_ANDROID_OS
    148 status_t PointerCoords::readFromParcel(Parcel* parcel) {
    149     bits = parcel->readInt64();
    150 
    151     uint32_t count = BitSet64::count(bits);
    152     if (count > MAX_AXES) {
    153         return BAD_VALUE;
    154     }
    155 
    156     for (uint32_t i = 0; i < count; i++) {
    157         values[i] = parcel->readFloat();
    158     }
    159     return OK;
    160 }
    161 
    162 status_t PointerCoords::writeToParcel(Parcel* parcel) const {
    163     parcel->writeInt64(bits);
    164 
    165     uint32_t count = BitSet64::count(bits);
    166     for (uint32_t i = 0; i < count; i++) {
    167         parcel->writeFloat(values[i]);
    168     }
    169     return OK;
    170 }
    171 #endif
    172 
    173 void PointerCoords::tooManyAxes(int axis) {
    174     ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
    175             "cannot contain more than %d axis values.", axis, int(MAX_AXES));
    176 }
    177 
    178 bool PointerCoords::operator==(const PointerCoords& other) const {
    179     if (bits != other.bits) {
    180         return false;
    181     }
    182     uint32_t count = BitSet64::count(bits);
    183     for (uint32_t i = 0; i < count; i++) {
    184         if (values[i] != other.values[i]) {
    185             return false;
    186         }
    187     }
    188     return true;
    189 }
    190 
    191 void PointerCoords::copyFrom(const PointerCoords& other) {
    192     bits = other.bits;
    193     uint32_t count = BitSet64::count(bits);
    194     for (uint32_t i = 0; i < count; i++) {
    195         values[i] = other.values[i];
    196     }
    197 }
    198 
    199 
    200 // --- PointerProperties ---
    201 
    202 bool PointerProperties::operator==(const PointerProperties& other) const {
    203     return id == other.id
    204             && toolType == other.toolType;
    205 }
    206 
    207 void PointerProperties::copyFrom(const PointerProperties& other) {
    208     id = other.id;
    209     toolType = other.toolType;
    210 }
    211 
    212 
    213 // --- MotionEvent ---
    214 
    215 void MotionEvent::initialize(
    216         int32_t deviceId,
    217         int32_t source,
    218         int32_t action,
    219         int32_t flags,
    220         int32_t edgeFlags,
    221         int32_t metaState,
    222         int32_t buttonState,
    223         float xOffset,
    224         float yOffset,
    225         float xPrecision,
    226         float yPrecision,
    227         nsecs_t downTime,
    228         nsecs_t eventTime,
    229         size_t pointerCount,
    230         const PointerProperties* pointerProperties,
    231         const PointerCoords* pointerCoords) {
    232     InputEvent::initialize(deviceId, source);
    233     mAction = action;
    234     mFlags = flags;
    235     mEdgeFlags = edgeFlags;
    236     mMetaState = metaState;
    237     mButtonState = buttonState;
    238     mXOffset = xOffset;
    239     mYOffset = yOffset;
    240     mXPrecision = xPrecision;
    241     mYPrecision = yPrecision;
    242     mDownTime = downTime;
    243     mPointerProperties.clear();
    244     mPointerProperties.appendArray(pointerProperties, pointerCount);
    245     mSampleEventTimes.clear();
    246     mSamplePointerCoords.clear();
    247     addSample(eventTime, pointerCoords);
    248 }
    249 
    250 void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
    251     InputEvent::initialize(other->mDeviceId, other->mSource);
    252     mAction = other->mAction;
    253     mFlags = other->mFlags;
    254     mEdgeFlags = other->mEdgeFlags;
    255     mMetaState = other->mMetaState;
    256     mButtonState = other->mButtonState;
    257     mXOffset = other->mXOffset;
    258     mYOffset = other->mYOffset;
    259     mXPrecision = other->mXPrecision;
    260     mYPrecision = other->mYPrecision;
    261     mDownTime = other->mDownTime;
    262     mPointerProperties = other->mPointerProperties;
    263 
    264     if (keepHistory) {
    265         mSampleEventTimes = other->mSampleEventTimes;
    266         mSamplePointerCoords = other->mSamplePointerCoords;
    267     } else {
    268         mSampleEventTimes.clear();
    269         mSampleEventTimes.push(other->getEventTime());
    270         mSamplePointerCoords.clear();
    271         size_t pointerCount = other->getPointerCount();
    272         size_t historySize = other->getHistorySize();
    273         mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
    274                 + (historySize * pointerCount), pointerCount);
    275     }
    276 }
    277 
    278 void MotionEvent::addSample(
    279         int64_t eventTime,
    280         const PointerCoords* pointerCoords) {
    281     mSampleEventTimes.push(eventTime);
    282     mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
    283 }
    284 
    285 const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
    286     return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
    287 }
    288 
    289 float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
    290     return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
    291 }
    292 
    293 float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
    294     float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
    295     switch (axis) {
    296     case AMOTION_EVENT_AXIS_X:
    297         return value + mXOffset;
    298     case AMOTION_EVENT_AXIS_Y:
    299         return value + mYOffset;
    300     }
    301     return value;
    302 }
    303 
    304 const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
    305         size_t pointerIndex, size_t historicalIndex) const {
    306     return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
    307 }
    308 
    309 float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
    310         size_t historicalIndex) const {
    311     return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
    312 }
    313 
    314 float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
    315         size_t historicalIndex) const {
    316     float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
    317     switch (axis) {
    318     case AMOTION_EVENT_AXIS_X:
    319         return value + mXOffset;
    320     case AMOTION_EVENT_AXIS_Y:
    321         return value + mYOffset;
    322     }
    323     return value;
    324 }
    325 
    326 ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
    327     size_t pointerCount = mPointerProperties.size();
    328     for (size_t i = 0; i < pointerCount; i++) {
    329         if (mPointerProperties.itemAt(i).id == pointerId) {
    330             return i;
    331         }
    332     }
    333     return -1;
    334 }
    335 
    336 void MotionEvent::offsetLocation(float xOffset, float yOffset) {
    337     mXOffset += xOffset;
    338     mYOffset += yOffset;
    339 }
    340 
    341 void MotionEvent::scale(float scaleFactor) {
    342     mXOffset *= scaleFactor;
    343     mYOffset *= scaleFactor;
    344     mXPrecision *= scaleFactor;
    345     mYPrecision *= scaleFactor;
    346 
    347     size_t numSamples = mSamplePointerCoords.size();
    348     for (size_t i = 0; i < numSamples; i++) {
    349         mSamplePointerCoords.editItemAt(i).scale(scaleFactor);
    350     }
    351 }
    352 
    353 static void transformPoint(const float matrix[9], float x, float y, float *outX, float *outY) {
    354     // Apply perspective transform like Skia.
    355     float newX = matrix[0] * x + matrix[1] * y + matrix[2];
    356     float newY = matrix[3] * x + matrix[4] * y + matrix[5];
    357     float newZ = matrix[6] * x + matrix[7] * y + matrix[8];
    358     if (newZ) {
    359         newZ = 1.0f / newZ;
    360     }
    361     *outX = newX * newZ;
    362     *outY = newY * newZ;
    363 }
    364 
    365 static float transformAngle(const float matrix[9], float angleRadians,
    366         float originX, float originY) {
    367     // Construct and transform a vector oriented at the specified clockwise angle from vertical.
    368     // Coordinate system: down is increasing Y, right is increasing X.
    369     float x = sinf(angleRadians);
    370     float y = -cosf(angleRadians);
    371     transformPoint(matrix, x, y, &x, &y);
    372     x -= originX;
    373     y -= originY;
    374 
    375     // Derive the transformed vector's clockwise angle from vertical.
    376     float result = atan2f(x, -y);
    377     if (result < - M_PI_2) {
    378         result += M_PI;
    379     } else if (result > M_PI_2) {
    380         result -= M_PI;
    381     }
    382     return result;
    383 }
    384 
    385 void MotionEvent::transform(const float matrix[9]) {
    386     // The tricky part of this implementation is to preserve the value of
    387     // rawX and rawY.  So we apply the transformation to the first point
    388     // then derive an appropriate new X/Y offset that will preserve rawX
    389      // and rawY for that point.
    390     float oldXOffset = mXOffset;
    391     float oldYOffset = mYOffset;
    392     float newX, newY;
    393     float rawX = getRawX(0);
    394     float rawY = getRawY(0);
    395     transformPoint(matrix, rawX + oldXOffset, rawY + oldYOffset, &newX, &newY);
    396     mXOffset = newX - rawX;
    397     mYOffset = newY - rawY;
    398 
    399     // Determine how the origin is transformed by the matrix so that we
    400     // can transform orientation vectors.
    401     float originX, originY;
    402     transformPoint(matrix, 0, 0, &originX, &originY);
    403 
    404     // Apply the transformation to all samples.
    405     size_t numSamples = mSamplePointerCoords.size();
    406     for (size_t i = 0; i < numSamples; i++) {
    407         PointerCoords& c = mSamplePointerCoords.editItemAt(i);
    408         float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
    409         float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
    410         transformPoint(matrix, x, y, &x, &y);
    411         c.setAxisValue(AMOTION_EVENT_AXIS_X, x - mXOffset);
    412         c.setAxisValue(AMOTION_EVENT_AXIS_Y, y - mYOffset);
    413 
    414         float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
    415         c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
    416                 transformAngle(matrix, orientation, originX, originY));
    417     }
    418 }
    419 
    420 #ifdef HAVE_ANDROID_OS
    421 status_t MotionEvent::readFromParcel(Parcel* parcel) {
    422     size_t pointerCount = parcel->readInt32();
    423     size_t sampleCount = parcel->readInt32();
    424     if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) {
    425         return BAD_VALUE;
    426     }
    427 
    428     mDeviceId = parcel->readInt32();
    429     mSource = parcel->readInt32();
    430     mAction = parcel->readInt32();
    431     mFlags = parcel->readInt32();
    432     mEdgeFlags = parcel->readInt32();
    433     mMetaState = parcel->readInt32();
    434     mButtonState = parcel->readInt32();
    435     mXOffset = parcel->readFloat();
    436     mYOffset = parcel->readFloat();
    437     mXPrecision = parcel->readFloat();
    438     mYPrecision = parcel->readFloat();
    439     mDownTime = parcel->readInt64();
    440 
    441     mPointerProperties.clear();
    442     mPointerProperties.setCapacity(pointerCount);
    443     mSampleEventTimes.clear();
    444     mSampleEventTimes.setCapacity(sampleCount);
    445     mSamplePointerCoords.clear();
    446     mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
    447 
    448     for (size_t i = 0; i < pointerCount; i++) {
    449         mPointerProperties.push();
    450         PointerProperties& properties = mPointerProperties.editTop();
    451         properties.id = parcel->readInt32();
    452         properties.toolType = parcel->readInt32();
    453     }
    454 
    455     while (sampleCount-- > 0) {
    456         mSampleEventTimes.push(parcel->readInt64());
    457         for (size_t i = 0; i < pointerCount; i++) {
    458             mSamplePointerCoords.push();
    459             status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
    460             if (status) {
    461                 return status;
    462             }
    463         }
    464     }
    465     return OK;
    466 }
    467 
    468 status_t MotionEvent::writeToParcel(Parcel* parcel) const {
    469     size_t pointerCount = mPointerProperties.size();
    470     size_t sampleCount = mSampleEventTimes.size();
    471 
    472     parcel->writeInt32(pointerCount);
    473     parcel->writeInt32(sampleCount);
    474 
    475     parcel->writeInt32(mDeviceId);
    476     parcel->writeInt32(mSource);
    477     parcel->writeInt32(mAction);
    478     parcel->writeInt32(mFlags);
    479     parcel->writeInt32(mEdgeFlags);
    480     parcel->writeInt32(mMetaState);
    481     parcel->writeInt32(mButtonState);
    482     parcel->writeFloat(mXOffset);
    483     parcel->writeFloat(mYOffset);
    484     parcel->writeFloat(mXPrecision);
    485     parcel->writeFloat(mYPrecision);
    486     parcel->writeInt64(mDownTime);
    487 
    488     for (size_t i = 0; i < pointerCount; i++) {
    489         const PointerProperties& properties = mPointerProperties.itemAt(i);
    490         parcel->writeInt32(properties.id);
    491         parcel->writeInt32(properties.toolType);
    492     }
    493 
    494     const PointerCoords* pc = mSamplePointerCoords.array();
    495     for (size_t h = 0; h < sampleCount; h++) {
    496         parcel->writeInt64(mSampleEventTimes.itemAt(h));
    497         for (size_t i = 0; i < pointerCount; i++) {
    498             status_t status = (pc++)->writeToParcel(parcel);
    499             if (status) {
    500                 return status;
    501             }
    502         }
    503     }
    504     return OK;
    505 }
    506 #endif
    507 
    508 bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
    509     if (source & AINPUT_SOURCE_CLASS_POINTER) {
    510         // Specifically excludes HOVER_MOVE and SCROLL.
    511         switch (action & AMOTION_EVENT_ACTION_MASK) {
    512         case AMOTION_EVENT_ACTION_DOWN:
    513         case AMOTION_EVENT_ACTION_MOVE:
    514         case AMOTION_EVENT_ACTION_UP:
    515         case AMOTION_EVENT_ACTION_POINTER_DOWN:
    516         case AMOTION_EVENT_ACTION_POINTER_UP:
    517         case AMOTION_EVENT_ACTION_CANCEL:
    518         case AMOTION_EVENT_ACTION_OUTSIDE:
    519             return true;
    520         }
    521     }
    522     return false;
    523 }
    524 
    525 const char* MotionEvent::getLabel(int32_t axis) {
    526     return getAxisLabel(axis);
    527 }
    528 
    529 int32_t MotionEvent::getAxisFromLabel(const char* label) {
    530     return getAxisByLabel(label);
    531 }
    532 
    533 
    534 // --- PooledInputEventFactory ---
    535 
    536 PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
    537         mMaxPoolSize(maxPoolSize) {
    538 }
    539 
    540 PooledInputEventFactory::~PooledInputEventFactory() {
    541     for (size_t i = 0; i < mKeyEventPool.size(); i++) {
    542         delete mKeyEventPool.itemAt(i);
    543     }
    544     for (size_t i = 0; i < mMotionEventPool.size(); i++) {
    545         delete mMotionEventPool.itemAt(i);
    546     }
    547 }
    548 
    549 KeyEvent* PooledInputEventFactory::createKeyEvent() {
    550     if (!mKeyEventPool.isEmpty()) {
    551         KeyEvent* event = mKeyEventPool.top();
    552         mKeyEventPool.pop();
    553         return event;
    554     }
    555     return new KeyEvent();
    556 }
    557 
    558 MotionEvent* PooledInputEventFactory::createMotionEvent() {
    559     if (!mMotionEventPool.isEmpty()) {
    560         MotionEvent* event = mMotionEventPool.top();
    561         mMotionEventPool.pop();
    562         return event;
    563     }
    564     return new MotionEvent();
    565 }
    566 
    567 void PooledInputEventFactory::recycle(InputEvent* event) {
    568     switch (event->getType()) {
    569     case AINPUT_EVENT_TYPE_KEY:
    570         if (mKeyEventPool.size() < mMaxPoolSize) {
    571             mKeyEventPool.push(static_cast<KeyEvent*>(event));
    572             return;
    573         }
    574         break;
    575     case AINPUT_EVENT_TYPE_MOTION:
    576         if (mMotionEventPool.size() < mMaxPoolSize) {
    577             mMotionEventPool.push(static_cast<MotionEvent*>(event));
    578             return;
    579         }
    580         break;
    581     }
    582     delete event;
    583 }
    584 
    585 } // namespace android
    586