1c29fa5a6Sopenharmony_ci/* 2c29fa5a6Sopenharmony_ci * Copyright (c) 2022-2023 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 "device_manager.h" 17c29fa5a6Sopenharmony_ci 18c29fa5a6Sopenharmony_ci#include <algorithm> 19c29fa5a6Sopenharmony_ci#include <cstring> 20c29fa5a6Sopenharmony_ci#include <regex> 21c29fa5a6Sopenharmony_ci#include <unistd.h> 22c29fa5a6Sopenharmony_ci 23c29fa5a6Sopenharmony_ci#include <sys/epoll.h> 24c29fa5a6Sopenharmony_ci#include <sys/stat.h> 25c29fa5a6Sopenharmony_ci 26c29fa5a6Sopenharmony_ci#ifdef OHOS_BUILD_ENABLE_COORDINATION 27c29fa5a6Sopenharmony_ci#include "coordination_util.h" 28c29fa5a6Sopenharmony_ci#endif // OHOS_BUILD_ENABLE_COORDINATION 29c29fa5a6Sopenharmony_ci#include "device.h" 30c29fa5a6Sopenharmony_ci#include "devicestatus_define.h" 31c29fa5a6Sopenharmony_ci#include "fi_log.h" 32c29fa5a6Sopenharmony_ci#include "napi_constants.h" 33c29fa5a6Sopenharmony_ci 34c29fa5a6Sopenharmony_ci#undef LOG_TAG 35c29fa5a6Sopenharmony_ci#define LOG_TAG "DeviceManager" 36c29fa5a6Sopenharmony_ci 37c29fa5a6Sopenharmony_cinamespace OHOS { 38c29fa5a6Sopenharmony_cinamespace Msdp { 39c29fa5a6Sopenharmony_cinamespace DeviceStatus { 40c29fa5a6Sopenharmony_cinamespace { 41c29fa5a6Sopenharmony_ciconstexpr size_t EXPECTED_N_SUBMATCHES { 2 }; 42c29fa5a6Sopenharmony_ciconstexpr size_t EXPECTED_SUBMATCH { 1 }; 43c29fa5a6Sopenharmony_ciconst std::string FINGER_PRINT { "hw_fingerprint_mouse" }; 44c29fa5a6Sopenharmony_ci} // namespace 45c29fa5a6Sopenharmony_ci 46c29fa5a6Sopenharmony_ciDeviceManager::HotplugHandler::HotplugHandler(DeviceManager &devMgr) 47c29fa5a6Sopenharmony_ci : devMgr_(devMgr) 48c29fa5a6Sopenharmony_ci{} 49c29fa5a6Sopenharmony_ci 50c29fa5a6Sopenharmony_civoid DeviceManager::HotplugHandler::AddDevice(const std::string &devNode) 51c29fa5a6Sopenharmony_ci{ 52c29fa5a6Sopenharmony_ci devMgr_.AddDevice(devNode); 53c29fa5a6Sopenharmony_ci} 54c29fa5a6Sopenharmony_ci 55c29fa5a6Sopenharmony_civoid DeviceManager::HotplugHandler::RemoveDevice(const std::string &devNode) 56c29fa5a6Sopenharmony_ci{ 57c29fa5a6Sopenharmony_ci devMgr_.RemoveDevice(devNode); 58c29fa5a6Sopenharmony_ci} 59c29fa5a6Sopenharmony_ci 60c29fa5a6Sopenharmony_ciDeviceManager::DeviceManager() 61c29fa5a6Sopenharmony_ci : hotplug_(*this) 62c29fa5a6Sopenharmony_ci{} 63c29fa5a6Sopenharmony_ci 64c29fa5a6Sopenharmony_ciint32_t DeviceManager::Init(IContext *context) 65c29fa5a6Sopenharmony_ci{ 66c29fa5a6Sopenharmony_ci CALL_INFO_TRACE; 67c29fa5a6Sopenharmony_ci CHKPR(context, RET_ERR); 68c29fa5a6Sopenharmony_ci int32_t ret = context->GetDelegateTasks().PostSyncTask([this, context] { 69c29fa5a6Sopenharmony_ci return this->OnInit(context); 70c29fa5a6Sopenharmony_ci }); 71c29fa5a6Sopenharmony_ci if (ret != RET_OK) { 72c29fa5a6Sopenharmony_ci FI_HILOGE("Post sync task failed"); 73c29fa5a6Sopenharmony_ci } 74c29fa5a6Sopenharmony_ci return ret; 75c29fa5a6Sopenharmony_ci} 76c29fa5a6Sopenharmony_ci 77c29fa5a6Sopenharmony_ciint32_t DeviceManager::OnInit(IContext *context) 78c29fa5a6Sopenharmony_ci{ 79c29fa5a6Sopenharmony_ci CALL_INFO_TRACE; 80c29fa5a6Sopenharmony_ci CHKPR(context, RET_ERR); 81c29fa5a6Sopenharmony_ci context_ = context; 82c29fa5a6Sopenharmony_ci monitor_.SetDeviceMgr(&hotplug_); 83c29fa5a6Sopenharmony_ci enumerator_.SetDeviceMgr(&hotplug_); 84c29fa5a6Sopenharmony_ci return RET_OK; 85c29fa5a6Sopenharmony_ci} 86c29fa5a6Sopenharmony_ci 87c29fa5a6Sopenharmony_ciint32_t DeviceManager::Enable() 88c29fa5a6Sopenharmony_ci{ 89c29fa5a6Sopenharmony_ci CALL_INFO_TRACE; 90c29fa5a6Sopenharmony_ci CHKPR(context_, RET_ERR); 91c29fa5a6Sopenharmony_ci int32_t ret = context_->GetDelegateTasks().PostSyncTask([this] { 92c29fa5a6Sopenharmony_ci return this->OnEnable(); 93c29fa5a6Sopenharmony_ci }); 94c29fa5a6Sopenharmony_ci if (ret != RET_OK) { 95c29fa5a6Sopenharmony_ci FI_HILOGE("Post sync task failed"); 96c29fa5a6Sopenharmony_ci } 97c29fa5a6Sopenharmony_ci return ret; 98c29fa5a6Sopenharmony_ci} 99c29fa5a6Sopenharmony_ci 100c29fa5a6Sopenharmony_ciint32_t DeviceManager::OnEnable() 101c29fa5a6Sopenharmony_ci{ 102c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 103c29fa5a6Sopenharmony_ci epollMgr_ = std::make_shared<EpollManager>(); 104c29fa5a6Sopenharmony_ci int32_t ret = epollMgr_->Open(); 105c29fa5a6Sopenharmony_ci if (ret != RET_OK) { 106c29fa5a6Sopenharmony_ci return ret; 107c29fa5a6Sopenharmony_ci } 108c29fa5a6Sopenharmony_ci ret = monitor_.Enable(); 109c29fa5a6Sopenharmony_ci if (ret != RET_OK) { 110c29fa5a6Sopenharmony_ci goto CLOSE_EPOLL; 111c29fa5a6Sopenharmony_ci } 112c29fa5a6Sopenharmony_ci ret = epollMgr_->Add(monitor_); 113c29fa5a6Sopenharmony_ci if (ret != RET_OK) { 114c29fa5a6Sopenharmony_ci goto DISABLE_MONITOR; 115c29fa5a6Sopenharmony_ci } 116c29fa5a6Sopenharmony_ci enumerator_.ScanDevices(); 117c29fa5a6Sopenharmony_ci return RET_OK; 118c29fa5a6Sopenharmony_ci 119c29fa5a6Sopenharmony_ciDISABLE_MONITOR: 120c29fa5a6Sopenharmony_ci monitor_.Disable(); 121c29fa5a6Sopenharmony_ci 122c29fa5a6Sopenharmony_ciCLOSE_EPOLL: 123c29fa5a6Sopenharmony_ci epollMgr_.reset(); 124c29fa5a6Sopenharmony_ci return ret; 125c29fa5a6Sopenharmony_ci} 126c29fa5a6Sopenharmony_ci 127c29fa5a6Sopenharmony_ciint32_t DeviceManager::Disable() 128c29fa5a6Sopenharmony_ci{ 129c29fa5a6Sopenharmony_ci CALL_INFO_TRACE; 130c29fa5a6Sopenharmony_ci CHKPR(context_, RET_ERR); 131c29fa5a6Sopenharmony_ci int32_t ret = context_->GetDelegateTasks().PostSyncTask([this] { 132c29fa5a6Sopenharmony_ci return this->OnDisable(); 133c29fa5a6Sopenharmony_ci }); 134c29fa5a6Sopenharmony_ci if (ret != RET_OK) { 135c29fa5a6Sopenharmony_ci FI_HILOGE("PostSyncTask failed"); 136c29fa5a6Sopenharmony_ci } 137c29fa5a6Sopenharmony_ci return ret; 138c29fa5a6Sopenharmony_ci} 139c29fa5a6Sopenharmony_ci 140c29fa5a6Sopenharmony_ciint32_t DeviceManager::OnDisable() 141c29fa5a6Sopenharmony_ci{ 142c29fa5a6Sopenharmony_ci CHKPR(epollMgr_, RET_ERR); 143c29fa5a6Sopenharmony_ci epollMgr_->Remove(monitor_); 144c29fa5a6Sopenharmony_ci monitor_.Disable(); 145c29fa5a6Sopenharmony_ci epollMgr_.reset(); 146c29fa5a6Sopenharmony_ci return RET_OK; 147c29fa5a6Sopenharmony_ci} 148c29fa5a6Sopenharmony_ci 149c29fa5a6Sopenharmony_cistd::shared_ptr<IDevice> DeviceManager::FindDevice(const std::string &devPath) 150c29fa5a6Sopenharmony_ci{ 151c29fa5a6Sopenharmony_ci auto tIter = std::find_if(devices_.cbegin(), devices_.cend(), 152c29fa5a6Sopenharmony_ci [devPath](const auto &item) { 153c29fa5a6Sopenharmony_ci return ((item.second != nullptr) && (item.second->GetDevPath() == devPath)); 154c29fa5a6Sopenharmony_ci }); 155c29fa5a6Sopenharmony_ci return (tIter != devices_.cend() ? tIter->second : nullptr); 156c29fa5a6Sopenharmony_ci} 157c29fa5a6Sopenharmony_ci 158c29fa5a6Sopenharmony_ciint32_t DeviceManager::ParseDeviceId(const std::string &devNode) 159c29fa5a6Sopenharmony_ci{ 160c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 161c29fa5a6Sopenharmony_ci std::regex pattern("^event(\\d+)$"); 162c29fa5a6Sopenharmony_ci std::smatch mr; 163c29fa5a6Sopenharmony_ci 164c29fa5a6Sopenharmony_ci if (std::regex_match(devNode, mr, pattern)) { 165c29fa5a6Sopenharmony_ci if (mr.ready() && mr.size() == EXPECTED_N_SUBMATCHES) { 166c29fa5a6Sopenharmony_ci return std::stoi(mr[EXPECTED_SUBMATCH].str()); 167c29fa5a6Sopenharmony_ci } 168c29fa5a6Sopenharmony_ci } 169c29fa5a6Sopenharmony_ci return RET_ERR; 170c29fa5a6Sopenharmony_ci} 171c29fa5a6Sopenharmony_ci 172c29fa5a6Sopenharmony_cistd::shared_ptr<IDevice> DeviceManager::AddDevice(const std::string &devNode) 173c29fa5a6Sopenharmony_ci{ 174c29fa5a6Sopenharmony_ci CALL_INFO_TRACE; 175c29fa5a6Sopenharmony_ci const std::string SYS_INPUT_PATH { "/sys/class/input/" }; 176c29fa5a6Sopenharmony_ci const std::string devPath { DEV_INPUT_PATH + devNode }; 177c29fa5a6Sopenharmony_ci struct stat statbuf; 178c29fa5a6Sopenharmony_ci 179c29fa5a6Sopenharmony_ci if (stat(devPath.c_str(), &statbuf) != 0) { 180c29fa5a6Sopenharmony_ci FI_HILOGD("Invalid device path:%{private}s", devPath.c_str()); 181c29fa5a6Sopenharmony_ci return nullptr; 182c29fa5a6Sopenharmony_ci } 183c29fa5a6Sopenharmony_ci if (!S_ISCHR(statbuf.st_mode)) { 184c29fa5a6Sopenharmony_ci FI_HILOGD("Not character device:%{public}s", devPath.c_str()); 185c29fa5a6Sopenharmony_ci return nullptr; 186c29fa5a6Sopenharmony_ci } 187c29fa5a6Sopenharmony_ci 188c29fa5a6Sopenharmony_ci int32_t deviceId = ParseDeviceId(devNode); 189c29fa5a6Sopenharmony_ci if (deviceId < 0) { 190c29fa5a6Sopenharmony_ci FI_HILOGE("Parsing device name failed:%{public}s", devNode.c_str()); 191c29fa5a6Sopenharmony_ci return nullptr; 192c29fa5a6Sopenharmony_ci } 193c29fa5a6Sopenharmony_ci 194c29fa5a6Sopenharmony_ci std::shared_ptr<IDevice> dev = FindDevice(devPath); 195c29fa5a6Sopenharmony_ci if (dev != nullptr) { 196c29fa5a6Sopenharmony_ci FI_HILOGD("Already exists:%{public}s", devPath.c_str()); 197c29fa5a6Sopenharmony_ci return dev; 198c29fa5a6Sopenharmony_ci } 199c29fa5a6Sopenharmony_ci 200c29fa5a6Sopenharmony_ci const std::string lSysPath { SYS_INPUT_PATH + devNode }; 201c29fa5a6Sopenharmony_ci char rpath[PATH_MAX]; 202c29fa5a6Sopenharmony_ci if (realpath(lSysPath.c_str(), rpath) == nullptr) { 203c29fa5a6Sopenharmony_ci FI_HILOGD("Invalid sysPath:%{private}s", lSysPath.c_str()); 204c29fa5a6Sopenharmony_ci return nullptr; 205c29fa5a6Sopenharmony_ci } 206c29fa5a6Sopenharmony_ci 207c29fa5a6Sopenharmony_ci dev = std::make_shared<Device>(deviceId); 208c29fa5a6Sopenharmony_ci dev->SetDevPath(devPath); 209c29fa5a6Sopenharmony_ci dev->SetSysPath(std::string(rpath)); 210c29fa5a6Sopenharmony_ci if (dev->Open() != RET_OK) { 211c29fa5a6Sopenharmony_ci FI_HILOGE("Unable to open \'%{public}s\'", devPath.c_str()); 212c29fa5a6Sopenharmony_ci return nullptr; 213c29fa5a6Sopenharmony_ci } 214c29fa5a6Sopenharmony_ci auto ret = devices_.insert_or_assign(dev->GetId(), dev); 215c29fa5a6Sopenharmony_ci if (ret.second) { 216c29fa5a6Sopenharmony_ci FI_HILOGD("\'%{public}s\' added", dev->GetName().c_str()); 217c29fa5a6Sopenharmony_ci OnDeviceAdded(dev); 218c29fa5a6Sopenharmony_ci } 219c29fa5a6Sopenharmony_ci return dev; 220c29fa5a6Sopenharmony_ci} 221c29fa5a6Sopenharmony_ci 222c29fa5a6Sopenharmony_cistd::shared_ptr<IDevice> DeviceManager::RemoveDevice(const std::string &devNode) 223c29fa5a6Sopenharmony_ci{ 224c29fa5a6Sopenharmony_ci CALL_INFO_TRACE; 225c29fa5a6Sopenharmony_ci const std::string devPath { DEV_INPUT_PATH + devNode }; 226c29fa5a6Sopenharmony_ci 227c29fa5a6Sopenharmony_ci for (auto devIter = devices_.begin(); devIter != devices_.end(); ++devIter) { 228c29fa5a6Sopenharmony_ci std::shared_ptr<IDevice> dev = devIter->second; 229c29fa5a6Sopenharmony_ci CHKPC(dev); 230c29fa5a6Sopenharmony_ci if (dev->GetDevPath() == devPath) { 231c29fa5a6Sopenharmony_ci devices_.erase(devIter); 232c29fa5a6Sopenharmony_ci FI_HILOGD("\'%{public}s\' removed", dev->GetName().c_str()); 233c29fa5a6Sopenharmony_ci dev->Close(); 234c29fa5a6Sopenharmony_ci OnDeviceRemoved(dev); 235c29fa5a6Sopenharmony_ci return dev; 236c29fa5a6Sopenharmony_ci } 237c29fa5a6Sopenharmony_ci } 238c29fa5a6Sopenharmony_ci FI_HILOGD("\'%{public}s\' was not found", devNode.c_str()); 239c29fa5a6Sopenharmony_ci return nullptr; 240c29fa5a6Sopenharmony_ci} 241c29fa5a6Sopenharmony_ci 242c29fa5a6Sopenharmony_civoid DeviceManager::OnDeviceAdded(std::shared_ptr<IDevice> dev) 243c29fa5a6Sopenharmony_ci{ 244c29fa5a6Sopenharmony_ci CHKPV(dev); 245c29fa5a6Sopenharmony_ci FI_HILOGI("Add device %{public}d:%{public}s", dev->GetId(), dev->GetDevPath().c_str()); 246c29fa5a6Sopenharmony_ci FI_HILOGI(" sysPath: \"%{private}s\"", dev->GetSysPath().c_str()); 247c29fa5a6Sopenharmony_ci FI_HILOGI(" bus: %{public}04x", dev->GetBus()); 248c29fa5a6Sopenharmony_ci FI_HILOGI(" vendor: %{public}04x", dev->GetVendor()); 249c29fa5a6Sopenharmony_ci FI_HILOGI(" product: %{public}04x", dev->GetProduct()); 250c29fa5a6Sopenharmony_ci FI_HILOGI(" version: %{public}04x", dev->GetVersion()); 251c29fa5a6Sopenharmony_ci FI_HILOGI(" name: \"%{public}s\"", dev->GetName().c_str()); 252c29fa5a6Sopenharmony_ci FI_HILOGI(" location: \"%{public}s\"", dev->GetPhys().c_str()); 253c29fa5a6Sopenharmony_ci FI_HILOGI(" unique id: \"%{public}s\"", dev->GetUniq().c_str()); 254c29fa5a6Sopenharmony_ci FI_HILOGI(" is pointer: %{public}s, is keyboard:%{public}s", 255c29fa5a6Sopenharmony_ci dev->IsPointerDevice() ? "True" : "False", dev->IsKeyboard() ? "True" : "False"); 256c29fa5a6Sopenharmony_ci 257c29fa5a6Sopenharmony_ci for (const auto &observer : observers_) { 258c29fa5a6Sopenharmony_ci std::shared_ptr<IDeviceObserver> ptr = observer.lock(); 259c29fa5a6Sopenharmony_ci CHKPC(ptr); 260c29fa5a6Sopenharmony_ci ptr->OnDeviceAdded(dev); 261c29fa5a6Sopenharmony_ci } 262c29fa5a6Sopenharmony_ci} 263c29fa5a6Sopenharmony_ci 264c29fa5a6Sopenharmony_civoid DeviceManager::OnDeviceRemoved(std::shared_ptr<IDevice> dev) 265c29fa5a6Sopenharmony_ci{ 266c29fa5a6Sopenharmony_ci for (const auto &observer : observers_) { 267c29fa5a6Sopenharmony_ci std::shared_ptr<IDeviceObserver> ptr = observer.lock(); 268c29fa5a6Sopenharmony_ci CHKPC(ptr); 269c29fa5a6Sopenharmony_ci ptr->OnDeviceRemoved(dev); 270c29fa5a6Sopenharmony_ci } 271c29fa5a6Sopenharmony_ci} 272c29fa5a6Sopenharmony_ci 273c29fa5a6Sopenharmony_civoid DeviceManager::Dispatch(const struct epoll_event &ev) 274c29fa5a6Sopenharmony_ci{ 275c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 276c29fa5a6Sopenharmony_ci CHKPV(context_); 277c29fa5a6Sopenharmony_ci int32_t ret = context_->GetDelegateTasks().PostAsyncTask([this, &ev] { 278c29fa5a6Sopenharmony_ci return this->OnEpollDispatch(ev.events); 279c29fa5a6Sopenharmony_ci }); 280c29fa5a6Sopenharmony_ci if (ret != RET_OK) { 281c29fa5a6Sopenharmony_ci FI_HILOGE("PostAsyncTask failed"); 282c29fa5a6Sopenharmony_ci } 283c29fa5a6Sopenharmony_ci} 284c29fa5a6Sopenharmony_ci 285c29fa5a6Sopenharmony_ciint32_t DeviceManager::OnEpollDispatch(uint32_t events) 286c29fa5a6Sopenharmony_ci{ 287c29fa5a6Sopenharmony_ci struct epoll_event ev {}; 288c29fa5a6Sopenharmony_ci ev.events = events; 289c29fa5a6Sopenharmony_ci ev.data.ptr = epollMgr_.get(); 290c29fa5a6Sopenharmony_ci 291c29fa5a6Sopenharmony_ci CHKPR(epollMgr_, RET_ERR); 292c29fa5a6Sopenharmony_ci epollMgr_->Dispatch(ev); 293c29fa5a6Sopenharmony_ci return RET_OK; 294c29fa5a6Sopenharmony_ci} 295c29fa5a6Sopenharmony_ci 296c29fa5a6Sopenharmony_cistd::shared_ptr<IDevice> DeviceManager::GetDevice(int32_t id) const 297c29fa5a6Sopenharmony_ci{ 298c29fa5a6Sopenharmony_ci CHKPP(context_); 299c29fa5a6Sopenharmony_ci std::packaged_task<std::shared_ptr<IDevice>(int32_t)> task {[this](int32_t id) { 300c29fa5a6Sopenharmony_ci return this->OnGetDevice(id); 301c29fa5a6Sopenharmony_ci }}; 302c29fa5a6Sopenharmony_ci auto fu = task.get_future(); 303c29fa5a6Sopenharmony_ci 304c29fa5a6Sopenharmony_ci int32_t ret = context_->GetDelegateTasks().PostSyncTask([this, &task, id] { 305c29fa5a6Sopenharmony_ci return this->RunGetDevice(std::ref(task), id); 306c29fa5a6Sopenharmony_ci }); 307c29fa5a6Sopenharmony_ci if (ret != RET_OK) { 308c29fa5a6Sopenharmony_ci FI_HILOGE("Post task failed"); 309c29fa5a6Sopenharmony_ci return nullptr; 310c29fa5a6Sopenharmony_ci } 311c29fa5a6Sopenharmony_ci return fu.get(); 312c29fa5a6Sopenharmony_ci} 313c29fa5a6Sopenharmony_ci 314c29fa5a6Sopenharmony_cistd::shared_ptr<IDevice> DeviceManager::OnGetDevice(int32_t id) const 315c29fa5a6Sopenharmony_ci{ 316c29fa5a6Sopenharmony_ci if (auto devIter = devices_.find(id); devIter != devices_.cend()) { 317c29fa5a6Sopenharmony_ci return devIter->second; 318c29fa5a6Sopenharmony_ci } 319c29fa5a6Sopenharmony_ci FI_HILOGE("Device id not found"); 320c29fa5a6Sopenharmony_ci return nullptr; 321c29fa5a6Sopenharmony_ci} 322c29fa5a6Sopenharmony_ci 323c29fa5a6Sopenharmony_ciint32_t DeviceManager::RunGetDevice(std::packaged_task<std::shared_ptr<IDevice>(int32_t)> &task, 324c29fa5a6Sopenharmony_ci int32_t id) const 325c29fa5a6Sopenharmony_ci{ 326c29fa5a6Sopenharmony_ci task(id); 327c29fa5a6Sopenharmony_ci return RET_OK; 328c29fa5a6Sopenharmony_ci} 329c29fa5a6Sopenharmony_ci 330c29fa5a6Sopenharmony_civoid DeviceManager::RetriggerHotplug(std::weak_ptr<IDeviceObserver> observer) 331c29fa5a6Sopenharmony_ci{ 332c29fa5a6Sopenharmony_ci CALL_INFO_TRACE; 333c29fa5a6Sopenharmony_ci CHKPV(context_); 334c29fa5a6Sopenharmony_ci int32_t ret = context_->GetDelegateTasks().PostSyncTask([this, observer] { 335c29fa5a6Sopenharmony_ci return this->OnRetriggerHotplug(observer); 336c29fa5a6Sopenharmony_ci }); 337c29fa5a6Sopenharmony_ci if (ret != RET_OK) { 338c29fa5a6Sopenharmony_ci FI_HILOGE("Post task failed"); 339c29fa5a6Sopenharmony_ci } 340c29fa5a6Sopenharmony_ci} 341c29fa5a6Sopenharmony_ci 342c29fa5a6Sopenharmony_ciint32_t DeviceManager::OnRetriggerHotplug(std::weak_ptr<IDeviceObserver> observer) 343c29fa5a6Sopenharmony_ci{ 344c29fa5a6Sopenharmony_ci CALL_INFO_TRACE; 345c29fa5a6Sopenharmony_ci CHKPR(observer, RET_ERR); 346c29fa5a6Sopenharmony_ci std::shared_ptr<IDeviceObserver> ptr = observer.lock(); 347c29fa5a6Sopenharmony_ci CHKPR(ptr, RET_ERR); 348c29fa5a6Sopenharmony_ci std::for_each(devices_.cbegin(), devices_.cend(), 349c29fa5a6Sopenharmony_ci [ptr] (const auto &item) { 350c29fa5a6Sopenharmony_ci if (item.second != nullptr) { 351c29fa5a6Sopenharmony_ci ptr->OnDeviceAdded(item.second); 352c29fa5a6Sopenharmony_ci } 353c29fa5a6Sopenharmony_ci }); 354c29fa5a6Sopenharmony_ci return RET_OK; 355c29fa5a6Sopenharmony_ci} 356c29fa5a6Sopenharmony_ci 357c29fa5a6Sopenharmony_ciint32_t DeviceManager::AddDeviceObserver(std::weak_ptr<IDeviceObserver> observer) 358c29fa5a6Sopenharmony_ci{ 359c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 360c29fa5a6Sopenharmony_ci CHKPR(context_, RET_ERR); 361c29fa5a6Sopenharmony_ci int32_t ret = context_->GetDelegateTasks().PostSyncTask([this, observer] { 362c29fa5a6Sopenharmony_ci return this->OnAddDeviceObserver(observer); 363c29fa5a6Sopenharmony_ci }); 364c29fa5a6Sopenharmony_ci if (ret != RET_OK) { 365c29fa5a6Sopenharmony_ci FI_HILOGE("Post task failed"); 366c29fa5a6Sopenharmony_ci } 367c29fa5a6Sopenharmony_ci return ret; 368c29fa5a6Sopenharmony_ci} 369c29fa5a6Sopenharmony_ci 370c29fa5a6Sopenharmony_ciint32_t DeviceManager::OnAddDeviceObserver(std::weak_ptr<IDeviceObserver> observer) 371c29fa5a6Sopenharmony_ci{ 372c29fa5a6Sopenharmony_ci CALL_INFO_TRACE; 373c29fa5a6Sopenharmony_ci CHKPR(observer, RET_ERR); 374c29fa5a6Sopenharmony_ci auto ret = observers_.insert(observer); 375c29fa5a6Sopenharmony_ci if (!ret.second) { 376c29fa5a6Sopenharmony_ci FI_HILOGW("Observer is duplicated"); 377c29fa5a6Sopenharmony_ci } 378c29fa5a6Sopenharmony_ci return RET_OK; 379c29fa5a6Sopenharmony_ci} 380c29fa5a6Sopenharmony_ci 381c29fa5a6Sopenharmony_civoid DeviceManager::RemoveDeviceObserver(std::weak_ptr<IDeviceObserver> observer) 382c29fa5a6Sopenharmony_ci{ 383c29fa5a6Sopenharmony_ci CALL_INFO_TRACE; 384c29fa5a6Sopenharmony_ci CHKPV(context_); 385c29fa5a6Sopenharmony_ci int32_t ret = context_->GetDelegateTasks().PostSyncTask([this, observer] { 386c29fa5a6Sopenharmony_ci return this->OnRemoveDeviceObserver(observer); 387c29fa5a6Sopenharmony_ci }); 388c29fa5a6Sopenharmony_ci if (ret != RET_OK) { 389c29fa5a6Sopenharmony_ci FI_HILOGE("Post task failed"); 390c29fa5a6Sopenharmony_ci } 391c29fa5a6Sopenharmony_ci} 392c29fa5a6Sopenharmony_ci 393c29fa5a6Sopenharmony_ciint32_t DeviceManager::OnRemoveDeviceObserver(std::weak_ptr<IDeviceObserver> observer) 394c29fa5a6Sopenharmony_ci{ 395c29fa5a6Sopenharmony_ci CALL_INFO_TRACE; 396c29fa5a6Sopenharmony_ci CHKPR(observer, RET_ERR); 397c29fa5a6Sopenharmony_ci observers_.erase(observer); 398c29fa5a6Sopenharmony_ci return RET_OK; 399c29fa5a6Sopenharmony_ci} 400c29fa5a6Sopenharmony_ci 401c29fa5a6Sopenharmony_cibool DeviceManager::AnyOf(std::function<bool(std::shared_ptr<IDevice>)> pred) 402c29fa5a6Sopenharmony_ci{ 403c29fa5a6Sopenharmony_ci return std::any_of(devices_.cbegin(), devices_.cend(), [pred](const auto &item) { 404c29fa5a6Sopenharmony_ci return (pred != nullptr ? pred(item.second) : false); 405c29fa5a6Sopenharmony_ci }); 406c29fa5a6Sopenharmony_ci} 407c29fa5a6Sopenharmony_ci 408c29fa5a6Sopenharmony_cibool DeviceManager::HasLocalPointerDevice() 409c29fa5a6Sopenharmony_ci{ 410c29fa5a6Sopenharmony_ci return AnyOf([this](std::shared_ptr<IDevice> dev) { 411c29fa5a6Sopenharmony_ci if ((dev == nullptr) || (dev->GetName() == FINGER_PRINT)) { 412c29fa5a6Sopenharmony_ci return false; 413c29fa5a6Sopenharmony_ci } 414c29fa5a6Sopenharmony_ci return (dev->IsPointerDevice() && !dev->IsRemote()); 415c29fa5a6Sopenharmony_ci }); 416c29fa5a6Sopenharmony_ci} 417c29fa5a6Sopenharmony_ci 418c29fa5a6Sopenharmony_cibool DeviceManager::HasLocalKeyboardDevice() 419c29fa5a6Sopenharmony_ci{ 420c29fa5a6Sopenharmony_ci return AnyOf([this](std::shared_ptr<IDevice> dev) { 421c29fa5a6Sopenharmony_ci CHKPR(dev, false); 422c29fa5a6Sopenharmony_ci return (dev->IsKeyboard() && !dev->IsRemote()); 423c29fa5a6Sopenharmony_ci }); 424c29fa5a6Sopenharmony_ci} 425c29fa5a6Sopenharmony_ci 426c29fa5a6Sopenharmony_cibool DeviceManager::HasKeyboard() 427c29fa5a6Sopenharmony_ci{ 428c29fa5a6Sopenharmony_ci return AnyOf([this](std::shared_ptr<IDevice> dev) { 429c29fa5a6Sopenharmony_ci if ((dev == nullptr)) { 430c29fa5a6Sopenharmony_ci return false; 431c29fa5a6Sopenharmony_ci } 432c29fa5a6Sopenharmony_ci return (dev->IsKeyboard() && !dev->IsRemote() && 433c29fa5a6Sopenharmony_ci dev->GetKeyboardType() == IDevice::KeyboardType::KEYBOARD_TYPE_ALPHABETICKEYBOARD); 434c29fa5a6Sopenharmony_ci }); 435c29fa5a6Sopenharmony_ci} 436c29fa5a6Sopenharmony_ci 437c29fa5a6Sopenharmony_cistd::vector<std::shared_ptr<IDevice>> DeviceManager::GetKeyboard() 438c29fa5a6Sopenharmony_ci{ 439c29fa5a6Sopenharmony_ci std::vector<std::shared_ptr<IDevice>> keyboards; 440c29fa5a6Sopenharmony_ci for (const auto &dev : devices_) { 441c29fa5a6Sopenharmony_ci if (dev.second->IsKeyboard() && !dev.second->IsRemote() && 442c29fa5a6Sopenharmony_ci dev.second->GetKeyboardType() == IDevice::KeyboardType::KEYBOARD_TYPE_ALPHABETICKEYBOARD) { 443c29fa5a6Sopenharmony_ci keyboards.push_back(dev.second); 444c29fa5a6Sopenharmony_ci } 445c29fa5a6Sopenharmony_ci } 446c29fa5a6Sopenharmony_ci return keyboards; 447c29fa5a6Sopenharmony_ci} 448c29fa5a6Sopenharmony_ci} // namespace DeviceStatus 449c29fa5a6Sopenharmony_ci} // namespace Msdp 450c29fa5a6Sopenharmony_ci} // namespace OHOS