1 /*
2  * Copyright (c) 2024 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 "mission/distributed_bundle_info.h"
17 
18 #include "mission/json_util.h"
19 #include "nlohmann/json.hpp"
20 #include "parcel_helper.h"
21 #include "parcel_macro.h"
22 #include "string_ex.h"
23 
24 namespace OHOS {
25 namespace DistributedSchedule {
26 namespace {
27 const std::string TAG = "dmsBundleInfo";
28 const std::string JSON_KEY_VERSION = "version";
29 const std::string JSON_KEY_VERSION_CODE = "versionCode";
30 const std::string JSON_KEY_COMPATIBLE_VERSION_CODE = "compatibleVersionCode";
31 const std::string JSON_KEY_VERSION_NAME = "versionName";
32 const std::string JSON_KEY_MIN_COMPATIBLE_VERSION = "minCompatibleVersion";
33 const std::string JSON_KEY_TARGET_VERSION_CODE = "targetVersionCode";
34 const std::string JSON_KEY_APP_ID = "appId";
35 const std::string JSON_KEY_ENABLED = "enabled";
36 const std::string JSON_KEY_BUNDLE_NAME_ID = "bundleNameId";
37 const std::string JSON_KEY_UPDATE_TIME = "updateTime";
38 const std::string JSON_KEY_DEVELOPER_ID = "developerId";
39 const std::string JSON_KEY_DMS_ABILITY_INFOS = "dmsAbilityInfos";
40 const std::string JSON_KEY_DMS_ABILITY_NAME = "abilityName";
41 const std::string JSON_KEY_DMS_CONTINUETYPE = "continueType";
42 const std::string JSON_KEY_DMS_CONTINUETYPEID = "continueTypeId";
43 const std::string JSON_KEY_DMS_USERID = "userIdArr";
44 const std::string JSON_KEY_DMS_MODULENAME = "moduleName";
45 const std::string JSON_KEY_DMS_MAX_BUNDLENAME_ID = "maxBundleNameId";
46 }
47 
ReadFromParcel(Parcel & parcel)48 bool PublicRecordsInfo::ReadFromParcel(Parcel &parcel)
49 {
50     maxBundleNameId = parcel.ReadUint16();
51     return true;
52 }
53 
Marshalling(Parcel & parcel) const54 bool PublicRecordsInfo::Marshalling(Parcel &parcel) const
55 {
56     parcel.WriteUint16(maxBundleNameId);
57     return true;
58 }
59 
Unmarshalling(Parcel & parcel)60 PublicRecordsInfo *PublicRecordsInfo::Unmarshalling(Parcel &parcel)
61 {
62     PublicRecordsInfo *info = new (std::nothrow) PublicRecordsInfo();
63     if (info != nullptr && !info->ReadFromParcel(parcel)) {
64         APP_LOGW("read from parcel failed");
65         delete info;
66         info = nullptr;
67     }
68     return info;
69 }
70 
ToString() const71 std::string PublicRecordsInfo::ToString() const
72 {
73     nlohmann::json jsonObject;
74     jsonObject[JSON_KEY_DMS_MAX_BUNDLENAME_ID] = maxBundleNameId;
75     return jsonObject.dump();
76 }
77 
to_json(nlohmann::json & jsonObject,const PublicRecordsInfo & publicRecordsInfo)78 void to_json(nlohmann::json &jsonObject, const PublicRecordsInfo &publicRecordsInfo)
79 {
80     APP_LOGI("call");
81     jsonObject = nlohmann::json {
82         {JSON_KEY_DMS_MAX_BUNDLENAME_ID, publicRecordsInfo.maxBundleNameId},
83     };
84     APP_LOGI("end");
85 }
86 
from_json(const nlohmann::json & jsonObject,PublicRecordsInfo & publicRecordsInfo)87 void from_json(const nlohmann::json &jsonObject, PublicRecordsInfo &publicRecordsInfo)
88 {
89     APP_LOGI("call");
90     const auto &jsonObjectEnd = jsonObject.end();
91     int32_t parseResult = ERR_OK;
92     GetValueIfFindKey<uint16_t>(jsonObject,
93         jsonObjectEnd,
94         JSON_KEY_DMS_CONTINUETYPEID,
95         publicRecordsInfo.maxBundleNameId,
96         JsonType::NUMBER,
97         false,
98         parseResult,
99         ArrayType::NOT_ARRAY);
100     if (parseResult != ERR_OK) {
101         APP_LOGE("read PublicRecordsInfo from jsonObject error, error code : %{public}d", parseResult);
102     }
103     APP_LOGI("end");
104 }
105 
FromJsonString(const std::string & jsonString)106 bool PublicRecordsInfo::FromJsonString(const std::string &jsonString)
107 {
108     nlohmann::json jsonObject = nlohmann::json::parse(jsonString, nullptr, false);
109     if (jsonObject.is_discarded()) {
110         return false;
111     }
112     const auto &jsonObjectEnd = jsonObject.end();
113     int32_t parseResult = ERR_OK;
114     GetValueIfFindKey<uint16_t>(jsonObject, jsonObjectEnd, JSON_KEY_DMS_MAX_BUNDLENAME_ID, maxBundleNameId,
115         JsonType::NUMBER, false, parseResult, ArrayType::NOT_ARRAY);
116     return parseResult == ERR_OK;
117 }
118 
ReadFromParcel(Parcel & parcel)119 bool DmsAbilityInfo::ReadFromParcel(Parcel &parcel)
120 {
121     abilityName = Str16ToStr8(parcel.ReadString16());
122 
123     int32_t continueTypeSize;
124     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, continueTypeSize);
125     CONTAINER_SECURITY_VERIFY(parcel, continueTypeSize, &continueType);
126     for (auto i = 0; i < continueTypeSize; i++) {
127         continueType.emplace_back(Str16ToStr8(parcel.ReadString16()));
128     }
129 
130     int32_t continueTypeIdSize;
131     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, continueTypeIdSize);
132     CONTAINER_SECURITY_VERIFY(parcel, continueTypeIdSize, &continueTypeId);
133     for (auto i = 0; i < continueTypeIdSize; i++) {
134         continueTypeId.emplace_back(parcel.ReadUint8());
135     }
136     moduleName = Str16ToStr8(parcel.ReadString16());
137     return true;
138 }
139 
Marshalling(Parcel & parcel) const140 bool DmsAbilityInfo::Marshalling(Parcel &parcel) const
141 {
142     parcel.WriteString16(Str8ToStr16(abilityName));
143     for (auto &ele : continueType) {
144         parcel.WriteString16(Str8ToStr16(ele));
145     }
146     for (auto &ele : continueTypeId) {
147         parcel.WriteUint8(ele);
148     }
149     parcel.WriteString16(Str8ToStr16(moduleName));
150     return true;
151 }
152 
Unmarshalling(Parcel & parcel)153 DmsAbilityInfo *DmsAbilityInfo::Unmarshalling(Parcel &parcel)
154 {
155     DmsAbilityInfo *info = new (std::nothrow) DmsAbilityInfo();
156     if (info != nullptr && !info->ReadFromParcel(parcel)) {
157         APP_LOGW("read from parcel failed");
158         delete info;
159         info = nullptr;
160     }
161     return info;
162 }
163 
to_json(nlohmann::json & jsonObject,const DmsAbilityInfo & dmsAbilityInfo)164 void to_json(nlohmann::json &jsonObject, const DmsAbilityInfo &dmsAbilityInfo)
165 {
166     jsonObject = nlohmann::json {
167         {JSON_KEY_DMS_ABILITY_NAME, dmsAbilityInfo.abilityName},
168         {JSON_KEY_DMS_CONTINUETYPE, dmsAbilityInfo.continueType},
169          {JSON_KEY_DMS_CONTINUETYPEID, dmsAbilityInfo.continueTypeId},
170         {JSON_KEY_DMS_MODULENAME, dmsAbilityInfo.moduleName}
171     };
172 }
173 
from_json(const nlohmann::json & jsonObject,DmsAbilityInfo & dmsAbilityInfo)174 void from_json(const nlohmann::json &jsonObject, DmsAbilityInfo &dmsAbilityInfo)
175 {
176     const auto &jsonObjectEnd = jsonObject.end();
177     int32_t parseResult = ERR_OK;
178     GetValueIfFindKey<std::string>(jsonObject,
179         jsonObjectEnd,
180         JSON_KEY_DMS_ABILITY_NAME,
181         dmsAbilityInfo.abilityName,
182         JsonType::STRING,
183         false,
184         parseResult,
185         ArrayType::NOT_ARRAY);
186     GetValueIfFindKey<std::vector<std::string>>(jsonObject,
187         jsonObjectEnd,
188         JSON_KEY_DMS_CONTINUETYPE,
189         dmsAbilityInfo.continueType,
190         JsonType::ARRAY,
191         false,
192         parseResult,
193         ArrayType::STRING);
194     GetValueIfFindKey<std::vector<uint8_t>>(jsonObject,
195         jsonObjectEnd,
196         JSON_KEY_DMS_CONTINUETYPEID,
197         dmsAbilityInfo.continueTypeId,
198         JsonType::ARRAY,
199         false,
200         parseResult,
201         ArrayType::NUMBER);
202     GetValueIfFindKey<std::string>(jsonObject,
203         jsonObjectEnd,
204         JSON_KEY_DMS_MODULENAME,
205         dmsAbilityInfo.moduleName,
206         JsonType::STRING,
207         false,
208         parseResult,
209         ArrayType::NOT_ARRAY);
210     if (parseResult != ERR_OK) {
211         APP_LOGE("read module moduleInfo from jsonObject error, error code : %{public}d", parseResult);
212     }
213 }
214 
ReadFromParcel(Parcel & parcel)215 bool DmsBundleInfo::ReadFromParcel(Parcel &parcel)
216 {
217     version = parcel.ReadUint32();
218     versionCode = parcel.ReadUint32();
219     compatibleVersionCode = parcel.ReadUint32();
220     minCompatibleVersion = parcel.ReadUint32();
221     targetVersionCode = parcel.ReadUint32();
222     bundleName = Str16ToStr8(parcel.ReadString16());
223     versionName = Str16ToStr8(parcel.ReadString16());
224     appId = Str16ToStr8(parcel.ReadString16());
225     enabled = parcel.ReadBool();
226     bundleNameId = parcel.ReadUint16();
227     updateTime = parcel.ReadInt64();
228     developerId = Str16ToStr8(parcel.ReadString16());
229     uint32_t abilityInfosSize;
230     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, abilityInfosSize);
231     CONTAINER_SECURITY_VERIFY(parcel, abilityInfosSize, &dmsAbilityInfos);
232     for (uint32_t i = 0; i < abilityInfosSize; i++) {
233         std::unique_ptr<DmsAbilityInfo> dmsAbilityInfo(parcel.ReadParcelable<DmsAbilityInfo>());
234         if (!dmsAbilityInfo) {
235             APP_LOGE("ReadParcelable<DmsAbilityInfo> failed");
236             return false;
237         }
238         dmsAbilityInfos.emplace_back(*dmsAbilityInfo);
239     }
240     uint32_t userIdArrSize;
241     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, userIdArrSize);
242     CONTAINER_SECURITY_VERIFY(parcel, userIdArrSize, &userIdArr);
243     for (uint32_t i = 0; i < userIdArrSize; i++) {
244         uint8_t userId = parcel.ReadUint8();
245         userIdArr.emplace_back(userId);
246     }
247     return true;
248 }
249 
Marshalling(Parcel & parcel) const250 bool DmsBundleInfo::Marshalling(Parcel &parcel) const
251 {
252     parcel.WriteUint32(version);
253     parcel.WriteUint32(versionCode);
254     parcel.WriteUint32(compatibleVersionCode);
255     parcel.WriteUint32(minCompatibleVersion);
256     parcel.WriteUint32(targetVersionCode);
257     parcel.WriteString16(Str8ToStr16(bundleName));
258     parcel.WriteString16(Str8ToStr16(versionName));
259     parcel.WriteString16(Str8ToStr16(appId));
260     parcel.WriteBool(enabled);
261     parcel.WriteUint16(bundleNameId);
262     parcel.WriteInt64(updateTime);
263     for (auto &dmsAbilityInfo : dmsAbilityInfos) {
264         (parcel).WriteParcelable(&dmsAbilityInfo);
265     }
266     for (auto userId : userIdArr) {
267         (parcel).WriteUint8(userId);
268     }
269     return true;
270 }
271 
Unmarshalling(Parcel & parcel)272 DmsBundleInfo *DmsBundleInfo::Unmarshalling(Parcel &parcel)
273 {
274     DmsBundleInfo *info = new (std::nothrow) DmsBundleInfo();
275     if (info != nullptr && !info->ReadFromParcel(parcel)) {
276         delete info;
277         info = nullptr;
278     }
279     return info;
280 }
281 
ToString() const282 std::string DmsBundleInfo::ToString() const
283 {
284     nlohmann::json jsonObject;
285     jsonObject[JSON_KEY_VERSION] = version;
286     jsonObject[AppExecFwk::Constants::BUNDLE_NAME] = bundleName;
287     jsonObject[JSON_KEY_VERSION_CODE] = versionCode;
288     jsonObject[JSON_KEY_VERSION_NAME] = versionName;
289     jsonObject[JSON_KEY_COMPATIBLE_VERSION_CODE] = compatibleVersionCode;
290     jsonObject[JSON_KEY_MIN_COMPATIBLE_VERSION] = minCompatibleVersion;
291     jsonObject[JSON_KEY_TARGET_VERSION_CODE] = targetVersionCode;
292     jsonObject[JSON_KEY_APP_ID] = appId;
293     jsonObject[JSON_KEY_ENABLED] = enabled;
294     jsonObject[JSON_KEY_BUNDLE_NAME_ID] = bundleNameId;
295     jsonObject[JSON_KEY_UPDATE_TIME] = updateTime;
296     jsonObject[JSON_KEY_DEVELOPER_ID] = developerId;
297     jsonObject[JSON_KEY_DMS_ABILITY_INFOS] = dmsAbilityInfos;
298     jsonObject[JSON_KEY_DMS_USERID] = userIdArr;
299     return jsonObject.dump();
300 }
301 
FromJsonString(const std::string & jsonString)302 bool DmsBundleInfo::FromJsonString(const std::string &jsonString)
303 {
304     nlohmann::json jsonObject = nlohmann::json::parse(jsonString, nullptr, false);
305     if (jsonObject.is_discarded()) {
306         return false;
307     }
308 
309     const auto &jsonObjectEnd = jsonObject.end();
310     int32_t parseResult = ERR_OK;
311     GetValueIfFindKey<uint32_t>(jsonObject, jsonObjectEnd, JSON_KEY_VERSION, version,
312         JsonType::NUMBER, false, parseResult, ArrayType::NOT_ARRAY);
313     GetValueIfFindKey<std::string>(jsonObject, jsonObjectEnd, AppExecFwk::Constants::BUNDLE_NAME, bundleName,
314         JsonType::STRING, false, parseResult, ArrayType::NOT_ARRAY);
315     GetValueIfFindKey<uint32_t>(jsonObject, jsonObjectEnd, JSON_KEY_VERSION_CODE, versionCode,
316         JsonType::NUMBER, false, parseResult, ArrayType::NOT_ARRAY);
317     GetValueIfFindKey<uint32_t>(jsonObject, jsonObjectEnd, JSON_KEY_COMPATIBLE_VERSION_CODE, compatibleVersionCode,
318         JsonType::NUMBER, false, parseResult, ArrayType::NOT_ARRAY);
319     GetValueIfFindKey<std::string>(jsonObject, jsonObjectEnd, JSON_KEY_VERSION_NAME, versionName,
320         JsonType::STRING, false, parseResult, ArrayType::NOT_ARRAY);
321     GetValueIfFindKey<uint32_t>(jsonObject, jsonObjectEnd, JSON_KEY_MIN_COMPATIBLE_VERSION, minCompatibleVersion,
322         JsonType::NUMBER, false, parseResult, ArrayType::NOT_ARRAY);
323     GetValueIfFindKey<uint32_t>(jsonObject, jsonObjectEnd, JSON_KEY_TARGET_VERSION_CODE, targetVersionCode,
324         JsonType::NUMBER, false, parseResult, ArrayType::NOT_ARRAY);
325     GetValueIfFindKey<std::string>(jsonObject, jsonObjectEnd, JSON_KEY_APP_ID, appId,
326         JsonType::STRING, false, parseResult, ArrayType::NOT_ARRAY);
327     GetValueIfFindKey<bool>(jsonObject, jsonObjectEnd, JSON_KEY_ENABLED, enabled,
328         JsonType::BOOLEAN, false, parseResult, ArrayType::NOT_ARRAY);
329     GetValueIfFindKey<uint16_t>(jsonObject, jsonObjectEnd, JSON_KEY_BUNDLE_NAME_ID, bundleNameId,
330         JsonType::NUMBER, false, parseResult, ArrayType::NOT_ARRAY);
331     GetValueIfFindKey<int64_t>(jsonObject, jsonObjectEnd, JSON_KEY_UPDATE_TIME, updateTime,
332         JsonType::NUMBER, false, parseResult, ArrayType::NOT_ARRAY);
333     GetValueIfFindKey<std::string>(jsonObject, jsonObjectEnd, JSON_KEY_DEVELOPER_ID, developerId,
334         JsonType::STRING, false, parseResult, ArrayType::NOT_ARRAY);
335     GetValueIfFindKey<std::vector<DmsAbilityInfo>>(jsonObject, jsonObjectEnd, JSON_KEY_DMS_ABILITY_INFOS,
336         dmsAbilityInfos, JsonType::ARRAY, false, parseResult, ArrayType::OBJECT);
337     GetValueIfFindKey<std::vector<uint8_t>>(jsonObject, jsonObjectEnd, JSON_KEY_DMS_USERID, userIdArr,
338         JsonType::ARRAY, false, parseResult, ArrayType::NUMBER);
339     return parseResult == ERR_OK;
340 }
341 }  // namespace DistributedSchedule
342 }  // namespace OHOS