• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "bundle_info.h"
17 
18 #include "json_util.h"
19 #include "parcel_macro.h"
20 #include "string_ex.h"
21 
22 namespace OHOS {
23 namespace AppExecFwk {
24 namespace {
25 const std::string BUNDLE_INFO_NAME = "name";
26 const std::string BUNDLE_INFO_LABEL = "label";
27 const std::string BUNDLE_INFO_DESCRIPTION = "description";
28 const std::string BUNDLE_INFO_VENDOR = "vendor";
29 const std::string BUNDLE_INFO_IS_KEEP_ALIVE = "isKeepAlive";
30 const std::string BUNDLE_INFO_SINGLETON = "singleton";
31 const std::string BUNDLE_INFO_IS_NATIVE_APP = "isNativeApp";
32 const std::string BUNDLE_INFO_IS_PREINSTALL_APP = "isPreInstallApp";
33 const std::string BUNDLE_INFO_IS_DIFFERENT_NAME = "isDifferentName";
34 const std::string BUNDLE_INFO_APPLICATION_INFO = "applicationInfo";
35 const std::string BUNDLE_INFO_ABILITY_INFOS = "abilityInfos";
36 const std::string BUNDLE_INFO_HAP_MODULE_INFOS = "hapModuleInfos";
37 const std::string BUNDLE_INFO_EXTENSION_ABILITY_INFOS = "extensionAbilityInfo";
38 const std::string BUNDLE_INFO_JOINT_USERID = "jointUserId";
39 const std::string BUNDLE_INFO_VERSION_CODE = "versionCode";
40 const std::string BUNDLE_INFO_MIN_COMPATIBLE_VERSION_CODE = "minCompatibleVersionCode";
41 const std::string BUNDLE_INFO_VERSION_NAME = "versionName";
42 const std::string BUNDLE_INFO_MIN_SDK_VERSION = "minSdkVersion";
43 const std::string BUNDLE_INFO_MAX_SDK_VERSION = "maxSdkVersion";
44 const std::string BUNDLE_INFO_MAIN_ENTRY = "mainEntry";
45 const std::string BUNDLE_INFO_CPU_ABI = "cpuAbi";
46 const std::string BUNDLE_INFO_APPID = "appId";
47 const std::string BUNDLE_INFO_COMPATIBLE_VERSION = "compatibleVersion";
48 const std::string BUNDLE_INFO_TARGET_VERSION = "targetVersion";
49 const std::string BUNDLE_INFO_RELEASE_TYPE = "releaseType";
50 const std::string BUNDLE_INFO_UID = "uid";
51 const std::string BUNDLE_INFO_GID = "gid";
52 const std::string BUNDLE_INFO_SEINFO = "seInfo";
53 const std::string BUNDLE_INFO_INSTALL_TIME = "installTime";
54 const std::string BUNDLE_INFO_UPDATE_TIME = "updateTime";
55 const std::string BUNDLE_INFO_ENTRY_MODULE_NAME = "entryModuleName";
56 const std::string BUNDLE_INFO_ENTRY_INSTALLATION_FREE = "entryInstallationFree";
57 const std::string BUNDLE_INFO_REQ_PERMISSIONS = "reqPermissions";
58 const std::string BUNDLE_INFO_REQ_PERMISSION_STATES = "reqPermissionStates";
59 const std::string BUNDLE_INFO_REQ_PERMISSION_DETAILS = "reqPermissionDetails";
60 const std::string BUNDLE_INFO_DEF_PERMISSIONS = "defPermissions";
61 const std::string BUNDLE_INFO_HAP_MODULE_NAMES = "hapModuleNames";
62 const std::string BUNDLE_INFO_MODULE_NAMES = "moduleNames";
63 const std::string BUNDLE_INFO_MODULE_PUBLIC_DIRS = "modulePublicDirs";
64 const std::string BUNDLE_INFO_MODULE_DIRS = "moduleDirs";
65 const std::string BUNDLE_INFO_MODULE_RES_PATHS = "moduleResPaths";
66 const std::string REQUESTPERMISSION_NAME = "name";
67 const std::string REQUESTPERMISSION_REASON = "reason";
68 const std::string REQUESTPERMISSION_REASON_ID = "reasonId";
69 const std::string REQUESTPERMISSION_USEDSCENE = "usedScene";
70 const std::string REQUESTPERMISSION_ABILITIES = "abilities";
71 const std::string REQUESTPERMISSION_ABILITY = "ability";
72 const std::string REQUESTPERMISSION_WHEN = "when";
73 const std::string SIGNATUREINFO_APPID = "appId";
74 const std::string SIGNATUREINFO_FINGERPRINT = "fingerprint";
75 const std::string BUNDLE_INFO_APP_INDEX = "appIndex";
76 const std::string BUNDLE_INFO_SIGNATURE_INFO = "signatureInfo";
77 const std::string BUNDLE_INFO_ASAN_ENABLED = "asanEnabled";
78 }
79 
ReadFromParcel(Parcel & parcel)80 bool RequestPermissionUsedScene::ReadFromParcel(Parcel &parcel)
81 {
82     int32_t size;
83     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, size);
84     for (int32_t i = 0; i < size; i++) {
85         abilities.emplace_back(Str16ToStr8(parcel.ReadString16()));
86     }
87     when = Str16ToStr8(parcel.ReadString16());
88     return true;
89 }
90 
Marshalling(Parcel & parcel) const91 bool RequestPermissionUsedScene::Marshalling(Parcel &parcel) const
92 {
93     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, abilities.size());
94     for (auto &ability : abilities) {
95         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(ability));
96     }
97     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(when));
98     return true;
99 }
100 
Unmarshalling(Parcel & parcel)101 RequestPermissionUsedScene *RequestPermissionUsedScene::Unmarshalling(Parcel &parcel)
102 {
103     RequestPermissionUsedScene *info = new (std::nothrow) RequestPermissionUsedScene();
104     if (info && !info->ReadFromParcel(parcel)) {
105         APP_LOGW("read from parcel failed");
106         delete info;
107         info = nullptr;
108     }
109     return info;
110 }
111 
ReadFromParcel(Parcel & parcel)112 bool RequestPermission::ReadFromParcel(Parcel &parcel)
113 {
114     name = Str16ToStr8(parcel.ReadString16());
115     reason = Str16ToStr8(parcel.ReadString16());
116     reasonId = parcel.ReadInt32();
117     std::unique_ptr<RequestPermissionUsedScene> scene(parcel.ReadParcelable<RequestPermissionUsedScene>());
118     if (!scene) {
119         APP_LOGE("ReadParcelable<RequestPermissionUsedScene> failed");
120         return false;
121     }
122     usedScene = *scene;
123     return true;
124 }
125 
Marshalling(Parcel & parcel) const126 bool RequestPermission::Marshalling(Parcel &parcel) const
127 {
128     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(name));
129     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(reason));
130     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, reasonId);
131     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Parcelable, parcel, &usedScene);
132     return true;
133 }
134 
Unmarshalling(Parcel & parcel)135 RequestPermission *RequestPermission::Unmarshalling(Parcel &parcel)
136 {
137     RequestPermission *info = new (std::nothrow) RequestPermission();
138     if (info && !info->ReadFromParcel(parcel)) {
139         APP_LOGW("read from parcel failed");
140         delete info;
141         info = nullptr;
142     }
143     return info;
144 }
145 
ReadFromParcel(Parcel & parcel)146 bool SignatureInfo::ReadFromParcel(Parcel &parcel)
147 {
148     appId = Str16ToStr8(parcel.ReadString16());
149     fingerprint = Str16ToStr8(parcel.ReadString16());
150     return true;
151 }
152 
Marshalling(Parcel & parcel) const153 bool SignatureInfo::Marshalling(Parcel &parcel) const
154 {
155     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(appId));
156     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(fingerprint));
157     return true;
158 }
159 
Unmarshalling(Parcel & parcel)160 SignatureInfo *SignatureInfo::Unmarshalling(Parcel &parcel)
161 {
162     SignatureInfo *info = new (std::nothrow) SignatureInfo();
163     if (info && !info->ReadFromParcel(parcel)) {
164         APP_LOGW("read from parcel failed");
165         delete info;
166         info = nullptr;
167     }
168     return info;
169 }
170 
ReadFromParcel(Parcel & parcel)171 bool BundleInfo::ReadFromParcel(Parcel &parcel)
172 {
173     name = Str16ToStr8(parcel.ReadString16());
174     versionCode = parcel.ReadUint32();
175     versionName = Str16ToStr8(parcel.ReadString16());
176     minCompatibleVersionCode = parcel.ReadUint32();
177     compatibleVersion = parcel.ReadUint32();
178     targetVersion = parcel.ReadUint32();
179     isKeepAlive = parcel.ReadBool();
180     singleton = parcel.ReadBool();
181     isPreInstallApp = parcel.ReadBool();
182 
183     vendor = Str16ToStr8(parcel.ReadString16());
184     releaseType = Str16ToStr8(parcel.ReadString16());
185     isNativeApp = parcel.ReadBool();
186 
187     mainEntry = Str16ToStr8(parcel.ReadString16());
188     entryModuleName = Str16ToStr8(parcel.ReadString16());
189     entryInstallationFree = parcel.ReadBool();
190 
191     appId = Str16ToStr8(parcel.ReadString16());
192     uid = parcel.ReadInt32();
193     gid = parcel.ReadInt32();
194     installTime = parcel.ReadInt64();
195     updateTime = parcel.ReadInt64();
196     std::unique_ptr<ApplicationInfo> appInfo(parcel.ReadParcelable<ApplicationInfo>());
197     if (!appInfo) {
198         APP_LOGE("ReadParcelable<ApplicationInfo> failed");
199         return false;
200     }
201     applicationInfo = *appInfo;
202 
203     int32_t abilityInfosSize;
204     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, abilityInfosSize);
205     for (auto i = 0; i < abilityInfosSize; i++) {
206         std::unique_ptr<AbilityInfo> abilityInfo(parcel.ReadParcelable<AbilityInfo>());
207         if (!abilityInfo) {
208             APP_LOGE("ReadParcelable<AbilityInfo> failed");
209             return false;
210         }
211         abilityInfos.emplace_back(*abilityInfo);
212     }
213 
214     int32_t extensionInfosSize;
215     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, extensionInfosSize);
216     for (auto i = 0; i < extensionInfosSize; i++) {
217         std::unique_ptr<ExtensionAbilityInfo> extensionAbilityInfo(parcel.ReadParcelable<ExtensionAbilityInfo>());
218         if (!extensionAbilityInfo) {
219             APP_LOGE("ReadParcelable<ExtensionAbilityInfo> failed");
220             return false;
221         }
222         extensionInfos.emplace_back(*extensionAbilityInfo);
223     }
224 
225     int32_t hapModuleInfosSize;
226     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, hapModuleInfosSize);
227     for (auto i = 0; i < hapModuleInfosSize; i++) {
228         std::unique_ptr<HapModuleInfo> hapModuleInfo(parcel.ReadParcelable<HapModuleInfo>());
229         if (!hapModuleInfo) {
230             APP_LOGE("ReadParcelable<HapModuleInfo> failed");
231             return false;
232         }
233         hapModuleInfos.emplace_back(*hapModuleInfo);
234     }
235 
236     int32_t hapModuleNamesSize;
237     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, hapModuleNamesSize);
238     for (auto i = 0; i < hapModuleNamesSize; i++) {
239         hapModuleNames.emplace_back(Str16ToStr8(parcel.ReadString16()));
240     }
241 
242     int32_t moduleNamesSize;
243     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, moduleNamesSize);
244     for (auto i = 0; i < moduleNamesSize; i++) {
245         moduleNames.emplace_back(Str16ToStr8(parcel.ReadString16()));
246     }
247 
248     int32_t modulePublicDirsSize;
249     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, modulePublicDirsSize);
250     for (auto i = 0; i < modulePublicDirsSize; i++) {
251         modulePublicDirs.emplace_back(Str16ToStr8(parcel.ReadString16()));
252     }
253 
254     int32_t moduleDirsSize;
255     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, moduleDirsSize);
256     for (auto i = 0; i < moduleDirsSize; i++) {
257         moduleDirs.emplace_back(Str16ToStr8(parcel.ReadString16()));
258     }
259 
260     int32_t moduleResPathsSize;
261     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, moduleResPathsSize);
262     for (auto i = 0; i < moduleResPathsSize; i++) {
263         moduleResPaths.emplace_back(Str16ToStr8(parcel.ReadString16()));
264     }
265 
266     int32_t reqPermissionsSize;
267     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, reqPermissionsSize);
268     for (auto i = 0; i < reqPermissionsSize; i++) {
269         reqPermissions.emplace_back(Str16ToStr8(parcel.ReadString16()));
270     }
271 
272     int32_t defPermissionsSize;
273     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, defPermissionsSize);
274     for (auto i = 0; i < defPermissionsSize; i++) {
275         defPermissions.emplace_back(Str16ToStr8(parcel.ReadString16()));
276     }
277 
278     int32_t reqPermissionStatesSize;
279     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, reqPermissionStatesSize);
280     for (auto i = 0; i < reqPermissionStatesSize; i++) {
281         reqPermissionStates.emplace_back(parcel.ReadInt32());
282     }
283 
284     int32_t reqPermissionDetailsSize;
285     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, reqPermissionDetailsSize);
286     for (auto i = 0; i < reqPermissionDetailsSize; i++) {
287         std::unique_ptr<RequestPermission> requestPermission(parcel.ReadParcelable<RequestPermission>());
288         if (!requestPermission) {
289             APP_LOGE("ReadParcelable<RequestPermission> failed");
290             return false;
291         }
292         reqPermissionDetails.emplace_back(*requestPermission);
293     }
294 
295     cpuAbi = Str16ToStr8(parcel.ReadString16());
296     seInfo = Str16ToStr8(parcel.ReadString16());
297     label = Str16ToStr8(parcel.ReadString16());
298     description = Str16ToStr8(parcel.ReadString16());
299     jointUserId = Str16ToStr8(parcel.ReadString16());
300     minSdkVersion = parcel.ReadInt32();
301     maxSdkVersion = parcel.ReadInt32();
302     isDifferentName = parcel.ReadBool();
303     appIndex = parcel.ReadInt32();
304 
305     std::unique_ptr<SignatureInfo> sigInfo(parcel.ReadParcelable<SignatureInfo>());
306     if (!sigInfo) {
307         APP_LOGE("ReadParcelable<SignatureInfo> failed");
308         return false;
309     }
310     signatureInfo = *sigInfo;
311     asanEnabled = parcel.ReadBool();
312     return true;
313 }
314 
Marshalling(Parcel & parcel) const315 bool BundleInfo::Marshalling(Parcel &parcel) const
316 {
317     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(name));
318     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, versionCode);
319     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(versionName));
320     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, minCompatibleVersionCode);
321     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, compatibleVersion);
322     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, targetVersion);
323 
324     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isKeepAlive);
325     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, singleton);
326     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isPreInstallApp);
327 
328     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(vendor));
329     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(releaseType));
330     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isNativeApp);
331 
332     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(mainEntry));
333     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(entryModuleName));
334     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, entryInstallationFree);
335 
336     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(appId));
337 
338     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, uid);
339     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, gid);
340 
341     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int64, parcel, installTime);
342     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int64, parcel, updateTime);
343 
344     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Parcelable, parcel, &applicationInfo);
345 
346     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, abilityInfos.size());
347     for (auto &abilityInfo : abilityInfos) {
348         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Parcelable, parcel, &abilityInfo);
349     }
350 
351     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, extensionInfos.size());
352     for (auto &extensionInfo : extensionInfos) {
353         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Parcelable, parcel, &extensionInfo);
354     }
355 
356     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, hapModuleInfos.size());
357     for (auto &hapModuleInfo : hapModuleInfos) {
358         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Parcelable, parcel, &hapModuleInfo);
359     }
360 
361     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, hapModuleNames.size());
362     for (auto &hapModuleName : hapModuleNames) {
363         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(hapModuleName));
364     }
365 
366     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, moduleNames.size());
367     for (auto &moduleName : moduleNames) {
368         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(moduleName));
369     }
370 
371     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, modulePublicDirs.size());
372     for (auto &modulePublicDir : modulePublicDirs) {
373         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(modulePublicDir));
374     }
375 
376     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, moduleDirs.size());
377     for (auto &moduleDir : moduleDirs) {
378         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(moduleDir));
379     }
380 
381     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, moduleResPaths.size());
382     for (auto &moduleResPath : moduleResPaths) {
383         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(moduleResPath));
384     }
385 
386     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, reqPermissions.size());
387     for (auto &reqPermission : reqPermissions) {
388         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(reqPermission));
389     }
390 
391     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, defPermissions.size());
392     for (auto &defPermission : defPermissions) {
393         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(defPermission));
394     }
395 
396     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, reqPermissionStates.size());
397     for (auto &reqPermissionState : reqPermissionStates) {
398         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, reqPermissionState);
399     }
400 
401     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, reqPermissionDetails.size());
402     for (auto &reqPermissionDetail : reqPermissionDetails) {
403         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Parcelable, parcel, &reqPermissionDetail);
404     }
405 
406     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(cpuAbi));
407     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(seInfo));
408     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(label));
409     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(description));
410     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(jointUserId));
411     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, minSdkVersion);
412     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, maxSdkVersion);
413     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isDifferentName);
414     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, appIndex);
415     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Parcelable, parcel, &signatureInfo);
416     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, asanEnabled);
417     return true;
418 }
419 
Unmarshalling(Parcel & parcel)420 BundleInfo *BundleInfo::Unmarshalling(Parcel &parcel)
421 {
422     BundleInfo *info = new (std::nothrow) BundleInfo();
423     if (info && !info->ReadFromParcel(parcel)) {
424         APP_LOGW("read from parcel failed");
425         delete info;
426         info = nullptr;
427     }
428     return info;
429 }
430 
to_json(nlohmann::json & jsonObject,const RequestPermissionUsedScene & usedScene)431 void to_json(nlohmann::json &jsonObject, const RequestPermissionUsedScene &usedScene)
432 {
433     jsonObject = nlohmann::json {
434         {REQUESTPERMISSION_ABILITIES, usedScene.abilities},
435         {REQUESTPERMISSION_WHEN, usedScene.when}
436     };
437 }
438 
to_json(nlohmann::json & jsonObject,const RequestPermission & requestPermission)439 void to_json(nlohmann::json &jsonObject, const RequestPermission &requestPermission)
440 {
441     jsonObject = nlohmann::json {
442         {REQUESTPERMISSION_NAME, requestPermission.name},
443         {REQUESTPERMISSION_REASON, requestPermission.reason},
444         {REQUESTPERMISSION_REASON_ID, requestPermission.reasonId},
445         {REQUESTPERMISSION_USEDSCENE, requestPermission.usedScene}
446     };
447 }
448 
to_json(nlohmann::json & jsonObject,const SignatureInfo & signatureInfo)449 void to_json(nlohmann::json &jsonObject, const SignatureInfo &signatureInfo)
450 {
451     jsonObject = nlohmann::json {
452         {SIGNATUREINFO_APPID, signatureInfo.appId},
453         {SIGNATUREINFO_FINGERPRINT, signatureInfo.fingerprint}
454     };
455 }
456 
from_json(const nlohmann::json & jsonObject,RequestPermissionUsedScene & usedScene)457 void from_json(const nlohmann::json &jsonObject, RequestPermissionUsedScene &usedScene)
458 {
459     const auto &jsonObjectEnd = jsonObject.end();
460     int32_t parseResult = ERR_OK;
461     GetValueIfFindKey<std::vector<std::string>>(jsonObject,
462         jsonObjectEnd,
463         REQUESTPERMISSION_ABILITIES,
464         usedScene.abilities,
465         JsonType::ARRAY,
466         false,
467         parseResult,
468         ArrayType::STRING);
469     GetValueIfFindKey<std::vector<std::string>>(jsonObject,
470         jsonObjectEnd,
471         REQUESTPERMISSION_ABILITY,
472         usedScene.abilities,
473         JsonType::ARRAY,
474         false,
475         parseResult,
476         ArrayType::STRING);
477     GetValueIfFindKey<std::string>(jsonObject,
478         jsonObjectEnd,
479         REQUESTPERMISSION_WHEN,
480         usedScene.when,
481         JsonType::STRING,
482         false,
483         parseResult,
484         ArrayType::NOT_ARRAY);
485     if (parseResult != ERR_OK) {
486         APP_LOGE("read RequestPermissionUsedScene from database error, error code : %{public}d", parseResult);
487     }
488 }
489 
from_json(const nlohmann::json & jsonObject,RequestPermission & requestPermission)490 void from_json(const nlohmann::json &jsonObject, RequestPermission &requestPermission)
491 {
492     const auto &jsonObjectEnd = jsonObject.end();
493     int32_t parseResult = ERR_OK;
494     GetValueIfFindKey<std::string>(jsonObject,
495         jsonObjectEnd,
496         REQUESTPERMISSION_NAME,
497         requestPermission.name,
498         JsonType::STRING,
499         false,
500         parseResult,
501         ArrayType::NOT_ARRAY);
502     GetValueIfFindKey<std::string>(jsonObject,
503         jsonObjectEnd,
504         REQUESTPERMISSION_REASON,
505         requestPermission.reason,
506         JsonType::STRING,
507         false,
508         parseResult,
509         ArrayType::NOT_ARRAY);
510     GetValueIfFindKey<int32_t>(jsonObject,
511         jsonObjectEnd,
512         REQUESTPERMISSION_REASON_ID,
513         requestPermission.reasonId,
514         JsonType::NUMBER,
515         false,
516         parseResult,
517         ArrayType::NOT_ARRAY);
518     GetValueIfFindKey<RequestPermissionUsedScene>(jsonObject,
519         jsonObjectEnd,
520         REQUESTPERMISSION_USEDSCENE,
521         requestPermission.usedScene,
522         JsonType::OBJECT,
523         false,
524         parseResult,
525         ArrayType::NOT_ARRAY);
526     if (parseResult != ERR_OK) {
527         APP_LOGE("read RequestPermission from database error, error code : %{public}d", parseResult);
528     }
529 }
530 
from_json(const nlohmann::json & jsonObject,SignatureInfo & signatureInfo)531 void from_json(const nlohmann::json &jsonObject, SignatureInfo &signatureInfo)
532 {
533     const auto &jsonObjectEnd = jsonObject.end();
534     int32_t parseResult = ERR_OK;
535     GetValueIfFindKey<std::string>(jsonObject,
536         jsonObjectEnd,
537         SIGNATUREINFO_APPID,
538         signatureInfo.appId,
539         JsonType::STRING,
540         false,
541         parseResult,
542         ArrayType::NOT_ARRAY);
543     GetValueIfFindKey<std::string>(jsonObject,
544         jsonObjectEnd,
545         SIGNATUREINFO_FINGERPRINT,
546         signatureInfo.fingerprint,
547         JsonType::STRING,
548         false,
549         parseResult,
550         ArrayType::NOT_ARRAY);
551     if (parseResult != ERR_OK) {
552         APP_LOGE("read SignatureInfo from database error, error code : %{public}d", parseResult);
553     }
554 }
555 
to_json(nlohmann::json & jsonObject,const BundleInfo & bundleInfo)556 void to_json(nlohmann::json &jsonObject, const BundleInfo &bundleInfo)
557 {
558     jsonObject = nlohmann::json {
559         {BUNDLE_INFO_NAME, bundleInfo.name},
560         {BUNDLE_INFO_LABEL, bundleInfo.label},
561         {BUNDLE_INFO_DESCRIPTION, bundleInfo.description},
562         {BUNDLE_INFO_VENDOR, bundleInfo.vendor},
563         {BUNDLE_INFO_IS_KEEP_ALIVE, bundleInfo.isKeepAlive},
564         {BUNDLE_INFO_IS_NATIVE_APP, bundleInfo.isNativeApp},
565         {BUNDLE_INFO_IS_PREINSTALL_APP, bundleInfo.isPreInstallApp},
566         {BUNDLE_INFO_IS_DIFFERENT_NAME, bundleInfo.isDifferentName},
567         {BUNDLE_INFO_APPLICATION_INFO, bundleInfo.applicationInfo},
568         {BUNDLE_INFO_ABILITY_INFOS, bundleInfo.abilityInfos},
569         {BUNDLE_INFO_HAP_MODULE_INFOS, bundleInfo.hapModuleInfos},
570         {BUNDLE_INFO_EXTENSION_ABILITY_INFOS, bundleInfo.extensionInfos},
571         {BUNDLE_INFO_JOINT_USERID, bundleInfo.jointUserId},
572         {BUNDLE_INFO_VERSION_CODE, bundleInfo.versionCode},
573         {BUNDLE_INFO_MIN_COMPATIBLE_VERSION_CODE, bundleInfo.minCompatibleVersionCode},
574         {BUNDLE_INFO_VERSION_NAME, bundleInfo.versionName},
575         {BUNDLE_INFO_MIN_SDK_VERSION, bundleInfo.minSdkVersion},
576         {BUNDLE_INFO_MAX_SDK_VERSION, bundleInfo.maxSdkVersion},
577         {BUNDLE_INFO_MAIN_ENTRY, bundleInfo.mainEntry},
578         {BUNDLE_INFO_CPU_ABI, bundleInfo.cpuAbi},
579         {BUNDLE_INFO_APPID, bundleInfo.appId},
580         {BUNDLE_INFO_COMPATIBLE_VERSION, bundleInfo.compatibleVersion},
581         {BUNDLE_INFO_TARGET_VERSION, bundleInfo.targetVersion},
582         {BUNDLE_INFO_RELEASE_TYPE, bundleInfo.releaseType},
583         {BUNDLE_INFO_UID, bundleInfo.uid},
584         {BUNDLE_INFO_GID, bundleInfo.gid},
585         {BUNDLE_INFO_SEINFO, bundleInfo.seInfo},
586         {BUNDLE_INFO_INSTALL_TIME, bundleInfo.installTime},
587         {BUNDLE_INFO_UPDATE_TIME, bundleInfo.updateTime},
588         {BUNDLE_INFO_ENTRY_MODULE_NAME, bundleInfo.entryModuleName},
589         {BUNDLE_INFO_ENTRY_INSTALLATION_FREE, bundleInfo.entryInstallationFree},
590         {BUNDLE_INFO_REQ_PERMISSIONS, bundleInfo.reqPermissions},
591         {BUNDLE_INFO_REQ_PERMISSION_STATES, bundleInfo.reqPermissionStates},
592         {BUNDLE_INFO_REQ_PERMISSION_DETAILS, bundleInfo.reqPermissionDetails},
593         {BUNDLE_INFO_DEF_PERMISSIONS, bundleInfo.defPermissions},
594         {BUNDLE_INFO_HAP_MODULE_NAMES, bundleInfo.hapModuleNames},
595         {BUNDLE_INFO_MODULE_NAMES, bundleInfo.moduleNames},
596         {BUNDLE_INFO_MODULE_PUBLIC_DIRS, bundleInfo.modulePublicDirs},
597         {BUNDLE_INFO_MODULE_DIRS, bundleInfo.moduleDirs},
598         {BUNDLE_INFO_MODULE_RES_PATHS, bundleInfo.moduleResPaths},
599         {BUNDLE_INFO_SINGLETON, bundleInfo.singleton},
600         {BUNDLE_INFO_APP_INDEX, bundleInfo.appIndex},
601         {BUNDLE_INFO_SIGNATURE_INFO, bundleInfo.signatureInfo},
602         {BUNDLE_INFO_ASAN_ENABLED, bundleInfo.asanEnabled},
603     };
604 }
605 
from_json(const nlohmann::json & jsonObject,BundleInfo & bundleInfo)606 void from_json(const nlohmann::json &jsonObject, BundleInfo &bundleInfo)
607 {
608     const auto &jsonObjectEnd = jsonObject.end();
609     int32_t parseResult = ERR_OK;
610     GetValueIfFindKey<std::string>(jsonObject,
611         jsonObjectEnd,
612         BUNDLE_INFO_NAME,
613         bundleInfo.name,
614         JsonType::STRING,
615         false,
616         parseResult,
617         ArrayType::NOT_ARRAY);
618     GetValueIfFindKey<std::string>(jsonObject,
619         jsonObjectEnd,
620         BUNDLE_INFO_LABEL,
621         bundleInfo.label,
622         JsonType::STRING,
623         false,
624         parseResult,
625         ArrayType::NOT_ARRAY);
626     GetValueIfFindKey<std::string>(jsonObject,
627         jsonObjectEnd,
628         BUNDLE_INFO_DESCRIPTION,
629         bundleInfo.description,
630         JsonType::STRING,
631         false,
632         parseResult,
633         ArrayType::NOT_ARRAY);
634     GetValueIfFindKey<std::string>(jsonObject,
635         jsonObjectEnd,
636         BUNDLE_INFO_VENDOR,
637         bundleInfo.vendor,
638         JsonType::STRING,
639         false,
640         parseResult,
641         ArrayType::NOT_ARRAY);
642     GetValueIfFindKey<bool>(jsonObject,
643         jsonObjectEnd,
644         BUNDLE_INFO_IS_KEEP_ALIVE,
645         bundleInfo.isKeepAlive,
646         JsonType::BOOLEAN,
647         false,
648         parseResult,
649         ArrayType::NOT_ARRAY);
650     GetValueIfFindKey<bool>(jsonObject,
651         jsonObjectEnd,
652         BUNDLE_INFO_IS_NATIVE_APP,
653         bundleInfo.isNativeApp,
654         JsonType::BOOLEAN,
655         false,
656         parseResult,
657         ArrayType::NOT_ARRAY);
658     GetValueIfFindKey<bool>(jsonObject,
659         jsonObjectEnd,
660         BUNDLE_INFO_IS_PREINSTALL_APP,
661         bundleInfo.isPreInstallApp,
662         JsonType::BOOLEAN,
663         false,
664         parseResult,
665         ArrayType::NOT_ARRAY);
666     GetValueIfFindKey<bool>(jsonObject,
667         jsonObjectEnd,
668         BUNDLE_INFO_IS_DIFFERENT_NAME,
669         bundleInfo.isDifferentName,
670         JsonType::BOOLEAN,
671         false,
672         parseResult,
673         ArrayType::NOT_ARRAY);
674     GetValueIfFindKey<ApplicationInfo>(jsonObject,
675         jsonObjectEnd,
676         BUNDLE_INFO_APPLICATION_INFO,
677         bundleInfo.applicationInfo,
678         JsonType::OBJECT,
679         false,
680         parseResult,
681         ArrayType::NOT_ARRAY);
682     GetValueIfFindKey<std::vector<AbilityInfo>>(jsonObject,
683         jsonObjectEnd,
684         BUNDLE_INFO_ABILITY_INFOS,
685         bundleInfo.abilityInfos,
686         JsonType::ARRAY,
687         false,
688         parseResult,
689         ArrayType::OBJECT);
690     GetValueIfFindKey<std::vector<HapModuleInfo>>(jsonObject,
691         jsonObjectEnd,
692         BUNDLE_INFO_HAP_MODULE_INFOS,
693         bundleInfo.hapModuleInfos,
694         JsonType::ARRAY,
695         false,
696         parseResult,
697         ArrayType::OBJECT);
698     GetValueIfFindKey<uint32_t>(jsonObject,
699         jsonObjectEnd,
700         BUNDLE_INFO_VERSION_CODE,
701         bundleInfo.versionCode,
702         JsonType::NUMBER,
703         false,
704         parseResult,
705         ArrayType::NOT_ARRAY);
706     GetValueIfFindKey<uint32_t>(jsonObject,
707         jsonObjectEnd,
708         BUNDLE_INFO_MIN_COMPATIBLE_VERSION_CODE,
709         bundleInfo.minCompatibleVersionCode,
710         JsonType::NUMBER,
711         false,
712         parseResult,
713         ArrayType::NOT_ARRAY);
714     GetValueIfFindKey<std::string>(jsonObject,
715         jsonObjectEnd,
716         BUNDLE_INFO_VERSION_NAME,
717         bundleInfo.versionName,
718         JsonType::STRING,
719         false,
720         parseResult,
721         ArrayType::NOT_ARRAY);
722     GetValueIfFindKey<std::string>(jsonObject,
723         jsonObjectEnd,
724         BUNDLE_INFO_JOINT_USERID,
725         bundleInfo.jointUserId,
726         JsonType::STRING,
727         false,
728         parseResult,
729         ArrayType::NOT_ARRAY);
730     GetValueIfFindKey<int32_t>(jsonObject,
731         jsonObjectEnd,
732         BUNDLE_INFO_MIN_SDK_VERSION,
733         bundleInfo.minSdkVersion,
734         JsonType::NUMBER,
735         false,
736         parseResult,
737         ArrayType::NOT_ARRAY);
738     GetValueIfFindKey<int32_t>(jsonObject,
739         jsonObjectEnd,
740         BUNDLE_INFO_MAX_SDK_VERSION,
741         bundleInfo.maxSdkVersion,
742         JsonType::NUMBER,
743         false,
744         parseResult,
745         ArrayType::NOT_ARRAY);
746     GetValueIfFindKey<std::string>(jsonObject,
747         jsonObjectEnd,
748         BUNDLE_INFO_MAIN_ENTRY,
749         bundleInfo.mainEntry,
750         JsonType::STRING,
751         false,
752         parseResult,
753         ArrayType::NOT_ARRAY);
754     GetValueIfFindKey<std::string>(jsonObject,
755         jsonObjectEnd,
756         BUNDLE_INFO_CPU_ABI,
757         bundleInfo.cpuAbi,
758         JsonType::STRING,
759         false,
760         parseResult,
761         ArrayType::NOT_ARRAY);
762     GetValueIfFindKey<std::string>(jsonObject,
763         jsonObjectEnd,
764         BUNDLE_INFO_APPID,
765         bundleInfo.appId,
766         JsonType::STRING,
767         false,
768         parseResult,
769         ArrayType::NOT_ARRAY);
770     GetValueIfFindKey<int>(jsonObject,
771         jsonObjectEnd,
772         BUNDLE_INFO_COMPATIBLE_VERSION,
773         bundleInfo.compatibleVersion,
774         JsonType::NUMBER,
775         false,
776         parseResult,
777         ArrayType::NOT_ARRAY);
778     GetValueIfFindKey<uint32_t>(jsonObject,
779         jsonObjectEnd,
780         BUNDLE_INFO_TARGET_VERSION,
781         bundleInfo.targetVersion,
782         JsonType::NUMBER,
783         false,
784         parseResult,
785         ArrayType::NOT_ARRAY);
786     GetValueIfFindKey<std::string>(jsonObject,
787         jsonObjectEnd,
788         BUNDLE_INFO_RELEASE_TYPE,
789         bundleInfo.releaseType,
790         JsonType::STRING,
791         false,
792         parseResult,
793         ArrayType::NOT_ARRAY);
794     GetValueIfFindKey<int>(jsonObject,
795         jsonObjectEnd,
796         BUNDLE_INFO_UID,
797         bundleInfo.uid,
798         JsonType::NUMBER,
799         false,
800         parseResult,
801         ArrayType::NOT_ARRAY);
802     GetValueIfFindKey<int>(jsonObject,
803         jsonObjectEnd,
804         BUNDLE_INFO_GID,
805         bundleInfo.gid,
806         JsonType::NUMBER,
807         false,
808         parseResult,
809         ArrayType::NOT_ARRAY);
810     GetValueIfFindKey<std::string>(jsonObject,
811         jsonObjectEnd,
812         BUNDLE_INFO_SEINFO,
813         bundleInfo.seInfo,
814         JsonType::STRING,
815         false,
816         parseResult,
817         ArrayType::NOT_ARRAY);
818     GetValueIfFindKey<int64_t>(jsonObject,
819         jsonObjectEnd,
820         BUNDLE_INFO_INSTALL_TIME,
821         bundleInfo.installTime,
822         JsonType::NUMBER,
823         false,
824         parseResult,
825         ArrayType::NOT_ARRAY);
826     GetValueIfFindKey<int64_t>(jsonObject,
827         jsonObjectEnd,
828         BUNDLE_INFO_UPDATE_TIME,
829         bundleInfo.updateTime,
830         JsonType::NUMBER,
831         false,
832         parseResult,
833         ArrayType::NOT_ARRAY);
834     GetValueIfFindKey<std::string>(jsonObject,
835         jsonObjectEnd,
836         BUNDLE_INFO_ENTRY_MODULE_NAME,
837         bundleInfo.entryModuleName,
838         JsonType::STRING,
839         false,
840         parseResult,
841         ArrayType::NOT_ARRAY);
842     GetValueIfFindKey<bool>(jsonObject,
843         jsonObjectEnd,
844         BUNDLE_INFO_ENTRY_INSTALLATION_FREE,
845         bundleInfo.entryInstallationFree,
846         JsonType::BOOLEAN,
847         false,
848         parseResult,
849         ArrayType::NOT_ARRAY);
850     GetValueIfFindKey<std::vector<std::string>>(jsonObject,
851         jsonObjectEnd,
852         BUNDLE_INFO_REQ_PERMISSIONS,
853         bundleInfo.reqPermissions,
854         JsonType::ARRAY,
855         false,
856         parseResult,
857         ArrayType::STRING);
858     GetValueIfFindKey<std::vector<int32_t>>(jsonObject,
859         jsonObjectEnd,
860         BUNDLE_INFO_REQ_PERMISSION_STATES,
861         bundleInfo.reqPermissionStates,
862         JsonType::ARRAY,
863         false,
864         parseResult,
865         ArrayType::NUMBER);
866     GetValueIfFindKey<std::vector<RequestPermission>>(jsonObject,
867         jsonObjectEnd,
868         BUNDLE_INFO_REQ_PERMISSION_DETAILS,
869         bundleInfo.reqPermissionDetails,
870         JsonType::ARRAY,
871         false,
872         parseResult,
873         ArrayType::OBJECT);
874     GetValueIfFindKey<std::vector<std::string>>(jsonObject,
875         jsonObjectEnd,
876         BUNDLE_INFO_DEF_PERMISSIONS,
877         bundleInfo.defPermissions,
878         JsonType::ARRAY,
879         false,
880         parseResult,
881         ArrayType::STRING);
882     GetValueIfFindKey<std::vector<std::string>>(jsonObject,
883         jsonObjectEnd,
884         BUNDLE_INFO_HAP_MODULE_NAMES,
885         bundleInfo.hapModuleNames,
886         JsonType::ARRAY,
887         false,
888         parseResult,
889         ArrayType::STRING);
890     GetValueIfFindKey<std::vector<std::string>>(jsonObject,
891         jsonObjectEnd,
892         BUNDLE_INFO_MODULE_NAMES,
893         bundleInfo.moduleNames,
894         JsonType::ARRAY,
895         false,
896         parseResult,
897         ArrayType::STRING);
898     GetValueIfFindKey<std::vector<std::string>>(jsonObject,
899         jsonObjectEnd,
900         BUNDLE_INFO_MODULE_PUBLIC_DIRS,
901         bundleInfo.modulePublicDirs,
902         JsonType::ARRAY,
903         false,
904         parseResult,
905         ArrayType::STRING);
906     GetValueIfFindKey<std::vector<std::string>>(jsonObject,
907         jsonObjectEnd,
908         BUNDLE_INFO_MODULE_DIRS,
909         bundleInfo.moduleDirs,
910         JsonType::ARRAY,
911         false,
912         parseResult,
913         ArrayType::STRING);
914     GetValueIfFindKey<std::vector<std::string>>(jsonObject,
915         jsonObjectEnd,
916         BUNDLE_INFO_MODULE_RES_PATHS,
917         bundleInfo.moduleResPaths,
918         JsonType::ARRAY,
919         false,
920         parseResult,
921         ArrayType::STRING);
922     GetValueIfFindKey<bool>(jsonObject,
923         jsonObjectEnd,
924         BUNDLE_INFO_SINGLETON,
925         bundleInfo.singleton,
926         JsonType::BOOLEAN,
927         false,
928         parseResult,
929         ArrayType::NOT_ARRAY);
930     GetValueIfFindKey<std::vector<ExtensionAbilityInfo>>(jsonObject,
931         jsonObjectEnd,
932         BUNDLE_INFO_EXTENSION_ABILITY_INFOS,
933         bundleInfo.extensionInfos,
934         JsonType::ARRAY,
935         false,
936         parseResult,
937         ArrayType::OBJECT);
938     GetValueIfFindKey<int32_t>(jsonObject,
939         jsonObjectEnd,
940         BUNDLE_INFO_APP_INDEX,
941         bundleInfo.appIndex,
942         JsonType::NUMBER,
943         false,
944         parseResult,
945         ArrayType::NOT_ARRAY);
946     GetValueIfFindKey<SignatureInfo>(jsonObject,
947         jsonObjectEnd,
948         BUNDLE_INFO_SIGNATURE_INFO,
949         bundleInfo.signatureInfo,
950         JsonType::OBJECT,
951         false,
952         parseResult,
953         ArrayType::NOT_ARRAY);
954     GetValueIfFindKey<bool>(jsonObject,
955         jsonObjectEnd,
956         BUNDLE_INFO_ASAN_ENABLED,
957         bundleInfo.asanEnabled,
958         JsonType::BOOLEAN,
959         false,
960         parseResult,
961         ArrayType::NOT_ARRAY);
962     if (parseResult != ERR_OK) {
963         APP_LOGE("BundleInfo from_json error, error code : %{public}d", parseResult);
964     }
965 }
966 }  // namespace AppExecFwk
967 }  // namespace OHOS
968