| Prabir Pradhan | baa5c82 | 2019-08-30 15:27:05 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2019 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 | #include "Macros.h" | 
 | 18 |  | 
 | 19 | #include "RotaryEncoderInputMapper.h" | 
 | 20 |  | 
 | 21 | #include "CursorScrollAccumulator.h" | 
 | 22 |  | 
 | 23 | namespace android { | 
 | 24 |  | 
 | 25 | RotaryEncoderInputMapper::RotaryEncoderInputMapper(InputDevice* device) | 
 | 26 |       : InputMapper(device), mOrientation(DISPLAY_ORIENTATION_0) { | 
 | 27 |     mSource = AINPUT_SOURCE_ROTARY_ENCODER; | 
 | 28 | } | 
 | 29 |  | 
 | 30 | RotaryEncoderInputMapper::~RotaryEncoderInputMapper() {} | 
 | 31 |  | 
 | 32 | uint32_t RotaryEncoderInputMapper::getSources() { | 
 | 33 |     return mSource; | 
 | 34 | } | 
 | 35 |  | 
 | 36 | void RotaryEncoderInputMapper::populateDeviceInfo(InputDeviceInfo* info) { | 
 | 37 |     InputMapper::populateDeviceInfo(info); | 
 | 38 |  | 
 | 39 |     if (mRotaryEncoderScrollAccumulator.haveRelativeVWheel()) { | 
 | 40 |         float res = 0.0f; | 
 | 41 |         if (!mDevice->getConfiguration().tryGetProperty(String8("device.res"), res)) { | 
 | 42 |             ALOGW("Rotary Encoder device configuration file didn't specify resolution!\n"); | 
 | 43 |         } | 
 | 44 |         if (!mDevice->getConfiguration().tryGetProperty(String8("device.scalingFactor"), | 
 | 45 |                                                         mScalingFactor)) { | 
 | 46 |             ALOGW("Rotary Encoder device configuration file didn't specify scaling factor," | 
 | 47 |                   "default to 1.0!\n"); | 
 | 48 |             mScalingFactor = 1.0f; | 
 | 49 |         } | 
 | 50 |         info->addMotionRange(AMOTION_EVENT_AXIS_SCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, | 
 | 51 |                              res * mScalingFactor); | 
 | 52 |     } | 
 | 53 | } | 
 | 54 |  | 
 | 55 | void RotaryEncoderInputMapper::dump(std::string& dump) { | 
 | 56 |     dump += INDENT2 "Rotary Encoder Input Mapper:\n"; | 
 | 57 |     dump += StringPrintf(INDENT3 "HaveWheel: %s\n", | 
 | 58 |                          toString(mRotaryEncoderScrollAccumulator.haveRelativeVWheel())); | 
 | 59 | } | 
 | 60 |  | 
 | 61 | void RotaryEncoderInputMapper::configure(nsecs_t when, const InputReaderConfiguration* config, | 
 | 62 |                                          uint32_t changes) { | 
 | 63 |     InputMapper::configure(when, config, changes); | 
 | 64 |     if (!changes) { | 
 | 65 |         mRotaryEncoderScrollAccumulator.configure(getDevice()); | 
 | 66 |     } | 
 | 67 |     if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) { | 
 | 68 |         std::optional<DisplayViewport> internalViewport = | 
 | 69 |                 config->getDisplayViewportByType(ViewportType::VIEWPORT_INTERNAL); | 
 | 70 |         if (internalViewport) { | 
 | 71 |             mOrientation = internalViewport->orientation; | 
 | 72 |         } else { | 
 | 73 |             mOrientation = DISPLAY_ORIENTATION_0; | 
 | 74 |         } | 
 | 75 |     } | 
 | 76 | } | 
 | 77 |  | 
 | 78 | void RotaryEncoderInputMapper::reset(nsecs_t when) { | 
 | 79 |     mRotaryEncoderScrollAccumulator.reset(getDevice()); | 
 | 80 |  | 
 | 81 |     InputMapper::reset(when); | 
 | 82 | } | 
 | 83 |  | 
 | 84 | void RotaryEncoderInputMapper::process(const RawEvent* rawEvent) { | 
 | 85 |     mRotaryEncoderScrollAccumulator.process(rawEvent); | 
 | 86 |  | 
 | 87 |     if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) { | 
 | 88 |         sync(rawEvent->when); | 
 | 89 |     } | 
 | 90 | } | 
 | 91 |  | 
 | 92 | void RotaryEncoderInputMapper::sync(nsecs_t when) { | 
 | 93 |     PointerCoords pointerCoords; | 
 | 94 |     pointerCoords.clear(); | 
 | 95 |  | 
 | 96 |     PointerProperties pointerProperties; | 
 | 97 |     pointerProperties.clear(); | 
 | 98 |     pointerProperties.id = 0; | 
 | 99 |     pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_UNKNOWN; | 
 | 100 |  | 
 | 101 |     float scroll = mRotaryEncoderScrollAccumulator.getRelativeVWheel(); | 
 | 102 |     bool scrolled = scroll != 0; | 
 | 103 |  | 
 | 104 |     // This is not a pointer, so it's not associated with a display. | 
 | 105 |     int32_t displayId = ADISPLAY_ID_NONE; | 
 | 106 |  | 
 | 107 |     // Moving the rotary encoder should wake the device (if specified). | 
 | 108 |     uint32_t policyFlags = 0; | 
 | 109 |     if (scrolled && getDevice()->isExternal()) { | 
 | 110 |         policyFlags |= POLICY_FLAG_WAKE; | 
 | 111 |     } | 
 | 112 |  | 
 | 113 |     if (mOrientation == DISPLAY_ORIENTATION_180) { | 
 | 114 |         scroll = -scroll; | 
 | 115 |     } | 
 | 116 |  | 
 | 117 |     // Send motion event. | 
 | 118 |     if (scrolled) { | 
 | 119 |         int32_t metaState = mContext->getGlobalMetaState(); | 
 | 120 |         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_SCROLL, scroll * mScalingFactor); | 
 | 121 |  | 
 | 122 |         NotifyMotionArgs scrollArgs(mContext->getNextSequenceNum(), when, getDeviceId(), mSource, | 
 | 123 |                                     displayId, policyFlags, AMOTION_EVENT_ACTION_SCROLL, 0, 0, | 
 | 124 |                                     metaState, /* buttonState */ 0, MotionClassification::NONE, | 
 | 125 |                                     AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties, | 
 | 126 |                                     &pointerCoords, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION, | 
 | 127 |                                     AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, /* videoFrames */ {}); | 
 | 128 |         getListener()->notifyMotion(&scrollArgs); | 
 | 129 |     } | 
 | 130 |  | 
 | 131 |     mRotaryEncoderScrollAccumulator.finishSync(); | 
 | 132 | } | 
 | 133 |  | 
 | 134 | } // namespace android |