1c29fa5a6Sopenharmony_ci/* 2c29fa5a6Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3c29fa5a6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4c29fa5a6Sopenharmony_ci * you may not use this file except in compliance with the License. 5c29fa5a6Sopenharmony_ci * You may obtain a copy of the License at 6c29fa5a6Sopenharmony_ci * 7c29fa5a6Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8c29fa5a6Sopenharmony_ci * 9c29fa5a6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10c29fa5a6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11c29fa5a6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12c29fa5a6Sopenharmony_ci * See the License for the specific language governing permissions and 13c29fa5a6Sopenharmony_ci * limitations under the License. 14c29fa5a6Sopenharmony_ci */ 15c29fa5a6Sopenharmony_ci 16c29fa5a6Sopenharmony_ci#include "general_device.h" 17c29fa5a6Sopenharmony_ci 18c29fa5a6Sopenharmony_ci#include <iostream> 19c29fa5a6Sopenharmony_ci#include <sstream> 20c29fa5a6Sopenharmony_ci#include <thread> 21c29fa5a6Sopenharmony_ci 22c29fa5a6Sopenharmony_cinamespace OHOS { 23c29fa5a6Sopenharmony_cinamespace MMI { 24c29fa5a6Sopenharmony_cinamespace { 25c29fa5a6Sopenharmony_ciconstexpr size_t DEFAULT_BUF_SIZE { 1024 }; 26c29fa5a6Sopenharmony_ciconstexpr int32_t SLEEP_TIME { 500 }; 27c29fa5a6Sopenharmony_ci} 28c29fa5a6Sopenharmony_ci 29c29fa5a6Sopenharmony_civoid GeneralDevice::Close() 30c29fa5a6Sopenharmony_ci{ 31c29fa5a6Sopenharmony_ci vDev_.reset(); 32c29fa5a6Sopenharmony_ci} 33c29fa5a6Sopenharmony_ci 34c29fa5a6Sopenharmony_civoid GeneralDevice::SendEvent(uint16_t type, uint16_t code, int32_t value) 35c29fa5a6Sopenharmony_ci{ 36c29fa5a6Sopenharmony_ci if (vDev_ == nullptr) { 37c29fa5a6Sopenharmony_ci std::cout << "No input device" << std::endl; 38c29fa5a6Sopenharmony_ci return; 39c29fa5a6Sopenharmony_ci } 40c29fa5a6Sopenharmony_ci vDev_->SendEvent(type, code, value); 41c29fa5a6Sopenharmony_ci} 42c29fa5a6Sopenharmony_ci 43c29fa5a6Sopenharmony_cistd::string GeneralDevice::GetDevPath() const 44c29fa5a6Sopenharmony_ci{ 45c29fa5a6Sopenharmony_ci return (vDev_ != nullptr ? vDev_->GetDevPath() : std::string()); 46c29fa5a6Sopenharmony_ci} 47c29fa5a6Sopenharmony_ci 48c29fa5a6Sopenharmony_cibool GeneralDevice::OpenDevice(const std::string &name) 49c29fa5a6Sopenharmony_ci{ 50c29fa5a6Sopenharmony_ci int32_t nTries = 6; 51c29fa5a6Sopenharmony_ci 52c29fa5a6Sopenharmony_ci while (nTries-- > 0) { 53c29fa5a6Sopenharmony_ci std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME)); 54c29fa5a6Sopenharmony_ci std::string node; 55c29fa5a6Sopenharmony_ci if (GeneralDevice::FindDeviceNode(name, node)) { 56c29fa5a6Sopenharmony_ci std::cout << "Found node path: " << node << std::endl; 57c29fa5a6Sopenharmony_ci auto vInpuDev = std::make_unique<VInputDevice>(node); 58c29fa5a6Sopenharmony_ci vInpuDev->Open(); 59c29fa5a6Sopenharmony_ci if (vInpuDev->IsActive()) { 60c29fa5a6Sopenharmony_ci vDev_ = std::move(vInpuDev); 61c29fa5a6Sopenharmony_ci return true; 62c29fa5a6Sopenharmony_ci } 63c29fa5a6Sopenharmony_ci } 64c29fa5a6Sopenharmony_ci } 65c29fa5a6Sopenharmony_ci return false; 66c29fa5a6Sopenharmony_ci} 67c29fa5a6Sopenharmony_ci 68c29fa5a6Sopenharmony_cibool GeneralDevice::FindDeviceNode(const std::string &name, std::string &node) 69c29fa5a6Sopenharmony_ci{ 70c29fa5a6Sopenharmony_ci std::map<std::string, std::string> nodes; 71c29fa5a6Sopenharmony_ci GetInputDeviceNodes(nodes); 72c29fa5a6Sopenharmony_ci std::cout << "There are " << nodes.size() << " device nodes" << std::endl; 73c29fa5a6Sopenharmony_ci 74c29fa5a6Sopenharmony_ci std::map<std::string, std::string>::const_iterator cItr = nodes.find(name); 75c29fa5a6Sopenharmony_ci if (cItr == nodes.cend()) { 76c29fa5a6Sopenharmony_ci std::cout << "No virtual stylus were found" << std::endl; 77c29fa5a6Sopenharmony_ci return false; 78c29fa5a6Sopenharmony_ci } 79c29fa5a6Sopenharmony_ci std::cout << "Node name : \'" << cItr->second << "\'" << std::endl; 80c29fa5a6Sopenharmony_ci std::ostringstream ss; 81c29fa5a6Sopenharmony_ci ss << "/dev/input/" << cItr->second; 82c29fa5a6Sopenharmony_ci node = ss.str(); 83c29fa5a6Sopenharmony_ci return true; 84c29fa5a6Sopenharmony_ci} 85c29fa5a6Sopenharmony_ci 86c29fa5a6Sopenharmony_civoid GeneralDevice::Execute(std::vector<std::string> &results) 87c29fa5a6Sopenharmony_ci{ 88c29fa5a6Sopenharmony_ci char buffer[DEFAULT_BUF_SIZE] {}; 89c29fa5a6Sopenharmony_ci FILE *pin = popen("cat /proc/bus/input/devices", "r"); 90c29fa5a6Sopenharmony_ci if (pin == nullptr) { 91c29fa5a6Sopenharmony_ci std::cout << "Failed to popen command" << std::endl; 92c29fa5a6Sopenharmony_ci return; 93c29fa5a6Sopenharmony_ci } 94c29fa5a6Sopenharmony_ci while (!feof(pin)) { 95c29fa5a6Sopenharmony_ci if (fgets(buffer, sizeof(buffer), pin) != nullptr) { 96c29fa5a6Sopenharmony_ci results.push_back(buffer); 97c29fa5a6Sopenharmony_ci } 98c29fa5a6Sopenharmony_ci } 99c29fa5a6Sopenharmony_ci pclose(pin); 100c29fa5a6Sopenharmony_ci} 101c29fa5a6Sopenharmony_ci 102c29fa5a6Sopenharmony_civoid GeneralDevice::GetInputDeviceNodes(std::map<std::string, std::string> &nodes) 103c29fa5a6Sopenharmony_ci{ 104c29fa5a6Sopenharmony_ci std::vector<std::string> results; 105c29fa5a6Sopenharmony_ci Execute(results); 106c29fa5a6Sopenharmony_ci if (results.empty()) { 107c29fa5a6Sopenharmony_ci std::cout << "Failed to list devices" << std::endl; 108c29fa5a6Sopenharmony_ci return; 109c29fa5a6Sopenharmony_ci } 110c29fa5a6Sopenharmony_ci const std::string kname { "Name=\"" }; 111c29fa5a6Sopenharmony_ci const std::string kevent { "event" }; 112c29fa5a6Sopenharmony_ci std::string name; 113c29fa5a6Sopenharmony_ci for (const auto &res : results) { 114c29fa5a6Sopenharmony_ci if (res[0] == 'N') { 115c29fa5a6Sopenharmony_ci std::string::size_type spos = res.find(kname); 116c29fa5a6Sopenharmony_ci if (spos != std::string::npos) { 117c29fa5a6Sopenharmony_ci spos += kname.size(); 118c29fa5a6Sopenharmony_ci std::string::size_type tpos = res.find("\"", spos); 119c29fa5a6Sopenharmony_ci if (tpos != std::string::npos) { 120c29fa5a6Sopenharmony_ci name = res.substr(spos, tpos - spos); 121c29fa5a6Sopenharmony_ci } 122c29fa5a6Sopenharmony_ci } 123c29fa5a6Sopenharmony_ci } else if (!name.empty() && (res[0] == 'H')) { 124c29fa5a6Sopenharmony_ci std::string::size_type spos = res.find(kevent); 125c29fa5a6Sopenharmony_ci if (spos != std::string::npos) { 126c29fa5a6Sopenharmony_ci std::map<std::string, std::string>::const_iterator cItr = nodes.find(name); 127c29fa5a6Sopenharmony_ci if (cItr != nodes.end()) { 128c29fa5a6Sopenharmony_ci nodes.erase(cItr); 129c29fa5a6Sopenharmony_ci } 130c29fa5a6Sopenharmony_ci std::string::size_type tpos = spos + kevent.size(); 131c29fa5a6Sopenharmony_ci while (std::isalnum(res[tpos])) { 132c29fa5a6Sopenharmony_ci ++tpos; 133c29fa5a6Sopenharmony_ci } 134c29fa5a6Sopenharmony_ci auto [_, ret] = nodes.emplace(name, res.substr(spos, tpos - spos)); 135c29fa5a6Sopenharmony_ci if (!ret) { 136c29fa5a6Sopenharmony_ci std::cout << "name is duplicated" << std::endl; 137c29fa5a6Sopenharmony_ci } 138c29fa5a6Sopenharmony_ci name.clear(); 139c29fa5a6Sopenharmony_ci } 140c29fa5a6Sopenharmony_ci } 141c29fa5a6Sopenharmony_ci } 142c29fa5a6Sopenharmony_ci} 143c29fa5a6Sopenharmony_ci} // namespace MMI 144c29fa5a6Sopenharmony_ci} // namespace OHOS