• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-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 "dm_comm_tool.h"
17 #include "device_manager_service.h"
18 #include "dm_anonymous.h"
19 #include "dm_error_type.h"
20 #include "dm_transport.h"
21 #include "dm_transport_msg.h"
22 #include "dm_log.h"
23 #include "dm_softbus_cache.h"
24 #include "multiple_user_connector.h"
25 #include "parameter.h"
26 
27 namespace OHOS {
28 namespace DistributedHardware {
29 // send local foreground userids msg
30 constexpr int32_t DM_COMM_SEND_LOCAL_USERIDS = 1;
31 // if receive remote device send foreground userids, response local foreground uerids
32 // This msg no need response
33 constexpr int32_t DM_COMM_RSP_LOCAL_USERIDS = 2;
34 constexpr int32_t DM_COMM_SEND_USER_STOP = 3;
35 constexpr int32_t DM_COMM_RSP_USER_STOP = 4;
36 constexpr int32_t DM_COMM_ACCOUNT_LOGOUT = 5;
37 
38 const char* const USER_STOP_MSG_KEY = "stopUserId";
39 
DMCommTool()40 DMCommTool::DMCommTool() : dmTransportPtr_(nullptr)
41 {
42     LOGI("Ctor DMCommTool");
43 }
44 
Init()45 void DMCommTool::Init()
46 {
47     LOGI("Init DMCommTool");
48     dmTransportPtr_ = std::make_shared<DMTransport>(shared_from_this());
49     std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create(true);
50     eventHandler_ = std::make_shared<DMCommTool::DMCommToolEventHandler>(runner, shared_from_this());
51     dmTransportPtr_->Init();
52 }
53 
UnInit()54 void DMCommTool::UnInit()
55 {
56     LOGI("UnInit DMCommTool");
57     if (dmTransportPtr_ == nullptr) {
58         LOGI("dmTransportPtr_ is null");
59         return;
60     }
61     dmTransportPtr_->UnInit();
62 }
63 
GetInstance()64 std::shared_ptr<DMCommTool> DMCommTool::GetInstance()
65 {
66     static std::shared_ptr<DMCommTool> instance = std::make_shared<DMCommTool>();
67     return instance;
68 }
69 
SendUserIds(const std::string rmtNetworkId,const std::vector<uint32_t> & foregroundUserIds,const std::vector<uint32_t> & backgroundUserIds)70 int32_t DMCommTool::SendUserIds(const std::string rmtNetworkId,
71     const std::vector<uint32_t> &foregroundUserIds, const std::vector<uint32_t> &backgroundUserIds)
72 {
73     if (!IsIdLengthValid(rmtNetworkId) || foregroundUserIds.empty() || dmTransportPtr_ == nullptr) {
74         LOGE("param invalid, networkId: %{public}s, foreground userids size: %{public}d",
75             GetAnonyString(rmtNetworkId).c_str(), static_cast<int32_t>(foregroundUserIds.size()));
76         return ERR_DM_INPUT_PARA_INVALID;
77     }
78     int32_t socketId;
79     if (dmTransportPtr_->StartSocket(rmtNetworkId, socketId) != DM_OK || socketId <= 0) {
80         LOGE("Start socket error");
81         return ERR_DM_FAILED;
82     }
83 
84     UserIdsMsg userIdsMsg(foregroundUserIds, backgroundUserIds);
85     cJSON *root = cJSON_CreateObject();
86     if (root == nullptr) {
87         LOGE("Create cJSON object failed.");
88         return ERR_DM_FAILED;
89     }
90     ToJson(root, userIdsMsg);
91     char *msg = cJSON_PrintUnformatted(root);
92     if (msg == nullptr) {
93         cJSON_Delete(root);
94         return ERR_DM_FAILED;
95     }
96     std::string msgStr(msg);
97     cJSON_Delete(root);
98     cJSON_free(msg);
99     CommMsg commMsg(DM_COMM_SEND_LOCAL_USERIDS, msgStr);
100     std::string payload = GetCommMsgString(commMsg);
101 
102     int32_t ret = dmTransportPtr_->Send(rmtNetworkId, payload, socketId);
103     if (ret != DM_OK) {
104         LOGE("Send local foreground userids failed, ret: %{public}d", ret);
105         return ERR_DM_FAILED;
106     }
107     LOGI("Send local foreground userids success");
108     return DM_OK;
109 }
110 
RspLocalFrontOrBackUserIds(const std::string rmtNetworkId,const std::vector<uint32_t> & foregroundUserIds,const std::vector<uint32_t> & backgroundUserIds,int32_t socketId)111 void DMCommTool::RspLocalFrontOrBackUserIds(const std::string rmtNetworkId,
112     const std::vector<uint32_t> &foregroundUserIds, const std::vector<uint32_t> &backgroundUserIds, int32_t socketId)
113 {
114     UserIdsMsg userIdsMsg(foregroundUserIds, backgroundUserIds);
115     cJSON *root = cJSON_CreateObject();
116     if (root == nullptr) {
117         LOGE("Create cJSON object failed.");
118         return;
119     }
120     ToJson(root, userIdsMsg);
121     char *msg = cJSON_PrintUnformatted(root);
122     if (msg == nullptr) {
123         cJSON_Delete(root);
124         return;
125     }
126     std::string msgStr(msg);
127     cJSON_Delete(root);
128     cJSON_free(msg);
129     CommMsg commMsg(DM_COMM_RSP_LOCAL_USERIDS, msgStr);
130     std::string payload = GetCommMsgString(commMsg);
131 
132     int32_t ret = dmTransportPtr_->Send(rmtNetworkId, payload, socketId);
133     if (ret != DM_OK) {
134         LOGE("Response local foreground userids failed, ret: %{public}d", ret);
135         return;
136     }
137     LOGI("Response local foreground userids success");
138 }
139 
DMCommToolEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> runner,std::shared_ptr<DMCommTool> dmCommToolPtr)140 DMCommTool::DMCommToolEventHandler::DMCommToolEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> runner,
141     std::shared_ptr<DMCommTool> dmCommToolPtr) : AppExecFwk::EventHandler(runner), dmCommToolWPtr_(dmCommToolPtr)
142 {
143     LOGI("Ctor DMCommToolEventHandler");
144 }
145 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)146 void DMCommTool::DMCommToolEventHandler::ProcessEvent(
147     const AppExecFwk::InnerEvent::Pointer &event)
148 {
149     uint32_t eventId = event->GetInnerEventId();
150     std::shared_ptr<InnerCommMsg> commMsg = event->GetSharedObject<InnerCommMsg>();
151     if (commMsg == nullptr) {
152         LOGE("ProcessEvent commMsg is null");
153         return;
154     }
155     if (dmCommToolWPtr_.expired()) {
156         LOGE("dmCommToolWPtr_ is expired");
157         return;
158     }
159     std::shared_ptr<DMCommTool> dmCommToolPtr = dmCommToolWPtr_.lock();
160     if (dmCommToolPtr == nullptr) {
161         LOGE("dmCommToolPtr is null");
162         return;
163     }
164     switch (eventId) {
165         case DM_COMM_SEND_LOCAL_USERIDS: {
166             // Process remote foreground userids and send back local user ids
167             dmCommToolPtr->ProcessReceiveUserIdsEvent(commMsg);
168             break;
169         }
170         case DM_COMM_RSP_LOCAL_USERIDS: {
171             // Process remote foreground userids and close session
172             dmCommToolPtr->ProcessResponseUserIdsEvent(commMsg);
173             break;
174         }
175         case DM_COMM_SEND_USER_STOP: {
176             dmCommToolPtr->ProcessReceiveUserStopEvent(commMsg);
177             break;
178         }
179         case DM_COMM_RSP_USER_STOP: {
180             dmCommToolPtr->ProcessResponseUserStopEvent(commMsg);
181             break;
182         }
183         case DM_COMM_ACCOUNT_LOGOUT: {
184             dmCommToolPtr->ProcessReceiveLogoutEvent(commMsg);
185             break;
186         }
187         default:
188             LOGE("event is undefined, id is %{public}d", eventId);
189             break;
190     }
191 }
192 
ProcessReceiveUserIdsEvent(const std::shared_ptr<InnerCommMsg> commMsg)193 void DMCommTool::ProcessReceiveUserIdsEvent(const std::shared_ptr<InnerCommMsg> commMsg)
194 {
195     LOGI("Receive remote userids, process and rsp local userid");
196     std::string rmtUdid = "";
197     SoftbusCache::GetInstance().GetUdidFromCache(commMsg->remoteNetworkId.c_str(), rmtUdid);
198     if (rmtUdid.empty()) {
199         LOGE("Can not find remote udid by networkid: %{public}s", commMsg->remoteNetworkId.c_str());
200         return;
201     }
202 
203     std::string payload = commMsg->commMsg->msg;
204     cJSON *root = cJSON_Parse(payload.c_str());
205     if (root == NULL) {
206         LOGE("the msg is not json format");
207         return;
208     }
209     UserIdsMsg userIdsMsg;
210     FromJson(root, userIdsMsg);
211     cJSON_Delete(root);
212     uint32_t totalUserNum = static_cast<uint32_t>(userIdsMsg.foregroundUserIds.size()) +
213         static_cast<uint32_t>(userIdsMsg.backgroundUserIds.size());
214 
215     // step1: send back local userids
216     std::vector<int32_t> foregroundUserIds;
217     std::vector<int32_t> backgroundUserIds;
218     MultipleUserConnector::GetForegroundUserIds(foregroundUserIds);
219     MultipleUserConnector::GetBackgroundUserIds(backgroundUserIds);
220     if (DeviceManagerService::GetInstance().IsPC()) {
221         MultipleUserConnector::ClearLockedUser(foregroundUserIds, backgroundUserIds);
222     }
223     std::vector<uint32_t> foregroundUserIdsU32;
224     std::vector<uint32_t> backgroundUserIdsU32;
225     for (auto const &u : foregroundUserIds) {
226         foregroundUserIdsU32.push_back(static_cast<uint32_t>(u));
227     }
228     for (auto const &u : backgroundUserIds) {
229         backgroundUserIdsU32.push_back(static_cast<uint32_t>(u));
230     }
231     RspLocalFrontOrBackUserIds(commMsg->remoteNetworkId, foregroundUserIdsU32, backgroundUserIdsU32,
232         commMsg->socketId);
233 
234     if (userIdsMsg.foregroundUserIds.empty()) {
235         LOGE("Parse but get none remote foreground userids");
236     } else {
237         // step2: process remote foreground/background userids
238         DeviceManagerService::GetInstance().ProcessSyncUserIds(userIdsMsg.foregroundUserIds,
239             userIdsMsg.backgroundUserIds, rmtUdid);
240     }
241 }
242 
ProcessResponseUserIdsEvent(const std::shared_ptr<InnerCommMsg> commMsg)243 void DMCommTool::ProcessResponseUserIdsEvent(const std::shared_ptr<InnerCommMsg> commMsg)
244 {
245     LOGI("process receive remote userids response");
246     // step1: close socket
247     this->dmTransportPtr_->StopSocket(commMsg->remoteNetworkId);
248 
249     std::string rmtUdid = "";
250     SoftbusCache::GetInstance().GetUdidFromCache(commMsg->remoteNetworkId.c_str(), rmtUdid);
251     if (rmtUdid.empty()) {
252         LOGE("Can not find remote udid by networkid: %{public}s", commMsg->remoteNetworkId.c_str());
253         return;
254     }
255 
256     std::string payload = commMsg->commMsg->msg;
257     cJSON *root = cJSON_Parse(payload.c_str());
258     if (root == NULL) {
259         LOGE("the msg is not json format");
260         return;
261     }
262     UserIdsMsg userIdsMsg;
263     FromJson(root, userIdsMsg);
264     cJSON_Delete(root);
265     if (userIdsMsg.foregroundUserIds.empty()) {
266         LOGE("Parse but get none remote userids");
267         return;
268     }
269     // step2: process remote foreground/background userids
270     if (!userIdsMsg.foregroundUserIds.empty()) {
271         DeviceManagerService::GetInstance().ProcessSyncUserIds(userIdsMsg.foregroundUserIds,
272             userIdsMsg.backgroundUserIds, rmtUdid);
273     } else {
274         LOGE("Receive remote foreground userid empty");
275     }
276 }
277 
GetEventHandler()278 std::shared_ptr<DMCommTool::DMCommToolEventHandler> DMCommTool::GetEventHandler()
279 {
280     return this->eventHandler_;
281 }
282 
GetDMTransportPtr()283 const std::shared_ptr<DMTransport> DMCommTool::GetDMTransportPtr()
284 {
285     return this->dmTransportPtr_;
286 }
287 
CreateUserStopMessage(int32_t stopUserId,std::string & msgStr)288 int32_t DMCommTool::CreateUserStopMessage(int32_t stopUserId, std::string &msgStr)
289 {
290     cJSON *root = cJSON_CreateObject();
291     if (root == nullptr) {
292         LOGE("Create cJSON object failed.");
293         return ERR_DM_FAILED;
294     }
295     cJSON *numberObj = cJSON_CreateNumber(stopUserId);
296     if (numberObj == nullptr) {
297         cJSON_Delete(root);
298         return ERR_DM_FAILED;
299     }
300     cJSON_AddItemToObject(root, USER_STOP_MSG_KEY, numberObj);
301     char *msg = cJSON_PrintUnformatted(root);
302     if (msg == nullptr) {
303         cJSON_Delete(root);
304         return ERR_DM_FAILED;
305     }
306     msgStr = std::string(msg);
307     cJSON_free(msg);
308     cJSON_Delete(root);
309     return DM_OK;
310 }
311 
ParseUserStopMessage(const std::string & msgStr,int32_t & stopUserId)312 int32_t DMCommTool::ParseUserStopMessage(const std::string &msgStr, int32_t &stopUserId)
313 {
314     cJSON *root = cJSON_Parse(msgStr.c_str());
315     if (root == NULL) {
316         LOGE("the msg is not json format");
317         return ERR_DM_FAILED;
318     }
319     cJSON *stopUserIdObj = cJSON_GetObjectItem(root, USER_STOP_MSG_KEY);
320     if (stopUserIdObj == NULL || !cJSON_IsNumber(stopUserIdObj)) {
321         LOGE("parse stopUserId id failed.");
322         cJSON_Delete(root);
323         return ERR_DM_FAILED;
324     }
325     stopUserId = static_cast<int32_t>(stopUserIdObj->valueint);
326     cJSON_Delete(root);
327     return DM_OK;
328 }
329 
SendUserStop(const std::string rmtNetworkId,int32_t stopUserId)330 int32_t DMCommTool::SendUserStop(const std::string rmtNetworkId, int32_t stopUserId)
331 {
332     std::string msgStr;
333     int32_t ret = CreateUserStopMessage(stopUserId, msgStr);
334     if (ret != DM_OK) {
335         LOGE("error ret: %{public}d", ret);
336         return ret;
337     }
338     return SendMsg(rmtNetworkId, DM_COMM_SEND_USER_STOP, msgStr);
339 }
340 
SendMsg(const std::string rmtNetworkId,int32_t msgType,const std::string & msg)341 int32_t DMCommTool::SendMsg(const std::string rmtNetworkId, int32_t msgType, const std::string &msg)
342 {
343     if (!IsIdLengthValid(rmtNetworkId) || dmTransportPtr_ == nullptr) {
344         LOGE("param invalid, networkId: %{public}s", GetAnonyString(rmtNetworkId).c_str());
345         return ERR_DM_INPUT_PARA_INVALID;
346     }
347     int32_t socketId;
348     if (dmTransportPtr_->StartSocket(rmtNetworkId, socketId) != DM_OK || socketId <= 0) {
349         LOGE("Start socket error");
350         return ERR_DM_FAILED;
351     }
352     CommMsg commMsg(msgType, msg);
353     std::string payload = GetCommMsgString(commMsg);
354     int32_t ret = dmTransportPtr_->Send(rmtNetworkId, payload, socketId);
355     if (ret != DM_OK) {
356         LOGE("SendMsg failed, ret: %{public}d", ret);
357         return ERR_DM_FAILED;
358     }
359     LOGI("SendMsg success");
360     return DM_OK;
361 }
362 
ProcessReceiveUserStopEvent(const std::shared_ptr<InnerCommMsg> commMsg)363 void DMCommTool::ProcessReceiveUserStopEvent(const std::shared_ptr<InnerCommMsg> commMsg)
364 {
365     LOGI("start");
366     CHECK_NULL_VOID(commMsg);
367     std::string rmtUdid = "";
368     SoftbusCache::GetInstance().GetUdidFromCache(commMsg->remoteNetworkId.c_str(), rmtUdid);
369     if (rmtUdid.empty()) {
370         LOGE("Can not find remote udid by networkid: %{public}s", GetAnonyString(commMsg->remoteNetworkId).c_str());
371         return;
372     }
373     int32_t stopUserId = -1;
374     int32_t ret = ParseUserStopMessage(commMsg->commMsg->msg, stopUserId);
375     if (ret != DM_OK) {
376         LOGE("ParseUserStopMessage error ret: %{public}d", ret);
377         return;
378     }
379     RspUserStop(commMsg->remoteNetworkId, commMsg->socketId, stopUserId);
380     DeviceManagerService::GetInstance().HandleUserStop(stopUserId, rmtUdid);
381 }
382 
RspUserStop(const std::string rmtNetworkId,int32_t socketId,int32_t stopUserId)383 void DMCommTool::RspUserStop(const std::string rmtNetworkId, int32_t socketId, int32_t stopUserId)
384 {
385     std::string msgStr = "";
386     CHECK_NULL_VOID(dmTransportPtr_);
387     int32_t ret = CreateUserStopMessage(stopUserId, msgStr);
388     if (ret != DM_OK || msgStr.empty()) {
389         LOGE("error ret: %{public}d", ret);
390         return;
391     }
392     CommMsg commMsg(DM_COMM_RSP_USER_STOP, msgStr);
393     std::string payload = GetCommMsgString(commMsg);
394     ret = dmTransportPtr_->Send(rmtNetworkId, payload, socketId);
395     if (ret != DM_OK) {
396         LOGE("failed, ret: %{public}d", ret);
397         return;
398     }
399     LOGI("success");
400 }
401 
ProcessResponseUserStopEvent(const std::shared_ptr<InnerCommMsg> commMsg)402 void DMCommTool::ProcessResponseUserStopEvent(const std::shared_ptr<InnerCommMsg> commMsg)
403 {
404     LOGI("start");
405     CHECK_NULL_VOID(commMsg);
406     this->dmTransportPtr_->StopSocket(commMsg->remoteNetworkId);
407     std::string rmtUdid = "";
408     SoftbusCache::GetInstance().GetUdidFromCache(commMsg->remoteNetworkId.c_str(), rmtUdid);
409     if (rmtUdid.empty()) {
410         LOGE("Can not find remote udid by networkid: %{public}s", GetAnonyString(commMsg->remoteNetworkId).c_str());
411         return;
412     }
413     int32_t stopUserId = -1;
414     int32_t ret = ParseUserStopMessage(commMsg->commMsg->msg, stopUserId);
415     if (ret != DM_OK) {
416         LOGE("ParseUserStopMessage error ret: %{public}d", ret);
417         return;
418     }
419     std::vector<std::string> acceptEventUdids;
420     acceptEventUdids.push_back(rmtUdid);
421     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
422     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
423     std::string localUdid = static_cast<std::string>(localDeviceId);
424     DeviceManagerService::GetInstance().HandleUserStop(stopUserId, localUdid, acceptEventUdids);
425 }
426 
SendLogoutAccountInfo(const std::string & rmtNetworkId,const std::string & accountId,int32_t userId)427 int32_t DMCommTool::SendLogoutAccountInfo(const std::string &rmtNetworkId,
428     const std::string &accountId, int32_t userId)
429 {
430     if (!IsIdLengthValid(rmtNetworkId) || accountId.empty() || dmTransportPtr_ == nullptr) {
431         LOGE("param invalid, networkId: %{public}s, userId: %{public}d",
432             GetAnonyString(rmtNetworkId).c_str(), userId);
433         return ERR_DM_INPUT_PARA_INVALID;
434     }
435     LOGI("Start, send networkId: %{public}s", GetAnonyString(rmtNetworkId).c_str());
436     int32_t socketId = 0;
437     if (dmTransportPtr_->StartSocket(rmtNetworkId, socketId) != DM_OK || socketId <= 0) {
438         LOGE("Start socket error");
439         return ERR_DM_FAILED;
440     }
441 
442     cJSON *root = cJSON_CreateObject();
443     if (root == nullptr) {
444         LOGE("Create cJSON object failed.");
445         return ERR_DM_FAILED;
446     }
447     LogoutAccountMsg LogoutAccountMsg(accountId, userId);
448     ToJson(root, LogoutAccountMsg);
449     char *msg = cJSON_PrintUnformatted(root);
450     if (msg == nullptr) {
451         cJSON_Delete(root);
452         return ERR_DM_FAILED;
453     }
454     std::string msgStr(msg);
455     cJSON_Delete(root);
456     cJSON_free(msg);
457     CommMsg commMsg(DM_COMM_ACCOUNT_LOGOUT, msgStr);
458     std::string payload = GetCommMsgString(commMsg);
459 
460     int32_t ret = dmTransportPtr_->Send(rmtNetworkId, payload, socketId);
461     if (ret != DM_OK) {
462         LOGE("Send account logout failed, ret: %{public}d", ret);
463         return ERR_DM_FAILED;
464     }
465     LOGI("Send account logout success");
466     return DM_OK;
467 }
468 
ProcessReceiveLogoutEvent(const std::shared_ptr<InnerCommMsg> commMsg)469 void DMCommTool::ProcessReceiveLogoutEvent(const std::shared_ptr<InnerCommMsg> commMsg)
470 {
471     CHECK_NULL_VOID(commMsg);
472     LOGI("Receive remote logout, networkId: %{public}s", GetAnonyString(commMsg->remoteNetworkId).c_str());
473     std::string rmtUdid = "";
474     SoftbusCache::GetInstance().GetUdidFromCache(commMsg->remoteNetworkId.c_str(), rmtUdid);
475     if (rmtUdid.empty()) {
476         LOGE("Can not find remote udid by networkid: %{public}s", GetAnonyString(commMsg->remoteNetworkId).c_str());
477         return;
478     }
479 
480     CHECK_NULL_VOID(commMsg->commMsg);
481     std::string payload = commMsg->commMsg->msg;
482     cJSON *root = cJSON_Parse(payload.c_str());
483     if (root == NULL) {
484         LOGE("the msg is not json format");
485         return;
486     }
487     LogoutAccountMsg logoutAccountMsg;
488     FromJson(root, logoutAccountMsg);
489     cJSON_Delete(root);
490 
491     if (logoutAccountMsg.accountId.empty() || logoutAccountMsg.userId == -1) {
492         LOGE("param invalid, accountId: %{public}s, userId: %{public}d",
493             GetAnonyString(logoutAccountMsg.accountId).c_str(), logoutAccountMsg.userId);
494         return;
495     }
496     DeviceManagerService::GetInstance().ProcessSyncAccountLogout(logoutAccountMsg.accountId,
497         rmtUdid, logoutAccountMsg.userId);
498     LOGI("process remote logout success.");
499 }
500 } // DistributedHardware
501 } // OHOS