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