1 /*
2 * Copyright (c) 2021-2025 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 "dh_context.h"
17
18 #include <algorithm>
19
20 #include "cJSON.h"
21
22 #include "anonymous_string.h"
23 #include "constants.h"
24 #include "dh_utils_tool.h"
25 #include "distributed_hardware_errno.h"
26 #include "distributed_hardware_log.h"
27 #include "device_manager.h"
28 #include "publisher.h"
29
30 namespace OHOS {
31 namespace DistributedHardware {
32 namespace {
33 constexpr const char *ISOMERISM_EVENT_KEY = "isomerism_event";
34 const std::string ISOMERISM_EVENT_CONNECT_VAL = "isomerism_connect";
35 const std::string ISOMERISM_EVENT_DISCONNECT_VAL = "isomerism_disconnect";
36 }
37 IMPLEMENT_SINGLE_INSTANCE(DHContext);
DHContext()38 DHContext::DHContext()
39 {
40 DHLOGI("Ctor DHContext");
41 std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create(true);
42 eventHandler_ = std::make_shared<DHContext::CommonEventHandler>(runner);
43 RegisDHFWKIsomerismListener();
44 }
45
~DHContext()46 DHContext::~DHContext()
47 {
48 DHLOGI("Dtor DHContext");
49 }
50
CommonEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> runner)51 DHContext::CommonEventHandler::CommonEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> runner)
52 : AppExecFwk::EventHandler(runner)
53 {
54 DHLOGI("Ctor CommonEventHandler");
55 }
56
GetEventHandler()57 std::shared_ptr<DHContext::CommonEventHandler> DHContext::GetEventHandler()
58 {
59 return eventHandler_;
60 }
61
PostTask(const Callback & callback,const std::string & name,int64_t delayTime)62 bool DHContext::CommonEventHandler::PostTask(const Callback &callback, const std::string &name, int64_t delayTime)
63 {
64 return AppExecFwk::EventHandler::PostTask(callback, name, delayTime);
65 }
66
RemoveTask(const std::string & name)67 void DHContext::CommonEventHandler::RemoveTask(const std::string &name)
68 {
69 AppExecFwk::EventHandler::RemoveTask(name);
70 }
71
GetDeviceInfo()72 const DeviceInfo& DHContext::GetDeviceInfo()
73 {
74 std::lock_guard<std::mutex> lock(devMutex_);
75 if (!devInfo_.uuid.empty()) {
76 return devInfo_;
77 }
78 devInfo_ = GetLocalDeviceInfo();
79 return devInfo_;
80 }
81
AddOnlineDevice(const std::string & udid,const std::string & uuid,const std::string & networkId)82 void DHContext::AddOnlineDevice(const std::string &udid, const std::string &uuid, const std::string &networkId)
83 {
84 if (!IsIdLengthValid(udid) || !IsIdLengthValid(uuid) || !IsIdLengthValid(networkId)) {
85 return;
86 }
87 std::unique_lock<std::shared_mutex> lock(onlineDevMutex_);
88 if (devIdEntrySet_.size() > MAX_ONLINE_DEVICE_SIZE) {
89 DHLOGE("devIdEntrySet_ is over size!");
90 return;
91 }
92 std::string deviceId = Sha256(uuid);
93 std::string udidHash = Sha256(udid);
94 DeviceIdEntry idEntry = {
95 .networkId = networkId,
96 .uuid = uuid,
97 .deviceId = deviceId,
98 .udid = udid,
99 .udidHash = udidHash
100 };
101 devIdEntrySet_.insert(idEntry);
102 }
103
RemoveOnlineDeviceIdEntryByNetworkId(const std::string & networkId)104 void DHContext::RemoveOnlineDeviceIdEntryByNetworkId(const std::string &networkId)
105 {
106 if (!IsIdLengthValid(networkId)) {
107 return;
108 }
109 std::unique_lock<std::shared_mutex> lock(onlineDevMutex_);
110 for (auto iter = devIdEntrySet_.begin(); iter != devIdEntrySet_.end(); iter++) {
111 if (iter->networkId == networkId) {
112 devIdEntrySet_.erase(iter);
113 break;
114 }
115 }
116 }
117
IsDeviceOnline(const std::string & uuid)118 bool DHContext::IsDeviceOnline(const std::string &uuid)
119 {
120 if (!IsIdLengthValid(uuid)) {
121 return false;
122 }
123 std::shared_lock<std::shared_mutex> lock(onlineDevMutex_);
124 bool flag = false;
125 for (auto iter = devIdEntrySet_.begin(); iter != devIdEntrySet_.end(); iter++) {
126 if (iter->uuid == uuid) {
127 flag = true;
128 break;
129 }
130 }
131 return flag;
132 }
133
GetOnlineCount()134 size_t DHContext::GetOnlineCount()
135 {
136 std::shared_lock<std::shared_mutex> lock(onlineDevMutex_);
137 return devIdEntrySet_.size();
138 }
139
GetNetworkIdByUUID(const std::string & uuid)140 std::string DHContext::GetNetworkIdByUUID(const std::string &uuid)
141 {
142 if (!IsIdLengthValid(uuid)) {
143 return "";
144 }
145 std::unique_lock<std::shared_mutex> lock(onlineDevMutex_);
146 std::string networkId = "";
147 for (auto iter = devIdEntrySet_.begin(); iter != devIdEntrySet_.end(); iter++) {
148 if (iter->uuid == uuid) {
149 networkId = iter->networkId;
150 break;
151 }
152 }
153 return networkId;
154 }
155
GetNetworkIdByUDID(const std::string & udid)156 std::string DHContext::GetNetworkIdByUDID(const std::string &udid)
157 {
158 if (!IsIdLengthValid(udid)) {
159 return "";
160 }
161 std::unique_lock<std::shared_mutex> lock(onlineDevMutex_);
162 std::string networkId = "";
163 for (auto iter = devIdEntrySet_.begin(); iter != devIdEntrySet_.end(); iter++) {
164 if (iter->udid == udid) {
165 networkId = iter->networkId;
166 break;
167 }
168 }
169 return networkId;
170 }
171
GetUdidHashIdByUUID(const std::string & uuid)172 std::string DHContext::GetUdidHashIdByUUID(const std::string &uuid)
173 {
174 if (!IsIdLengthValid(uuid)) {
175 return "";
176 }
177 std::unique_lock<std::shared_mutex> lock(onlineDevMutex_);
178 std::string udidHash = "";
179 for (auto iter = devIdEntrySet_.begin(); iter != devIdEntrySet_.end(); iter++) {
180 if (iter->uuid == uuid) {
181 udidHash = iter->udidHash;
182 break;
183 }
184 }
185 return udidHash;
186 }
187
GetUUIDByNetworkId(const std::string & networkId)188 std::string DHContext::GetUUIDByNetworkId(const std::string &networkId)
189 {
190 if (!IsIdLengthValid(networkId)) {
191 return "";
192 }
193 std::unique_lock<std::shared_mutex> lock(onlineDevMutex_);
194 std::string uuid = "";
195 for (auto iter = devIdEntrySet_.begin(); iter != devIdEntrySet_.end(); iter++) {
196 if (iter->networkId == networkId) {
197 uuid = iter->uuid;
198 break;
199 }
200 }
201 return uuid;
202 }
203
GetUDIDByNetworkId(const std::string & networkId)204 std::string DHContext::GetUDIDByNetworkId(const std::string &networkId)
205 {
206 if (!IsIdLengthValid(networkId)) {
207 return "";
208 }
209 std::unique_lock<std::shared_mutex> lock(onlineDevMutex_);
210 std::string udid = "";
211 for (auto iter = devIdEntrySet_.begin(); iter != devIdEntrySet_.end(); iter++) {
212 if (iter->networkId == networkId) {
213 udid = iter->udid;
214 break;
215 }
216 }
217 return udid;
218 }
219
GetUUIDByDeviceId(const std::string & deviceId)220 std::string DHContext::GetUUIDByDeviceId(const std::string &deviceId)
221 {
222 if (!IsIdLengthValid(deviceId)) {
223 return "";
224 }
225 std::unique_lock<std::shared_mutex> lock(onlineDevMutex_);
226 std::string uuid = "";
227 for (auto iter = devIdEntrySet_.begin(); iter != devIdEntrySet_.end(); iter++) {
228 if (iter->deviceId == deviceId || iter->udidHash == deviceId) {
229 uuid = iter->uuid;
230 break;
231 }
232 }
233 return uuid;
234 }
235
GetNetworkIdByDeviceId(const std::string & deviceId)236 std::string DHContext::GetNetworkIdByDeviceId(const std::string &deviceId)
237 {
238 if (!IsIdLengthValid(deviceId)) {
239 return "";
240 }
241 std::unique_lock<std::shared_mutex> lock(onlineDevMutex_);
242 std::string networkId = "";
243 for (auto iter = devIdEntrySet_.begin(); iter != devIdEntrySet_.end(); iter++) {
244 if (iter->deviceId == deviceId) {
245 networkId = iter->networkId;
246 break;
247 }
248 }
249 return networkId;
250 }
251
GetOnlineDeviceUdidHash(std::vector<std::string> & udidHashVec)252 void DHContext::GetOnlineDeviceUdidHash(std::vector<std::string> &udidHashVec)
253 {
254 std::unique_lock<std::shared_mutex> lock(onlineDevMutex_);
255 for (auto iter = devIdEntrySet_.begin(); iter != devIdEntrySet_.end(); iter++) {
256 udidHashVec.push_back(iter->udidHash);
257 }
258 }
259
GetOnlineDeviceDeviceId(std::vector<std::string> & deviceIdVec)260 void DHContext::GetOnlineDeviceDeviceId(std::vector<std::string> &deviceIdVec)
261 {
262 std::unique_lock<std::shared_mutex> lock(onlineDevMutex_);
263 for (auto iter = devIdEntrySet_.begin(); iter != devIdEntrySet_.end(); iter++) {
264 deviceIdVec.push_back(iter->deviceId);
265 }
266 }
267
GetDeviceIdByDBGetPrefix(const std::string & prefix)268 std::string DHContext::GetDeviceIdByDBGetPrefix(const std::string &prefix)
269 {
270 if (!IsIdLengthValid(prefix)) {
271 return "";
272 }
273 std::string id = "";
274 if (prefix.empty()) {
275 return id;
276 }
277
278 if (prefix.find(RESOURCE_SEPARATOR) != std::string::npos) {
279 id = prefix.substr(0, prefix.find_first_of(RESOURCE_SEPARATOR));
280 } else {
281 id = prefix;
282 }
283
284 return id;
285 }
286
AddRealTimeOnlineDeviceNetworkId(const std::string & networkId)287 void DHContext::AddRealTimeOnlineDeviceNetworkId(const std::string &networkId)
288 {
289 DHLOGI("AddRealTimeOnlineDeviceNetworkId: %{public}s", GetAnonyString(networkId).c_str());
290 std::unique_lock<std::shared_mutex> lock(realTimeNetworkIdMutex_);
291 realTimeOnLineNetworkIdSet_.insert(networkId);
292 }
293
DeleteRealTimeOnlineDeviceNetworkId(const std::string & networkId)294 void DHContext::DeleteRealTimeOnlineDeviceNetworkId(const std::string &networkId)
295 {
296 DHLOGI("DeleteRealTimeOnlineDeviceNetworkId: %{public}s", GetAnonyString(networkId).c_str());
297 std::unique_lock<std::shared_mutex> lock(realTimeNetworkIdMutex_);
298 realTimeOnLineNetworkIdSet_.erase(networkId);
299 }
300
GetRealTimeOnlineDeviceCount()301 size_t DHContext::GetRealTimeOnlineDeviceCount()
302 {
303 std::shared_lock<std::shared_mutex> lock(realTimeNetworkIdMutex_);
304 return realTimeOnLineNetworkIdSet_.size();
305 }
306
RegisDHFWKIsomerismListener()307 void DHContext::RegisDHFWKIsomerismListener()
308 {
309 sptr<IPublisherListener> dhFwkIsomerismListener(new (std::nothrow) DHFWKIsomerismListener());
310 if (dhFwkIsomerismListener == nullptr) {
311 DHLOGE("dhFwkIsomerismListener Create Error");
312 return;
313 }
314 Publisher::GetInstance().RegisterListener(DHTopic::TOPIC_ISOMERISM, dhFwkIsomerismListener);
315 }
316
OnMessage(const DHTopic topic,const std::string & message)317 void DHContext::DHFWKIsomerismListener::OnMessage(const DHTopic topic, const std::string &message)
318 {
319 if (!IsMessageLengthValid(message)) {
320 return;
321 }
322 DHLOGI("OnMessage topic: %{public}u", static_cast<uint32_t>(topic));
323 if (topic != DHTopic::TOPIC_ISOMERISM) {
324 DHLOGE("OnMessage topic is wrong");
325 return;
326 }
327 cJSON *messageJson = cJSON_Parse(message.c_str());
328 if (messageJson == nullptr) {
329 DHLOGE("OnMessage error, parse failed");
330 return;
331 }
332 cJSON *eventObj = cJSON_GetObjectItemCaseSensitive(messageJson, ISOMERISM_EVENT_KEY);
333 if (!IsString(eventObj)) {
334 cJSON_Delete(messageJson);
335 DHLOGE("OnMessage event invaild");
336 return;
337 }
338 cJSON *devObj = cJSON_GetObjectItemCaseSensitive(messageJson, DEV_ID);
339 if (!IsString(devObj)) {
340 cJSON_Delete(messageJson);
341 DHLOGE("OnMessage deviceId invaild");
342 return;
343 }
344 std::string event = eventObj->valuestring;
345 std::string deviceId = devObj->valuestring;
346 cJSON_Delete(messageJson);
347 if (event == ISOMERISM_EVENT_CONNECT_VAL) {
348 DHContext::GetInstance().AddIsomerismConnectDev(deviceId);
349 } else if (event == ISOMERISM_EVENT_DISCONNECT_VAL) {
350 DHContext::GetInstance().DelIsomerismConnectDev(deviceId);
351 }
352 DHLOGI("OnMessage end");
353 }
354
AddIsomerismConnectDev(const std::string & IsomerismDeviceId)355 void DHContext::AddIsomerismConnectDev(const std::string &IsomerismDeviceId)
356 {
357 if (!IsIdLengthValid(IsomerismDeviceId)) {
358 return;
359 }
360 DHLOGI("AddIsomerismConnectDev id = %{public}s", GetAnonyString(IsomerismDeviceId).c_str());
361 std::unique_lock<std::shared_mutex> lock(connectDevMutex_);
362 connectedDevIds_.insert(IsomerismDeviceId);
363 }
364
DelIsomerismConnectDev(const std::string & IsomerismDeviceId)365 void DHContext::DelIsomerismConnectDev(const std::string &IsomerismDeviceId)
366 {
367 if (!IsIdLengthValid(IsomerismDeviceId)) {
368 return;
369 }
370 DHLOGI("DelIsomerismConnectDev id = %{public}s", GetAnonyString(IsomerismDeviceId).c_str());
371 std::unique_lock<std::shared_mutex> lock(connectDevMutex_);
372 if (connectedDevIds_.find(IsomerismDeviceId) == connectedDevIds_.end()) {
373 DHLOGI("DelIsomerismConnectDev is not exist.");
374 return;
375 }
376 connectedDevIds_.erase(IsomerismDeviceId);
377 }
378
GetIsomerismConnectCount()379 uint32_t DHContext::GetIsomerismConnectCount()
380 {
381 std::shared_lock<std::shared_mutex> lock(connectDevMutex_);
382 return static_cast<uint32_t>(connectedDevIds_.size());
383 }
384
DHFWKIsomerismListener()385 DHContext::DHFWKIsomerismListener::DHFWKIsomerismListener()
386 {
387 DHLOGI("DHFWKIsomerismListener ctor");
388 }
389
~DHFWKIsomerismListener()390 DHContext::DHFWKIsomerismListener::~DHFWKIsomerismListener()
391 {
392 DHLOGI("DHFWKIsomerismListener dtor");
393 }
394
AsObject()395 sptr<IRemoteObject> DHContext::DHFWKIsomerismListener::AsObject()
396 {
397 return nullptr;
398 }
399
AddOnlineDeviceType(const std::string & networkId,uint16_t deviceType)400 void DHContext::AddOnlineDeviceType(const std::string &networkId, uint16_t deviceType)
401 {
402 DHLOGI("Add DeviceType, networkId: %{public}s", GetAnonyString(networkId).c_str());
403 std::unique_lock<std::shared_mutex> lock(onlineDevTypeMutex_);
404 onlineDevTypeMap_.insert(std::make_pair(networkId, deviceType));
405 }
406
DeleteOnlineDeviceType(const std::string & networkId)407 void DHContext::DeleteOnlineDeviceType(const std::string &networkId)
408 {
409 DHLOGI("Delete DeviceType, networkId: %{public}s", GetAnonyString(networkId).c_str());
410 std::unique_lock<std::shared_mutex> lock(onlineDevTypeMutex_);
411 auto iter = onlineDevTypeMap_.find(networkId);
412 if (iter != onlineDevTypeMap_.end()) {
413 onlineDevTypeMap_.erase(networkId);
414 }
415 }
416
GetDeviceTypeByNetworkId(const std::string & networkId)417 uint16_t DHContext::GetDeviceTypeByNetworkId(const std::string &networkId)
418 {
419 DHLOGI("Get DeviceType networkId: %{public}s", GetAnonyString(networkId).c_str());
420 std::shared_lock<std::shared_mutex> lock(onlineDevTypeMutex_);
421 auto iter = onlineDevTypeMap_.find(networkId);
422 if (iter == onlineDevTypeMap_.end()) {
423 DHLOGE("NetworkId not exist.");
424 return static_cast<uint16_t>(DmDeviceType::DEVICE_TYPE_UNKNOWN);
425 }
426 return onlineDevTypeMap_[networkId];
427 }
428 } // namespace DistributedHardware
429 } // namespace OHOS
430