• 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 "relationship_sync_mgr.h"
17 #include "dm_anonymous.h"
18 #include "dm_log.h"
19 
20 namespace OHOS {
21 namespace DistributedHardware {
22     DM_IMPLEMENT_SINGLE_INSTANCE(ReleationShipSyncMgr);
23 namespace {
24     /**
25      * @brief account logout payload length 8 bytes
26      * |      2 bytes         |         6 bytes          |
27      * | userid lower 2 bytes | account id first 6 bytes |
28      */
29     const int32_t ACCOUNT_LOGOUT_PAYLOAD_LEN = 8;
30     /**
31      * @brief device unbind payload length 2 bytes
32      * |      2 bytes         |
33      * | userid lower 2 bytes |
34      */
35     const int32_t DEVICE_UNBIND_PAYLOAD_LEN = 2;
36     /**
37      * @brief app unbind payload length 6 bytes
38      * |      2 bytes         |         4 bytes          |
39      * | userid lower 2 bytes |  token id lower 4 bytes  |
40      */
41     const int32_t APP_UNBIND_PAYLOAD_LEN = 10;
42     /**
43      * @brief delete user payload length 2 bytes
44      * |      2 bytes         |
45      * | userid lower 2 bytes |
46      */
47     const int32_t DEL_USER_PAYLOAD_LEN = 2;
48     const int32_t STOP_USER_PAYLOAD_LEN = 2;
49     /**
50      * @brief the userid payload cost 2 bytes.
51      *
52      */
53     const int32_t USERID_PAYLOAD_LEN = 2;
54     const int32_t TOKENID_PAYLOAD_LEN = 6;
55     const int32_t ACCOUNTID_PAYLOAD_LEN = 6;
56     const int32_t SYNC_FRONT_OR_BACK_USERID_PAYLOAD_MAX_LEN = 11;
57     const int32_t SYNC_FRONT_OR_BACK_USERID_PAYLOAD_MIN_LEN = 3;
58     const int32_t USERID_BYTES = 2;
59     const int32_t BITS_PER_BYTE = 8;
60     const int32_t INVALIED_PAYLOAD_SIZE = 12;
61 
62     const char * const MSG_TYPE = "TYPE";
63     const char * const MSG_VALUE = "VALUE";
64     const char * const MSG_PEER_UDID = "PEER_UDID";
65     const char * const MSG_ACCOUNTID = "ACCOUNTID";
66     const char * const MSG_PEER_TOKENID = "PEER_TOKENID";
67 
68     // The need response mask offset, the 8th bit.
69     const int32_t NEED_RSP_MASK_OFFSET = 7;
70     /**
71      * @brief The userid cost 2 byte, the heigher part set on the 2th byte.
72      *        The Max user id is just above 10000+, cost 15bits. We use the first bit
73      *        to mark the user id foreground or background.
74      *        1 means foreground user, 0 means background user.
75      * @example foreground userid: 100 -> 0000 0000 0110 0100
76      *          we save it in payload:
77      *          |----first byte----|----second byte----|
78      *          ----------------------------------------
79      *          |     0110 0100    |    1000 0000      |
80      */
81     const int32_t FRONT_OR_BACK_USER_FLAG_OFFSET = 7;
82     const uint8_t FRONT_OR_BACK_USER_FLAG_MASK = 0b01111111;
83     const uint8_t FRONT_OR_BACK_FLAG_MASK = 0b10000000;
84     // The total number of foreground and background userids offset, the 3th ~ 5th bits.
85     const uint16_t ALL_USERID_NUM_MASK_OFFSET = 3;
86     const uint16_t FOREGROUND_USERID_LEN_MASK = 0b00000111;
87     const uint16_t ALL_USERID_NUM_MASK = 0b00111000;
88     const uint32_t MAX_MEM_MALLOC_SIZE = 4 * 1024;
89     const uint32_t MAX_USER_ID_NUM = 5;
90 }
91 
RelationShipChangeMsg()92 RelationShipChangeMsg::RelationShipChangeMsg() : type(RelationShipChangeType::TYPE_MAX),
93     userId(UINT32_MAX), accountId(""), tokenId(UINT64_MAX), peerUdids({}), peerUdid(""), accountName(""),
94     syncUserIdFlag(false), userIdInfos({})
95 {
96 }
97 
ToBroadcastPayLoad(uint8_t * & msg,uint32_t & len) const98 bool RelationShipChangeMsg::ToBroadcastPayLoad(uint8_t *&msg, uint32_t &len) const
99 {
100     if (!IsValid()) {
101         LOGE("invalid");
102         return false;
103     }
104 
105     bool ret = false;
106     switch (type) {
107         case RelationShipChangeType::ACCOUNT_LOGOUT:
108             ToAccountLogoutPayLoad(msg, len);
109             ret = true;
110             break;
111         case RelationShipChangeType::DEVICE_UNBIND:
112             ToDeviceUnbindPayLoad(msg, len);
113             ret = true;
114             break;
115         case RelationShipChangeType::APP_UNBIND:
116             ToAppUnbindPayLoad(msg, len);
117             ret = true;
118             break;
119         case RelationShipChangeType::SYNC_USERID:
120             ret = ToSyncFrontOrBackUserIdPayLoad(msg, len);
121             break;
122         case RelationShipChangeType::DEL_USER:
123             ToDelUserPayLoad(msg, len);
124             ret = true;
125             break;
126         case RelationShipChangeType::STOP_USER:
127             ToStopUserPayLoad(msg, len);
128             ret = true;
129             break;
130         default:
131             LOGE("RelationShipChange type invalid");
132             break;
133     }
134     return ret;
135 }
136 
FromBroadcastPayLoad(const cJSON * payloadJson,RelationShipChangeType type)137 bool RelationShipChangeMsg::FromBroadcastPayLoad(const cJSON *payloadJson, RelationShipChangeType type)
138 {
139     LOGI("FromBroadcastPayLoad type %{public}d.", type);
140     if (type == RelationShipChangeType::TYPE_MAX) {
141         LOGE("ChangeType invalid, type: %{public}d", type);
142         return false;
143     }
144     bool ret = false;
145     switch (type) {
146         case RelationShipChangeType::ACCOUNT_LOGOUT:
147             ret = FromAccountLogoutPayLoad(payloadJson);
148             break;
149         case RelationShipChangeType::DEVICE_UNBIND:
150             ret = FromDeviceUnbindPayLoad(payloadJson);
151             break;
152         case RelationShipChangeType::APP_UNBIND:
153             ret = FromAppUnbindPayLoad(payloadJson);
154             break;
155         case RelationShipChangeType::SYNC_USERID:
156             ret = FromSyncFrontOrBackUserIdPayLoad(payloadJson);
157             break;
158         case RelationShipChangeType::DEL_USER:
159             ret = FromDelUserPayLoad(payloadJson);
160             break;
161         case RelationShipChangeType::STOP_USER:
162             ret = FromStopUserPayLoad(payloadJson);
163             break;
164         default:
165             LOGE("RelationShipChange type invalid");
166             break;
167     }
168     return ret;
169 }
170 
IsValid() const171 bool RelationShipChangeMsg::IsValid() const
172 {
173     bool ret = false;
174     switch (type) {
175         case RelationShipChangeType::ACCOUNT_LOGOUT:
176             ret = (userId != UINT32_MAX && accountId.length() >= ACCOUNTID_PAYLOAD_LEN);
177             break;
178         case RelationShipChangeType::DEVICE_UNBIND:
179             ret = (userId != UINT32_MAX);
180             break;
181         case RelationShipChangeType::APP_UNBIND:
182             ret = (userId != UINT32_MAX && tokenId != UINT64_MAX);
183             break;
184         case RelationShipChangeType::DEL_USER:
185             ret = (userId != UINT32_MAX);
186             break;
187         case RelationShipChangeType::STOP_USER:
188             ret = (userId != UINT32_MAX);
189             break;
190         case RelationShipChangeType::SERVICE_UNBIND:
191         case RelationShipChangeType::APP_UNINSTALL:
192             // current NOT support
193             ret = false;
194             break;
195         case RelationShipChangeType::SYNC_USERID:
196             ret = (!userIdInfos.empty() &&
197                 (static_cast<uint32_t>(userIdInfos.size()) <= MAX_USER_ID_NUM));
198             break;
199         case RelationShipChangeType::TYPE_MAX:
200             ret = false;
201             break;
202         default:
203             ret = false;
204             break;
205     }
206     return ret;
207 }
208 
IsChangeTypeValid()209 bool RelationShipChangeMsg::IsChangeTypeValid()
210 {
211     return (type == RelationShipChangeType::ACCOUNT_LOGOUT) || (type == RelationShipChangeType::DEVICE_UNBIND) ||
212         (type == RelationShipChangeType::APP_UNBIND) || (type == RelationShipChangeType::SYNC_USERID) ||
213         (type == RelationShipChangeType::DEL_USER) || (type == RelationShipChangeType::STOP_USER);
214 }
215 
IsChangeTypeValid(uint32_t type)216 bool RelationShipChangeMsg::IsChangeTypeValid(uint32_t type)
217 {
218     return (type == (uint32_t)RelationShipChangeType::ACCOUNT_LOGOUT) ||
219         (type == (uint32_t)RelationShipChangeType::DEVICE_UNBIND) ||
220         (type == (uint32_t)RelationShipChangeType::APP_UNBIND) ||
221         (type == (uint32_t)RelationShipChangeType::SYNC_USERID) ||
222         (type == (uint32_t)RelationShipChangeType::DEL_USER) ||
223         (type == (uint32_t)RelationShipChangeType::STOP_USER);
224 }
225 
ToAccountLogoutPayLoad(uint8_t * & msg,uint32_t & len) const226 void RelationShipChangeMsg::ToAccountLogoutPayLoad(uint8_t *&msg, uint32_t &len) const
227 {
228     msg = new uint8_t[ACCOUNT_LOGOUT_PAYLOAD_LEN]();
229     for (int i = 0; i < USERID_PAYLOAD_LEN; i++) {
230         msg[i] |= (userId >> (i * BITS_PER_BYTE)) & 0xFF;
231     }
232 
233     for (int j = USERID_PAYLOAD_LEN; j < ACCOUNT_LOGOUT_PAYLOAD_LEN; j++) {
234         msg[j] = accountId[j - USERID_PAYLOAD_LEN];
235     }
236     len = ACCOUNT_LOGOUT_PAYLOAD_LEN;
237 }
238 
ToDeviceUnbindPayLoad(uint8_t * & msg,uint32_t & len) const239 void RelationShipChangeMsg::ToDeviceUnbindPayLoad(uint8_t *&msg, uint32_t &len) const
240 {
241     msg = new uint8_t[DEVICE_UNBIND_PAYLOAD_LEN]();
242     for (int i = 0; i < USERID_PAYLOAD_LEN; i++) {
243         msg[i] |= (userId >> (i * BITS_PER_BYTE)) & 0xFF;
244     }
245     len = DEVICE_UNBIND_PAYLOAD_LEN;
246 }
247 
ToAppUnbindPayLoad(uint8_t * & msg,uint32_t & len) const248 void RelationShipChangeMsg::ToAppUnbindPayLoad(uint8_t *&msg, uint32_t &len) const
249 {
250     msg = new uint8_t[APP_UNBIND_PAYLOAD_LEN]();
251     for (int i = 0; i < USERID_PAYLOAD_LEN; i++) {
252         msg[i] |= (userId >> (i * BITS_PER_BYTE)) & 0xFF;
253     }
254 
255     for (int i = USERID_PAYLOAD_LEN; i < TOKENID_PAYLOAD_LEN; i++) {
256         msg[i] |= (tokenId >> ((i - USERID_PAYLOAD_LEN) * BITS_PER_BYTE)) & 0xFF;
257     }
258 
259     for (int i = TOKENID_PAYLOAD_LEN; i < APP_UNBIND_PAYLOAD_LEN; i++) {
260         msg[i] |= (peerTokenId >> ((i - TOKENID_PAYLOAD_LEN) * BITS_PER_BYTE)) & 0xFF;
261     }
262 
263     len = APP_UNBIND_PAYLOAD_LEN;
264 }
265 
ToSyncFrontOrBackUserIdPayLoad(uint8_t * & msg,uint32_t & len) const266 bool RelationShipChangeMsg::ToSyncFrontOrBackUserIdPayLoad(uint8_t *&msg, uint32_t &len) const
267 {
268     uint32_t userIdNum = static_cast<uint32_t>(userIdInfos.size());
269     if (userIdNum > MAX_USER_ID_NUM) {
270         LOGE("userIdNum too many, %{public}u", userIdNum);
271         return false;
272     }
273 
274     len = userIdNum * USERID_BYTES + 1;
275 
276     if (len > MAX_MEM_MALLOC_SIZE) {
277         LOGE("len too long");
278         return false;
279     }
280     msg = new uint8_t[len]();
281     if (syncUserIdFlag) {
282         msg[0] |= 0x1 << NEED_RSP_MASK_OFFSET;
283     } else {
284         msg[0] |= 0x0 << NEED_RSP_MASK_OFFSET;
285     }
286 
287     msg[0] |= userIdNum;
288     int32_t userIdIdx = 0;
289     for (uint32_t idx = 1; idx <=  (len - USERID_BYTES);) {
290         msg[idx] |= userIdInfos[userIdIdx].userId & 0xFF;
291         msg[idx + 1] |= (userIdInfos[userIdIdx].userId >> BITS_PER_BYTE) & 0xFF;
292         if (userIdInfos[userIdIdx].isForeground) {
293             msg[idx + 1] |= (0x1 << FRONT_OR_BACK_USER_FLAG_OFFSET);
294         }
295         idx += USERID_BYTES;
296         userIdIdx++;
297     }
298     return true;
299 }
300 
ToDelUserPayLoad(uint8_t * & msg,uint32_t & len) const301 void RelationShipChangeMsg::ToDelUserPayLoad(uint8_t *&msg, uint32_t &len) const
302 {
303     len = DEL_USER_PAYLOAD_LEN;
304     msg = new uint8_t[DEL_USER_PAYLOAD_LEN]();
305     for (int i = 0; i < DEL_USER_PAYLOAD_LEN; i++) {
306         msg[i] |= (userId >> (i * BITS_PER_BYTE)) & 0xFF;
307     }
308 }
309 
ToStopUserPayLoad(uint8_t * & msg,uint32_t & len) const310 void RelationShipChangeMsg::ToStopUserPayLoad(uint8_t *&msg, uint32_t &len) const
311 {
312     len = STOP_USER_PAYLOAD_LEN;
313     msg = new uint8_t[STOP_USER_PAYLOAD_LEN]();
314     for (int i = 0; i < STOP_USER_PAYLOAD_LEN; i++) {
315         msg[i] |= (userId >> (i * BITS_PER_BYTE)) & 0xFF;
316     }
317 }
318 
FromAccountLogoutPayLoad(const cJSON * payloadJson)319 bool RelationShipChangeMsg::FromAccountLogoutPayLoad(const cJSON *payloadJson)
320 {
321     if (payloadJson == NULL) {
322         LOGE("Account logout payloadJson is null.");
323         return false;
324     }
325     int32_t arraySize = cJSON_GetArraySize(payloadJson);
326     if (arraySize < ACCOUNT_LOGOUT_PAYLOAD_LEN || arraySize >= INVALIED_PAYLOAD_SIZE) {
327         LOGE("Payload invalied,the size is %{public}d.", arraySize);
328         return false;
329     }
330     userId = 0;
331     for (uint32_t i = 0; i < USERID_PAYLOAD_LEN; i++) {
332         cJSON *payloadItem = cJSON_GetArrayItem(payloadJson, i);
333         CHECK_NULL_RETURN(payloadItem, false);
334         if (cJSON_IsNumber(payloadItem)) {
335             userId |= (static_cast<uint8_t>(payloadItem->valueint)) << (i * BITS_PER_BYTE);
336         }
337     }
338     accountId = "";
339     for (uint32_t j = USERID_PAYLOAD_LEN; j < ACCOUNT_LOGOUT_PAYLOAD_LEN; j++) {
340         cJSON *payloadItem = cJSON_GetArrayItem(payloadJson, j);
341         CHECK_NULL_RETURN(payloadItem, false);
342         if (cJSON_IsNumber(payloadItem)) {
343             accountId += static_cast<char>(payloadItem->valueint);
344         }
345     }
346     return true;
347 }
348 
FromDeviceUnbindPayLoad(const cJSON * payloadJson)349 bool RelationShipChangeMsg::FromDeviceUnbindPayLoad(const cJSON *payloadJson)
350 {
351     if (payloadJson == NULL) {
352         LOGE("Device unbind payloadJson is null.");
353         return false;
354     }
355     int32_t arraySize = cJSON_GetArraySize(payloadJson);
356     if (arraySize < ACCOUNT_LOGOUT_PAYLOAD_LEN || arraySize >= INVALIED_PAYLOAD_SIZE) {
357         LOGE("Payload invalied,the size is %{public}d.", arraySize);
358         return false;
359     }
360     userId = 0;
361     for (uint32_t i = 0; i < USERID_PAYLOAD_LEN; i++) {
362         cJSON *payloadItem = cJSON_GetArrayItem(payloadJson, i);
363         CHECK_NULL_RETURN(payloadItem, false);
364         if (cJSON_IsNumber(payloadItem)) {
365             userId |= (static_cast<uint8_t>(payloadItem->valueint)) << (i * BITS_PER_BYTE);
366         }
367     }
368     return true;
369 }
370 
FromAppUnbindPayLoad(const cJSON * payloadJson)371 bool RelationShipChangeMsg::FromAppUnbindPayLoad(const cJSON *payloadJson)
372 {
373     if (payloadJson == NULL) {
374         LOGE("App unbind payloadJson is null.");
375         return false;
376     }
377     int32_t arraySize = cJSON_GetArraySize(payloadJson);
378     if (arraySize < ACCOUNT_LOGOUT_PAYLOAD_LEN || arraySize >= INVALIED_PAYLOAD_SIZE) {
379         LOGE("Payload invalied,the size is %{public}d.", arraySize);
380         return false;
381     }
382     userId = 0;
383     for (uint32_t i = 0; i < USERID_PAYLOAD_LEN; i++) {
384         cJSON *payloadItem = cJSON_GetArrayItem(payloadJson, i);
385         CHECK_NULL_RETURN(payloadItem, false);
386         if (cJSON_IsNumber(payloadItem)) {
387             userId |= (static_cast<uint8_t>(payloadItem->valueint)) << (i * BITS_PER_BYTE);
388         }
389     }
390     tokenId = 0;
391     for (uint32_t j = USERID_PAYLOAD_LEN; j < TOKENID_PAYLOAD_LEN; j++) {
392         cJSON *payloadItem = cJSON_GetArrayItem(payloadJson, j);
393         CHECK_NULL_RETURN(payloadItem, false);
394         if (cJSON_IsNumber(payloadItem)) {
395             tokenId |= (static_cast<uint8_t>(payloadItem->valueint)) <<  ((j - USERID_PAYLOAD_LEN) * BITS_PER_BYTE);
396         }
397     }
398     peerTokenId = 0;
399     for (uint32_t j = TOKENID_PAYLOAD_LEN; j < APP_UNBIND_PAYLOAD_LEN; j++) {
400         cJSON *payloadItem = cJSON_GetArrayItem(payloadJson, j);
401         CHECK_NULL_RETURN(payloadItem, false);
402         if (cJSON_IsNumber(payloadItem)) {
403             peerTokenId |= (static_cast<uint8_t>(payloadItem->valueint)) <<
404                 ((j - TOKENID_PAYLOAD_LEN) * BITS_PER_BYTE);
405         }
406     }
407     return true;
408 }
409 
FromSyncFrontOrBackUserIdPayLoad(const cJSON * payloadJson)410 bool RelationShipChangeMsg::FromSyncFrontOrBackUserIdPayLoad(const cJSON *payloadJson)
411 {
412     if (payloadJson == NULL) {
413         LOGE("payloadJson is null.");
414         return false;
415     }
416 
417     int32_t arraySize = cJSON_GetArraySize(payloadJson);
418     if (arraySize < SYNC_FRONT_OR_BACK_USERID_PAYLOAD_MIN_LEN ||
419         arraySize > SYNC_FRONT_OR_BACK_USERID_PAYLOAD_MAX_LEN) {
420         LOGE("Payload invalid, the size is %{public}d.", arraySize);
421         return false;
422     }
423 
424     cJSON *payloadItem = cJSON_GetArrayItem(payloadJson, 0);
425     CHECK_NULL_RETURN(payloadItem, false);
426     uint32_t userIdNum = 0;
427     if (cJSON_IsNumber(payloadItem)) {
428         uint8_t val = static_cast<uint8_t>(payloadItem->valueint);
429         this->syncUserIdFlag = (((val >> NEED_RSP_MASK_OFFSET) & 0x1) == 0x1);
430         userIdNum = ((static_cast<uint8_t>(payloadItem->valueint)) & FOREGROUND_USERID_LEN_MASK);
431     }
432 
433     int32_t effectiveLen = static_cast<int32_t>(userIdNum * USERID_BYTES + 1);
434     if (effectiveLen > arraySize) {
435         LOGE("payload userIdNum invalid, userIdNum: %{public}u, arraySize: %{public}d", userIdNum, arraySize);
436         return false;
437     }
438 
439     uint16_t tempUserId = 0;
440     bool isForegroundUser = false;
441     for (int32_t idx = 1; idx < effectiveLen; idx++) {
442         cJSON *payloadItem = cJSON_GetArrayItem(payloadJson, idx);
443         CHECK_NULL_RETURN(payloadItem, false);
444         if (!cJSON_IsNumber(payloadItem)) {
445             LOGE("Payload invalid, user id not integer");
446             return false;
447         }
448         if ((idx - 1) % USERID_BYTES == 0) {
449             tempUserId |= (static_cast<uint8_t>(payloadItem->valueint));
450         }
451         if ((idx - 1) % USERID_BYTES == 1) {
452             tempUserId |= (static_cast<uint8_t>(payloadItem->valueint) << BITS_PER_BYTE);
453             tempUserId &= FRONT_OR_BACK_USER_FLAG_MASK;
454             isForegroundUser = (((static_cast<uint8_t>(payloadItem->valueint) & FRONT_OR_BACK_FLAG_MASK) >>
455                 FRONT_OR_BACK_USER_FLAG_OFFSET) == 0b1);
456             UserIdInfo userIdInfo(isForegroundUser, tempUserId);
457             this->userIdInfos.push_back(userIdInfo);
458             tempUserId = 0;
459             isForegroundUser = false;
460         }
461     }
462     return true;
463 }
464 
FromDelUserPayLoad(const cJSON * payloadJson)465 bool RelationShipChangeMsg::FromDelUserPayLoad(const cJSON *payloadJson)
466 {
467     if (payloadJson == NULL) {
468         LOGE("FromDelUserPayLoad payloadJson is null.");
469         return false;
470     }
471 
472     int32_t arraySize = cJSON_GetArraySize(payloadJson);
473     if (arraySize < DEL_USER_PAYLOAD_LEN) {
474         LOGE("Payload invalid, the size is %{public}d.", arraySize);
475         return false;
476     }
477     this->userId = 0;
478     for (uint32_t i = 0; i < USERID_PAYLOAD_LEN; i++) {
479         cJSON *payloadItem = cJSON_GetArrayItem(payloadJson, i);
480         CHECK_NULL_RETURN(payloadItem, false);
481         if (cJSON_IsNumber(payloadItem)) {
482             this->userId |= (static_cast<uint8_t>(payloadItem->valueint)) << (i * BITS_PER_BYTE);
483         }
484     }
485     return true;
486 }
487 
FromStopUserPayLoad(const cJSON * payloadJson)488 bool RelationShipChangeMsg::FromStopUserPayLoad(const cJSON *payloadJson)
489 {
490     if (payloadJson == NULL) {
491         LOGE("FromStopUserPayLoad payloadJson is null.");
492         return false;
493     }
494 
495     int32_t arraySize = cJSON_GetArraySize(payloadJson);
496     if (arraySize < STOP_USER_PAYLOAD_LEN) {
497         LOGE("Payload invalid, the size is %{public}d.", arraySize);
498         return false;
499     }
500     this->userId = 0;
501     for (uint32_t i = 0; i < USERID_PAYLOAD_LEN; i++) {
502         cJSON *payloadItem = cJSON_GetArrayItem(payloadJson, i);
503         CHECK_NULL_RETURN(payloadItem, false);
504         if (cJSON_IsNumber(payloadItem)) {
505             this->userId |= (static_cast<uint8_t>(payloadItem->valueint)) << (i * BITS_PER_BYTE);
506         }
507     }
508     return true;
509 }
510 
ToPayLoadJson() const511 cJSON *RelationShipChangeMsg::ToPayLoadJson() const
512 {
513     uint8_t *payload = nullptr;
514     uint32_t len = 0;
515     if (!this->ToBroadcastPayLoad(payload, len)) {
516         LOGE("Get broadcast payload failed");
517         return nullptr;
518     }
519     cJSON *arrayObj = cJSON_CreateArray();
520     if (arrayObj == nullptr) {
521         LOGE("cJSON_CreateArray failed");
522         if (payload != nullptr) {
523             delete[] payload;
524         }
525         return nullptr;
526     }
527     cJSON *numberObj = nullptr;
528     for (uint32_t index = 0; index < len; index++) {
529         numberObj = cJSON_CreateNumber(payload[index]);
530         if (numberObj == nullptr || !cJSON_AddItemToArray(arrayObj, numberObj)) {
531             cJSON_Delete(numberObj);
532             cJSON_Delete(arrayObj);
533             if (payload != nullptr) {
534                 delete[] payload;
535             }
536             return nullptr;
537         }
538     }
539     if (payload != nullptr) {
540         delete[] payload;
541     }
542     return arrayObj;
543 }
544 
ToJson() const545 std::string RelationShipChangeMsg::ToJson() const
546 {
547     cJSON *msg = cJSON_CreateObject();
548     if (msg == NULL) {
549         LOGE("failed to create cjson object");
550         return "";
551     }
552     cJSON_AddNumberToObject(msg, MSG_TYPE, (uint32_t)type);
553     cJSON *arrayObj = ToPayLoadJson();
554     if (arrayObj == nullptr) {
555         LOGE("ArrayObj is nullptr.");
556         cJSON_Delete(msg);
557         return "";
558     }
559     cJSON_AddItemToObject(msg, MSG_VALUE, arrayObj);
560 
561     cJSON *udidArrayObj = cJSON_CreateArray();
562     if (udidArrayObj == nullptr) {
563         LOGE("cJSON_CreateArray failed");
564         cJSON_Delete(msg);
565         return "";
566     }
567     cJSON *udidStringObj = nullptr;
568     for (uint32_t index = 0; index < peerUdids.size(); index++) {
569         udidStringObj = cJSON_CreateString(peerUdids[index].c_str());
570         if (udidStringObj == nullptr || !cJSON_AddItemToArray(udidArrayObj, udidStringObj)) {
571             cJSON_Delete(udidStringObj);
572             cJSON_Delete(udidArrayObj);
573             cJSON_Delete(msg);
574             return "";
575         }
576     }
577     cJSON_AddItemToObject(msg, MSG_PEER_UDID, udidArrayObj);
578     cJSON_AddStringToObject(msg, MSG_ACCOUNTID, accountName.c_str());
579     char *retStr = cJSON_PrintUnformatted(msg);
580     if (retStr == nullptr) {
581         LOGE("to json is nullptr.");
582         cJSON_Delete(msg);
583         return "";
584     }
585     std::string ret = std::string(retStr);
586     cJSON_Delete(msg);
587     cJSON_free(retStr);
588     return ret;
589 }
590 
FromJson(const std::string & msgJson)591 bool RelationShipChangeMsg::FromJson(const std::string &msgJson)
592 {
593     cJSON *msgObj = cJSON_Parse(msgJson.c_str());
594     if (msgObj == NULL) {
595         LOGE("parse msg failed");
596         return false;
597     }
598 
599     cJSON *typeJson = cJSON_GetObjectItem(msgObj, MSG_TYPE);
600     if (typeJson == NULL || !cJSON_IsNumber(typeJson) || !IsChangeTypeValid(typeJson->valueint)) {
601         LOGE("parse type failed.");
602         cJSON_Delete(msgObj);
603         return false;
604     }
605     this->type = (RelationShipChangeType)typeJson->valueint;
606 
607     cJSON *payloadJson = cJSON_GetObjectItem(msgObj, MSG_VALUE);
608     if (payloadJson == NULL || !cJSON_IsArray(payloadJson)) {
609         LOGE("parse payload failed.");
610         cJSON_Delete(msgObj);
611         return false;
612     }
613     if (!this->FromBroadcastPayLoad(payloadJson, type)) {
614         LOGE("parse payload error.");
615         cJSON_Delete(msgObj);
616         return false;
617     }
618 
619     cJSON *peerUdidJson = cJSON_GetObjectItem(msgObj, MSG_PEER_UDID);
620     if (peerUdidJson == NULL || !cJSON_IsString(peerUdidJson)) {
621         LOGE("parse peer udid failed.");
622         cJSON_Delete(msgObj);
623         return false;
624     }
625     this->peerUdid = std::string(peerUdidJson->valuestring);
626     cJSON_Delete(msgObj);
627     return true;
628 }
629 
SyncTrustRelationShip(const RelationShipChangeMsg & msg)630 std::string ReleationShipSyncMgr::SyncTrustRelationShip(const RelationShipChangeMsg &msg)
631 {
632     return msg.ToJson();
633 }
634 
ParseTrustRelationShipChange(const std::string & msgJson)635 RelationShipChangeMsg ReleationShipSyncMgr::ParseTrustRelationShipChange(const std::string &msgJson)
636 {
637     RelationShipChangeMsg msgObj;
638     if (!msgObj.FromJson(msgJson)) {
639         LOGE("Parse json failed");
640     }
641     return msgObj;
642 }
643 
ToString() const644 const std::string RelationShipChangeMsg::ToString() const
645 {
646     std::string ret;
647     ret += "{ MsgType: " + std::to_string(static_cast<uint32_t>(type));
648     ret += ", userId: " + std::to_string(userId);
649     ret += ", accountId: " + GetAnonyString(accountId);
650     ret += ", tokenId: " + std::to_string(tokenId);
651     ret += ", peerUdids: " + GetAnonyStringList(peerUdids);
652     ret += ", peerUdid: " + GetAnonyString(peerUdid);
653     ret += ", accountName: " + GetAnonyString(accountName);
654     ret += ", syncUserIdFlag: " + std::to_string(syncUserIdFlag);
655     ret += ", userIds: " + GetUserIdInfoList(userIdInfos) + " }";
656     return ret;
657 }
658 
ToString() const659 const std::string UserIdInfo::ToString() const
660 {
661     std::string ret;
662     ret += "{ " + std::to_string(this->isForeground);
663     ret += ", userId: " + std::to_string(this->userId) + " }";
664     return ret;
665 }
666 
GetUserIdInfoList(const std::vector<UserIdInfo> & list)667 const std::string GetUserIdInfoList(const std::vector<UserIdInfo> &list)
668 {
669     std::string temp = "[ ";
670     bool flag = false;
671     for (auto const &userId : list) {
672         temp += userId.ToString() + PRINT_LIST_SPLIT;
673         flag = true;
674     }
675     if (flag) {
676         temp.erase(temp.length() - LIST_SPLIT_LEN);
677     }
678     temp += " ]";
679     return temp;
680 }
681 
GetFrontAndBackUserIdInfos(const std::vector<UserIdInfo> & remoteUserIdInfos,std::vector<UserIdInfo> & foregroundUserIdInfos,std::vector<UserIdInfo> & backgroundUserIdInfos)682 void GetFrontAndBackUserIdInfos(const std::vector<UserIdInfo> &remoteUserIdInfos,
683     std::vector<UserIdInfo> &foregroundUserIdInfos, std::vector<UserIdInfo> &backgroundUserIdInfos)
684 {
685     foregroundUserIdInfos.clear();
686     backgroundUserIdInfos.clear();
687     for (auto const &u : remoteUserIdInfos) {
688         if (u.isForeground) {
689             foregroundUserIdInfos.push_back(u);
690         } else {
691             backgroundUserIdInfos.push_back(u);
692         }
693     }
694 }
695 } // DistributedHardware
696 } // OHOS