OH5.0 updater适配触摸功能
·
在不适配HDF(Hardware Driver Foundation)的情况下,OH(OpenHarmony)中Updater 触摸功能当前无法正常使用。为此,我们提出一种实现触摸功能的支持方案。
主要思路如下:
通过使用 epoll
监听 Linux Input 子系统上报的事件信息,对事件进行解析和处理后,将相关触摸数据送入 PointersInputDevice
类的回调函数中,从而实现对 Updater 的触摸支持功能。
1. base/update/updater/services/ui/driver/input_event.cpp
创建新线程通过epoll_wait 监控设备
constexpr auto INPUT_DEVICES_PATH { "/dev/input/" };
constexpr const int MAX_EPOLL_DEVICES = 100;
constexpr const int EPOLL_TIMEOUT = -1;
InputEvent::~InputEvent() {
if (thread_.joinable()) {
thread_.join();
}
for (int fd : inputFds_) {
close(fd);
}
if (epollFd_ != -1) {
close(epollFd_);
}
}
void InputEvent::OnThread(){
while(true){
epoll_event events[100]={};
int count = epoll_wait(epollFd_, &events[0], MAX_EPOLL_DEVICES, EPOLL_TIMEOUT);
if (count == -1) {
LOG(INFO) << "count err";
continue;
}
for (int32_t i = 0; i < count ; i++){
struct input_event ev;
// 从输入设备文件描述符中读取 input_event 数据
ssize_t bytesRead = read(events[i].data.fd, &ev, sizeof(ev));
if (bytesRead == sizeof(ev)) {
LOG(INFO) << "Event type: " << ev.type << ", code: " << ev.code << ", value: " << ev.value;
uint32_t type = 0;
InputEvent::GetInstance().HandleInputEvent(&ev, type);
}
}
}
}
int InputEvent::LIDInit()
{
LOG(INFO) << "LIDInit start";
epollFd_ = epoll_create1(0);
DIR *dir = opendir(INPUT_DEVICES_PATH);
if (dir == nullptr) {
LOG(INFO) << "opendir err";
return 0;
}
struct dirent *entry;
while ((entry = readdir(dir)) != nullptr) {
if (entry->d_name[0] == '.') continue;
std::string devicePath = INPUT_DEVICES_PATH + std::string(entry->d_name);
int inputFd = open(devicePath.c_str(), O_RDONLY);
if (inputFd == -1) {
continue;
}
// 添加到 epoll 监听
epoll_event ev;
ev.events = EPOLLIN;
ev.data.fd = inputFd;
if (epoll_ctl(epollFd_, EPOLL_CTL_ADD, inputFd, &ev) == -1) {
close(inputFd);
LOG(INFO) << "epoll_ctl err";
continue;
}
inputFds_.push_back(inputFd);
}
thread_ = std::thread([this] { this->OnThread(); });
OHOS::InputDeviceManager::GetInstance()->Add(&KeysInputDevice::GetInstance());
addInputDeviceHelper_();
LOG(INFO) << "add InputDevice done";
return 0;
}
base/update/updater/services/ui/driver/input_event.h
class InputEvent {
DISALLOW_COPY_MOVE(InputEvent);
public:
void RegisterAddInputDeviceHelper(AddInputDeviceFunc ptr);
void RegisterHandleEventHelper(HandlePointersEventFunc ptr);
InputEvent() = default;
~InputEvent(); //+
static InputEvent &GetInstance();
int HandleInputEvent(const struct input_event *iev, uint32_t type);
void GetInputDeviceType(uint32_t devIndex, uint32_t &type);
static void ReportEventPkgCallback(const InputEventPackage **pkgs, const uint32_t count, uint32_t devIndex);
/**
* @brief Init input device driver.
*/
int HdfInit(); //+
int LIDInit(); //+
void OnThread(); //+
private:
IInputInterface *inputInterface_;
InputEventCb callback_;
std::unordered_map<uint32_t, uint32_t> devTypeMap_{};
AddInputDeviceFunc addInputDeviceHelper_;
HandlePointersEventFunc handlePointersEventHelper_;
int32_t epollFd_ ; //+
std::vector<int> inputFds_; //+
std::thread thread_; //+
};
2.base/update/updater/services/ui/updater_ui_env.cpp
初始化对应功能
void UpdaterUiEnv::InitInputDriver()
{
InputEvent::GetInstance().HdfInit();
InputEvent::GetInstance().LIDInit(); //+
}
3.注意事项
可能会出现上报的POSITION不是触摸屏幕的实际坐标,需自行进行转换,如下图
正常上报触摸信息是触摸实际坐标就不用调整;
4.PointersInputDevice的回调
上报的触摸数据最后都会进入到HandleEvAbsMt里面装载
#如果有误还请大佬指出#
更多推荐
所有评论(0)