• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 "hichain_connector.h"
17 
18 #include <cstdlib>
19 #include <ctime>
20 #include <functional>
21 #include <securec.h>
22 
23 #include "dm_anonymous.h"
24 #include "dm_constants.h"
25 #include "dm_dfx_constants.h"
26 #include "dm_hisysevent.h"
27 #include "dm_log.h"
28 #include "dm_random.h"
29 #include "dm_radar_helper.h"
30 #include "hichain_connector_callback.h"
31 #include "multiple_user_connector.h"
32 #include "json_object.h"
33 #include "parameter.h"
34 #include "unistd.h"
35 
36 namespace OHOS {
37 namespace DistributedHardware {
38 const int32_t PIN_CODE_NETWORK = 0;
39 const int32_t CREDENTIAL_NETWORK = 1;
40 const int32_t DELAY_TIME_MS = 10000; // 10ms
41 const int32_t FIELD_EXPIRE_TIME_VALUE = 7;
42 const int32_t SAME_ACCOUNT = 1;
43 const int32_t DEVICE_ID_HALF = 2;
44 
45 constexpr const char* DEVICE_ID = "DEVICE_ID";
46 constexpr const char* FIELD_CREDENTIAL = "credential";
47 constexpr const char* ADD_HICHAIN_GROUP_SUCCESS = "ADD_HICHAIN_GROUP_SUCCESS";
48 constexpr const char* ADD_HICHAIN_GROUP_FAILED = "ADD_HICHAIN_GROUP_FAILED";
49 constexpr const char* DM_CREATE_GROUP_SUCCESS = "DM_CREATE_GROUP_SUCCESS";
50 constexpr const char* DM_CREATE_GROUP_FAILED = "DM_CREATE_GROUP_FAILED";
51 constexpr const char* ADD_HICHAIN_GROUP_SUCCESS_MSG = "dm add member to group success.";
52 constexpr const char* ADD_HICHAIN_GROUP_FAILED_MSG = "dm add member to group failed.";
53 constexpr const char* DM_CREATE_GROUP_SUCCESS_MSG = "dm create group success.";
54 constexpr const char* DM_CREATE_GROUP_FAILED_MSG = "dm create group failed.";
55 constexpr const char* DM_PKG_NAME_EXT = "com.huawei.devicemanager";
56 constexpr const char* FIELD_OPERATION_CODE = "operationCode";
57 constexpr const char* FIELD_META_NODE_TYPE = "metaNodeType";
58 constexpr const char* FIELD_TYPE = "TType";
59 
60 static const std::unordered_map<int32_t, AuthFormPriority> g_authFormPriorityMap = {
61     {GROUP_TYPE_IDENTICAL_ACCOUNT_GROUP, AuthFormPriority::PRIORITY_IDENTICAL_ACCOUNT},
62     {GROUP_TYPE_ACROSS_ACCOUNT_GROUP, AuthFormPriority::PRIORITY_ACROSS_ACCOUNT},
63     {GROUP_TYPE_PEER_TO_PEER_GROUP, AuthFormPriority::PRIORITY_PEER_TO_PEER}
64 };
65 
FromJson(const JsonItemObject & jsonObject,GroupInfo & groupInfo)66 void FromJson(const JsonItemObject &jsonObject, GroupInfo &groupInfo)
67 {
68     if (jsonObject.Contains(FIELD_GROUP_NAME) && jsonObject.At(FIELD_GROUP_NAME).IsString()) {
69         groupInfo.groupName = jsonObject.At(FIELD_GROUP_NAME).Get<std::string>();
70     }
71 
72     if (jsonObject.Contains(FIELD_GROUP_ID) && jsonObject.At(FIELD_GROUP_ID).IsString()) {
73         groupInfo.groupId = jsonObject.At(FIELD_GROUP_ID).Get<std::string>();
74     }
75 
76     if (jsonObject.Contains(FIELD_GROUP_OWNER) && jsonObject.At(FIELD_GROUP_OWNER).IsString()) {
77         groupInfo.groupOwner = jsonObject.At(FIELD_GROUP_OWNER).Get<std::string>();
78     }
79 
80     if (jsonObject.Contains(FIELD_GROUP_TYPE) && jsonObject.At(FIELD_GROUP_TYPE).IsNumberInteger()) {
81         groupInfo.groupType = jsonObject.At(FIELD_GROUP_TYPE).Get<int32_t>();
82     }
83 
84     if (jsonObject.Contains(FIELD_GROUP_VISIBILITY) &&
85         jsonObject.At(FIELD_GROUP_VISIBILITY).IsNumberInteger()) {
86         groupInfo.groupVisibility = jsonObject.At(FIELD_GROUP_VISIBILITY).Get<int32_t>();
87     }
88 
89     if (jsonObject.Contains(FIELD_USER_ID) && jsonObject.At(FIELD_USER_ID).IsString()) {
90         groupInfo.userId = jsonObject.At(FIELD_USER_ID).Get<std::string>();
91     }
92 }
93 
94 std::shared_ptr<IHiChainConnectorCallback> HiChainConnector::hiChainConnectorCallback_ = nullptr;
95 std::shared_ptr<IDmGroupResCallback> HiChainConnector::hiChainResCallback_ = nullptr;
96 int32_t HiChainConnector::networkStyle_ = PIN_CODE_NETWORK;
97 bool g_createGroupFlag = false;
98 bool g_deleteGroupFlag = false;
99 bool g_groupIsRedundance = false;
100 
HiChainConnector()101 HiChainConnector::HiChainConnector()
102 {
103     LOGI("HiChainConnector::constructor");
104     deviceAuthCallback_ = {.onTransmit = nullptr,
105                            .onSessionKeyReturned = nullptr,
106                            .onFinish = HiChainConnector::onFinish,
107                            .onError = HiChainConnector::onError,
108                            .onRequest = HiChainConnector::onRequest};
109     deviceGroupManager_ = GetGmInstance();
110     if (deviceGroupManager_ == nullptr) {
111         LOGE("[HICHAIN]failed to init group manager.");
112         return;
113     }
114     int32_t ret = deviceGroupManager_->regCallback(DM_PKG_NAME, &deviceAuthCallback_);
115     if (ret != HC_SUCCESS) {
116         LOGE("[HICHAIN]fail to register callback to hachain with ret:%{public}d.", ret);
117         return;
118     }
119     LOGI("HiChainConnector::constructor success.");
120 }
121 
~HiChainConnector()122 HiChainConnector::~HiChainConnector()
123 {
124     LOGI("HiChainConnector::destructor.");
125 }
126 
RegisterHiChainCallback(std::shared_ptr<IHiChainConnectorCallback> callback)127 int32_t HiChainConnector::RegisterHiChainCallback(std::shared_ptr<IHiChainConnectorCallback> callback)
128 {
129     hiChainConnectorCallback_ = callback;
130     return DM_OK;
131 }
132 
UnRegisterHiChainCallback()133 int32_t HiChainConnector::UnRegisterHiChainCallback()
134 {
135     hiChainConnectorCallback_ = nullptr;
136     return DM_OK;
137 }
138 
CreateGroup(int64_t requestId,const std::string & groupName)139 int32_t HiChainConnector::CreateGroup(int64_t requestId, const std::string &groupName)
140 {
141     if (deviceGroupManager_ == nullptr) {
142         LOGE("HiChainConnector::CreateGroup group manager is null, requestId %{public}" PRId64, requestId);
143         return ERR_DM_INPUT_PARA_INVALID;
144     }
145     networkStyle_ = PIN_CODE_NETWORK;
146     GroupInfo groupInfo;
147     if (IsGroupCreated(groupName, groupInfo)) {
148         DeleteGroup(groupInfo.groupId);
149     }
150     LOGI("HiChainConnector::CreateGroup requestId %{public}" PRId64, requestId);
151     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
152     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
153     std::string sLocalDeviceId = localDeviceId;
154     JsonObject jsonObj;
155     jsonObj[FIELD_GROUP_TYPE] = GROUP_TYPE_PEER_TO_PEER_GROUP;
156     jsonObj[FIELD_DEVICE_ID] = sLocalDeviceId;
157     jsonObj[FIELD_GROUP_NAME] = groupName;
158     jsonObj[FIELD_USER_TYPE] = 0;
159     jsonObj[FIELD_GROUP_VISIBILITY] = GROUP_VISIBILITY_PUBLIC;
160     jsonObj[FIELD_EXPIRE_TIME] = FIELD_EXPIRE_TIME_VALUE;
161     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
162     if (userId < 0) {
163         LOGE("get current process account user id failed");
164         return ERR_DM_FAILED;
165     }
166     int32_t ret = deviceGroupManager_->createGroup(userId, requestId, DM_PKG_NAME, SafetyDump(jsonObj).c_str());
167     struct RadarInfo info = {
168         .funcName = "CreateGroup",
169         .toCallPkg = HICHAINNAME,
170         .stageRes = (ret != 0) ?
171             static_cast<int32_t>(StageRes::STAGE_FAIL) : static_cast<int32_t>(StageRes::STAGE_IDLE),
172         .bizState = (ret != 0) ?
173             static_cast<int32_t>(BizState::BIZ_STATE_END) : static_cast<int32_t>(BizState::BIZ_STATE_START),
174         .errCode = DmRadarHelper::GetInstance().GetErrCode(ERR_DM_CREATE_GROUP_FAILED),
175     };
176     if (!DmRadarHelper::GetInstance().ReportAuthCreateGroup(info)) {
177         LOGE("ReportAuthCreateGroup failed");
178     }
179     if (ret != 0) {
180         LOGE("[HICHAIN]fail to create group with ret:%{public}d, requestId:%{public}" PRId64, ret, requestId);
181         return ERR_DM_CREATE_GROUP_FAILED;
182     }
183     return DM_OK;
184 }
185 
IsGroupCreated(std::string groupName,GroupInfo & groupInfo)186 bool HiChainConnector::IsGroupCreated(std::string groupName, GroupInfo &groupInfo)
187 {
188     JsonObject jsonObj;
189     jsonObj[FIELD_GROUP_NAME] = groupName.c_str();
190     std::string queryParams = SafetyDump(jsonObj);
191     std::vector<GroupInfo> groupList;
192     if (GetGroupInfo(queryParams, groupList)) {
193         groupInfo = groupList[0];
194         return true;
195     }
196     return false;
197 }
198 
IsRedundanceGroup(const std::string & userId,int32_t authType,std::vector<GroupInfo> & groupList)199 bool HiChainConnector::IsRedundanceGroup(const std::string &userId, int32_t authType, std::vector<GroupInfo> &groupList)
200 {
201     JsonObject jsonObj;
202     jsonObj[FIELD_GROUP_TYPE] = authType;
203     std::string queryParams = SafetyDump(jsonObj);
204 
205     int32_t osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
206     if (osAccountUserId < 0) {
207         LOGE("get current process account user id failed");
208         return ERR_DM_FAILED;
209     }
210     if (!GetGroupInfo(osAccountUserId, queryParams, groupList)) {
211         return false;
212     }
213     for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
214         if (iter->userId != userId) {
215             return true;
216         }
217     }
218     return false;
219 }
220 
GetGroupInfo(const std::string & queryParams,std::vector<GroupInfo> & groupList)221 bool HiChainConnector::GetGroupInfo(const std::string &queryParams, std::vector<GroupInfo> &groupList)
222 {
223     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
224     if (userId < 0) {
225         LOGE("get current process account user id failed");
226         return false;
227     }
228     return GetGroupInfo(userId, queryParams, groupList);
229 }
230 
GetGroupInfo(const int32_t userId,const std::string & queryParams,std::vector<GroupInfo> & groupList)231 bool HiChainConnector::GetGroupInfo(const int32_t userId, const std::string &queryParams,
232     std::vector<GroupInfo> &groupList)
233 {
234     return GetGroupInfoCommon(userId, queryParams, DM_PKG_NAME, groupList);
235 }
236 
GetGroupInfoExt(const int32_t userId,const std::string & queryParams,std::vector<GroupInfo> & groupList)237 bool HiChainConnector::GetGroupInfoExt(const int32_t userId, const std::string &queryParams,
238     std::vector<GroupInfo> &groupList)
239 {
240     return GetGroupInfoCommon(userId, queryParams, DM_PKG_NAME_EXT, groupList);
241 }
242 
GetGroupInfoCommon(const int32_t userId,const std::string & queryParams,const char * pkgName,std::vector<GroupInfo> & groupList)243 bool HiChainConnector::GetGroupInfoCommon(const int32_t userId, const std::string &queryParams, const char* pkgName,
244     std::vector<GroupInfo> &groupList)
245 {
246     char *groupVec = nullptr;
247     uint32_t num = 0;
248     if (deviceGroupManager_ == nullptr) {
249         LOGE("deviceGroupManager_ is null");
250         return false;
251     }
252     int32_t ret = deviceGroupManager_->getGroupInfo(userId, pkgName, queryParams.c_str(), &groupVec, &num);
253     if (ret != 0) {
254         LOGE("[HICHAIN]fail to get group info with ret:%{public}d.", ret);
255         deviceGroupManager_->destroyInfo(&groupVec);
256         return false;
257     }
258     if (groupVec == nullptr) {
259         LOGE("[HICHAIN]return groups info point is nullptr");
260         return false;
261     }
262     if (num == 0) {
263         LOGE("[HICHAIN]return groups info number is zero.");
264         deviceGroupManager_->destroyInfo(&groupVec);
265         return false;
266     }
267     LOGI("HiChainConnector::GetGroupInfo groupNum(%{public}u)", num);
268     std::string relatedGroups = std::string(groupVec);
269     deviceGroupManager_->destroyInfo(&groupVec);
270     JsonObject jsonObject(relatedGroups);
271     if (jsonObject.IsDiscarded()) {
272         LOGE("returnGroups parse error");
273         return false;
274     }
275     if (!jsonObject.IsArray()) {
276         LOGE("json string is not array.");
277         return false;
278     }
279     std::vector<GroupInfo> groupInfos;
280     jsonObject.Get(groupInfos);
281     if (groupInfos.empty()) {
282         LOGE("HiChainConnector::GetGroupInfo group failed, groupInfos is empty.");
283         return false;
284     }
285     groupList = groupInfos;
286     return true;
287 }
288 
GetGroupType(const std::string & deviceId)289 DmAuthForm HiChainConnector::GetGroupType(const std::string &deviceId)
290 {
291     std::vector<OHOS::DistributedHardware::GroupInfo> groupList;
292     int32_t ret = GetRelatedGroups(deviceId, groupList);
293     if (ret != DM_OK) {
294         LOGE("HiChainConnector::GetGroupType get related groups failed");
295         return DmAuthForm::INVALID_TYPE;
296     }
297 
298     if (groupList.size() == 0) {
299         LOGE("HiChainConnector::GetGroupType group list is empty");
300         return DmAuthForm::INVALID_TYPE;
301     }
302 
303     AuthFormPriority highestPriority = AuthFormPriority::PRIORITY_PEER_TO_PEER;
304     for (auto it = groupList.begin(); it != groupList.end(); ++it) {
305         if (g_authFormPriorityMap.count(it->groupType) == 0) {
306             LOGE("HiChainConnector::GetGroupType unsupported auth form");
307             return DmAuthForm::INVALID_TYPE;
308         }
309         AuthFormPriority priority = g_authFormPriorityMap.at(it->groupType);
310         if (priority > highestPriority) {
311             highestPriority = priority;
312         }
313     }
314 
315     if (highestPriority == AuthFormPriority::PRIORITY_IDENTICAL_ACCOUNT) {
316         return DmAuthForm::IDENTICAL_ACCOUNT;
317     } else if (highestPriority == AuthFormPriority::PRIORITY_ACROSS_ACCOUNT) {
318         return DmAuthForm::ACROSS_ACCOUNT;
319     } else if (highestPriority == AuthFormPriority::PRIORITY_PEER_TO_PEER) {
320         return DmAuthForm::PEER_TO_PEER;
321     }
322 
323     return DmAuthForm::INVALID_TYPE;
324 }
325 
AddMember(const std::string & deviceId,const std::string & connectInfo)326 int32_t HiChainConnector::AddMember(const std::string &deviceId, const std::string &connectInfo)
327 {
328     LOGI("HiChainConnector::AddMember");
329     if (deviceGroupManager_ == nullptr) {
330         LOGI("HiChainConnector::AddMember group manager is null.");
331         return ERR_DM_POINT_NULL;
332     }
333     JsonObject jsonObject(connectInfo);
334     if (jsonObject.IsDiscarded()) {
335         LOGE("DecodeRequestAuth jsonStr error");
336         return ERR_DM_FAILED;
337     }
338     if (!IsString(jsonObject, TAG_DEVICE_ID) || !IsInt32(jsonObject, PIN_CODE_KEY) ||
339         !IsString(jsonObject, TAG_GROUP_ID) || !IsInt64(jsonObject, TAG_REQUEST_ID) ||
340         !IsString(jsonObject, TAG_GROUP_NAME)) {
341         LOGE("HiChainConnector::AddMember err json string.");
342         return ERR_DM_FAILED;
343     }
344     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
345     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
346     std::string connectInfomation = GetConnectPara(deviceId, jsonObject[TAG_DEVICE_ID].Get<std::string>());
347 
348     int32_t pinCode = jsonObject[PIN_CODE_KEY].Get<int32_t>();
349     std::string groupId = jsonObject[TAG_GROUP_ID].Get<std::string>();
350     JsonObject jsonObj;
351     jsonObj[FIELD_GROUP_ID] = groupId;
352     jsonObj[FIELD_GROUP_TYPE] = GROUP_TYPE_PEER_TO_PEER_GROUP;
353     jsonObj[FIELD_PIN_CODE] = std::to_string(pinCode).c_str();
354     jsonObj[FIELD_IS_ADMIN] = false;
355     jsonObj[FIELD_DEVICE_ID] = localDeviceId;
356     jsonObj[FIELD_GROUP_NAME] = jsonObject[TAG_GROUP_NAME].Get<std::string>();
357     jsonObj[FIELD_CONNECT_PARAMS] = connectInfomation.c_str();
358     std::string tmpStr = SafetyDump(jsonObj);
359     int64_t requestId = jsonObject[TAG_REQUEST_ID].Get<int64_t>();
360     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
361     if (userId < 0) {
362         LOGE("get current process account user id failed");
363         return ERR_DM_FAILED;
364     }
365     int32_t ret = deviceGroupManager_->addMemberToGroup(userId, requestId, DM_PKG_NAME, tmpStr.c_str());
366     if (ret != 0) {
367         LOGE("[HICHAIN]fail to add number to hichain group with ret:%{public}d.", ret);
368     }
369     LOGI("HiChainConnector::AddMember completed");
370     return ret;
371 }
372 
onFinish(int64_t requestId,int operationCode,const char * returnData)373 void HiChainConnector::onFinish(int64_t requestId, int operationCode, const char *returnData)
374 {
375     std::string data = (returnData != nullptr) ? std::string(returnData) : "";
376     LOGI("HiChainConnector::onFinish reqId:%{public}" PRId64 ", operation:%{public}d", requestId, operationCode);
377     if (operationCode == GroupOperationCode::MEMBER_JOIN) {
378         LOGI("Add Member To Group success");
379         if (!DmRadarHelper::GetInstance().ReportAuthAddGroupCb(
380             "onFinish", static_cast<int32_t>(StageRes::STAGE_SUCC))) {
381             LOGE("ReportAuthAddGroupCb failed");
382         }
383         SysEventWrite(std::string(ADD_HICHAIN_GROUP_SUCCESS), DM_HISYEVENT_BEHAVIOR,
384             std::string(ADD_HICHAIN_GROUP_SUCCESS_MSG));
385         if (hiChainConnectorCallback_ != nullptr) {
386             hiChainConnectorCallback_->OnMemberJoin(requestId, DM_OK);
387         }
388     }
389     if (operationCode == GroupOperationCode::GROUP_CREATE) {
390         LOGI("Create group success");
391         if (!DmRadarHelper::GetInstance().ReportAuthCreateGroupCb(
392             "onFinish", static_cast<int32_t>(StageRes::STAGE_SUCC))) {
393             LOGE("ReportAuthCreateGroupCb failed");
394         }
395         SysEventWrite(std::string(DM_CREATE_GROUP_SUCCESS), DM_HISYEVENT_BEHAVIOR,
396             std::string(DM_CREATE_GROUP_SUCCESS_MSG));
397         if (networkStyle_ == CREDENTIAL_NETWORK) {
398             if (hiChainResCallback_ != nullptr) {
399                 int32_t importAction = 0;
400                 hiChainResCallback_->OnGroupResult(requestId, importAction, data);
401                 g_createGroupFlag = true;
402             }
403         } else {
404             if (hiChainConnectorCallback_ != nullptr) {
405                 hiChainConnectorCallback_->OnMemberJoin(requestId, DM_OK);
406                 hiChainConnectorCallback_->OnGroupCreated(requestId, data);
407             }
408         }
409     }
410     if (operationCode == GroupOperationCode::MEMBER_DELETE) {
411         LOGI("Delete Member from group success");
412     }
413     if (operationCode == GroupOperationCode::GROUP_DISBAND) {
414         if (networkStyle_ == CREDENTIAL_NETWORK && hiChainResCallback_ != nullptr) {
415             if (!g_groupIsRedundance) {
416                 int32_t deleteAction = 1;
417                 hiChainResCallback_->OnGroupResult(requestId, deleteAction, data);
418             }
419             g_deleteGroupFlag = true;
420         }
421         LOGI("Disband group success");
422     }
423 }
424 
onError(int64_t requestId,int operationCode,int errorCode,const char * errorReturn)425 void HiChainConnector::onError(int64_t requestId, int operationCode, int errorCode, const char *errorReturn)
426 {
427     std::string data = (errorReturn != nullptr) ? std::string(errorReturn) : "";
428     LOGI("HichainAuthenCallBack::onError reqId:%{public}" PRId64 ", operation:%{public}d, errorCode:%{public}d.",
429         requestId, operationCode, errorCode);
430     if (operationCode == GroupOperationCode::MEMBER_JOIN) {
431         LOGE("Add Member To Group failed");
432         if (!DmRadarHelper::GetInstance().ReportAuthAddGroupCb(
433             "onError", static_cast<int32_t>(StageRes::STAGE_FAIL))) {
434             LOGE("ReportAuthAddGroupCb failed");
435         }
436         SysEventWrite(std::string(ADD_HICHAIN_GROUP_FAILED), DM_HISYEVENT_BEHAVIOR,
437             std::string(ADD_HICHAIN_GROUP_FAILED_MSG));
438         if (hiChainConnectorCallback_ != nullptr) {
439             hiChainConnectorCallback_->OnMemberJoin(requestId, ERR_DM_ADD_GROUP_FAILED);
440         }
441     }
442     if (operationCode == GroupOperationCode::GROUP_CREATE) {
443         LOGE("Create group failed");
444         if (!DmRadarHelper::GetInstance().ReportAuthCreateGroupCb(
445             "onError", static_cast<int32_t>(StageRes::STAGE_FAIL))) {
446             LOGE("ReportAuthCreateGroupCb failed");
447         }
448         SysEventWrite(std::string(DM_CREATE_GROUP_FAILED), DM_HISYEVENT_BEHAVIOR,
449             std::string(DM_CREATE_GROUP_FAILED_MSG));
450         if (networkStyle_ == CREDENTIAL_NETWORK) {
451             if (hiChainResCallback_ != nullptr) {
452                 int32_t importAction = 0;
453                 hiChainResCallback_->OnGroupResult(requestId, importAction, data);
454                 g_createGroupFlag = true;
455             }
456         } else {
457             if (hiChainConnectorCallback_ != nullptr) {
458                 hiChainConnectorCallback_->OnGroupCreated(requestId, "{}");
459             }
460         }
461     }
462     if (operationCode == GroupOperationCode::MEMBER_DELETE) {
463         LOGE("Delete Member from group failed");
464     }
465     if (operationCode == GroupOperationCode::GROUP_DISBAND) {
466         if (networkStyle_ == CREDENTIAL_NETWORK && hiChainResCallback_ != nullptr) {
467             if (!g_groupIsRedundance) {
468                 int32_t deleteAction = 1;
469                 hiChainResCallback_->OnGroupResult(requestId, deleteAction, data);
470             }
471             g_deleteGroupFlag = true;
472         }
473         LOGE("Disband group failed");
474     }
475 }
476 
onRequest(int64_t requestId,int operationCode,const char * reqParams)477 char *HiChainConnector::onRequest(int64_t requestId, int operationCode, const char *reqParams)
478 {
479     (void)requestId;
480     (void)reqParams;
481     if (operationCode != GroupOperationCode::MEMBER_JOIN) {
482         LOGE("HiChainConnector::onRequest operationCode %{public}d", operationCode);
483         return nullptr;
484     }
485     if (hiChainConnectorCallback_ == nullptr) {
486         LOGE("HiChainConnector::onRequest hiChainConnectorCallback_ is nullptr.");
487         return nullptr;
488     }
489     JsonObject jsonObj;
490     int32_t pinCode = INVALID_PINCODE;
491     if (hiChainConnectorCallback_->GetPinCode(pinCode) == ERR_DM_FAILED || pinCode == INVALID_PINCODE) {
492         jsonObj[FIELD_CONFIRMATION] = REQUEST_REJECTED;
493     } else {
494         jsonObj[FIELD_CONFIRMATION] = REQUEST_ACCEPTED;
495         jsonObj[FIELD_PIN_CODE] = std::to_string(pinCode);
496     }
497     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
498     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
499     jsonObj[FIELD_DEVICE_ID] = localDeviceId;
500 
501     std::string jsonStr = SafetyDump(jsonObj);
502     char *buffer = strdup(jsonStr.c_str());
503     return buffer;
504 }
505 
GenRequestId()506 int64_t HiChainConnector::GenRequestId()
507 {
508     return GenRandLongLong(MIN_REQUEST_ID, MAX_REQUEST_ID);
509 }
510 
GetConnectPara(std::string deviceId,std::string reqDeviceId)511 std::string HiChainConnector::GetConnectPara(std::string deviceId, std::string reqDeviceId)
512 {
513     LOGI("HiChainConnector::GetConnectPara get addrInfo");
514     if (hiChainConnectorCallback_ == nullptr) {
515         LOGE("HiChainConnector::GetConnectPara hiChainConnectorCallback_ is nullptr.");
516         return "";
517     }
518     std::string connectAddr = hiChainConnectorCallback_->GetConnectAddr(deviceId);
519     JsonObject jsonObject(connectAddr);
520     if (jsonObject.IsDiscarded()) {
521         LOGE("DecodeRequestAuth jsonStr error");
522         return connectAddr;
523     }
524     jsonObject[DEVICE_ID] = reqDeviceId;
525 
526     return SafetyDump(jsonObject);
527 }
528 
GetRelatedGroups(const std::string & deviceId,std::vector<GroupInfo> & groupList)529 int32_t HiChainConnector::GetRelatedGroups(const std::string &deviceId, std::vector<GroupInfo> &groupList)
530 {
531     return GetRelatedGroupsCommon(deviceId, DM_PKG_NAME, groupList);
532 }
533 
GetRelatedGroups(int32_t userId,const std::string & deviceId,std::vector<GroupInfo> & groupList)534 int32_t HiChainConnector::GetRelatedGroups(int32_t userId, const std::string &deviceId,
535     std::vector<GroupInfo> &groupList)
536 {
537     return GetRelatedGroupsCommon(userId, deviceId, DM_PKG_NAME, groupList);
538 }
539 
GetRelatedGroupsExt(const std::string & deviceId,std::vector<GroupInfo> & groupList)540 int32_t HiChainConnector::GetRelatedGroupsExt(const std::string &deviceId, std::vector<GroupInfo> &groupList)
541 {
542     return GetRelatedGroupsCommon(deviceId, DM_PKG_NAME_EXT, groupList);
543 }
544 
GetRelatedGroupsExt(int32_t userId,const std::string & deviceId,std::vector<GroupInfo> & groupList)545 int32_t HiChainConnector::GetRelatedGroupsExt(int32_t userId, const std::string &deviceId,
546     std::vector<GroupInfo> &groupList)
547 {
548     return GetRelatedGroupsCommon(userId, deviceId, DM_PKG_NAME_EXT, groupList);
549 }
550 
GetSyncGroupList(std::vector<GroupInfo> & groupList,std::vector<std::string> & syncGroupList)551 int32_t HiChainConnector::GetSyncGroupList(std::vector<GroupInfo> &groupList, std::vector<std::string> &syncGroupList)
552 {
553     if (groupList.empty()) {
554         LOGE("groupList is empty.");
555         return ERR_DM_FAILED;
556     }
557     for (auto group : groupList) {
558         if (IsGroupInfoInvalid(group)) {
559             continue;
560         }
561         syncGroupList.push_back(group.groupId);
562     }
563     return DM_OK;
564 }
565 
IsDevicesInP2PGroup(const std::string & hostDevice,const std::string & peerDevice)566 bool HiChainConnector::IsDevicesInP2PGroup(const std::string &hostDevice, const std::string &peerDevice)
567 {
568     LOGI("HiChainConnector::IsDevicesInP2PGroup");
569     std::vector<GroupInfo> hostGroupInfoList;
570     GetRelatedGroups(hostDevice, hostGroupInfoList);
571     std::vector<GroupInfo> peerGroupInfoList;
572     GetRelatedGroups(peerDevice, peerGroupInfoList);
573     for (const auto &hostGroupInfo : hostGroupInfoList) {
574         if (hostGroupInfo.groupType != GROUP_TYPE_PEER_TO_PEER_GROUP) {
575             continue;
576         }
577         for (const auto &peerGroupInfo : peerGroupInfoList) {
578             if (peerGroupInfo.groupType != GROUP_TYPE_PEER_TO_PEER_GROUP) {
579                 continue;
580             }
581             if (hostGroupInfo.groupId == peerGroupInfo.groupId && hostGroupInfo.groupName == peerGroupInfo.groupName) {
582                 LOGE("these are authenticated");
583                 return true;
584             }
585         }
586     }
587     return false;
588 }
589 
IsGroupInfoInvalid(GroupInfo & group)590 bool HiChainConnector::IsGroupInfoInvalid(GroupInfo &group)
591 {
592     if (group.groupType == GROUP_TYPE_IDENTICAL_ACCOUNT_GROUP || group.groupVisibility == GROUP_VISIBILITY_PUBLIC ||
593         group.groupOwner != std::string(DM_PKG_NAME)) {
594         return true;
595     }
596     return false;
597 }
598 
SyncGroups(std::string deviceId,std::vector<std::string> & remoteGroupIdList)599 int32_t HiChainConnector::SyncGroups(std::string deviceId, std::vector<std::string> &remoteGroupIdList)
600 {
601     std::vector<GroupInfo> groupInfoList;
602     GetRelatedGroups(deviceId, groupInfoList);
603     for (auto &groupInfo : groupInfoList) {
604         if (IsGroupInfoInvalid(groupInfo)) {
605             continue;
606         }
607         auto iter = std::find(remoteGroupIdList.begin(), remoteGroupIdList.end(), groupInfo.groupId);
608         if (iter == remoteGroupIdList.end()) {
609             (void)DelMemberFromGroup(groupInfo.groupId, deviceId);
610         }
611     }
612     return DM_OK;
613 }
614 
DelMemberFromGroup(const std::string & groupId,const std::string & deviceId)615 int32_t HiChainConnector::DelMemberFromGroup(const std::string &groupId, const std::string &deviceId)
616 {
617     int64_t requestId = GenRequestId();
618     LOGI("Start to delete member from group, requestId %{public}" PRId64", deviceId %{public}s, groupId %{public}s",
619         requestId, GetAnonyString(deviceId).c_str(), GetAnonyString(groupId).c_str());
620     JsonObject jsonObj;
621     jsonObj[FIELD_GROUP_ID] = groupId;
622     jsonObj[FIELD_DELETE_ID] = deviceId;
623     std::string deleteParams = SafetyDump(jsonObj);
624     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
625     if (userId < 0) {
626         LOGE("get current process account user id failed");
627         return ERR_DM_FAILED;
628     }
629     int32_t ret = deviceGroupManager_->deleteMemberFromGroup(userId, requestId, DM_PKG_NAME, deleteParams.c_str());
630     if (ret != 0) {
631         LOGE("[HICHAIN]fail to delete member from group with ret:%{public}d.", ret);
632         return ret;
633     }
634     return DM_OK;
635 }
636 
DeleteGroup(std::string & groupId)637 int32_t HiChainConnector::DeleteGroup(std::string &groupId)
638 {
639     int64_t requestId = GenRequestId();
640     JsonObject jsonObj;
641     jsonObj[FIELD_GROUP_ID] = groupId;
642     std::string disbandParams = SafetyDump(jsonObj);
643     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
644     if (userId < 0) {
645         LOGE("get current process account user id failed");
646         return ERR_DM_FAILED;
647     }
648 
649     int32_t ret = deviceGroupManager_->deleteGroup(userId, requestId, DM_PKG_NAME, disbandParams.c_str());
650     if (ret != 0) {
651         LOGE("[HICHAIN]fail to delete group with ret:%{public}d.", ret);
652         return ERR_DM_FAILED;
653     }
654     return DM_OK;
655 }
656 
DeleteGroupExt(std::string & groupId)657 int32_t HiChainConnector::DeleteGroupExt(std::string &groupId)
658 {
659     int64_t requestId = GenRequestId();
660     JsonObject jsonObj;
661     jsonObj[FIELD_GROUP_ID] = groupId;
662     std::string disbandParams = SafetyDump(jsonObj);
663     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
664     if (userId < 0) {
665         LOGE("get current process account user id failed");
666         return ERR_DM_FAILED;
667     }
668 
669     int32_t ret = deviceGroupManager_->deleteGroup(userId, requestId, DM_PKG_NAME_EXT, disbandParams.c_str());
670     if (ret != 0) {
671         LOGE("[HICHAIN]fail to delete group with ret:%{public}d.", ret);
672         return ERR_DM_FAILED;
673     }
674     return DM_OK;
675 }
676 
DeleteGroupExt(int32_t userId,std::string & groupId)677 int32_t HiChainConnector::DeleteGroupExt(int32_t userId, std::string &groupId)
678 {
679     int64_t requestId = GenRequestId();
680     JsonObject jsonObj;
681     jsonObj[FIELD_GROUP_ID] = groupId;
682     std::string disbandParams = SafetyDump(jsonObj);
683     int32_t ret = deviceGroupManager_->deleteGroup(userId, requestId, DM_PKG_NAME_EXT, disbandParams.c_str());
684     if (ret != 0) {
685         LOGE("[HICHAIN]fail to delete group with ret:%{public}d.", ret);
686         return ERR_DM_FAILED;
687     }
688     return DM_OK;
689 }
690 
DeleteGroup(int64_t requestId_,const std::string & userId,const int32_t authType)691 int32_t HiChainConnector::DeleteGroup(int64_t requestId_, const std::string &userId, const int32_t authType)
692 {
693     networkStyle_ = CREDENTIAL_NETWORK;
694     JsonObject jsonObj;
695     jsonObj[FIELD_GROUP_TYPE] = authType;
696     std::string queryParams = SafetyDump(jsonObj);
697     std::vector<GroupInfo> groupList;
698     if (!GetGroupInfo(queryParams, groupList)) {
699         LOGE("failed to get device join groups");
700         return ERR_DM_FAILED;
701     }
702     LOGI("HiChainConnector::DeleteGroup groupList count = %{public}zu", groupList.size());
703     bool userIsExist = false;
704     std::string groupId = "";
705     for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
706         if (iter->userId == userId) {
707             userIsExist = true;
708             groupId = iter->groupId;
709             break;
710         }
711     }
712     if (!userIsExist) {
713         LOGE("input userId is exist in groupList!");
714         return ERR_DM_FAILED;
715     }
716     jsonObj[FIELD_GROUP_ID] = groupId;
717     std::string disbandParams = SafetyDump(jsonObj);
718     g_deleteGroupFlag = false;
719     int32_t osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
720     if (osAccountUserId < 0) {
721         LOGE("get current process account user id failed");
722         return ERR_DM_FAILED;
723     }
724     int32_t ret = deviceGroupManager_->deleteGroup(osAccountUserId, requestId_, DM_PKG_NAME,
725         disbandParams.c_str());
726     if (ret != 0) {
727         LOGE("[HICHAIN]fail to delete hichain group with ret:%{public}d.", ret);
728         return ERR_DM_FAILED;
729     }
730     int32_t nTickTimes = 0;
731     while (!g_deleteGroupFlag) {
732         usleep(DELAY_TIME_MS);
733         if (++nTickTimes > SERVICE_INIT_TRY_MAX_NUM) {
734             LOGE("failed to delete group because timeout!");
735             return ERR_DM_FAILED;
736         }
737     }
738     return DM_OK;
739 }
740 
DeleteTimeOutGroup(const char * deviceId)741 int32_t HiChainConnector::DeleteTimeOutGroup(const char* deviceId)
742 {
743     LOGI("HiChainConnector::DeleteTimeOutGroup start");
744     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
745     if (userId < 0) {
746         LOGE("get current process account user id failed");
747         return ERR_DM_FAILED;
748     }
749     std::vector<GroupInfo> peerGroupInfoList;
750     GetRelatedGroups(deviceId, peerGroupInfoList);
751     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
752     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
753     for (auto &group : peerGroupInfoList) {
754         if (!(deviceGroupManager_->isDeviceInGroup(userId, DM_PKG_NAME, group.groupId.c_str(), localDeviceId))) {
755             continue;
756         }
757         if ((!group.groupName.empty()) && (group.groupName[CHECK_AUTH_ALWAYS_POS] == AUTH_ALWAYS)) {
758             LOGI("HiChainConnector::DeleteTimeOutGroup always trusted group");
759             continue;
760         }
761         if (group.groupType == GROUP_TYPE_PEER_TO_PEER_GROUP) {
762             DeleteGroup(group.groupId);
763         }
764     }
765     return DM_OK;
766 }
767 
DeleteRedundanceGroup(std::string & userId)768 void HiChainConnector::DeleteRedundanceGroup(std::string &userId)
769 {
770     int32_t nTickTimes = 0;
771     g_deleteGroupFlag = false;
772     DeleteGroup(userId);
773     while (!g_deleteGroupFlag) {
774         usleep(DELAY_TIME_MS);
775         if (++nTickTimes > SERVICE_INIT_TRY_MAX_NUM) {
776             LOGE("failed to delete group because timeout!");
777             return;
778         }
779     }
780 }
781 
DealRedundanceGroup(const std::string & userId,int32_t authType)782 void HiChainConnector::DealRedundanceGroup(const std::string &userId, int32_t authType)
783 {
784     g_groupIsRedundance = false;
785     std::vector<GroupInfo> groupList;
786     if (IsRedundanceGroup(userId, authType, groupList)) {
787         LOGI("HiChainConnector::CreateGroup IsRedundanceGroup");
788         g_groupIsRedundance = true;
789         for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
790             if (iter->userId != userId) {
791                 DeleteRedundanceGroup(iter->userId);
792             }
793         }
794         g_groupIsRedundance = false;
795     }
796 }
797 
CreateGroup(int64_t requestId,int32_t authType,const std::string & userId,JsonObject & jsonOutObj)798 int32_t HiChainConnector::CreateGroup(int64_t requestId, int32_t authType, const std::string &userId,
799     JsonObject &jsonOutObj)
800 {
801     LOGI("HiChainConnector::CreateGroup start.");
802     if (deviceGroupManager_ == nullptr) {
803         LOGE("HiChainConnector::CreateGroup group manager is null, requestId %{public}" PRId64, requestId);
804         return ERR_DM_INPUT_PARA_INVALID;
805     }
806     DealRedundanceGroup(userId, authType);
807     networkStyle_ = CREDENTIAL_NETWORK;
808     LOGI("HiChainConnector::CreateGroup requestId %{public}" PRId64, requestId);
809     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
810     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
811     std::string sLocalDeviceId = localDeviceId;
812     JsonObject jsonObj;
813     jsonObj[FIELD_GROUP_TYPE] = authType;
814     jsonObj[FIELD_USER_ID] = userId;
815     jsonObj.Insert(FIELD_CREDENTIAL, jsonOutObj);
816     jsonObj[FIELD_DEVICE_ID] = sLocalDeviceId;
817     jsonObj[FIELD_USER_TYPE] = 0;
818     jsonObj[FIELD_GROUP_VISIBILITY] = GROUP_VISIBILITY_PUBLIC;
819     jsonObj[FIELD_EXPIRE_TIME] = FIELD_EXPIRE_TIME_VALUE;
820     g_createGroupFlag = false;
821     int32_t osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
822     if (osAccountUserId < 0) {
823         LOGE("get current process account user id failed");
824         return ERR_DM_FAILED;
825     }
826     int32_t ret = deviceGroupManager_->createGroup(osAccountUserId, requestId, DM_PKG_NAME,
827         SafetyDump(jsonObj).c_str());
828     if (ret != DM_OK) {
829         LOGE("[HICHAIN]fail to create group with ret:%{public}d, requestId:%{public}" PRId64, ret, requestId);
830         return ERR_DM_CREATE_GROUP_FAILED;
831     }
832     int32_t nTickTimes = 0;
833     while (!g_createGroupFlag) {
834         usleep(DELAY_TIME_MS);
835         if (++nTickTimes > SERVICE_INIT_TRY_MAX_NUM) {
836             LOGE("failed to create group because timeout!");
837             return ERR_DM_CREATE_GROUP_FAILED;
838         }
839     }
840     return DM_OK;
841 }
842 
RegisterHiChainGroupCallback(const std::shared_ptr<IDmGroupResCallback> & callback)843 int32_t HiChainConnector::RegisterHiChainGroupCallback(const std::shared_ptr<IDmGroupResCallback> &callback)
844 {
845     hiChainResCallback_ = callback;
846     return DM_OK;
847 }
848 
UnRegisterHiChainGroupCallback()849 int32_t HiChainConnector::UnRegisterHiChainGroupCallback()
850 {
851     hiChainResCallback_ = nullptr;
852     return DM_OK;
853 }
854 
getRegisterInfo(const std::string & queryParams,std::string & returnJsonStr)855 int32_t HiChainConnector::getRegisterInfo(const std::string &queryParams, std::string &returnJsonStr)
856 {
857     if (deviceGroupManager_ == nullptr) {
858         LOGE("HiChainConnector::deviceGroupManager_ is nullptr.");
859         return ERR_DM_INPUT_PARA_INVALID;
860     }
861     char *credentialInfo = nullptr;
862     if (deviceGroupManager_->getRegisterInfo(queryParams.c_str(), &credentialInfo) != DM_OK) {
863         LOGE("[HICHAIN]fail to request hichain registerinfo.");
864         deviceGroupManager_->destroyInfo(&credentialInfo);
865         return ERR_DM_FAILED;
866     }
867 
868     returnJsonStr = credentialInfo;
869     deviceGroupManager_->destroyInfo(&credentialInfo);
870     LOGI("request hichain device registerinfo successfully.");
871     return DM_OK;
872 }
873 
GetGroupId(const std::string & userId,const int32_t groupType,std::string & groupId)874 int32_t HiChainConnector::GetGroupId(const std::string &userId, const int32_t groupType, std::string &groupId)
875 {
876     JsonObject jsonObjGroup;
877     jsonObjGroup[FIELD_GROUP_TYPE] = groupType;
878     std::string queryParams = SafetyDump(jsonObjGroup);
879     std::vector<GroupInfo> groupList;
880 
881     if (!GetGroupInfo(queryParams.c_str(), groupList)) {
882         LOGE("failed to get device join groups");
883         return ERR_DM_FAILED;
884     }
885     for (auto &groupinfo : groupList) {
886         LOGI("groupinfo.groupId:%{public}s", GetAnonyString(groupinfo.groupId).c_str());
887         if (groupinfo.userId == userId) {
888             groupId = groupinfo.groupId;
889             return DM_OK;
890         }
891     }
892     return ERR_DM_FAILED;
893 }
894 
ParseRemoteCredential(const int32_t groupType,const std::string & userId,const JsonObject & jsonDeviceList,std::string & params,int32_t & osAccountUserId)895 int32_t HiChainConnector::ParseRemoteCredential(const int32_t groupType, const std::string &userId,
896     const JsonObject &jsonDeviceList, std::string &params, int32_t &osAccountUserId)
897 {
898     if (userId.empty() || !jsonDeviceList.Contains(FIELD_DEVICE_LIST)) {
899         LOGE("userId or deviceList is empty");
900         return ERR_DM_INPUT_PARA_INVALID;
901     }
902     std::string groupId;
903     if (GetGroupId(userId, groupType, groupId) != DM_OK) {
904         LOGE("failed to get groupid");
905         return ERR_DM_FAILED;
906     }
907     JsonObject jsonObj;
908     jsonObj[FIELD_GROUP_ID] = groupId;
909     jsonObj[FIELD_GROUP_TYPE] = groupType;
910     jsonObj[FIELD_DEVICE_LIST] = jsonDeviceList[FIELD_DEVICE_LIST];
911     params = SafetyDump(jsonObj);
912     osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
913     if (osAccountUserId < 0) {
914         LOGE("get current process account user id failed");
915         return ERR_DM_FAILED;
916     }
917     return DM_OK;
918 }
919 
addMultiMembers(const int32_t groupType,const std::string & userId,const JsonObject & jsonDeviceList)920 int32_t HiChainConnector::addMultiMembers(const int32_t groupType, const std::string &userId,
921     const JsonObject &jsonDeviceList)
922 {
923     if (deviceGroupManager_ == nullptr) {
924         LOGE("HiChainConnector::deviceGroupManager_ is nullptr.");
925         return ERR_DM_INPUT_PARA_INVALID;
926     }
927     std::string addParams;
928     int32_t osAccountUserId = 0;
929     if (ParseRemoteCredential(groupType, userId, jsonDeviceList, addParams, osAccountUserId) != DM_OK) {
930         LOGE("addMultiMembers ParseRemoteCredential failed!");
931         return ERR_DM_FAILED;
932     }
933 
934     int32_t ret = deviceGroupManager_->addMultiMembersToGroup(osAccountUserId, DM_PKG_NAME, addParams.c_str());
935     if (ret != DM_OK) {
936         LOGE("[HICHAIN]fail to add member to hichain group with ret:%{public}d.", ret);
937         return ERR_DM_ADD_GROUP_FAILED;
938     }
939     return DM_OK;
940 }
941 
GetJsonStr(const JsonObject & jsonObj,const std::string & key)942 std::string HiChainConnector::GetJsonStr(const JsonObject &jsonObj, const std::string &key)
943 {
944     if (!IsString(jsonObj, key)) {
945         LOGE("User string key not exist!");
946         return "";
947     }
948     return jsonObj[key].Get<std::string>();
949 }
950 
GetJsonInt(const JsonObject & jsonObj,const std::string & key)951 int32_t HiChainConnector::GetJsonInt(const JsonObject &jsonObj, const std::string &key)
952 {
953     if (!IsInt32(jsonObj, key)) {
954         LOGE("User string key not exist!");
955         return ERR_DM_FAILED;
956     }
957     return jsonObj[key].Get<int32_t>();
958 }
959 
GetGroupIdExt(const std::string & userId,const int32_t groupType,std::string & groupId,std::string & groupOwner)960 int32_t HiChainConnector::GetGroupIdExt(const std::string &userId, const int32_t groupType,
961     std::string &groupId, std::string &groupOwner)
962 {
963     JsonObject jsonObjGroup;
964     jsonObjGroup[FIELD_GROUP_TYPE] = groupType;
965     std::string queryParams = SafetyDump(jsonObjGroup);
966     std::vector<GroupInfo> groupList;
967 
968     if (!GetGroupInfo(queryParams.c_str(), groupList)) {
969         LOGE("failed to get device join groups");
970         return ERR_DM_FAILED;
971     }
972     for (auto &groupinfo : groupList) {
973         LOGI("groupinfo.groupId:%{public}s", GetAnonyString(groupinfo.groupId).c_str());
974         if (groupinfo.userId == userId) {
975             groupId = groupinfo.groupId;
976             groupOwner = groupinfo.groupOwner;
977             return DM_OK;
978         }
979     }
980     return ERR_DM_FAILED;
981 }
982 
ParseRemoteCredentialExt(const std::string & credentialInfo,std::string & params,std::string & groupOwner)983 int32_t HiChainConnector::ParseRemoteCredentialExt(const std::string &credentialInfo, std::string &params,
984     std::string &groupOwner)
985 {
986     LOGI("ParseRemoteCredentialExt start.");
987     JsonObject jsonObject(credentialInfo);
988     if (jsonObject.IsDiscarded()) {
989         LOGE("CredentialInfo string not a json type.");
990         return ERR_DM_FAILED;
991     }
992     JsonObject jsonObj;
993     int32_t groupType = 0;
994     std::string userId = "";
995     int32_t authType = GetJsonInt(jsonObject, AUTH_TYPE);
996     if (authType == SAME_ACCOUNT) {
997         groupType = IDENTICAL_ACCOUNT_GROUP;
998         userId = GetJsonStr(jsonObject, FIELD_USER_ID);
999     } else {
1000         LOGE("Failed to get userId.");
1001         return ERR_DM_FAILED;
1002     }
1003     std::string groupId = "";
1004     if (GetGroupIdExt(userId, groupType, groupId, groupOwner) != DM_OK) {
1005         LOGE("Failed to get groupid");
1006         return ERR_DM_FAILED;
1007     }
1008     jsonObj[FIELD_GROUP_TYPE] = groupType;
1009     jsonObj[FIELD_GROUP_ID] = groupId;
1010     jsonObj[FIELD_USER_ID] = userId;
1011     jsonObj[FIELD_CREDENTIAL_TYPE] = GetJsonInt(jsonObject, FIELD_CREDENTIAL_TYPE);
1012     jsonObj[FIELD_OPERATION_CODE] = GetJsonInt(jsonObject, FIELD_OPERATION_CODE);
1013     jsonObj[FIELD_META_NODE_TYPE] = GetJsonStr(jsonObject, FIELD_TYPE);
1014     if (!jsonObject.Contains(FIELD_DEVICE_LIST)) {
1015         LOGE("Credentaildata or authType string key not exist!");
1016         return ERR_DM_FAILED;
1017     }
1018     jsonObj[FIELD_DEVICE_LIST] = jsonObject[FIELD_DEVICE_LIST];
1019     params = SafetyDump(jsonObj);
1020     return DM_OK;
1021 }
1022 
addMultiMembersExt(const std::string & credentialInfo)1023 int32_t HiChainConnector::addMultiMembersExt(const std::string &credentialInfo)
1024 {
1025     if (deviceGroupManager_ == nullptr) {
1026         LOGE("HiChainConnector::deviceGroupManager_ is nullptr.");
1027         return ERR_DM_INPUT_PARA_INVALID;
1028     }
1029     std::string addParams = "";
1030     std::string groupOwner = "";
1031     if (ParseRemoteCredentialExt(credentialInfo, addParams, groupOwner) != DM_OK) {
1032         LOGE("AddMultiMembers ParseRemoteCredentialExt failed!");
1033         return ERR_DM_FAILED;
1034     }
1035     int32_t osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
1036     if (osAccountUserId < 0) {
1037         LOGE("Get current process account user id failed");
1038         return ERR_DM_FAILED;
1039     }
1040     int32_t ret = deviceGroupManager_->addMultiMembersToGroup(osAccountUserId, groupOwner.c_str(), addParams.c_str());
1041     if (ret != DM_OK) {
1042         LOGE("[HICHAIN]fail to add member to hichain group with ret:%{public}d.", ret);
1043         return ret;
1044     }
1045     return DM_OK;
1046 }
1047 
deleteMultiMembers(const int32_t groupType,const std::string & userId,const JsonObject & jsonDeviceList)1048 int32_t HiChainConnector::deleteMultiMembers(const int32_t groupType, const std::string &userId,
1049     const JsonObject &jsonDeviceList)
1050 {
1051     if (deviceGroupManager_ == nullptr) {
1052         LOGE("HiChainConnector::deviceGroupManager_ is nullptr.");
1053         return ERR_DM_INPUT_PARA_INVALID;
1054     }
1055 
1056     std::string deleteParams;
1057     int32_t osAccountUserId = 0;
1058     if (ParseRemoteCredential(groupType, userId, jsonDeviceList, deleteParams, osAccountUserId) != DM_OK) {
1059         LOGE("deleteMultiMembers ParseRemoteCredential failed!");
1060         return ERR_DM_FAILED;
1061     }
1062 
1063     int32_t ret = deviceGroupManager_->delMultiMembersFromGroup(osAccountUserId, DM_PKG_NAME, deleteParams.c_str());
1064     if (ret != DM_OK) {
1065         LOGE("[HICHAIN]fail to delete member from hichain group with ret:%{public}d.", ret);
1066         return ret;
1067     }
1068     return DM_OK;
1069 }
1070 
GetTrustedDevices(const std::string & localDeviceUdid)1071 std::vector<std::string> HiChainConnector::GetTrustedDevices(const std::string &localDeviceUdid)
1072 {
1073     LOGI("get localDeviceUdid: %{public}s trusted devices.", GetAnonyString(localDeviceUdid).c_str());
1074     std::vector<GroupInfo> groups;
1075     int32_t ret = GetRelatedGroups(localDeviceUdid, groups);
1076     if (ret != DM_OK) {
1077         LOGE("failed to get groupInfo, ret: %{public}d", ret);
1078         return {};
1079     }
1080 
1081     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
1082     if (userId < 0) {
1083         LOGE("get current process account user id failed");
1084         return {};
1085     }
1086     std::vector<std::string> trustedDevices;
1087     for (const auto &group : groups) {
1088         char *devicesJson = nullptr;
1089         uint32_t devNum = 0;
1090         ret = deviceGroupManager_->getTrustedDevices(userId, DM_PKG_NAME, group.groupId.c_str(),
1091         &devicesJson, &devNum);
1092         if (ret != 0 || devicesJson == nullptr) {
1093             LOGE("[HICHAIN]failed to get trusted devicesJson, ret: %{public}d", ret);
1094             deviceGroupManager_->destroyInfo(&devicesJson);
1095             return {};
1096         }
1097         GetTrustedDevicesUdid(devicesJson, trustedDevices);
1098         deviceGroupManager_->destroyInfo(&devicesJson);
1099     }
1100     return trustedDevices;
1101 }
1102 
GetTrustedDevicesUdid(const char * jsonStr,std::vector<std::string> & udidList)1103 int32_t HiChainConnector::GetTrustedDevicesUdid(const char* jsonStr, std::vector<std::string> &udidList)
1104 {
1105     JsonObject jsonObject(jsonStr);
1106     if (jsonObject.IsDiscarded()) {
1107         LOGE("credentialInfo string not a json type.");
1108         return ERR_DM_FAILED;
1109     }
1110     std::vector<JsonItemObject> children = jsonObject.Items();
1111     for (auto it1 = children.begin(); it1 != children.end(); it1++) {
1112         if (!IsString((*it1), FIELD_AUTH_ID)) {
1113             continue;
1114         }
1115         std::string udid = (*it1)[FIELD_AUTH_ID].Get<std::string>();
1116         udidList.push_back(udid);
1117     }
1118     return DM_OK;
1119 }
1120 
DeleteAllGroup(int32_t userId)1121 void HiChainConnector::DeleteAllGroup(int32_t userId)
1122 {
1123     LOGI("HiChainConnector::DeleteAllGroup");
1124     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
1125     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
1126     std::string localUdid = static_cast<std::string>(localDeviceId);
1127     std::vector<GroupInfo> groupList;
1128     GetRelatedGroups(userId, localUdid, groupList);
1129     for (auto &iter : groupList) {
1130         if (iter.groupType == GROUP_TYPE_IDENTICAL_ACCOUNT_GROUP) {
1131             continue;
1132         }
1133         if (DeleteGroup(userId, iter.groupId) != DM_OK) {
1134             LOGE("Delete groupId %{public}s failed.", GetAnonyString(iter.groupId).c_str());
1135         }
1136     }
1137     std::vector<GroupInfo> groupListExt;
1138     GetRelatedGroupsExt(userId, localUdid, groupListExt);
1139     for (auto &iter : groupListExt) {
1140         if (iter.groupType == GROUP_TYPE_IDENTICAL_ACCOUNT_GROUP) {
1141             continue;
1142         }
1143         if (DeleteGroupExt(userId, iter.groupId) != DM_OK) {
1144             LOGE("DeleteGroupExt groupId %{public}s failed.", GetAnonyString(iter.groupId).c_str());
1145         }
1146     }
1147 }
1148 
GetRelatedGroupsCommon(const std::string & deviceId,const char * pkgName,std::vector<GroupInfo> & groupList)1149 int32_t HiChainConnector::GetRelatedGroupsCommon(const std::string &deviceId, const char* pkgName,
1150     std::vector<GroupInfo> &groupList)
1151 {
1152     LOGI("HiChainConnector::GetRelatedGroupsCommon Start to get local related groups.");
1153     uint32_t groupNum = 0;
1154     char *returnGroups = nullptr;
1155     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
1156     if (userId < 0) {
1157         LOGE("get current process account user id failed");
1158         return ERR_DM_FAILED;
1159     }
1160     int32_t ret =
1161         deviceGroupManager_->getRelatedGroups(userId, pkgName, deviceId.c_str(), &returnGroups, &groupNum);
1162     if (ret != 0) {
1163         LOGE("[HICHAIN] fail to get related groups with ret:%{public}d.", ret);
1164         deviceGroupManager_->destroyInfo(&returnGroups);
1165         return ERR_DM_FAILED;
1166     }
1167     if (returnGroups == nullptr) {
1168         LOGE("[HICHAIN] return related goups point is nullptr");
1169         return ERR_DM_FAILED;
1170     }
1171     if (groupNum == 0) {
1172         LOGE("[HICHAIN]return related goups number is zero.");
1173         deviceGroupManager_->destroyInfo(&returnGroups);
1174         return ERR_DM_FAILED;
1175     }
1176     std::string relatedGroups = std::string(returnGroups);
1177     deviceGroupManager_->destroyInfo(&returnGroups);
1178     JsonObject jsonObject(relatedGroups);
1179     if (jsonObject.IsDiscarded()) {
1180         LOGE("returnGroups parse error");
1181         return ERR_DM_FAILED;
1182     }
1183     if (!jsonObject.IsArray()) {
1184         LOGE("jsonObject is not an array.");
1185         return ERR_DM_FAILED;
1186     }
1187     std::vector<GroupInfo> groupInfos;
1188     jsonObject.Get(groupInfos);
1189     if (groupInfos.empty()) {
1190         LOGE("HiChainConnector::GetRelatedGroups group failed, groupInfos is empty.");
1191         return ERR_DM_FAILED;
1192     }
1193     groupList = groupInfos;
1194     return DM_OK;
1195 }
1196 
DeleteGroup(const int32_t userId,std::string & groupId)1197 int32_t HiChainConnector::DeleteGroup(const int32_t userId, std::string &groupId)
1198 {
1199     if (userId < 0) {
1200         LOGE("user id failed");
1201         return ERR_DM_FAILED;
1202     }
1203     int64_t requestId = GenRequestId();
1204     JsonObject jsonObj;
1205     jsonObj[FIELD_GROUP_ID] = groupId;
1206     std::string disbandParams = SafetyDump(jsonObj);
1207     int32_t ret = deviceGroupManager_->deleteGroup(userId, requestId, DM_PKG_NAME, disbandParams.c_str());
1208     if (ret != 0) {
1209         LOGE("[HICHAIN]fail to delete group with ret:%{public}d.", ret);
1210         return ERR_DM_FAILED;
1211     }
1212     return DM_OK;
1213 }
1214 
GetRelatedGroupsCommon(int32_t userId,const std::string & deviceId,const char * pkgName,std::vector<GroupInfo> & groupList)1215 int32_t HiChainConnector::GetRelatedGroupsCommon(int32_t userId, const std::string &deviceId, const char* pkgName,
1216     std::vector<GroupInfo> &groupList)
1217 {
1218     LOGI("Start to get related groups.");
1219     if (userId < 0) {
1220         LOGE("user id failed");
1221         return ERR_DM_FAILED;
1222     }
1223     uint32_t groupNum = 0;
1224     char *returnGroups = nullptr;
1225     int32_t ret =
1226         deviceGroupManager_->getRelatedGroups(userId, pkgName, deviceId.c_str(), &returnGroups, &groupNum);
1227     if (ret != 0) {
1228         LOGE("[HICHAIN] fail to get related groups with ret:%{public}d.", ret);
1229         deviceGroupManager_->destroyInfo(&returnGroups);
1230         return ERR_DM_FAILED;
1231     }
1232     if (returnGroups == nullptr) {
1233         LOGE("[HICHAIN] return related goups point is nullptr");
1234         return ERR_DM_FAILED;
1235     }
1236     if (groupNum == 0) {
1237         LOGE("[HICHAIN]return related goups number is zero.");
1238         deviceGroupManager_->destroyInfo(&returnGroups);
1239         return ERR_DM_FAILED;
1240     }
1241     std::string relatedGroups = std::string(returnGroups);
1242     deviceGroupManager_->destroyInfo(&returnGroups);
1243     JsonObject jsonObject(relatedGroups);
1244     if (jsonObject.IsDiscarded()) {
1245         LOGE("returnGroups parse error");
1246         return ERR_DM_FAILED;
1247     }
1248     if (!jsonObject.IsArray()) {
1249         LOGE("jsonObject is not an array.");
1250         return ERR_DM_FAILED;
1251     }
1252     std::vector<GroupInfo> groupInfos;
1253     jsonObject.Get(groupInfos);
1254     if (groupInfos.empty()) {
1255         LOGE("HiChainConnector::GetRelatedGroups group failed, groupInfos is empty.");
1256         return ERR_DM_FAILED;
1257     }
1258     groupList = groupInfos;
1259     return DM_OK;
1260 }
1261 
DeleteAllGroupByUdid(const std::string & udid)1262 void HiChainConnector::DeleteAllGroupByUdid(const std::string &udid)
1263 {
1264     LOGI("HiChainConnector::DeleteAllGroupByUdid %{public}s.", GetAnonyString(udid).c_str());
1265     std::vector<GroupInfo> groupList;
1266     GetRelatedGroups(udid, groupList);
1267     for (auto &iter : groupList) {
1268         if (DeleteGroup(iter.groupId) != DM_OK) {
1269             LOGE("Delete groupId %{public}s failed.", GetAnonyString(iter.groupId).c_str());
1270         }
1271     }
1272     std::vector<GroupInfo> groupListExt;
1273     GetRelatedGroupsExt(udid, groupListExt);
1274     for (auto &iter : groupListExt) {
1275         if (DeleteGroupExt(iter.groupId) != DM_OK) {
1276             LOGE("DeleteGroupExt groupId %{public}s failed.", GetAnonyString(iter.groupId).c_str());
1277         }
1278     }
1279 }
1280 
DeleteGroupByACL(std::vector<std::pair<int32_t,std::string>> & delACLInfoVec,std::vector<int32_t> & userIdVec)1281 int32_t HiChainConnector::DeleteGroupByACL(std::vector<std::pair<int32_t, std::string>> &delACLInfoVec,
1282     std::vector<int32_t> &userIdVec)
1283 {
1284     if (delACLInfoVec.size() == 0) {
1285         LOGI("delACLInfoVec is empty");
1286         return DM_OK;
1287     }
1288     if (userIdVec.size() == 0) {
1289         LOGI("userIdVec is empty");
1290         return DM_OK;
1291     }
1292     JsonObject jsonObj;
1293     jsonObj[FIELD_GROUP_TYPE] = GROUP_TYPE_PEER_TO_PEER_GROUP;
1294     std::string queryParams = SafetyDump(jsonObj);
1295     for (int32_t userId : userIdVec) {
1296         std::vector<GroupInfo> groupList;
1297         if (!GetGroupInfo(userId, queryParams, groupList)) {
1298             continue;
1299         }
1300         for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
1301             if (!IsNeedDelete(iter->groupName, userId, delACLInfoVec)) {
1302                 continue;
1303             }
1304             if (DeleteGroup(userId, iter->groupId) != DM_OK) {
1305                 LOGE("failed to delete group %{public}s", GetAnonyString(iter->groupId).c_str());
1306             }
1307         }
1308     }
1309     return DM_OK;
1310 }
1311 
IsNeedDelete(std::string & groupName,int32_t userId,std::vector<std::pair<int32_t,std::string>> & delACLInfoVec)1312 bool HiChainConnector::IsNeedDelete(std::string &groupName, int32_t userId,
1313     std::vector<std::pair<int32_t, std::string>> &delACLInfoVec)
1314 {
1315     if (delACLInfoVec.size() == 0 || groupName.empty()) {
1316         LOGI("delACLInfoVec or groupName is empty");
1317         return false;
1318     }
1319     for (auto item : delACLInfoVec) {
1320         uint32_t interceptLength = item.second.size() / DEVICE_ID_HALF;
1321         std::string interceptUdid = item.second.substr(0, interceptLength);
1322         if (groupName.find(interceptUdid) != std::string::npos && userId == item.first) {
1323             return true;
1324         }
1325     }
1326     return false;
1327 }
1328 } // namespace DistributedHardware
1329 } // namespace OHOS