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