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