• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "coordination_device_manager.h"
17 
18 #include <openssl/sha.h>
19 #include <regex>
20 
21 #include "coordination_event_manager.h"
22 #include "coordination_sm.h"
23 #include "coordination_util.h"
24 #include "devicestatus_define.h"
25 #include "napi_constants.h"
26 
27 namespace OHOS {
28 namespace Msdp {
29 namespace DeviceStatus {
30 namespace {
31 constexpr OHOS::HiviewDFX::HiLogLabel LABEL { LOG_CORE, MSDP_DOMAIN_ID, "CoordinationDeviceManager" };
32 constexpr size_t NETWORK_ID_NUMS { 3 };
33 constexpr size_t DESCRIPTOR_INDEX { 2 };
34 } // namespace
35 
CoordinationDeviceManager()36 CoordinationDeviceManager::CoordinationDeviceManager() {}
~CoordinationDeviceManager()37 CoordinationDeviceManager::~CoordinationDeviceManager() {}
38 
Device(std::shared_ptr<IDevice> dev)39 CoordinationDeviceManager::Device::Device(std::shared_ptr<IDevice> dev)
40     : device_(dev)
41 {
42     Populate();
43 }
44 
GetId() const45 int32_t CoordinationDeviceManager::Device::GetId() const
46 {
47     CHKPR(device_, RET_ERR);
48     return device_->GetId();
49 }
50 
GetName() const51 std::string CoordinationDeviceManager::Device::GetName() const
52 {
53     CHKPS(device_);
54     return device_->GetName();
55 }
56 
GetDhid() const57 std::string CoordinationDeviceManager::Device::GetDhid() const
58 {
59     return dhid_;
60 }
61 
GetNetworkId() const62 std::string CoordinationDeviceManager::Device::GetNetworkId() const
63 {
64     return networkId_;
65 }
66 
GetProduct() const67 int32_t CoordinationDeviceManager::Device::GetProduct() const
68 {
69     CHKPR(device_, RET_ERR);
70     return device_->GetProduct();
71 }
72 
GetVendor() const73 int32_t CoordinationDeviceManager::Device::GetVendor() const
74 {
75     CHKPR(device_, RET_ERR);
76     return device_->GetVendor();
77 }
78 
GetPhys() const79 std::string CoordinationDeviceManager::Device::GetPhys() const
80 {
81     CHKPS(device_);
82     return device_->GetPhys();
83 }
84 
GetUniq() const85 std::string CoordinationDeviceManager::Device::GetUniq() const
86 {
87     CHKPS(device_);
88     return device_->GetUniq();
89 }
90 
IsPointerDevice() const91 bool CoordinationDeviceManager::Device::IsPointerDevice() const
92 {
93     CHKPF(device_);
94     return device_->IsPointerDevice();
95 }
96 
GetKeyboardType() const97 IDevice::KeyboardType CoordinationDeviceManager::Device::GetKeyboardType() const
98 {
99     CHKPR(device_, IDevice::KeyboardType::KEYBOARD_TYPE_NONE);
100     return device_->GetKeyboardType();
101 }
102 
IsKeyboard() const103 bool CoordinationDeviceManager::Device::IsKeyboard() const
104 {
105     CHKPF(device_);
106     return device_->IsKeyboard();
107 }
108 
Populate()109 void CoordinationDeviceManager::Device::Populate()
110 {
111     CALL_DEBUG_ENTER;
112     if (IsRemote()) {
113         networkId_ = MakeNetworkId(GetPhys());
114     }
115     dhid_ = GenerateDescriptor();
116 }
117 
IsRemote()118 bool CoordinationDeviceManager::Device::IsRemote()
119 {
120     const std::string INPUT_VIRTUAL_DEVICE_NAME { "DistributedInput " };
121     return (GetName().find(INPUT_VIRTUAL_DEVICE_NAME) != std::string::npos);
122 }
123 
MakeNetworkId(const std::string & phys) const124 std::string CoordinationDeviceManager::Device::MakeNetworkId(const std::string &phys) const
125 {
126     std::vector<std::string> idParts;
127     const std::string SPLIT_SYMBOL { "|" };
128     StringSplit(phys, SPLIT_SYMBOL, idParts);
129     if (idParts.size() == NETWORK_ID_NUMS) {
130         return idParts[1];
131     }
132     return {};
133 }
134 
GenerateDescriptor()135 std::string CoordinationDeviceManager::Device::GenerateDescriptor()
136 {
137     const std::string phys = GetPhys();
138     const std::string SPLIT_SYMBOL { "|" };
139     const std::string DH_ID_PREFIX { "Input_" };
140     std::string descriptor;
141     if (IsRemote() && !phys.empty()) {
142         FI_HILOGD("physicalPath:%{public}s", phys.c_str());
143         std::vector<std::string> idParts;
144         StringSplit(phys.c_str(), SPLIT_SYMBOL, idParts);
145         if (idParts.size() == NETWORK_ID_NUMS) {
146             descriptor = idParts[DESCRIPTOR_INDEX];
147         }
148         return descriptor;
149     }
150 
151     const std::string name = GetName();
152     const std::string uniq = GetUniq();
153     std::string rawDescriptor = StringPrintf(":%04x:%04x:", GetVendor(), GetProduct());
154 
155     if (!uniq.empty()) {
156         rawDescriptor += "uniqueId:" + uniq;
157     }
158     if (!phys.empty()) {
159         rawDescriptor += "physicalPath:" + phys;
160     }
161     if (!name.empty()) {
162         rawDescriptor += "name:" + std::regex_replace(name, std::regex(" "), "");
163     }
164     descriptor = DH_ID_PREFIX + Sha256(rawDescriptor);
165     FI_HILOGD("Created descriptor raw:%{public}s", rawDescriptor.c_str());
166     return descriptor;
167 }
168 
Sha256(const std::string & in) const169 std::string CoordinationDeviceManager::Device::Sha256(const std::string &in) const
170 {
171     unsigned char out[SHA256_DIGEST_LENGTH * 2 + 1] = { 0 };
172     SHA256_CTX ctx;
173     SHA256_Init(&ctx);
174     SHA256_Update(&ctx, in.data(), in.size());
175     SHA256_Final(&out[SHA256_DIGEST_LENGTH], &ctx);
176 
177     constexpr int32_t width = 4;
178     constexpr unsigned char mask = 0x0F;
179     const char* hexCode = "0123456789abcdef";
180     constexpr int32_t DOUBLE_TIMES = 2;
181     for (int32_t i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
182         unsigned char value = out[SHA256_DIGEST_LENGTH + i];
183         out[i * DOUBLE_TIMES] = hexCode[(value >> width) & mask];
184         out[i * DOUBLE_TIMES + 1] = hexCode[value & mask];
185     }
186     out[SHA256_DIGEST_LENGTH * DOUBLE_TIMES] = 0;
187     return reinterpret_cast<char*>(out);
188 }
189 
Init()190 void CoordinationDeviceManager::Init()
191 {
192     CALL_INFO_TRACE;
193     auto* context = COOR_EVENT_MGR->GetIContext();
194     CHKPV(context);
195     devObserver_ = std::make_shared<DeviceObserver>(*this);
196     context->GetDeviceManager().AddDeviceObserver(devObserver_);
197     context->GetDeviceManager().RetriggerHotplug(devObserver_);
198 }
199 
IsRemote(int32_t id)200 bool CoordinationDeviceManager::IsRemote(int32_t id)
201 {
202     if (auto devIter = devices_.find(id); devIter != devices_.end()) {
203         CHKPF(devIter->second);
204         return devIter->second->IsRemote();
205     }
206     return false;
207 }
208 
GetCoordinationDhids(int32_t deviceId) const209 std::vector<std::string> CoordinationDeviceManager::GetCoordinationDhids(int32_t deviceId) const
210 {
211     CALL_INFO_TRACE;
212     std::vector<std::string> inputDeviceDhids;
213     auto devIter = devices_.find(deviceId);
214     if (devIter == devices_.end()) {
215         FI_HILOGW("Cannot find pointer id:%{public}d", deviceId);
216         return inputDeviceDhids;
217     }
218     if (devIter->second == nullptr) {
219         FI_HILOGW("Device is nullptr");
220         return inputDeviceDhids;
221     }
222     std::shared_ptr<Device> dev = devIter->second;
223     if (!dev->IsPointerDevice()) {
224         FI_HILOGD("Not pointer device");
225         return inputDeviceDhids;
226     }
227     inputDeviceDhids.push_back(dev->GetDhid());
228     FI_HILOGD("unq:%{public}s, type:%{public}s", inputDeviceDhids.back().c_str(), "pointer");
229 
230     const std::string localNetworkId { COORDINATION::GetLocalNetworkId() };
231     const std::string pointerNetworkId { dev->IsRemote() ? dev->GetNetworkId() : localNetworkId };
232 
233     for (const auto &[id, dev] : devices_) {
234         CHKPC(dev);
235         const std::string networkId { dev->IsRemote() ? dev->GetNetworkId() : localNetworkId };
236         if (networkId != pointerNetworkId) {
237             continue;
238         }
239         if (dev->GetKeyboardType() == IDevice::KEYBOARD_TYPE_ALPHABETICKEYBOARD) {
240             inputDeviceDhids.push_back(dev->GetDhid());
241             FI_HILOGD("unq:%{public}s, type:%{public}s", inputDeviceDhids.back().c_str(), "supportkey");
242         }
243     }
244     return inputDeviceDhids;
245 }
246 
GetCoordinationDhids(const std::string & dhid) const247 std::vector<std::string> CoordinationDeviceManager::GetCoordinationDhids(const std::string &dhid) const
248 {
249     int32_t deviceId { -1 };
250     for (const auto &[id, dev] : devices_) {
251         CHKPC(dev);
252         if (dev->GetDhid() == dhid) {
253             deviceId = id;
254             break;
255         }
256     }
257     return GetCoordinationDhids(deviceId);
258 }
259 
GetOriginNetworkId(int32_t id) const260 std::string CoordinationDeviceManager::GetOriginNetworkId(int32_t id) const
261 {
262     CALL_INFO_TRACE;
263     auto devIter = devices_.find(id);
264     if (devIter == devices_.end()) {
265         FI_HILOGE("Failed to search for the device, id:%{public}d", id);
266         return {};
267     }
268     CHKPS(devIter->second);
269     auto OriginNetworkId = devIter->second->GetNetworkId();
270     if (OriginNetworkId.empty()) {
271         OriginNetworkId = COORDINATION::GetLocalNetworkId();
272     }
273     return OriginNetworkId;
274 }
275 
GetOriginNetworkId(const std::string & dhid) const276 std::string CoordinationDeviceManager::GetOriginNetworkId(const std::string &dhid) const
277 {
278     CALL_INFO_TRACE;
279     if (dhid.empty()) {
280         FI_HILOGD("The current netWorkId is an empty string");
281         return {};
282     }
283     for (const auto &[id, dev] : devices_) {
284         CHKPC(dev);
285         if (dev->IsRemote() && dev->GetDhid() == dhid) {
286             return dev->GetNetworkId();
287         }
288     }
289     FI_HILOGD("The current netWorkId is an empty string");
290     return {};
291 }
292 
GetDhid(int32_t deviceId) const293 std::string CoordinationDeviceManager::GetDhid(int32_t deviceId) const
294 {
295     CALL_INFO_TRACE;
296     if (auto devIter = devices_.find(deviceId); devIter != devices_.end()) {
297         if (devIter->second != nullptr) {
298             return devIter->second->GetDhid();
299         }
300         FI_HILOGW("Device is nullptr");
301     }
302     return {};
303 }
304 
HasLocalPointerDevice() const305 bool CoordinationDeviceManager::HasLocalPointerDevice() const
306 {
307     for (const auto &[id, dev] : devices_) {
308         CHKPC(dev);
309         if (!dev->IsRemote() && dev->IsPointerDevice()) {
310             FI_HILOGD("It is currently a mouse device");
311             return true;
312         }
313     }
314     FI_HILOGD("Not currently a mouse device");
315     return false;
316 }
317 
OnDeviceAdded(std::shared_ptr<IDevice> device)318 void CoordinationDeviceManager::OnDeviceAdded(std::shared_ptr<IDevice> device)
319 {
320     CALL_INFO_TRACE;
321     CHKPV(device);
322     auto dev = std::make_shared<CoordinationDeviceManager::Device>(device);
323     devices_.insert_or_assign(dev->GetId(), dev);
324     if (dev->IsKeyboard()) {
325         COOR_SM->OnKeyboardOnline(dev->GetDhid());
326     }
327     FI_HILOGD("Add device %{public}d:%{public}s, Dhid:\"%{public}s\", Network id:\"%{public}s\", "
328         "local/remote:\"%{public}s\"", device->GetId(), device->GetDevPath().c_str(), dev->GetDhid().c_str(),
329         dev->GetNetworkId().c_str(), dev->IsRemote() ? "Remote Device" : "Local Device");
330 }
331 
OnDeviceRemoved(std::shared_ptr<IDevice> device)332 void CoordinationDeviceManager::OnDeviceRemoved(std::shared_ptr<IDevice> device)
333 {
334     CALL_INFO_TRACE;
335     CHKPV(device);
336     auto iter = devices_.find(device->GetId());
337     if (iter == devices_.end()) {
338         FI_HILOGE("The device corresponding to the current id:%{public}d cannot be found", device->GetId());
339         return;
340     }
341     std::shared_ptr<Device> dev = iter->second;
342     CHKPV(dev);
343     auto dhids = GetCoordinationDhids(dev->GetId());
344     devices_.erase(iter);
345     if (device->IsPointerDevice()) {
346         COOR_SM->OnPointerOffline(dev->GetDhid(), dhids);
347     } else if (device->IsKeyboard()) {
348         if (!dev->IsRemote() && dev->GetKeyboardType() == IDevice::KEYBOARD_TYPE_ALPHABETICKEYBOARD) {
349             COOR_SM->OnKeyboardOffline(dev->GetDhid());
350         }
351     }
352 }
353 
DeviceObserver(CoordinationDeviceManager & cooDevMgr)354 CoordinationDeviceManager::DeviceObserver::DeviceObserver(CoordinationDeviceManager &cooDevMgr)
355     : cooDevMgr_(cooDevMgr)
356 {}
357 
OnDeviceAdded(std::shared_ptr<IDevice> device)358 void CoordinationDeviceManager::DeviceObserver::OnDeviceAdded(std::shared_ptr<IDevice> device)
359 {
360     cooDevMgr_.OnDeviceAdded(device);
361 }
362 
OnDeviceRemoved(std::shared_ptr<IDevice> device)363 void CoordinationDeviceManager::DeviceObserver::OnDeviceRemoved(std::shared_ptr<IDevice> device)
364 {
365     cooDevMgr_.OnDeviceRemoved(device);
366 }
367 } // namespace DeviceStatus
368 } // namespace Msdp
369 } // namespace OHOS