1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
|
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <PointerControllerInterface.h>
#include <android-base/thread_annotations.h>
#include <utils/Condition.h>
#include <utils/Mutex.h>
#include <memory>
#include <unordered_map>
#include <vector>
#include "EventHub.h"
#include "InputListener.h"
#include "InputReaderBase.h"
#include "InputReaderContext.h"
#include "InputThread.h"
namespace android {
class InputDevice;
class InputMapper;
struct StylusState;
/* The input reader reads raw event data from the event hub and processes it into input events
* that it sends to the input listener. Some functions of the input reader, such as early
* event filtering in low power states, are controlled by a separate policy object.
*
* The InputReader owns a collection of InputMappers. InputReader starts its own thread, where
* most of the work happens, but the InputReader can receive queries from other system
* components running on arbitrary threads. To keep things manageable, the InputReader
* uses a single Mutex to guard its state. The Mutex may be held while calling into the
* EventHub or the InputReaderPolicy but it is never held while calling into the
* InputListener. All calls to InputListener must happen from InputReader's thread.
*/
class InputReader : public InputReaderInterface {
public:
InputReader(std::shared_ptr<EventHubInterface> eventHub,
const sp<InputReaderPolicyInterface>& policy, InputListenerInterface& listener);
virtual ~InputReader();
void dump(std::string& dump) override;
void monitor() override;
status_t start() override;
status_t stop() override;
std::vector<InputDeviceInfo> getInputDevices() const override;
bool isInputDeviceEnabled(int32_t deviceId) override;
int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask, int32_t scanCode) override;
int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask, int32_t keyCode) override;
int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t sw) override;
void addKeyRemapping(int32_t deviceId, int32_t fromKeyCode, int32_t toKeyCode) const override;
int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const override;
void toggleCapsLockState(int32_t deviceId) override;
bool hasKeys(int32_t deviceId, uint32_t sourceMask, const std::vector<int32_t>& keyCodes,
uint8_t* outFlags) override;
void requestRefreshConfiguration(ConfigurationChanges changes) override;
void vibrate(int32_t deviceId, const VibrationSequence& sequence, ssize_t repeat,
int32_t token) override;
void cancelVibrate(int32_t deviceId, int32_t token) override;
bool isVibrating(int32_t deviceId) override;
std::vector<int32_t> getVibratorIds(int32_t deviceId) override;
bool canDispatchToDisplay(int32_t deviceId, int32_t displayId) override;
bool enableSensor(int32_t deviceId, InputDeviceSensorType sensorType,
std::chrono::microseconds samplingPeriod,
std::chrono::microseconds maxBatchReportLatency) override;
void disableSensor(int32_t deviceId, InputDeviceSensorType sensorType) override;
void flushSensor(int32_t deviceId, InputDeviceSensorType sensorType) override;
std::optional<int32_t> getBatteryCapacity(int32_t deviceId) override;
std::optional<int32_t> getBatteryStatus(int32_t deviceId) override;
std::optional<std::string> getBatteryDevicePath(int32_t deviceId) override;
std::vector<InputDeviceLightInfo> getLights(int32_t deviceId) override;
std::vector<InputDeviceSensorInfo> getSensors(int32_t deviceId) override;
bool setLightColor(int32_t deviceId, int32_t lightId, int32_t color) override;
bool setLightPlayerId(int32_t deviceId, int32_t lightId, int32_t playerId) override;
std::optional<int32_t> getLightColor(int32_t deviceId, int32_t lightId) override;
std::optional<int32_t> getLightPlayerId(int32_t deviceId, int32_t lightId) override;
std::optional<std::string> getBluetoothAddress(int32_t deviceId) const override;
void sysfsNodeChanged(const std::string& sysfsNodePath) override;
protected:
// These members are protected so they can be instrumented by test cases.
virtual std::shared_ptr<InputDevice> createDeviceLocked(nsecs_t when, int32_t deviceId,
const InputDeviceIdentifier& identifier)
REQUIRES(mLock);
// With each iteration of the loop, InputReader reads and processes one incoming message from
// the EventHub.
void loopOnce();
class ContextImpl : public InputReaderContext {
InputReader* mReader;
IdGenerator mIdGenerator;
public:
explicit ContextImpl(InputReader* reader);
// lock is already held by the input loop
void updateGlobalMetaState() NO_THREAD_SAFETY_ANALYSIS override;
int32_t getGlobalMetaState() NO_THREAD_SAFETY_ANALYSIS override;
void disableVirtualKeysUntil(nsecs_t time) REQUIRES(mReader->mLock) override;
bool shouldDropVirtualKey(nsecs_t now, int32_t keyCode, int32_t scanCode)
REQUIRES(mReader->mLock) override;
void fadePointer() REQUIRES(mReader->mLock) override;
std::shared_ptr<PointerControllerInterface> getPointerController(int32_t deviceId)
REQUIRES(mReader->mLock) override;
void requestTimeoutAtTime(nsecs_t when) REQUIRES(mReader->mLock) override;
int32_t bumpGeneration() NO_THREAD_SAFETY_ANALYSIS override;
void getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices)
REQUIRES(mReader->mLock) override;
[[nodiscard]] std::list<NotifyArgs> dispatchExternalStylusState(const StylusState& outState)
REQUIRES(mReader->mLock) override;
InputReaderPolicyInterface* getPolicy() REQUIRES(mReader->mLock) override;
EventHubInterface* getEventHub() REQUIRES(mReader->mLock) override;
int32_t getNextId() NO_THREAD_SAFETY_ANALYSIS override;
void updateLedMetaState(int32_t metaState) REQUIRES(mReader->mLock) override;
int32_t getLedMetaState() REQUIRES(mReader->mLock) REQUIRES(mLock) override;
void setPreventingTouchpadTaps(bool prevent) REQUIRES(mReader->mLock)
REQUIRES(mLock) override;
bool isPreventingTouchpadTaps() REQUIRES(mReader->mLock) REQUIRES(mLock) override;
void setLastKeyDownTimestamp(nsecs_t when) REQUIRES(mReader->mLock)
REQUIRES(mLock) override;
nsecs_t getLastKeyDownTimestamp() REQUIRES(mReader->mLock) REQUIRES(mLock) override;
} mContext;
friend class ContextImpl;
// Test cases need to override the locked functions
mutable std::mutex mLock;
private:
std::unique_ptr<InputThread> mThread;
std::condition_variable mReaderIsAliveCondition;
// This could be unique_ptr, but due to the way InputReader tests are written,
// it is made shared_ptr here. In the tests, an EventHub reference is retained by the test
// in parallel to passing it to the InputReader.
std::shared_ptr<EventHubInterface> mEventHub;
sp<InputReaderPolicyInterface> mPolicy;
// The next stage that should receive the events generated inside InputReader.
InputListenerInterface& mNextListener;
// As various events are generated inside InputReader, they are stored inside this list. The
// list can only be accessed with the lock, so the events inside it are well-ordered.
// Once the reader is done working, these events will be swapped into a temporary storage and
// sent to the 'mNextListener' without holding the lock.
std::list<NotifyArgs> mPendingArgs GUARDED_BY(mLock);
InputReaderConfiguration mConfig GUARDED_BY(mLock);
// An input device can represent a collection of EventHub devices. This map provides a way
// to lookup the input device instance from the EventHub device id.
std::unordered_map<int32_t /*eventHubId*/, std::shared_ptr<InputDevice>> mDevices
GUARDED_BY(mLock);
// An input device contains one or more eventHubId, this map provides a way to lookup the
// EventHubIds contained in the input device from the input device instance.
std::unordered_map<std::shared_ptr<InputDevice>, std::vector<int32_t> /*eventHubId*/>
mDeviceToEventHubIdsMap GUARDED_BY(mLock);
// true if tap-to-click on touchpad currently disabled
bool mPreventingTouchpadTaps GUARDED_BY(mLock){false};
// records timestamp of the last key press on the physical keyboard
nsecs_t mLastKeyDownTimestamp GUARDED_BY(mLock){0};
// low-level input event decoding and device management
[[nodiscard]] std::list<NotifyArgs> processEventsLocked(const RawEvent* rawEvents, size_t count)
REQUIRES(mLock);
void addDeviceLocked(nsecs_t when, int32_t eventHubId) REQUIRES(mLock);
void removeDeviceLocked(nsecs_t when, int32_t eventHubId) REQUIRES(mLock);
[[nodiscard]] std::list<NotifyArgs> processEventsForDeviceLocked(int32_t eventHubId,
const RawEvent* rawEvents,
size_t count) REQUIRES(mLock);
[[nodiscard]] std::list<NotifyArgs> timeoutExpiredLocked(nsecs_t when) REQUIRES(mLock);
void handleConfigurationChangedLocked(nsecs_t when) REQUIRES(mLock);
int32_t mGlobalMetaState GUARDED_BY(mLock);
void updateGlobalMetaStateLocked() REQUIRES(mLock);
int32_t getGlobalMetaStateLocked() REQUIRES(mLock);
int32_t mLedMetaState GUARDED_BY(mLock);
void updateLedMetaStateLocked(int32_t metaState) REQUIRES(mLock);
int32_t getLedMetaStateLocked() REQUIRES(mLock);
void notifyExternalStylusPresenceChangedLocked() REQUIRES(mLock);
void getExternalStylusDevicesLocked(std::vector<InputDeviceInfo>& outDevices) REQUIRES(mLock);
[[nodiscard]] std::list<NotifyArgs> dispatchExternalStylusStateLocked(const StylusState& state)
REQUIRES(mLock);
// The PointerController that is shared among all the input devices that need it.
std::weak_ptr<PointerControllerInterface> mPointerController;
std::shared_ptr<PointerControllerInterface> getPointerControllerLocked(int32_t deviceId)
REQUIRES(mLock);
void updatePointerDisplayLocked() REQUIRES(mLock);
void fadePointerLocked() REQUIRES(mLock);
int32_t mGeneration GUARDED_BY(mLock);
int32_t bumpGenerationLocked() REQUIRES(mLock);
int32_t mNextInputDeviceId GUARDED_BY(mLock);
int32_t nextInputDeviceIdLocked() REQUIRES(mLock);
std::vector<InputDeviceInfo> getInputDevicesLocked() const REQUIRES(mLock);
nsecs_t mDisableVirtualKeysTimeout GUARDED_BY(mLock);
void disableVirtualKeysUntilLocked(nsecs_t time) REQUIRES(mLock);
bool shouldDropVirtualKeyLocked(nsecs_t now, int32_t keyCode, int32_t scanCode) REQUIRES(mLock);
nsecs_t mNextTimeout GUARDED_BY(mLock);
void requestTimeoutAtTimeLocked(nsecs_t when) REQUIRES(mLock);
ConfigurationChanges mConfigurationChangesToRefresh GUARDED_BY(mLock);
void refreshConfigurationLocked(ConfigurationChanges changes) REQUIRES(mLock);
PointerCaptureRequest mCurrentPointerCaptureRequest GUARDED_BY(mLock);
// state queries
typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code);
int32_t getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
GetStateFunc getStateFunc) REQUIRES(mLock);
bool markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask,
const std::vector<int32_t>& keyCodes, uint8_t* outFlags)
REQUIRES(mLock);
// find an InputDevice from an InputDevice id
InputDevice* findInputDeviceLocked(int32_t deviceId) const REQUIRES(mLock);
};
} // namespace android
|