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