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 "data_manager.h"
17
18#include "broadcast_manager.h"
19#include "common_defs.h"
20#include "device_auth.h"
21#include "device_auth_defines.h"
22#include "hc_dev_info.h"
23#include "hc_file.h"
24#include "hc_log.h"
25#include "hc_mutex.h"
26#include "hc_string_vector.h"
27#include "hc_types.h"
28#include "key_manager.h"
29#include "securec.h"
30#include "hidump_adapter.h"
31#include "os_account_adapter.h"
32#include "pseudonym_manager.h"
33#include "security_label_adapter.h"
34
35typedef struct {
36    DECLARE_TLV_STRUCT(10)
37    TlvString name;
38    TlvString id;
39    TlvUint32 type;
40    TlvInt32 visibility;
41    TlvInt32 expireTime;
42    TlvString userId;
43    TlvString sharedUserId;
44    TlvBuffer managers;
45    TlvBuffer friends;
46    TlvUint8 upgradeFlag;
47} TlvGroupElement;
48DECLEAR_INIT_FUNC(TlvGroupElement)
49DECLARE_TLV_VECTOR(TlvGroupVec, TlvGroupElement)
50
51typedef struct {
52    uint8_t credential;
53    uint8_t devType;
54    uint8_t source;
55    int64_t userId;
56    uint64_t lastTm;
57} DevAuthFixedLenInfo;
58DECLARE_TLV_FIX_LENGTH_TYPE(TlvDevAuthFixedLenInfo, DevAuthFixedLenInfo)
59DECLEAR_INIT_FUNC(TlvDevAuthFixedLenInfo)
60
61typedef struct {
62    DECLARE_TLV_STRUCT(8)
63    TlvString groupId;
64    TlvString udid;
65    TlvString authId;
66    TlvString userId;
67    TlvString serviceType;
68    TlvBuffer ext;
69    TlvDevAuthFixedLenInfo info;
70    TlvUint8 upgradeFlag;
71} TlvDeviceElement;
72DECLEAR_INIT_FUNC(TlvDeviceElement)
73DECLARE_TLV_VECTOR(TlvDeviceVec, TlvDeviceElement)
74
75typedef struct {
76    DECLARE_TLV_STRUCT(3)
77    TlvInt32 version;
78    TlvGroupVec groups;
79    TlvDeviceVec devices;
80} HCDataBaseV1;
81DECLEAR_INIT_FUNC(HCDataBaseV1)
82
83DEFINE_TLV_FIX_LENGTH_TYPE(TlvDevAuthFixedLenInfo, NO_REVERT)
84
85BEGIN_TLV_STRUCT_DEFINE(TlvGroupElement, 0x0001)
86    TLV_MEMBER(TlvString, name, 0x4001)
87    TLV_MEMBER(TlvString, id, 0x4002)
88    TLV_MEMBER(TlvUint32, type, 0x4003)
89    TLV_MEMBER(TlvInt32, visibility, 0x4004)
90    TLV_MEMBER(TlvInt32, expireTime, 0x4005)
91    TLV_MEMBER(TlvString, userId, 0x4006)
92    TLV_MEMBER(TlvString, sharedUserId, 0x4007)
93    TLV_MEMBER(TlvBuffer, managers, 0x4008)
94    TLV_MEMBER(TlvBuffer, friends, 0x4009)
95    TLV_MEMBER(TlvUint8, upgradeFlag, 0x400A)
96END_TLV_STRUCT_DEFINE()
97IMPLEMENT_TLV_VECTOR(TlvGroupVec, TlvGroupElement, 1)
98
99BEGIN_TLV_STRUCT_DEFINE(TlvDeviceElement, 0x0002)
100    TLV_MEMBER(TlvString, groupId, 0x4101)
101    TLV_MEMBER(TlvString, udid, 0x4102)
102    TLV_MEMBER(TlvString, authId, 0x4103)
103    TLV_MEMBER(TlvString, userId, 0x4107)
104    TLV_MEMBER(TlvString, serviceType, 0x4104)
105    TLV_MEMBER(TlvBuffer, ext, 0x4105)
106    TLV_MEMBER(TlvDevAuthFixedLenInfo, info, 0x4106)
107    TLV_MEMBER(TlvUint8, upgradeFlag, 0x4108)
108END_TLV_STRUCT_DEFINE()
109IMPLEMENT_TLV_VECTOR(TlvDeviceVec, TlvDeviceElement, 1)
110
111BEGIN_TLV_STRUCT_DEFINE(HCDataBaseV1, 0x0001)
112    TLV_MEMBER(TlvInt32, version, 0x6001)
113    TLV_MEMBER(TlvGroupVec, groups, 0x6002)
114    TLV_MEMBER(TlvDeviceVec, devices, 0x6003)
115END_TLV_STRUCT_DEFINE()
116
117IMPLEMENT_HC_VECTOR(GroupEntryVec, TrustedGroupEntry*, 1)
118IMPLEMENT_HC_VECTOR(DeviceEntryVec, TrustedDeviceEntry*, 1)
119
120typedef struct {
121    int32_t osAccountId;
122    GroupEntryVec groups;
123    DeviceEntryVec devices;
124} OsAccountTrustedInfo;
125
126DECLARE_HC_VECTOR(DeviceAuthDb, OsAccountTrustedInfo)
127IMPLEMENT_HC_VECTOR(DeviceAuthDb, OsAccountTrustedInfo, 1)
128
129#define MAX_DB_PATH_LEN 256
130
131static HcMutex *g_databaseMutex = NULL;
132static DeviceAuthDb g_deviceauthDb;
133
134static bool EndWithZero(HcParcel *parcel)
135{
136    const char *p = GetParcelLastChar(parcel);
137    if (p == NULL) {
138        return false;
139    }
140    return (*p == '\0');
141}
142
143static bool LoadStringVectorFromParcel(StringVector *vec, HcParcel *parcel)
144{
145    uint32_t strLen = 0;
146    do {
147        if (!ParcelReadUint32(parcel, &strLen)) {
148            return true;
149        }
150        if ((strLen == 0) || (strLen > MAX_STRING_LEN)) {
151            return false;
152        }
153        HcString str = CreateString();
154        ClearParcel(&str.parcel);
155        if (!ParcelReadParcel(parcel, &str.parcel, strLen, false) ||
156            !EndWithZero(&str.parcel)) {
157            DeleteString(&str);
158            return false;
159        } else {
160            if (vec->pushBack(vec, &str) == NULL) {
161                DeleteString(&str);
162                return false;
163            }
164        }
165    } while (1);
166}
167
168static bool SaveStringVectorToParcel(const StringVector *vec, HcParcel *parcel)
169{
170    uint32_t index;
171    HcString *str = NULL;
172    FOR_EACH_HC_VECTOR(*vec, index, str) {
173        uint32_t len = StringLength(str) + sizeof(char);
174        if (!ParcelWriteUint32(parcel, len)) {
175            return false;
176        }
177        if (!ParcelWrite(parcel, GetParcelData(&str->parcel), GetParcelDataSize(&str->parcel))) {
178            return false;
179        }
180    }
181    return true;
182}
183
184static bool GetOsAccountInfoPathCe(int32_t osAccountId, char *infoPath, uint32_t pathBufferLen)
185{
186    const char *beginPath = GetStorageDirPathCe();
187    if (beginPath == NULL) {
188        LOGE("[DB]: Failed to get the storage path!");
189        return false;
190    }
191    if (sprintf_s(infoPath, pathBufferLen, "%s/%d/deviceauth/hcgroup.dat", beginPath, osAccountId) <= 0) {
192        LOGE("[DB]: Failed to generate db file path!");
193        return false;
194    }
195    return true;
196}
197
198static bool GetOsAccountInfoPathDe(int32_t osAccountId, char *infoPath, uint32_t pathBufferLen)
199{
200    const char *beginPath = GetStorageDirPath();
201    if (beginPath == NULL) {
202        LOGE("[DB]: Failed to get the storage path dir!");
203        return false;
204    }
205    int32_t writeByteNum;
206    if (osAccountId == DEFAULT_OS_ACCOUNT) {
207        writeByteNum = sprintf_s(infoPath, pathBufferLen, "%s/hcgroup.dat", beginPath);
208    } else {
209        writeByteNum = sprintf_s(infoPath, pathBufferLen, "%s/hcgroup%d.dat", beginPath, osAccountId);
210    }
211    if (writeByteNum <= 0) {
212        LOGE("[DB]: sprintf_s fail!");
213        return false;
214    }
215    return true;
216}
217
218static bool GetOsAccountInfoPath(int32_t osAccountId, char *infoPath, uint32_t pathBufferLen)
219{
220    if (IsOsAccountSupported())  {
221        return GetOsAccountInfoPathCe(osAccountId, infoPath, pathBufferLen);
222    } else {
223        return GetOsAccountInfoPathDe(osAccountId, infoPath, pathBufferLen);
224    }
225}
226
227bool GenerateGroupEntryFromEntry(const TrustedGroupEntry *entry, TrustedGroupEntry *returnEntry)
228{
229    if (HC_VECTOR_SIZE(&entry->managers) <= 0) {
230        LOGE("[DB]: The group owner is lost!");
231        return false;
232    }
233    HcString entryOwner = HC_VECTOR_GET(&entry->managers, 0);
234    if (!StringSet(&returnEntry->name, entry->name)) {
235        LOGE("[DB]: Failed to copy groupName!");
236        return false;
237    }
238    if (!StringSet(&returnEntry->id, entry->id)) {
239        LOGE("[DB]: Failed to copy groupId!");
240        return false;
241    }
242    if (!StringSet(&returnEntry->userId, entry->userId)) {
243        LOGE("[DB]: Failed to copy userId!");
244        return false;
245    }
246    if (!StringSet(&returnEntry->sharedUserId, entry->sharedUserId)) {
247        LOGE("[DB]: Failed to copy sharedUserId!");
248        return false;
249    }
250    returnEntry->type = entry->type;
251    returnEntry->visibility = entry->visibility;
252    returnEntry->upgradeFlag = entry->upgradeFlag;
253    returnEntry->expireTime = entry->expireTime;
254    HcString ownerName = CreateString();
255    if (!StringSet(&ownerName, entryOwner)) {
256        LOGE("[DB]: Failed to copy groupOwner!");
257        DeleteString(&ownerName);
258        return false;
259    }
260    if (returnEntry->managers.pushBack(&returnEntry->managers, &ownerName) == NULL) {
261        LOGE("[DB]: Failed to push groupOwner to managers!");
262        DeleteString(&ownerName);
263        return false;
264    }
265    return true;
266}
267
268bool GenerateDeviceEntryFromEntry(const TrustedDeviceEntry *entry, TrustedDeviceEntry *returnEntry)
269{
270    returnEntry->groupEntry = NULL;
271    if (!StringSet(&returnEntry->groupId, entry->groupId)) {
272        LOGE("[DB]: Failed to copy udid!");
273        return false;
274    }
275    if (!StringSet(&returnEntry->udid, entry->udid)) {
276        LOGE("[DB]: Failed to copy udid!");
277        return false;
278    }
279    if (!StringSet(&returnEntry->authId, entry->authId)) {
280        LOGE("[DB]: Failed to copy authId!");
281        return false;
282    }
283    if (!StringSet(&returnEntry->userId, entry->userId)) {
284        LOGE("[DB]: Failed to copy userId!");
285        return false;
286    }
287    if (!StringSet(&returnEntry->serviceType, entry->serviceType)) {
288        LOGE("[DB]: Failed to copy serviceType!");
289        return false;
290    }
291    returnEntry->credential = entry->credential;
292    returnEntry->devType = entry->devType;
293    returnEntry->upgradeFlag = entry->upgradeFlag;
294    returnEntry->source = entry->source;
295    returnEntry->lastTm = entry->lastTm;
296    return true;
297}
298
299static bool GenerateGroupEntryFromTlv(TlvGroupElement *group, TrustedGroupEntry *entry)
300{
301    if (!StringSet(&entry->name, group->name.data)) {
302        LOGE("[DB]: Failed to load groupName from tlv!");
303        return false;
304    }
305    if (!StringSet(&entry->id, group->id.data)) {
306        LOGE("[DB]: Failed to load groupId from tlv!");
307        return false;
308    }
309    if (!StringSet(&entry->userId, group->userId.data)) {
310        LOGE("[DB]: Failed to load userId from tlv!");
311        return false;
312    }
313    if (!StringSet(&entry->sharedUserId, group->sharedUserId.data)) {
314        LOGE("[DB]: Failed to load sharedUserId from tlv!");
315        return false;
316    }
317    if (!LoadStringVectorFromParcel(&entry->managers, &group->managers.data)) {
318        LOGE("[DB]: Failed to load managers from tlv!");
319        return false;
320    }
321    if (!LoadStringVectorFromParcel(&entry->friends, &group->friends.data)) {
322        LOGE("[DB]: Failed to load friends from tlv!");
323        return false;
324    }
325    entry->type = group->type.data;
326    entry->visibility = group->visibility.data;
327    entry->upgradeFlag = group->upgradeFlag.data;
328    entry->expireTime = group->expireTime.data;
329    return true;
330}
331
332static bool GenerateDeviceEntryFromTlv(TlvDeviceElement *device, TrustedDeviceEntry *deviceEntry)
333{
334    deviceEntry->groupEntry = NULL;
335    if (!StringSet(&deviceEntry->groupId, device->groupId.data)) {
336        LOGE("[DB]: Failed to load groupId from tlv!");
337        return false;
338    }
339    if (!StringSet(&deviceEntry->udid, device->udid.data)) {
340        LOGE("[DB]: Failed to load udid from tlv!");
341        return false;
342    }
343    if (!StringSet(&deviceEntry->authId, device->authId.data)) {
344        LOGE("[DB]: Failed to load authId from tlv!");
345        return false;
346    }
347    if (!StringSet(&deviceEntry->userId, device->userId.data)) {
348        LOGE("[DB]: Failed to load userId from tlv!");
349        return false;
350    }
351    if (!StringSet(&deviceEntry->serviceType, device->serviceType.data)) {
352        LOGE("[DB]: Failed to load serviceType from tlv!");
353        return false;
354    }
355    if (!ParcelCopy(&device->ext.data, &deviceEntry->ext)) {
356        LOGE("[DB]: Failed to load external data from tlv!");
357        return false;
358    }
359    deviceEntry->credential = device->info.data.credential;
360    deviceEntry->devType = device->info.data.devType;
361    deviceEntry->upgradeFlag = device->upgradeFlag.data;
362    deviceEntry->source = device->info.data.source;
363    deviceEntry->lastTm = device->info.data.lastTm;
364    return true;
365}
366
367static bool LoadGroups(HCDataBaseV1 *db, GroupEntryVec *vec)
368{
369    uint32_t index;
370    TlvGroupElement *group = NULL;
371    FOR_EACH_HC_VECTOR(db->groups.data, index, group) {
372        if (group == NULL) {
373            continue;
374        }
375        TrustedGroupEntry *entry = CreateGroupEntry();
376        if (entry == NULL) {
377            LOGE("[DB]: Failed to allocate entry memory!");
378            ClearGroupEntryVec(vec);
379            return false;
380        }
381        if (!GenerateGroupEntryFromTlv(group, entry)) {
382            DestroyGroupEntry(entry);
383            ClearGroupEntryVec(vec);
384            return false;
385        }
386        if (vec->pushBackT(vec, entry) == NULL) {
387            LOGE("[DB]: Failed to push entry to vec!");
388            DestroyGroupEntry(entry);
389            ClearGroupEntryVec(vec);
390            return false;
391        }
392    }
393    return true;
394}
395
396static bool LoadDevices(HCDataBaseV1 *db, DeviceEntryVec *vec)
397{
398    uint32_t index;
399    TlvDeviceElement *device = NULL;
400    FOR_EACH_HC_VECTOR(db->devices.data, index, device) {
401        if (device == NULL) {
402            continue;
403        }
404        TrustedDeviceEntry *entry = CreateDeviceEntry();
405        if (entry == NULL) {
406            LOGE("[DB]: Failed to allocate entry memory!");
407            ClearDeviceEntryVec(vec);
408            return false;
409        }
410        if (!GenerateDeviceEntryFromTlv(device, entry)) {
411            DestroyDeviceEntry(entry);
412            ClearDeviceEntryVec(vec);
413            return false;
414        }
415        if (vec->pushBackT(vec, entry) == NULL) {
416            LOGE("[DB]: Failed to push entry to vec!");
417            DestroyDeviceEntry(entry);
418            ClearDeviceEntryVec(vec);
419            return false;
420        }
421    }
422    return true;
423}
424
425static bool ReadInfoFromParcel(HcParcel *parcel, OsAccountTrustedInfo *info)
426{
427    bool ret = false;
428    HCDataBaseV1 dbv1;
429    TLV_INIT(HCDataBaseV1, &dbv1)
430    if (DecodeTlvMessage((TlvBase *)&dbv1, parcel, false)) {
431        if (!LoadGroups(&dbv1, &info->groups)) {
432            TLV_DEINIT(dbv1)
433            return false;
434        }
435        if (!LoadDevices(&dbv1, &info->devices)) {
436            ClearGroupEntryVec(&info->groups);
437            TLV_DEINIT(dbv1)
438            return false;
439        }
440        ret = true;
441    } else {
442        LOGE("[DB]: Decode Tlv Message Failed!");
443    }
444    TLV_DEINIT(dbv1)
445    return ret;
446}
447
448static bool ReadParcelFromFile(const char *filePath, HcParcel *parcel)
449{
450    FileHandle file;
451    int ret = HcFileOpen(filePath, MODE_FILE_READ, &file);
452    if (ret != 0) {
453        LOGE("[DB]: Failed to open database file!");
454        return false;
455    }
456    SetSecurityLabel(filePath, SECURITY_LABEL_S2);
457    int fileSize = HcFileSize(file);
458    if (fileSize <= 0) {
459        LOGE("[DB]: The database file size is invalid!");
460        HcFileClose(file);
461        return false;
462    }
463    char *fileData = (char *)HcMalloc(fileSize, 0);
464    if (fileData == NULL) {
465        LOGE("[DB]: Failed to allocate fileData memory!");
466        HcFileClose(file);
467        return false;
468    }
469    if (HcFileRead(file, fileData, fileSize) != fileSize) {
470        LOGE("[DB]: Read file error!");
471        HcFileClose(file);
472        HcFree(fileData);
473        return false;
474    }
475    HcFileClose(file);
476    if (!ParcelWrite(parcel, fileData, fileSize)) {
477        LOGE("[DB]: parcel write error!");
478        HcFree(fileData);
479        return false;
480    }
481    HcFree(fileData);
482    return true;
483}
484
485static bool SaveParcelToFile(const char *filePath, HcParcel *parcel)
486{
487    FileHandle file;
488    int ret = HcFileOpen(filePath, MODE_FILE_WRITE, &file);
489    if (ret != HC_SUCCESS) {
490        LOGE("[DB]: Failed to open database file!");
491        return false;
492    }
493    SetSecurityLabel(filePath, SECURITY_LABEL_S2);
494    int fileSize = (int)GetParcelDataSize(parcel);
495    const char *fileData = GetParcelData(parcel);
496    int writeSize = HcFileWrite(file, fileData, fileSize);
497    HcFileClose(file);
498    if (writeSize == fileSize) {
499        return true;
500    } else {
501        LOGE("[DB]: write file error!");
502        return false;
503    }
504}
505
506static void LoadOsAccountDb(int32_t osAccountId)
507{
508    char filePath[MAX_DB_PATH_LEN] = { 0 };
509    if (!GetOsAccountInfoPath(osAccountId, filePath, MAX_DB_PATH_LEN)) {
510        LOGE("[DB]: Failed to get os account info path!");
511        return;
512    }
513    HcParcel parcel = CreateParcel(0, 0);
514    if (!ReadParcelFromFile(filePath, &parcel)) {
515        DeleteParcel(&parcel);
516        return;
517    }
518    OsAccountTrustedInfo info;
519    info.osAccountId = osAccountId;
520    info.groups = CreateGroupEntryVec();
521    info.devices = CreateDeviceEntryVec();
522    if (!ReadInfoFromParcel(&parcel, &info)) {
523        DestroyGroupEntryVec(&info.groups);
524        DestroyDeviceEntryVec(&info.devices);
525        DeleteParcel(&parcel);
526        return;
527    }
528    DeleteParcel(&parcel);
529    if (g_deviceauthDb.pushBackT(&g_deviceauthDb, info) == NULL) {
530        LOGE("[DB]: Failed to push osAccountInfo to database!");
531        ClearGroupEntryVec(&info.groups);
532        ClearDeviceEntryVec(&info.devices);
533        return;
534    }
535    LOGI("[DB]: Load os account db successfully! [Id]: %d", osAccountId);
536}
537
538static void TryMoveDeDataToCe(int32_t osAccountId)
539{
540    char ceFilePath[MAX_DB_PATH_LEN] = { 0 };
541    if (!GetOsAccountInfoPathCe(osAccountId, ceFilePath, MAX_DB_PATH_LEN)) {
542        LOGE("[DB]: Failed to get ce database file path!");
543        return;
544    }
545    HcParcel parcelCe = CreateParcel(0, 0);
546    if (ReadParcelFromFile(ceFilePath, &parcelCe)) {
547        LOGI("[DB]: ce data exists, no need to move.");
548        DeleteParcel(&parcelCe);
549        return;
550    }
551    DeleteParcel(&parcelCe);
552    char deFilePath[MAX_DB_PATH_LEN] = { 0 };
553    if (!GetOsAccountInfoPathDe(osAccountId, deFilePath, MAX_DB_PATH_LEN)) {
554        LOGE("[DB]: Failed to get de database file path!");
555        return;
556    }
557    HcParcel parcelDe = CreateParcel(0, 0);
558    if (!ReadParcelFromFile(deFilePath, &parcelDe)) {
559        LOGI("[DB]: no data in de file, no need to move!");
560        DeleteParcel(&parcelDe);
561        return;
562    }
563    if (!SaveParcelToFile(ceFilePath, &parcelDe)) {
564        LOGE("[DB]: save de parcel to ce file failed!");
565        DeleteParcel(&parcelDe);
566        return;
567    }
568    DeleteParcel(&parcelDe);
569    parcelCe = CreateParcel(0, 0);
570    if (!ReadParcelFromFile(ceFilePath, &parcelCe)) {
571        LOGE("[DB]: Failed to read ce file data!");
572        DeleteParcel(&parcelCe);
573        return;
574    }
575    DeleteParcel(&parcelCe);
576    LOGI("[DB]: move de data to ce successfully, remove de file!");
577    HcFileRemove(deFilePath);
578}
579
580static void RemoveOsAccountTrustedInfo(int32_t osAccountId)
581{
582    uint32_t index = 0;
583    OsAccountTrustedInfo *info = NULL;
584    FOR_EACH_HC_VECTOR(g_deviceauthDb, index, info) {
585        if (info->osAccountId == osAccountId) {
586            OsAccountTrustedInfo deleteInfo;
587            HC_VECTOR_POPELEMENT(&g_deviceauthDb, &deleteInfo, index);
588            ClearGroupEntryVec(&deleteInfo.groups);
589            ClearDeviceEntryVec(&deleteInfo.devices);
590            return;
591        }
592    }
593}
594
595static void LoadOsAccountDbCe(int32_t osAccountId)
596{
597    TryMoveDeDataToCe(osAccountId);
598    RemoveOsAccountTrustedInfo(osAccountId);
599    LoadOsAccountDb(osAccountId);
600}
601
602static void OnOsAccountUnlocked(int32_t osAccountId)
603{
604    (void)LockHcMutex(g_databaseMutex);
605    LoadOsAccountDbCe(osAccountId);
606    UnlockHcMutex(g_databaseMutex);
607}
608
609static void OnOsAccountRemoved(int32_t osAccountId)
610{
611    LOGI("[DB]: os account is removed, osAccountId: %d", osAccountId);
612    (void)LockHcMutex(g_databaseMutex);
613    RemoveOsAccountTrustedInfo(osAccountId);
614    UnlockHcMutex(g_databaseMutex);
615}
616
617static bool IsOsAccountDataLoaded(int32_t osAccountId)
618{
619    uint32_t index = 0;
620    OsAccountTrustedInfo *info = NULL;
621    FOR_EACH_HC_VECTOR(g_deviceauthDb, index, info) {
622        if (info->osAccountId == osAccountId) {
623            return true;
624        }
625    }
626    return false;
627}
628
629static void LoadDataIfNotLoaded(int32_t osAccountId)
630{
631    if (IsOsAccountDataLoaded(osAccountId)) {
632        return;
633    }
634    LOGI("[DB]: data has not been loaded, load it, osAccountId: %d", osAccountId);
635    LoadOsAccountDbCe(osAccountId);
636}
637
638static OsAccountTrustedInfo *GetTrustedInfoByOsAccountId(int32_t osAccountId)
639{
640    if (IsOsAccountSupported()) {
641        LoadDataIfNotLoaded(osAccountId);
642    }
643    uint32_t index = 0;
644    OsAccountTrustedInfo *info = NULL;
645    FOR_EACH_HC_VECTOR(g_deviceauthDb, index, info) {
646        if (info->osAccountId == osAccountId) {
647            return info;
648        }
649    }
650    LOGI("[DB]: Create a new os account database cache! [Id]: %d", osAccountId);
651    OsAccountTrustedInfo newInfo;
652    newInfo.osAccountId = osAccountId;
653    newInfo.groups = CreateGroupEntryVec();
654    newInfo.devices = CreateDeviceEntryVec();
655    OsAccountTrustedInfo *returnInfo = g_deviceauthDb.pushBackT(&g_deviceauthDb, newInfo);
656    if (returnInfo == NULL) {
657        LOGE("[DB]: Failed to push osAccountInfo to database!");
658        DestroyGroupEntryVec(&newInfo.groups);
659        DestroyDeviceEntryVec(&newInfo.devices);
660    }
661    return returnInfo;
662}
663
664static void LoadDeviceAuthDb(void)
665{
666    if (IsOsAccountSupported()) {
667        return;
668    }
669    (void)LockHcMutex(g_databaseMutex);
670    StringVector osAccountDbNameVec = CreateStrVector();
671    HcFileGetSubFileName(GetStorageDirPath(), &osAccountDbNameVec);
672    uint32_t index;
673    HcString *dbName;
674    FOR_EACH_HC_VECTOR(osAccountDbNameVec, index, dbName) {
675        int32_t osAccountId;
676        const char *osAccountIdStr = StringGet(dbName);
677        if (osAccountIdStr == NULL) {
678            continue;
679        }
680        if (strcmp(osAccountIdStr, "hcgroup.dat") == 0) {
681            LoadOsAccountDb(DEFAULT_OS_ACCOUNT);
682        } else if (sscanf_s(osAccountIdStr, "hcgroup%d.dat", &osAccountId) == 1) {
683            LoadOsAccountDb(osAccountId);
684        }
685    }
686    DestroyStrVector(&osAccountDbNameVec);
687    UnlockHcMutex(g_databaseMutex);
688}
689
690static bool SetGroupElement(TlvGroupElement *element, TrustedGroupEntry *entry)
691{
692    if (!StringSet(&element->name.data, entry->name)) {
693        LOGE("[DB]: Failed to copy groupName!");
694        return false;
695    }
696    if (!StringSet(&element->id.data, entry->id)) {
697        LOGE("[DB]: Failed to copy groupId!");
698        return false;
699    }
700    if (!StringSet(&element->userId.data, entry->userId)) {
701        LOGE("[DB]: Failed to copy userId!");
702        return false;
703    }
704    if (!StringSet(&element->sharedUserId.data, entry->sharedUserId)) {
705        LOGE("[DB]: Failed to copy sharedUserId!");
706        return false;
707    }
708    element->type.data = entry->type;
709    element->visibility.data = entry->visibility;
710    element->upgradeFlag.data = entry->upgradeFlag;
711    element->expireTime.data = entry->expireTime;
712    if (!SaveStringVectorToParcel(&entry->managers, &element->managers.data)) {
713        LOGE("[DB]: Failed to copy managers!");
714        return false;
715    }
716    if (!SaveStringVectorToParcel(&entry->friends, &element->friends.data)) {
717        LOGE("[DB]: Failed to copy friends!");
718        return false;
719    }
720    return true;
721}
722
723static bool SetDeviceElement(TlvDeviceElement *element, TrustedDeviceEntry *entry)
724{
725    if (!StringSet(&element->groupId.data, entry->groupId)) {
726        LOGE("[DB]: Failed to copy groupId!");
727        return false;
728    }
729    if (!StringSet(&element->udid.data, entry->udid)) {
730        LOGE("[DB]: Failed to copy udid!");
731        return false;
732    }
733    if (!StringSet(&element->authId.data, entry->authId)) {
734        LOGE("[DB]: Failed to copy authId!");
735        return false;
736    }
737    if (!StringSet(&element->userId.data, entry->userId)) {
738        LOGE("[DB]: Failed to copy userId!");
739        return false;
740    }
741    if (!StringSet(&element->serviceType.data, entry->serviceType)) {
742        LOGE("[DB]: Failed to copy serviceType!");
743        return false;
744    }
745    if (!ParcelCopy(&element->ext.data, &entry->ext)) {
746        LOGE("[DB]: Failed to copy external data!");
747        return false;
748    }
749    element->info.data.credential = entry->credential;
750    element->info.data.devType = entry->devType;
751    element->upgradeFlag.data = entry->upgradeFlag;
752    element->info.data.source = entry->source;
753    element->info.data.lastTm = entry->lastTm;
754    return true;
755}
756
757static bool SaveGroups(const GroupEntryVec *vec, HCDataBaseV1 *db)
758{
759    uint32_t index;
760    TrustedGroupEntry **entry;
761    FOR_EACH_HC_VECTOR(*vec, index, entry) {
762        TlvGroupElement tmp;
763        TlvGroupElement *element = db->groups.data.pushBack(&db->groups.data, &tmp);
764        if (element == NULL) {
765            return false;
766        }
767        TLV_INIT(TlvGroupElement, element);
768        if (!SetGroupElement(element, *entry)) {
769            TLV_DEINIT((*element));
770            return false;
771        }
772    }
773    return true;
774}
775
776static bool SaveDevices(const DeviceEntryVec *vec, HCDataBaseV1 *db)
777{
778    uint32_t index;
779    TrustedDeviceEntry **entry;
780    FOR_EACH_HC_VECTOR(*vec, index, entry) {
781        TlvDeviceElement tmp;
782        TlvDeviceElement *element = db->devices.data.pushBack(&db->devices.data, &tmp);
783        if (element == NULL) {
784            return false;
785        }
786        TLV_INIT(TlvDeviceElement, element);
787        if (!SetDeviceElement(element, *entry)) {
788            TLV_DEINIT((*element));
789            return false;
790        }
791    }
792    return true;
793}
794
795static bool SaveInfoToParcel(const OsAccountTrustedInfo *info, HcParcel *parcel)
796{
797    int32_t ret = false;
798    HCDataBaseV1 dbv1;
799    TLV_INIT(HCDataBaseV1, &dbv1)
800    dbv1.version.data = 1;
801    do {
802        if (!SaveGroups(&info->groups, &dbv1)) {
803            break;
804        }
805        if (!SaveDevices(&info->devices, &dbv1)) {
806            break;
807        }
808        if (!EncodeTlvMessage((TlvBase *)&dbv1, parcel)) {
809            LOGE("[DB]: Encode Tlv Message failed!");
810            break;
811        }
812        ret = true;
813    } while (0);
814    TLV_DEINIT(dbv1)
815    return ret;
816}
817
818static bool CompareQueryGroupParams(const QueryGroupParams *params, const TrustedGroupEntry *entry)
819{
820    if ((params->groupId != NULL) && (strcmp(params->groupId, StringGet(&entry->id)) != 0)) {
821        return false;
822    }
823    if ((params->groupName != NULL) && (strcmp(params->groupName, StringGet(&entry->name)) != 0)) {
824        return false;
825    }
826    if ((params->userId != NULL) && (strcmp(params->userId, StringGet(&entry->userId)) != 0)) {
827        return false;
828    }
829    if ((params->sharedUserId != NULL) && (strcmp(params->sharedUserId, StringGet(&entry->sharedUserId)) != 0)) {
830        return false;
831    }
832    if ((params->groupType != ALL_GROUP) && (params->groupType != entry->type)) {
833        return false;
834    }
835    if ((params->groupVisibility != ALL_GROUP_VISIBILITY) && (params->groupVisibility != entry->visibility)) {
836        return false;
837    }
838    if (params->ownerName != NULL) {
839        HcString entryOwner = HC_VECTOR_GET(&entry->managers, 0);
840        if (strcmp(params->ownerName, StringGet(&entryOwner)) != 0) {
841            return false;
842        }
843    }
844    return true;
845}
846
847static bool CompareQueryDeviceParams(const QueryDeviceParams *params, const TrustedDeviceEntry *entry)
848{
849    if ((params->groupId != NULL) && (strcmp(params->groupId, StringGet(&entry->groupId)) != 0)) {
850        return false;
851    }
852    if ((params->udid != NULL) && (strcmp(params->udid, StringGet(&entry->udid)) != 0)) {
853        return false;
854    }
855    if ((params->authId != NULL) && (strcmp(params->authId, StringGet(&entry->authId)) != 0)) {
856        return false;
857    }
858    if ((params->userId != NULL) && (strcmp(params->userId, StringGet(&entry->userId)) != 0)) {
859        return false;
860    }
861    return true;
862}
863
864static TrustedGroupEntry **QueryGroupEntryPtrIfMatch(const GroupEntryVec *vec, const QueryGroupParams *params)
865{
866    uint32_t index;
867    TrustedGroupEntry **entry;
868    FOR_EACH_HC_VECTOR(*vec, index, entry) {
869        if (CompareQueryGroupParams(params, *entry)) {
870            return entry;
871        }
872    }
873    return NULL;
874}
875
876static TrustedDeviceEntry **QueryDeviceEntryPtrIfMatch(const DeviceEntryVec *vec, const QueryDeviceParams *params)
877{
878    uint32_t index;
879    TrustedDeviceEntry **entry;
880    FOR_EACH_HC_VECTOR(*vec, index, entry) {
881        if (CompareQueryDeviceParams(params, *entry)) {
882            return entry;
883        }
884    }
885    return NULL;
886}
887
888static int32_t AddGroupNameToReturn(const TrustedGroupEntry *groupInfo, CJson *json)
889{
890    const char *groupName = StringGet(&groupInfo->name);
891    if (groupName == NULL) {
892        LOGE("Failed to get groupName from groupInfo!");
893        return HC_ERR_NULL_PTR;
894    }
895    if (AddStringToJson(json, FIELD_GROUP_NAME, groupName) != HC_SUCCESS) {
896        LOGE("Failed to add groupName to json!");
897        return HC_ERR_JSON_FAIL;
898    }
899    return HC_SUCCESS;
900}
901
902static int32_t AddGroupIdToReturn(const TrustedGroupEntry *groupInfo, CJson *json)
903{
904    const char *groupId = StringGet(&groupInfo->id);
905    if (groupId == NULL) {
906        LOGE("Failed to get groupId from groupInfo!");
907        return HC_ERR_NULL_PTR;
908    }
909    if (AddStringToJson(json, FIELD_GROUP_ID, groupId) != HC_SUCCESS) {
910        LOGE("Failed to add groupId to json!");
911        return HC_ERR_JSON_FAIL;
912    }
913    return HC_SUCCESS;
914}
915
916static int32_t AddGroupOwnerToReturn(const TrustedGroupEntry *groupInfo, CJson *json)
917{
918    HcString entryManager = HC_VECTOR_GET(&groupInfo->managers, 0);
919    const char *groupOwner = StringGet(&entryManager);
920    if (groupOwner == NULL) {
921        LOGE("Failed to get groupOwner from groupInfo!");
922        return HC_ERR_NULL_PTR;
923    }
924    if (AddStringToJson(json, FIELD_GROUP_OWNER, groupOwner) != HC_SUCCESS) {
925        LOGE("Failed to add groupOwner to json!");
926        return HC_ERR_JSON_FAIL;
927    }
928    return HC_SUCCESS;
929}
930
931static int32_t AddGroupTypeToReturn(const TrustedGroupEntry *groupInfo, CJson *json)
932{
933    int32_t groupType = groupInfo->type;
934    if (AddIntToJson(json, FIELD_GROUP_TYPE, groupType) != HC_SUCCESS) {
935        LOGE("Failed to add groupType to json!");
936        return HC_ERR_JSON_FAIL;
937    }
938    return HC_SUCCESS;
939}
940
941static int32_t AddGroupVisibilityToReturn(const TrustedGroupEntry *groupInfo, CJson *json)
942{
943    int groupVisibility = groupInfo->visibility;
944    if (AddIntToJson(json, FIELD_GROUP_VISIBILITY, groupVisibility) != HC_SUCCESS) {
945        LOGE("Failed to add groupType to json!");
946        return HC_ERR_JSON_FAIL;
947    }
948    return HC_SUCCESS;
949}
950
951static int32_t AddUserIdToReturnIfAccountGroup(const TrustedGroupEntry *groupInfo, CJson *json)
952{
953    if ((groupInfo->type != ACROSS_ACCOUNT_AUTHORIZE_GROUP) && (groupInfo->type != IDENTICAL_ACCOUNT_GROUP)) {
954        return HC_SUCCESS;
955    }
956    const char *userId = StringGet(&groupInfo->userId);
957    if (userId == NULL) {
958        LOGE("Failed to get userId from groupInfo!");
959        return HC_ERR_NULL_PTR;
960    }
961    if (AddStringToJson(json, FIELD_USER_ID, userId) != HC_SUCCESS) {
962        LOGE("Failed to add userId to json!");
963        return HC_ERR_JSON_FAIL;
964    }
965    return HC_SUCCESS;
966}
967
968static int32_t AddSharedUserIdToReturnIfAcrossAccountGroup(const TrustedGroupEntry *groupInfo, CJson *json)
969{
970    if (groupInfo->type != ACROSS_ACCOUNT_AUTHORIZE_GROUP) {
971        return HC_SUCCESS;
972    }
973    const char *sharedUserId = StringGet(&groupInfo->sharedUserId);
974    if (sharedUserId == NULL) {
975        LOGE("Failed to get sharedUserId from groupInfo!");
976        return HC_ERR_NULL_PTR;
977    }
978    if (AddStringToJson(json, FIELD_SHARED_USER_ID, sharedUserId) != HC_SUCCESS) {
979        LOGE("Failed to add sharedUserId to json!");
980        return HC_ERR_JSON_FAIL;
981    }
982    return HC_SUCCESS;
983}
984
985static int32_t AddAuthIdToReturn(const TrustedDeviceEntry *deviceInfo, CJson *json)
986{
987    const char *authId = StringGet(&deviceInfo->authId);
988    if (authId == NULL) {
989        LOGE("Failed to get authId from deviceInfo!");
990        return HC_ERR_NULL_PTR;
991    }
992    if (AddStringToJson(json, FIELD_AUTH_ID, authId) != HC_SUCCESS) {
993        LOGE("Failed to add authId to json!");
994        return HC_ERR_JSON_FAIL;
995    }
996    return HC_SUCCESS;
997}
998
999static int32_t AddCredentialTypeToReturn(const TrustedDeviceEntry *deviceInfo, CJson *json)
1000{
1001    int credentialType = deviceInfo->credential;
1002    if (AddIntToJson(json, FIELD_CREDENTIAL_TYPE, credentialType) != HC_SUCCESS) {
1003        LOGE("Failed to add credentialType to json!");
1004        return HC_ERR_JSON_FAIL;
1005    }
1006    return HC_SUCCESS;
1007}
1008
1009static int32_t AddUserTypeToReturn(const TrustedDeviceEntry *deviceInfo, CJson *json)
1010{
1011    int userType = deviceInfo->devType;
1012    if (AddIntToJson(json, FIELD_USER_TYPE, userType) != HC_SUCCESS) {
1013        LOGE("Failed to add userType to json!");
1014        return HC_ERR_JSON_FAIL;
1015    }
1016    return HC_SUCCESS;
1017}
1018
1019static int32_t GenerateMessage(const TrustedGroupEntry *groupEntry, char **returnGroupInfo)
1020{
1021    if (groupEntry == NULL) {
1022        LOGE("groupEntry is null!");
1023        return HC_ERR_NULL_PTR;
1024    }
1025    CJson *message = CreateJson();
1026    if (message == NULL) {
1027        LOGE("Failed to allocate message memory!");
1028        return HC_ERR_ALLOC_MEMORY;
1029    }
1030    int32_t result = GenerateReturnGroupInfo(groupEntry, message);
1031    if (result != HC_SUCCESS) {
1032        FreeJson(message);
1033        return result;
1034    }
1035    char *messageStr = PackJsonToString(message);
1036    FreeJson(message);
1037    if (messageStr == NULL) {
1038        LOGE("Failed to convert json to string!");
1039        return HC_ERR_JSON_FAIL;
1040    }
1041    *returnGroupInfo = messageStr;
1042    return HC_SUCCESS;
1043}
1044
1045static void PostGroupCreatedMsg(const TrustedGroupEntry *groupEntry)
1046{
1047    if (!IsBroadcastSupported()) {
1048        return;
1049    }
1050    char *messageStr = NULL;
1051    if (GenerateMessage(groupEntry, &messageStr) != HC_SUCCESS) {
1052        return;
1053    }
1054    GetBroadcaster()->postOnGroupCreated(messageStr);
1055    FreeJsonString(messageStr);
1056}
1057
1058static void PostGroupDeletedMsg(const TrustedGroupEntry *groupEntry)
1059{
1060    if (!IsBroadcastSupported()) {
1061        return;
1062    }
1063    char *messageStr = NULL;
1064    if (GenerateMessage(groupEntry, &messageStr) != HC_SUCCESS) {
1065        return;
1066    }
1067    GetBroadcaster()->postOnGroupDeleted(messageStr);
1068    FreeJsonString(messageStr);
1069}
1070
1071static void PostDeviceBoundMsg(OsAccountTrustedInfo *info, const TrustedDeviceEntry *deviceEntry)
1072{
1073    if (!IsBroadcastSupported()) {
1074        return;
1075    }
1076    QueryGroupParams groupParams = InitQueryGroupParams();
1077    groupParams.groupId = StringGet(&deviceEntry->groupId);
1078    TrustedGroupEntry **groupEntryPtr = QueryGroupEntryPtrIfMatch(&info->groups, &groupParams);
1079    if (groupEntryPtr != NULL) {
1080        char *messageStr = NULL;
1081        if (GenerateMessage(*groupEntryPtr, &messageStr) != HC_SUCCESS) {
1082            return;
1083        }
1084        GetBroadcaster()->postOnDeviceBound(StringGet(&deviceEntry->udid), messageStr);
1085        FreeJsonString(messageStr);
1086    }
1087}
1088
1089static bool IsSelfDeviceEntry(const TrustedDeviceEntry *deviceEntry)
1090{
1091    char selfUdid[INPUT_UDID_LEN] = { 0 };
1092    int32_t res = HcGetUdid((uint8_t *)selfUdid, INPUT_UDID_LEN);
1093    if (res != HC_SUCCESS) {
1094        LOGE("Failed to get local udid! res: %d", res);
1095        return false;
1096    }
1097    const char *entryUdid = StringGet(&deviceEntry->udid);
1098    if (entryUdid == NULL) {
1099        LOGE("The entryUdid is NULL!");
1100        return false;
1101    }
1102    return strcmp(selfUdid, entryUdid) == 0;
1103}
1104
1105static void PostDeviceUnBoundMsg(OsAccountTrustedInfo *info, const TrustedDeviceEntry *deviceEntry)
1106{
1107    if (!IsBroadcastSupported()) {
1108        return;
1109    }
1110    const char *groupId = StringGet(&deviceEntry->groupId);
1111    const char *udid = StringGet(&deviceEntry->udid);
1112    QueryGroupParams groupParams = InitQueryGroupParams();
1113    groupParams.groupId = groupId;
1114    TrustedGroupEntry **groupEntryPtr = QueryGroupEntryPtrIfMatch(&info->groups, &groupParams);
1115    if (groupEntryPtr != NULL) {
1116        char *messageStr = NULL;
1117        if (GenerateMessage(*groupEntryPtr, &messageStr) != HC_SUCCESS) {
1118            return;
1119        }
1120        GetBroadcaster()->postOnDeviceUnBound(udid, messageStr);
1121        FreeJsonString(messageStr);
1122    }
1123    QueryDeviceParams deviceParams = InitQueryDeviceParams();
1124    deviceParams.udid = udid;
1125    if (QueryDeviceEntryPtrIfMatch(&info->devices, &deviceParams) == NULL) {
1126        GetBroadcaster()->postOnDeviceNotTrusted(udid);
1127        if (!IsSelfDeviceEntry(deviceEntry)) {
1128            (void)DeleteMk(info->osAccountId, udid);
1129            (void)DeletePseudonymPsk(info->osAccountId, udid);
1130        }
1131    }
1132}
1133
1134static void DeletePdidByDeviceEntry(int32_t osAccountId, const TrustedDeviceEntry *deviceEntry)
1135{
1136    if (IsSelfDeviceEntry(deviceEntry)) {
1137        return;
1138    }
1139    const char *userId = StringGet(&deviceEntry->userId);
1140    if (userId == NULL) {
1141        LOGW("userId is null!");
1142        return;
1143    }
1144    if (deviceEntry->credential != ASYMMETRIC_CRED) {
1145        LOGW("credential type is not asymmetric!");
1146        return;
1147    }
1148    PseudonymManager *manager = GetPseudonymInstance();
1149    if (manager == NULL) {
1150        LOGE("Pseudonym manager is null!");
1151        return;
1152    }
1153    int32_t res = manager->deletePseudonymId(osAccountId, userId);
1154    if (res != HC_SUCCESS) {
1155        LOGE("Failed to delete pdid!");
1156    } else {
1157        LOGI("Delete pdid successfully!");
1158    }
1159}
1160
1161QueryGroupParams InitQueryGroupParams(void)
1162{
1163    QueryGroupParams params = {
1164        .groupId = NULL,
1165        .groupName = NULL,
1166        .ownerName = NULL,
1167        .userId = NULL,
1168        .groupType = ALL_GROUP,
1169        .groupVisibility = ALL_GROUP_VISIBILITY
1170    };
1171    return params;
1172}
1173
1174QueryDeviceParams InitQueryDeviceParams(void)
1175{
1176    QueryDeviceParams params = {
1177        .groupId = NULL,
1178        .udid = NULL,
1179        .authId = NULL,
1180        .userId = NULL
1181    };
1182    return params;
1183}
1184
1185TrustedGroupEntry *CreateGroupEntry(void)
1186{
1187    TrustedGroupEntry *ptr = (TrustedGroupEntry *)HcMalloc(sizeof(TrustedGroupEntry), 0);
1188    if (ptr == NULL) {
1189        LOGE("[DB]: Failed to allocate groupEntry memory!");
1190        return NULL;
1191    }
1192    ptr->name = CreateString();
1193    ptr->id = CreateString();
1194    ptr->userId = CreateString();
1195    ptr->sharedUserId = CreateString();
1196    ptr->managers = CreateStrVector();
1197    ptr->friends = CreateStrVector();
1198    return ptr;
1199}
1200
1201void DestroyGroupEntry(TrustedGroupEntry *groupEntry)
1202{
1203    if (groupEntry == NULL) {
1204        return;
1205    }
1206    DeleteString(&groupEntry->name);
1207    DeleteString(&groupEntry->id);
1208    DeleteString(&groupEntry->userId);
1209    DeleteString(&groupEntry->sharedUserId);
1210    DestroyStrVector(&groupEntry->managers);
1211    DestroyStrVector(&groupEntry->friends);
1212    HcFree(groupEntry);
1213}
1214
1215TrustedGroupEntry *DeepCopyGroupEntry(const TrustedGroupEntry *entry)
1216{
1217    TrustedGroupEntry *returnEntry = CreateGroupEntry();
1218    if (returnEntry == NULL) {
1219        return NULL;
1220    }
1221    if (!GenerateGroupEntryFromEntry(entry, returnEntry)) {
1222        DestroyGroupEntry(returnEntry);
1223        return NULL;
1224    }
1225    return returnEntry;
1226}
1227
1228TrustedDeviceEntry *CreateDeviceEntry(void)
1229{
1230    TrustedDeviceEntry *ptr = (TrustedDeviceEntry *)HcMalloc(sizeof(TrustedDeviceEntry), 0);
1231    if (ptr == NULL) {
1232        LOGE("[DB]: Failed to allocate deviceEntry memory!");
1233        return NULL;
1234    }
1235    ptr->groupId = CreateString();
1236    ptr->udid = CreateString();
1237    ptr->authId = CreateString();
1238    ptr->userId = CreateString();
1239    ptr->serviceType = CreateString();
1240    ptr->ext = CreateParcel(0, 0);
1241    return ptr;
1242}
1243
1244void DestroyDeviceEntry(TrustedDeviceEntry *deviceEntry)
1245{
1246    if (deviceEntry == NULL) {
1247        return;
1248    }
1249    DeleteString(&deviceEntry->groupId);
1250    DeleteString(&deviceEntry->udid);
1251    DeleteString(&deviceEntry->authId);
1252    DeleteString(&deviceEntry->userId);
1253    DeleteString(&deviceEntry->serviceType);
1254    DeleteParcel(&deviceEntry->ext);
1255    HcFree(deviceEntry);
1256}
1257
1258TrustedDeviceEntry *DeepCopyDeviceEntry(const TrustedDeviceEntry *entry)
1259{
1260    if (entry == NULL) {
1261        return NULL;
1262    }
1263    TrustedDeviceEntry *returnEntry = CreateDeviceEntry();
1264    if (returnEntry == NULL) {
1265        return NULL;
1266    }
1267    if (!GenerateDeviceEntryFromEntry(entry, returnEntry)) {
1268        DestroyDeviceEntry(returnEntry);
1269        return NULL;
1270    }
1271    return returnEntry;
1272}
1273
1274void ClearGroupEntryVec(GroupEntryVec *vec)
1275{
1276    uint32_t index;
1277    TrustedGroupEntry **entry;
1278    FOR_EACH_HC_VECTOR(*vec, index, entry) {
1279        DestroyGroupEntry(*entry);
1280    }
1281    DESTROY_HC_VECTOR(GroupEntryVec, vec);
1282}
1283
1284void ClearDeviceEntryVec(DeviceEntryVec *vec)
1285{
1286    uint32_t index;
1287    TrustedDeviceEntry **entry;
1288    FOR_EACH_HC_VECTOR(*vec, index, entry) {
1289        DestroyDeviceEntry(*entry);
1290    }
1291    DESTROY_HC_VECTOR(DeviceEntryVec, vec);
1292}
1293
1294int32_t GenerateReturnGroupInfo(const TrustedGroupEntry *groupEntry, CJson *returnJson)
1295{
1296    int32_t result;
1297    if (((result = AddGroupNameToReturn(groupEntry, returnJson)) != HC_SUCCESS) ||
1298        ((result = AddGroupIdToReturn(groupEntry, returnJson)) != HC_SUCCESS) ||
1299        ((result = AddGroupOwnerToReturn(groupEntry, returnJson)) != HC_SUCCESS) ||
1300        ((result = AddGroupTypeToReturn(groupEntry, returnJson)) != HC_SUCCESS) ||
1301        ((result = AddGroupVisibilityToReturn(groupEntry, returnJson)) != HC_SUCCESS) ||
1302        ((result = AddUserIdToReturnIfAccountGroup(groupEntry, returnJson)) != HC_SUCCESS) ||
1303        ((result = AddSharedUserIdToReturnIfAcrossAccountGroup(groupEntry, returnJson)) != HC_SUCCESS)) {
1304        return result;
1305    }
1306    return HC_SUCCESS;
1307}
1308
1309int32_t GenerateReturnDevInfo(const TrustedDeviceEntry *deviceEntry, CJson *returnJson)
1310{
1311    int32_t result;
1312    if (((result = AddAuthIdToReturn(deviceEntry, returnJson)) != HC_SUCCESS) ||
1313        ((result = AddCredentialTypeToReturn(deviceEntry, returnJson)) != HC_SUCCESS) ||
1314        ((result = AddUserTypeToReturn(deviceEntry, returnJson)) != HC_SUCCESS)) {
1315        return result;
1316    }
1317    return HC_SUCCESS;
1318}
1319
1320int32_t AddGroup(int32_t osAccountId, const TrustedGroupEntry *groupEntry)
1321{
1322    LOGI("[DB]: Start to add a group to database! [OsAccountId]: %d", osAccountId);
1323    if (groupEntry == NULL) {
1324        LOGE("[DB]: The input groupEntry is NULL!");
1325        return HC_ERR_NULL_PTR;
1326    }
1327    (void)LockHcMutex(g_databaseMutex);
1328    OsAccountTrustedInfo *info = GetTrustedInfoByOsAccountId(osAccountId);
1329    if (info == NULL) {
1330        UnlockHcMutex(g_databaseMutex);
1331        return HC_ERR_INVALID_PARAMS;
1332    }
1333    TrustedGroupEntry *newEntry = DeepCopyGroupEntry(groupEntry);
1334    if (newEntry == NULL) {
1335        UnlockHcMutex(g_databaseMutex);
1336        return HC_ERR_MEMORY_COPY;
1337    }
1338    QueryGroupParams params = InitQueryGroupParams();
1339    params.groupId = StringGet(&groupEntry->id);
1340    TrustedGroupEntry **oldEntryPtr = QueryGroupEntryPtrIfMatch(&info->groups, &params);
1341    if (oldEntryPtr != NULL) {
1342        DestroyGroupEntry(*oldEntryPtr);
1343        *oldEntryPtr = newEntry;
1344        PostGroupCreatedMsg(newEntry);
1345        UnlockHcMutex(g_databaseMutex);
1346        LOGI("[DB]: Replace an old group successfully! [GroupType]: %u", groupEntry->type);
1347        return HC_SUCCESS;
1348    }
1349    if (info->groups.pushBackT(&info->groups, newEntry) == NULL) {
1350        DestroyGroupEntry(newEntry);
1351        UnlockHcMutex(g_databaseMutex);
1352        LOGE("[DB]: Failed to push groupEntry to vec!");
1353        return HC_ERR_MEMORY_COPY;
1354    }
1355    PostGroupCreatedMsg(newEntry);
1356    UnlockHcMutex(g_databaseMutex);
1357    LOGI("[DB]: Add a group to database successfully! [GroupType]: %u", groupEntry->type);
1358    return HC_SUCCESS;
1359}
1360
1361int32_t AddTrustedDevice(int32_t osAccountId, const TrustedDeviceEntry *deviceEntry)
1362{
1363    LOGI("[DB]: Start to add a trusted device to database! [OsAccountId]: %d", osAccountId);
1364    if (deviceEntry == NULL) {
1365        LOGE("[DB]: The input deviceEntry is NULL!");
1366        return HC_ERR_NULL_PTR;
1367    }
1368    (void)LockHcMutex(g_databaseMutex);
1369    OsAccountTrustedInfo *info = GetTrustedInfoByOsAccountId(osAccountId);
1370    if (info == NULL) {
1371        UnlockHcMutex(g_databaseMutex);
1372        return HC_ERR_INVALID_PARAMS;
1373    }
1374    TrustedDeviceEntry *newEntry = DeepCopyDeviceEntry(deviceEntry);
1375    if (newEntry == NULL) {
1376        UnlockHcMutex(g_databaseMutex);
1377        return HC_ERR_MEMORY_COPY;
1378    }
1379    QueryDeviceParams params = InitQueryDeviceParams();
1380    params.udid = StringGet(&deviceEntry->udid);
1381    params.groupId = StringGet(&deviceEntry->groupId);
1382    TrustedDeviceEntry **oldEntryPtr = QueryDeviceEntryPtrIfMatch(&info->devices, &params);
1383    if (oldEntryPtr != NULL) {
1384        DestroyDeviceEntry(*oldEntryPtr);
1385        *oldEntryPtr = newEntry;
1386        PostDeviceBoundMsg(info, newEntry);
1387        UnlockHcMutex(g_databaseMutex);
1388        LOGI("[DB]: Replace an old trusted device successfully!");
1389        return HC_SUCCESS;
1390    }
1391    if (info->devices.pushBackT(&info->devices, newEntry) == NULL) {
1392        DestroyDeviceEntry(newEntry);
1393        UnlockHcMutex(g_databaseMutex);
1394        LOGE("[DB]: Failed to push deviceEntry to vec!");
1395        return HC_ERR_MEMORY_COPY;
1396    }
1397    PostDeviceBoundMsg(info, newEntry);
1398    UnlockHcMutex(g_databaseMutex);
1399    LOGI("[DB]: Add a trusted device to database successfully!");
1400    return HC_SUCCESS;
1401}
1402
1403int32_t DelGroup(int32_t osAccountId, const QueryGroupParams *params)
1404{
1405    LOGI("[DB]: Start to delete groups from database! [OsAccountId]: %d", osAccountId);
1406    if (params == NULL) {
1407        LOGE("[DB]: The input params is NULL!");
1408        return HC_ERR_NULL_PTR;
1409    }
1410    (void)LockHcMutex(g_databaseMutex);
1411    OsAccountTrustedInfo *info = GetTrustedInfoByOsAccountId(osAccountId);
1412    if (info == NULL) {
1413        UnlockHcMutex(g_databaseMutex);
1414        return HC_ERR_INVALID_PARAMS;
1415    }
1416    int32_t count = 0;
1417    uint32_t index = 0;
1418    TrustedGroupEntry **entry = NULL;
1419    while (index < HC_VECTOR_SIZE(&info->groups)) {
1420        entry = info->groups.getp(&info->groups, index);
1421        if ((entry == NULL) || (*entry == NULL) || (!CompareQueryGroupParams(params, *entry))) {
1422            index++;
1423            continue;
1424        }
1425        TrustedGroupEntry *popEntry;
1426        HC_VECTOR_POPELEMENT(&info->groups, &popEntry, index);
1427        PostGroupDeletedMsg(popEntry);
1428        LOGI("[DB]: Delete a group from database successfully! [GroupType]: %u", popEntry->type);
1429        DestroyGroupEntry(popEntry);
1430        count++;
1431    }
1432    UnlockHcMutex(g_databaseMutex);
1433    LOGI("[DB]: Number of groups deleted: %d", count);
1434    return HC_SUCCESS;
1435}
1436
1437int32_t DelTrustedDevice(int32_t osAccountId, const QueryDeviceParams *params)
1438{
1439    LOGI("[DB]: Start to delete devices from database! [OsAccountId]: %d", osAccountId);
1440    if (params == NULL) {
1441        LOGE("[DB]: The input params is NULL!");
1442        return HC_ERR_NULL_PTR;
1443    }
1444    (void)LockHcMutex(g_databaseMutex);
1445    OsAccountTrustedInfo *info = GetTrustedInfoByOsAccountId(osAccountId);
1446    if (info == NULL) {
1447        UnlockHcMutex(g_databaseMutex);
1448        return HC_ERR_INVALID_PARAMS;
1449    }
1450    int32_t count = 0;
1451    uint32_t index = 0;
1452    TrustedDeviceEntry **entry = NULL;
1453    while (index < HC_VECTOR_SIZE(&info->devices)) {
1454        entry = info->devices.getp(&info->devices, index);
1455        if ((entry == NULL) || (*entry == NULL) || (!CompareQueryDeviceParams(params, *entry))) {
1456            index++;
1457            continue;
1458        }
1459        TrustedDeviceEntry *popEntry;
1460        HC_VECTOR_POPELEMENT(&info->devices, &popEntry, index);
1461        PostDeviceUnBoundMsg(info, popEntry);
1462        DeletePdidByDeviceEntry(osAccountId, popEntry);
1463        LOGI("[DB]: Delete a trusted device from database successfully!");
1464        DestroyDeviceEntry(popEntry);
1465        count++;
1466    }
1467    UnlockHcMutex(g_databaseMutex);
1468    LOGI("[DB]: Number of trusted devices deleted: %d", count);
1469    return HC_SUCCESS;
1470}
1471
1472int32_t QueryGroups(int32_t osAccountId, const QueryGroupParams *params, GroupEntryVec *vec)
1473{
1474    if ((params == NULL) || (vec == NULL)) {
1475        LOGE("[DB]: The input params or vec is NULL!");
1476        return HC_ERR_NULL_PTR;
1477    }
1478    (void)LockHcMutex(g_databaseMutex);
1479    OsAccountTrustedInfo *info = GetTrustedInfoByOsAccountId(osAccountId);
1480    if (info == NULL) {
1481        UnlockHcMutex(g_databaseMutex);
1482        return HC_ERR_INVALID_PARAMS;
1483    }
1484    uint32_t index;
1485    TrustedGroupEntry **entry;
1486    FOR_EACH_HC_VECTOR(info->groups, index, entry) {
1487        if (!CompareQueryGroupParams(params, *entry)) {
1488            continue;
1489        }
1490        TrustedGroupEntry *newEntry = DeepCopyGroupEntry(*entry);
1491        if (newEntry == NULL) {
1492            continue;
1493        }
1494        if (vec->pushBackT(vec, newEntry) == NULL) {
1495            LOGE("[DB]: Failed to push entry to vec!");
1496            DestroyGroupEntry(newEntry);
1497        }
1498    }
1499    UnlockHcMutex(g_databaseMutex);
1500    return HC_SUCCESS;
1501}
1502
1503int32_t QueryDevices(int32_t osAccountId, const QueryDeviceParams *params, DeviceEntryVec *vec)
1504{
1505    if ((params == NULL) || (vec == NULL)) {
1506        LOGE("[DB]: The input params or vec is NULL!");
1507        return HC_ERR_NULL_PTR;
1508    }
1509    (void)LockHcMutex(g_databaseMutex);
1510    OsAccountTrustedInfo *info = GetTrustedInfoByOsAccountId(osAccountId);
1511    if (info == NULL) {
1512        UnlockHcMutex(g_databaseMutex);
1513        return HC_ERR_INVALID_PARAMS;
1514    }
1515    uint32_t index;
1516    TrustedDeviceEntry **entry;
1517    FOR_EACH_HC_VECTOR(info->devices, index, entry) {
1518        if (!CompareQueryDeviceParams(params, *entry)) {
1519            continue;
1520        }
1521        TrustedDeviceEntry *newEntry = DeepCopyDeviceEntry(*entry);
1522        if (newEntry == NULL) {
1523            continue;
1524        }
1525        if (vec->pushBackT(vec, newEntry) == NULL) {
1526            LOGE("[DB]: Failed to push entry to vec!");
1527            DestroyDeviceEntry(newEntry);
1528        }
1529    }
1530    UnlockHcMutex(g_databaseMutex);
1531    return HC_SUCCESS;
1532}
1533
1534int32_t SaveOsAccountDb(int32_t osAccountId)
1535{
1536    (void)LockHcMutex(g_databaseMutex);
1537    OsAccountTrustedInfo *info = GetTrustedInfoByOsAccountId(osAccountId);
1538    if (info == NULL) {
1539        UnlockHcMutex(g_databaseMutex);
1540        return HC_ERR_INVALID_PARAMS;
1541    }
1542    HcParcel parcel = CreateParcel(0, 0);
1543    if (!SaveInfoToParcel(info, &parcel)) {
1544        DeleteParcel(&parcel);
1545        UnlockHcMutex(g_databaseMutex);
1546        return HC_ERR_MEMORY_COPY;
1547    }
1548    char filePath[MAX_DB_PATH_LEN] = { 0 };
1549    if (!GetOsAccountInfoPath(osAccountId, filePath, MAX_DB_PATH_LEN)) {
1550        DeleteParcel(&parcel);
1551        UnlockHcMutex(g_databaseMutex);
1552        return HC_ERROR;
1553    }
1554    if (!SaveParcelToFile(filePath, &parcel)) {
1555        DeleteParcel(&parcel);
1556        UnlockHcMutex(g_databaseMutex);
1557        return HC_ERR_MEMORY_COPY;
1558    }
1559    DeleteParcel(&parcel);
1560    UnlockHcMutex(g_databaseMutex);
1561    LOGI("[DB]: Save an os account database successfully! [Id]: %d", osAccountId);
1562    return HC_SUCCESS;
1563}
1564
1565void ReloadOsAccountDb(int32_t osAccountId)
1566{
1567    if (g_databaseMutex == NULL) {
1568        LOGE("[DB]: not initialized!");
1569        return;
1570    }
1571    (void)LockHcMutex(g_databaseMutex);
1572    LoadOsAccountDbCe(osAccountId);
1573    UnlockHcMutex(g_databaseMutex);
1574}
1575
1576#ifdef DEV_AUTH_HIVIEW_ENABLE
1577static void DumpGroup(int fd, const TrustedGroupEntry *group)
1578{
1579    dprintf(fd, "||----------------------------Group----------------------------|                   |\n");
1580    dprintf(fd, "||%-12s = %-46.8s|                   |\n", "name", StringGet(&group->name));
1581    dprintf(fd, "||%-12s = %-46.8s|                   |\n", "id", StringGet(&group->id));
1582    dprintf(fd, "||%-12s = %-46d|                   |\n", "type", group->type);
1583    dprintf(fd, "||%-12s = %-46d|                   |\n", "visibility", group->visibility);
1584    dprintf(fd, "||%-12s = %-46d|                   |\n", "upgradeFlag", group->upgradeFlag);
1585    dprintf(fd, "||%-12s = %-46d|                   |\n", "expireTime", group->expireTime);
1586    HcString entryOwner = HC_VECTOR_GET(&group->managers, 0);
1587    dprintf(fd, "||%-12s = %-46.8s|                   |\n", "ownerName", StringGet(&entryOwner));
1588    dprintf(fd, "||%-12s = %-46.8s|                   |\n", "userId", StringGet(&group->userId));
1589    dprintf(fd, "||%-12s = %-46.8s|                   |\n", "sharedUserId", StringGet(&group->sharedUserId));
1590    dprintf(fd, "||----------------------------Group----------------------------|                   |\n");
1591}
1592
1593static void DumpDevice(int fd, const TrustedDeviceEntry *device)
1594{
1595    dprintf(fd, "|||--------------------DEV--------------------|                                    |\n");
1596    dprintf(fd, "|||%-12s = %-28.8s|                                    |\n", "groupId", StringGet(&device->groupId));
1597    dprintf(fd, "|||%-12s = %-28.8s|                                    |\n", "udid", StringGet(&device->udid));
1598    dprintf(fd, "|||%-12s = %-28.8s|                                    |\n", "authId", StringGet(&device->authId));
1599    dprintf(fd, "|||%-12s = %-28.8s|                                    |\n", "userId", StringGet(&device->userId));
1600    dprintf(fd, "|||%-12s = %-28.8s|                                    |\n", "serviceType",
1601        StringGet(&device->serviceType));
1602    dprintf(fd, "|||%-12s = %-28d|                                    |\n", "credential", device->credential);
1603    dprintf(fd, "|||%-12s = %-28d|                                    |\n", "devType", device->devType);
1604    dprintf(fd, "|||%-12s = %-28d|                                    |\n", "upgradeFlag", device->upgradeFlag);
1605    dprintf(fd, "|||%-12s = %-28d|                                    |\n", "credSource", device->source);
1606    dprintf(fd, "|||--------------------DEV--------------------|                                    |\n");
1607}
1608
1609static void DumpDb(int fd, const OsAccountTrustedInfo *db)
1610{
1611    const GroupEntryVec *groups = &db->groups;
1612    const DeviceEntryVec *devices = &db->devices;
1613    dprintf(fd, "|-------------------------------------DataBase-------------------------------------|\n");
1614    dprintf(fd, "|%-12s = %-67d|\n", "osAccountId", db->osAccountId);
1615    dprintf(fd, "|%-12s = %-67d|\n", "groupNum", groups->size(groups));
1616    dprintf(fd, "|%-12s = %-67d|\n", "deviceNum", devices->size(devices));
1617    uint32_t index;
1618    TrustedGroupEntry **groupEntry;
1619    FOR_EACH_HC_VECTOR(*groups, index, groupEntry) {
1620        DumpGroup(fd, *groupEntry);
1621    }
1622    TrustedDeviceEntry **deviceEntry;
1623    FOR_EACH_HC_VECTOR(*devices, index, deviceEntry) {
1624        DumpDevice(fd, *deviceEntry);
1625    }
1626    dprintf(fd, "|-------------------------------------DataBase-------------------------------------|\n");
1627}
1628
1629static void LoadAllAccountsData(void)
1630{
1631    int32_t *accountIds = NULL;
1632    uint32_t size = 0;
1633    int32_t ret = GetAllOsAccountIds(&accountIds, &size);
1634    if (ret != HC_SUCCESS) {
1635        LOGE("[DB]: Failed to get all os account ids, [res]: %d", ret);
1636        return;
1637    }
1638    for (uint32_t index = 0; index < size; index++) {
1639        LoadDataIfNotLoaded(accountIds[index]);
1640    }
1641    HcFree(accountIds);
1642}
1643
1644static void DevAuthDataBaseDump(int fd)
1645{
1646    if (g_databaseMutex == NULL) {
1647        LOGE("[DB]: Init mutex failed");
1648        return;
1649    }
1650    (void)LockHcMutex(g_databaseMutex);
1651    if (IsOsAccountSupported()) {
1652        LoadAllAccountsData();
1653    }
1654    uint32_t index;
1655    OsAccountTrustedInfo *info;
1656    FOR_EACH_HC_VECTOR(g_deviceauthDb, index, info) {
1657        DumpDb(fd, info);
1658    }
1659    UnlockHcMutex(g_databaseMutex);
1660}
1661#endif
1662
1663int32_t InitDatabase(void)
1664{
1665    if (g_databaseMutex == NULL) {
1666        g_databaseMutex = (HcMutex *)HcMalloc(sizeof(HcMutex), 0);
1667        if (g_databaseMutex == NULL) {
1668            LOGE("[DB]: Alloc databaseMutex failed");
1669            return HC_ERR_ALLOC_MEMORY;
1670        }
1671        if (InitHcMutex(g_databaseMutex) != HC_SUCCESS) {
1672            LOGE("[DB]: Init mutex failed");
1673            HcFree(g_databaseMutex);
1674            g_databaseMutex = NULL;
1675            return HC_ERROR;
1676        }
1677    }
1678    g_deviceauthDb = CREATE_HC_VECTOR(DeviceAuthDb);
1679    AddOsAccountEventCallback(GROUP_DATA_CALLBACK, OnOsAccountUnlocked, OnOsAccountRemoved);
1680    LoadDeviceAuthDb();
1681    DEV_AUTH_REG_DUMP_FUNC(DevAuthDataBaseDump);
1682    return HC_SUCCESS;
1683}
1684
1685void DestroyDatabase(void)
1686{
1687    RemoveOsAccountEventCallback(GROUP_DATA_CALLBACK);
1688    (void)LockHcMutex(g_databaseMutex);
1689    uint32_t index;
1690    OsAccountTrustedInfo *info;
1691    FOR_EACH_HC_VECTOR(g_deviceauthDb, index, info) {
1692        ClearGroupEntryVec(&info->groups);
1693        ClearDeviceEntryVec(&info->devices);
1694    }
1695    DESTROY_HC_VECTOR(DeviceAuthDb, &g_deviceauthDb);
1696    UnlockHcMutex(g_databaseMutex);
1697    DestroyHcMutex(g_databaseMutex);
1698    HcFree(g_databaseMutex);
1699    g_databaseMutex = NULL;
1700}