Android 11添加电容笔电量监测需求
软件平台:Android11
硬件平台:QCS6125
需求:PAD接入电容笔,该笔通过驱动上报坐标及当前电量等数据,即走系统的input通道,需要系统层监测到该硬件数据,这里主要展示电量,对用户显示提醒。
基本实现思路:通过在InputManager的本地层注册监听回调,实现监测的目的。
直接上代码改动:
1、input的native层面改动frameworks/native:
diff --git a/services/inputflinger/InputListener.cpp b/services/inputflinger/InputListener.cpp
index 84838ec8a..7b900e758 100644
--- a/services/inputflinger/InputListener.cpp
+++ b/services/inputflinger/InputListener.cpp
@@ -102,7 +102,8 @@ NotifyMotionArgs::NotifyMotionArgs(int32_t id, nsecs_t eventTime, int32_t device
const PointerCoords* pointerCoords, float xPrecision,
float yPrecision, float xCursorPosition, float yCursorPosition,
nsecs_t downTime,
- const std::vector<TouchVideoFrame>& videoFrames)
+ const std::vector<TouchVideoFrame>& videoFrames,
+ uint32_t penBattery)
: NotifyArgs(id, eventTime),
deviceId(deviceId),
source(source),
@@ -121,7 +122,8 @@ NotifyMotionArgs::NotifyMotionArgs(int32_t id, nsecs_t eventTime, int32_t device
xCursorPosition(xCursorPosition),
yCursorPosition(yCursorPosition),
downTime(downTime),
- videoFrames(videoFrames) {
+ videoFrames(videoFrames),
+ penBattery(penBattery) {
for (uint32_t i = 0; i < pointerCount; i++) {
this->pointerProperties[i].copyFrom(pointerProperties[i]);
this->pointerCoords[i].copyFrom(pointerCoords[i]);
@@ -147,7 +149,8 @@ NotifyMotionArgs::NotifyMotionArgs(const NotifyMotionArgs& other)
xCursorPosition(other.xCursorPosition),
yCursorPosition(other.yCursorPosition),
downTime(other.downTime),
- videoFrames(other.videoFrames) {
+ videoFrames(other.videoFrames),
+ penBattery(other.penBattery) {
for (uint32_t i = 0; i < pointerCount; i++) {
pointerProperties[i].copyFrom(other.pointerProperties[i]);
pointerCoords[i].copyFrom(other.pointerCoords[i]);
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index fe016af01..f86178917 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -3155,11 +3155,11 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
"displayId=%" PRId32 ", policyFlags=0x%x, "
"action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
"edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
- "yCursorPosition=%f, downTime=%" PRId64,
+ "yCursorPosition=%f, penBattery=%d, downTime=%" PRId64,
args->id, args->eventTime, args->deviceId, args->source, args->displayId,
args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
- args->xCursorPosition, args->yCursorPosition, args->downTime);
+ args->xCursorPosition, args->yCursorPosition, args->penBattery, args->downTime);
for (uint32_t i = 0; i < args->pointerCount; i++) {
ALOGD(" Pointer %d: id=%d, toolType=%d, "
"x=%f, y=%f, pressure=%f, size=%f, "
@@ -3192,6 +3192,20 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
std::to_string(t.duration().count()).c_str());
}
+ if (args->action == AMOTION_EVENT_ACTION_DOWN) {
+ uint32_t penBattery = args->penBattery;
+ if (PEN_BATTERY_MIN <= penBattery && penBattery <= PEN_BATTERY_MAX) {
+ ALOGD("reportPenBattery # penBattery:%d", penBattery);
+
+ android::base::Timer timer;
+ mPolicy->reportPenBattery(args->displayId, args->eventTime, penBattery);
+ if (timer.duration() > SLOW_INTERCEPTION_THRESHOLD) {
+ ALOGW("Excessive delay in reportPenBattery; took %s ms",
+ std::to_string(timer.duration().count()).c_str());
+ }
+ }
+ }
+
bool needWake;
{ // acquire lock
mLock.lock();
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
index 667af9bbd..cb9b930f1 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
@@ -83,6 +83,9 @@ public:
virtual void interceptMotionBeforeQueueing(const int32_t displayId, nsecs_t when,
uint32_t& policyFlags) = 0;
+ /* 上报主动笔的电量 */
+ virtual void reportPenBattery(const int32_t displayId, nsecs_t when, uint32_t penBattery) {}
+
/* Allows the policy a chance to intercept a key before dispatching. */
virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>& token,
const KeyEvent* keyEvent,
diff --git a/services/inputflinger/include/InputListener.h b/services/inputflinger/include/InputListener.h
index 8317b051e..c54830aa8 100644
--- a/services/inputflinger/include/InputListener.h
+++ b/services/inputflinger/include/InputListener.h
@@ -23,6 +23,14 @@
#include <input/TouchVideoFrame.h>
#include <utils/RefBase.h>
+// 主动笔电量值范围
+#define PEN_BATTERY_UNKNOWN 255
+#define PEN_BATTERY_MIN 0
+#define PEN_BATTERY_MAX 100
+
+// 主动笔电量值的 input-event-code
+#define ABS_PEN_BATT 0x1d
+
namespace android {
class InputListenerInterface;
@@ -121,6 +129,9 @@ struct NotifyMotionArgs : public NotifyArgs {
nsecs_t downTime;
std::vector<TouchVideoFrame> videoFrames;
+ // 主动笔电量值
+ uint32_t penBattery;
+
inline NotifyMotionArgs() { }
NotifyMotionArgs(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source,
@@ -130,7 +141,8 @@ struct NotifyMotionArgs : public NotifyArgs {
const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
float xPrecision, float yPrecision, float xCursorPosition,
float yCursorPosition, nsecs_t downTime,
- const std::vector<TouchVideoFrame>& videoFrames);
+ const std::vector<TouchVideoFrame>& videoFrames,
+ uint32_t penBattery = PEN_BATTERY_UNKNOWN);
NotifyMotionArgs(const NotifyMotionArgs& other);
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index decbea4c3..2445fcf0f 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -1407,6 +1407,13 @@ void TouchInputMapper::process(const RawEvent* rawEvent) {
mCursorScrollAccumulator.process(rawEvent);
mTouchButtonAccumulator.process(rawEvent);
+ if (rawEvent->type == EV_ABS && rawEvent->code == ABS_PEN_BATT) {
+ mPenBattery = rawEvent->value;
+ if (mPenBattery < PEN_BATTERY_MIN || mP