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