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