summaryrefslogtreecommitdiff
path: root/services/inputflinger/reader/InputDevice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/inputflinger/reader/InputDevice.cpp')
-rw-r--r--services/inputflinger/reader/InputDevice.cpp193
1 files changed, 155 insertions, 38 deletions
diff --git a/services/inputflinger/reader/InputDevice.cpp b/services/inputflinger/reader/InputDevice.cpp
index 4b19e5e353..7af014cb34 100644
--- a/services/inputflinger/reader/InputDevice.cpp
+++ b/services/inputflinger/reader/InputDevice.cpp
@@ -18,6 +18,7 @@
#include "InputDevice.h"
+#include <input/Flags.h>
#include <algorithm>
#include "CursorInputMapper.h"
@@ -26,7 +27,9 @@
#include "JoystickInputMapper.h"
#include "KeyboardInputMapper.h"
#include "MultiTouchInputMapper.h"
+#include "PeripheralController.h"
#include "RotaryEncoderInputMapper.h"
+#include "SensorInputMapper.h"
#include "SingleTouchInputMapper.h"
#include "SwitchInputMapper.h"
#include "VibratorInputMapper.h"
@@ -52,10 +55,11 @@ bool InputDevice::isEnabled() {
if (!hasEventHubDevices()) {
return false;
}
- // devices are either all enabled or all disabled, so we only need to check the first
- auto& devicePair = mDevices.begin()->second;
- auto& contextPtr = devicePair.first;
- return contextPtr->isDeviceEnabled();
+ // An input device composed of sub devices can be individually enabled or disabled.
+ // If any of the sub device is enabled then the input device is considered as enabled.
+ bool enabled = false;
+ for_each_subdevice([&enabled](auto& context) { enabled |= context.isDeviceEnabled(); });
+ return enabled;
}
void InputDevice::setEnabled(bool enabled, nsecs_t when) {
@@ -84,12 +88,12 @@ void InputDevice::setEnabled(bool enabled, nsecs_t when) {
bumpGeneration();
}
-void InputDevice::dump(std::string& dump) {
- InputDeviceInfo deviceInfo;
- getDeviceInfo(&deviceInfo);
+void InputDevice::dump(std::string& dump, const std::string& eventHubDevStr) {
+ InputDeviceInfo deviceInfo = getDeviceInfo();
dump += StringPrintf(INDENT "Device %d: %s\n", deviceInfo.getId(),
deviceInfo.getDisplayName().c_str());
+ dump += StringPrintf(INDENT "%s", eventHubDevStr.c_str());
dump += StringPrintf(INDENT2 "Generation: %d\n", mGeneration);
dump += StringPrintf(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
dump += StringPrintf(INDENT2 "AssociatedDisplayPort: ");
@@ -98,16 +102,23 @@ void InputDevice::dump(std::string& dump) {
} else {
dump += "<none>\n";
}
+ dump += StringPrintf(INDENT2 "AssociatedDisplayUniqueId: ");
+ if (mAssociatedDisplayUniqueId) {
+ dump += StringPrintf("%s\n", mAssociatedDisplayUniqueId->c_str());
+ } else {
+ dump += "<none>\n";
+ }
dump += StringPrintf(INDENT2 "HasMic: %s\n", toString(mHasMic));
dump += StringPrintf(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
dump += StringPrintf(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
+ dump += StringPrintf(INDENT2 "ControllerNum: %d\n", deviceInfo.getControllerNumber());
const std::vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
if (!ranges.empty()) {
dump += INDENT2 "Motion Ranges:\n";
for (size_t i = 0; i < ranges.size(); i++) {
const InputDeviceInfo::MotionRange& range = ranges[i];
- const char* label = getAxisLabel(range.axis);
+ const char* label = InputEventLookup::getAxisLabel(range.axis);
char name[32];
if (label) {
strncpy(name, label, sizeof(name));
@@ -124,6 +135,9 @@ void InputDevice::dump(std::string& dump) {
}
for_each_mapper([&dump](InputMapper& mapper) { mapper.dump(dump); });
+ if (mController) {
+ mController->dump(dump);
+ }
}
void InputDevice::addEventHubDevice(int32_t eventHubId, bool populateMappers) {
@@ -131,7 +145,7 @@ void InputDevice::addEventHubDevice(int32_t eventHubId, bool populateMappers) {
return;
}
std::unique_ptr<InputDeviceContext> contextPtr(new InputDeviceContext(*this, eventHubId));
- uint32_t classes = contextPtr->getDeviceClasses();
+ Flags<InputDeviceClass> classes = contextPtr->getDeviceClasses();
std::vector<std::unique_ptr<InputMapper>> mappers;
// Check if we should skip population
@@ -141,33 +155,39 @@ void InputDevice::addEventHubDevice(int32_t eventHubId, bool populateMappers) {
}
// Switch-like devices.
- if (classes & INPUT_DEVICE_CLASS_SWITCH) {
+ if (classes.test(InputDeviceClass::SWITCH)) {
mappers.push_back(std::make_unique<SwitchInputMapper>(*contextPtr));
}
// Scroll wheel-like devices.
- if (classes & INPUT_DEVICE_CLASS_ROTARY_ENCODER) {
+ if (classes.test(InputDeviceClass::ROTARY_ENCODER)) {
mappers.push_back(std::make_unique<RotaryEncoderInputMapper>(*contextPtr));
}
// Vibrator-like devices.
- if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
+ if (classes.test(InputDeviceClass::VIBRATOR)) {
mappers.push_back(std::make_unique<VibratorInputMapper>(*contextPtr));
}
+ // Battery-like devices or light-containing devices.
+ // PeripheralController will be created with associated EventHub device.
+ if (classes.test(InputDeviceClass::BATTERY) || classes.test(InputDeviceClass::LIGHT)) {
+ mController = std::make_unique<PeripheralController>(*contextPtr);
+ }
+
// Keyboard-like devices.
uint32_t keyboardSource = 0;
int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
- if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
+ if (classes.test(InputDeviceClass::KEYBOARD)) {
keyboardSource |= AINPUT_SOURCE_KEYBOARD;
}
- if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
+ if (classes.test(InputDeviceClass::ALPHAKEY)) {
keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
}
- if (classes & INPUT_DEVICE_CLASS_DPAD) {
+ if (classes.test(InputDeviceClass::DPAD)) {
keyboardSource |= AINPUT_SOURCE_DPAD;
}
- if (classes & INPUT_DEVICE_CLASS_GAMEPAD) {
+ if (classes.test(InputDeviceClass::GAMEPAD)) {
keyboardSource |= AINPUT_SOURCE_GAMEPAD;
}
@@ -177,29 +197,36 @@ void InputDevice::addEventHubDevice(int32_t eventHubId, bool populateMappers) {
}
// Cursor-like devices.
- if (classes & INPUT_DEVICE_CLASS_CURSOR) {
+ if (classes.test(InputDeviceClass::CURSOR)) {
mappers.push_back(std::make_unique<CursorInputMapper>(*contextPtr));
}
// Touchscreens and touchpad devices.
- if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
+ if (classes.test(InputDeviceClass::TOUCH_MT)) {
mappers.push_back(std::make_unique<MultiTouchInputMapper>(*contextPtr));
- } else if (classes & INPUT_DEVICE_CLASS_TOUCH) {
+ } else if (classes.test(InputDeviceClass::TOUCH)) {
mappers.push_back(std::make_unique<SingleTouchInputMapper>(*contextPtr));
}
// Joystick-like devices.
- if (classes & INPUT_DEVICE_CLASS_JOYSTICK) {
+ if (classes.test(InputDeviceClass::JOYSTICK)) {
mappers.push_back(std::make_unique<JoystickInputMapper>(*contextPtr));
}
+ // Motion sensor enabled devices.
+ if (classes.test(InputDeviceClass::SENSOR)) {
+ mappers.push_back(std::make_unique<SensorInputMapper>(*contextPtr));
+ }
+
// External stylus-like devices.
- if (classes & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
+ if (classes.test(InputDeviceClass::EXTERNAL_STYLUS)) {
mappers.push_back(std::make_unique<ExternalStylusInputMapper>(*contextPtr));
}
// insert the context into the devices set
mDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});
+ // Must change generation to flag this device as changed
+ bumpGeneration();
}
void InputDevice::removeEventHubDevice(int32_t eventHubId) {
@@ -209,7 +236,7 @@ void InputDevice::removeEventHubDevice(int32_t eventHubId) {
void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config,
uint32_t changes) {
mSources = 0;
- mClasses = 0;
+ mClasses = Flags<InputDeviceClass>(0);
mControllerNumber = 0;
for_each_subdevice([this](InputDeviceContext& context) {
@@ -224,8 +251,8 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config
}
});
- mIsExternal = !!(mClasses & INPUT_DEVICE_CLASS_EXTERNAL);
- mHasMic = !!(mClasses & INPUT_DEVICE_CLASS_MIC);
+ mIsExternal = mClasses.test(InputDeviceClass::EXTERNAL);
+ mHasMic = mClasses.test(InputDeviceClass::MIC);
if (!isIgnored()) {
if (!changes) { // first time only
@@ -238,8 +265,8 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config
}
if (!changes || (changes & InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS)) {
- if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
- sp<KeyCharacterMap> keyboardLayout =
+ if (!mClasses.test(InputDeviceClass::VIRTUAL)) {
+ std::shared_ptr<KeyCharacterMap> keyboardLayout =
mContext->getPolicy()->getKeyboardLayoutOverlay(mIdentifier);
bool shouldBumpGeneration = false;
for_each_subdevice(
@@ -255,7 +282,7 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config
}
if (!changes || (changes & InputReaderConfiguration::CHANGE_DEVICE_ALIAS)) {
- if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
+ if (!(mClasses.test(InputDeviceClass::VIRTUAL))) {
std::string alias = mContext->getPolicy()->getDeviceAlias(mIdentifier);
if (mAlias != alias) {
mAlias = alias;
@@ -271,8 +298,9 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config
}
if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
- // In most situations, no port will be specified.
+ // In most situations, no port or name will be specified.
mAssociatedDisplayPort = std::nullopt;
+ mAssociatedDisplayUniqueId = std::nullopt;
mAssociatedViewport = std::nullopt;
// Find the display port that corresponds to the current input port.
const std::string& inputPort = mIdentifier.location;
@@ -283,6 +311,13 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config
mAssociatedDisplayPort = std::make_optional(displayPort->second);
}
}
+ const std::string& inputDeviceName = mIdentifier.name;
+ const std::unordered_map<std::string, std::string>& names =
+ config->uniqueIdAssociations;
+ const auto& displayUniqueId = names.find(inputDeviceName);
+ if (displayUniqueId != names.end()) {
+ mAssociatedDisplayUniqueId = displayUniqueId->second;
+ }
// If the device was explicitly disabled by the user, it would be present in the
// "disabledDevices" list. If it is associated with a specific display, and it was not
@@ -297,6 +332,15 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config
getName().c_str(), *mAssociatedDisplayPort);
enabled = false;
}
+ } else if (mAssociatedDisplayUniqueId != std::nullopt) {
+ mAssociatedViewport =
+ config->getDisplayViewportByUniqueId(*mAssociatedDisplayUniqueId);
+ if (!mAssociatedViewport) {
+ ALOGW("Input device %s should be associated with display %s but the "
+ "corresponding viewport cannot be found",
+ inputDeviceName.c_str(), mAssociatedDisplayUniqueId->c_str());
+ enabled = false;
+ }
}
if (changes) {
@@ -372,11 +416,17 @@ void InputDevice::updateExternalStylusState(const StylusState& state) {
for_each_mapper([state](InputMapper& mapper) { mapper.updateExternalStylusState(state); });
}
-void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
- outDeviceInfo->initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias, mIsExternal,
- mHasMic);
+InputDeviceInfo InputDevice::getDeviceInfo() {
+ InputDeviceInfo outDeviceInfo;
+ outDeviceInfo.initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias, mIsExternal,
+ mHasMic);
for_each_mapper(
- [outDeviceInfo](InputMapper& mapper) { mapper.populateDeviceInfo(outDeviceInfo); });
+ [&outDeviceInfo](InputMapper& mapper) { mapper.populateDeviceInfo(&outDeviceInfo); });
+
+ if (mController) {
+ mController->populateDeviceInfo(&outDeviceInfo);
+ }
+ return outDeviceInfo;
}
int32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
@@ -424,10 +474,9 @@ bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
return result;
}
-void InputDevice::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
- int32_t token) {
- for_each_mapper([pattern, patternSize, repeat, token](InputMapper& mapper) {
- mapper.vibrate(pattern, patternSize, repeat, token);
+void InputDevice::vibrate(const VibrationSequence& sequence, ssize_t repeat, int32_t token) {
+ for_each_mapper([sequence, repeat, token](InputMapper& mapper) {
+ mapper.vibrate(sequence, repeat, token);
});
}
@@ -435,8 +484,72 @@ void InputDevice::cancelVibrate(int32_t token) {
for_each_mapper([token](InputMapper& mapper) { mapper.cancelVibrate(token); });
}
-void InputDevice::cancelTouch(nsecs_t when) {
- for_each_mapper([when](InputMapper& mapper) { mapper.cancelTouch(when); });
+bool InputDevice::isVibrating() {
+ bool vibrating = false;
+ for_each_mapper([&vibrating](InputMapper& mapper) { vibrating |= mapper.isVibrating(); });
+ return vibrating;
+}
+
+/* There's no guarantee the IDs provided by the different mappers are unique, so if we have two
+ * different vibration mappers then we could have duplicate IDs.
+ * Alternatively, if we have a merged device that has multiple evdev nodes with FF_* capabilities,
+ * we would definitely have duplicate IDs.
+ */
+std::vector<int32_t> InputDevice::getVibratorIds() {
+ std::vector<int32_t> vibrators;
+ for_each_mapper([&vibrators](InputMapper& mapper) {
+ std::vector<int32_t> devVibs = mapper.getVibratorIds();
+ vibrators.reserve(vibrators.size() + devVibs.size());
+ vibrators.insert(vibrators.end(), devVibs.begin(), devVibs.end());
+ });
+ return vibrators;
+}
+
+bool InputDevice::enableSensor(InputDeviceSensorType sensorType,
+ std::chrono::microseconds samplingPeriod,
+ std::chrono::microseconds maxBatchReportLatency) {
+ bool success = true;
+ for_each_mapper(
+ [&success, sensorType, samplingPeriod, maxBatchReportLatency](InputMapper& mapper) {
+ success &= mapper.enableSensor(sensorType, samplingPeriod, maxBatchReportLatency);
+ });
+ return success;
+}
+
+void InputDevice::disableSensor(InputDeviceSensorType sensorType) {
+ for_each_mapper([sensorType](InputMapper& mapper) { mapper.disableSensor(sensorType); });
+}
+
+void InputDevice::flushSensor(InputDeviceSensorType sensorType) {
+ for_each_mapper([sensorType](InputMapper& mapper) { mapper.flushSensor(sensorType); });
+}
+
+void InputDevice::cancelTouch(nsecs_t when, nsecs_t readTime) {
+ for_each_mapper([when, readTime](InputMapper& mapper) { mapper.cancelTouch(when, readTime); });
+}
+
+std::optional<int32_t> InputDevice::getBatteryCapacity() {
+ return mController ? mController->getBatteryCapacity(DEFAULT_BATTERY_ID) : std::nullopt;
+}
+
+std::optional<int32_t> InputDevice::getBatteryStatus() {
+ return mController ? mController->getBatteryStatus(DEFAULT_BATTERY_ID) : std::nullopt;
+}
+
+bool InputDevice::setLightColor(int32_t lightId, int32_t color) {
+ return mController ? mController->setLightColor(lightId, color) : false;
+}
+
+bool InputDevice::setLightPlayerId(int32_t lightId, int32_t playerId) {
+ return mController ? mController->setLightPlayerId(lightId, playerId) : false;
+}
+
+std::optional<int32_t> InputDevice::getLightColor(int32_t lightId) {
+ return mController ? mController->getLightColor(lightId) : std::nullopt;
+}
+
+std::optional<int32_t> InputDevice::getLightPlayerId(int32_t lightId) {
+ return mController ? mController->getLightPlayerId(lightId) : std::nullopt;
}
int32_t InputDevice::getMetaState() {
@@ -480,6 +593,10 @@ size_t InputDevice::getMapperCount() {
return count;
}
+void InputDevice::updateLedState(bool reset) {
+ for_each_mapper([reset](InputMapper& mapper) { mapper.updateLedState(reset); });
+}
+
InputDeviceContext::InputDeviceContext(InputDevice& device, int32_t eventHubId)
: mDevice(device),
mContext(device.getContext()),