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 "form_js_info.h"
17 #include "fms_log_wrapper.h"
18 #include "string_ex.h"
19 
20 namespace OHOS {
21 namespace AppExecFwk {
ReadFromParcel(Parcel & parcel)22 bool FormJsInfo::ReadFromParcel(Parcel &parcel)
23 {
24     formId = parcel.ReadInt64();
25     formName = Str16ToStr8(parcel.ReadString16());
26     bundleName = Str16ToStr8(parcel.ReadString16());
27     abilityName = Str16ToStr8(parcel.ReadString16());
28     moduleName = Str16ToStr8(parcel.ReadString16());
29 
30     formTempFlag = parcel.ReadBool();
31     jsFormCodePath = Str16ToStr8(parcel.ReadString16());
32     formData = Str16ToStr8(parcel.ReadString16());
33 
34     formSrc = Str16ToStr8(parcel.ReadString16());
35     formWindow.designWidth = parcel.ReadInt32();
36     formWindow.autoDesignWidth = parcel.ReadBool();
37 
38     versionCode = parcel.ReadUint32();
39     versionName = Str16ToStr8(parcel.ReadString16());
40     compatibleVersion = parcel.ReadUint32();
41     int32_t typeData = parcel.ReadInt32();
42     type = static_cast<FormType>(typeData);
43     uiSyntax = static_cast<FormType>(parcel.ReadInt32());
44     isDynamic = parcel.ReadBool();
45     transparencyEnabled = parcel.ReadBool();
46 
47     std::unique_ptr<FormProviderData> bindingData(parcel.ReadParcelable<FormProviderData>());
48     if (bindingData == nullptr) {
49         return false;
50     }
51     formProviderData = *bindingData;
52 
53     ReadImageData(parcel);
54     ReadPkgNameMap(parcel);
55     return true;
56 }
57 
Unmarshalling(Parcel & parcel)58 FormJsInfo *FormJsInfo::Unmarshalling(Parcel &parcel)
59 {
60     std::unique_ptr<FormJsInfo> formJsInfo = std::make_unique<FormJsInfo>();
61     if (formJsInfo && !formJsInfo->ReadFromParcel(parcel)) {
62         formJsInfo = nullptr;
63     }
64     return formJsInfo.release();
65 }
66 
Marshalling(Parcel & parcel) const67 bool FormJsInfo::Marshalling(Parcel &parcel) const
68 {
69     // write formId
70     if (!parcel.WriteInt64(formId)) {
71         return false;
72     }
73     // write formName
74     if (!parcel.WriteString16(Str8ToStr16(formName))) {
75         return false;
76     }
77     // write bundleName
78     if (!parcel.WriteString16(Str8ToStr16(bundleName))) {
79         return false;
80     }
81     // write abilityName
82     if (!parcel.WriteString16(Str8ToStr16(abilityName))) {
83         return false;
84     }
85 
86     // write moduleName
87     if (!parcel.WriteString16(Str8ToStr16(moduleName))) {
88         return false;
89     }
90 
91     // write tempFlag
92     if (!parcel.WriteBool(formTempFlag)) {
93         return false;
94     }
95 
96     // write jsFormCodePath
97     if (!parcel.WriteString16(Str8ToStr16(jsFormCodePath))) {
98         return false;
99     }
100 
101     // write formData and formSrc
102     if (!parcel.WriteString16(Str8ToStr16(formData)) || !parcel.WriteString16(Str8ToStr16(formSrc))) {
103         return false;
104     }
105 
106     // write formWindow
107     if (!parcel.WriteInt32(formWindow.designWidth) || !parcel.WriteBool(formWindow.autoDesignWidth)) {
108         return false;
109     }
110 
111     // write version
112     if (!parcel.WriteUint32(versionCode) ||
113         !parcel.WriteString16(Str8ToStr16(versionName)) ||
114         !parcel.WriteUint32(compatibleVersion)) {
115         return false;
116     }
117     if (!parcel.WriteInt32(static_cast<int32_t>(type))) {
118         return false;
119     }
120     if (!parcel.WriteInt32(static_cast<int32_t>(uiSyntax))) {
121         return false;
122     }
123     if (!parcel.WriteBool(isDynamic) || !parcel.WriteBool(transparencyEnabled)) {
124         return false;
125     }
126     if (!WriteObjects(parcel)) {
127         return false;
128     }
129     return true;
130 }
131 
WriteObjects(Parcel & parcel) const132 bool FormJsInfo::WriteObjects(Parcel &parcel) const
133 {
134     // write formProviderData
135     if (!parcel.WriteParcelable(&formProviderData)) {
136         return false;
137     }
138 
139     if (!WriteImageData(parcel)) {
140         return false;
141     }
142 
143     if (!WritePkgNameMap(parcel)) {
144         return false;
145     }
146     return true;
147 }
148 
WriteImageData(Parcel & parcel) const149 bool FormJsInfo::WriteImageData(Parcel &parcel) const
150 {
151     HILOG_DEBUG("call");
152     auto imageDateState = formProviderData.GetImageDataState();
153     if (!parcel.WriteInt32(imageDateState)) {
154         return false;
155     }
156     HILOG_DEBUG("imageDateState is %{public}d", imageDateState);
157     switch (imageDateState) {
158         case FormProviderData::IMAGE_DATA_STATE_ADDED: {
159             auto sharedImageMap = formProviderData.GetImageDataMap();
160             auto size = sharedImageMap.size();
161             if (!parcel.WriteInt32(size)) {
162                 return false;
163             }
164             if (size > IMAGE_DATA_THRESHOLD) {
165                 HILOG_INFO("unexpected image number %{public}zu", size);
166                 break;
167             }
168             for (auto entry : sharedImageMap) {
169                 if (!parcel.WriteParcelable(entry.second.first)) {
170                     return false;
171                 }
172                 if (!parcel.WriteString16(Str8ToStr16(entry.first))) {
173                     return false;
174                 }
175             }
176             break;
177         }
178         case FormProviderData::IMAGE_DATA_STATE_NO_OPERATION:
179             break;
180         case FormProviderData::IMAGE_DATA_STATE_REMOVED:
181             break;
182         default: {
183             HILOG_WARN("unexpected imageDateState %{public}d", imageDateState);
184             break;
185         }
186     }
187     HILOG_DEBUG("end");
188     return true;
189 }
190 
ReadImageData(Parcel & parcel)191 void FormJsInfo::ReadImageData(Parcel &parcel)
192 {
193     HILOG_DEBUG("call");
194     auto imageDateState = parcel.ReadInt32();
195     HILOG_DEBUG("imageDateState is %{public}d", imageDateState);
196     switch (imageDateState) {
197         case FormProviderData::IMAGE_DATA_STATE_ADDED: {
198             auto size = parcel.ReadInt32();
199             HILOG_INFO("image numer is %{public}d", size);
200             if (size > IMAGE_DATA_THRESHOLD) {
201                 HILOG_WARN("unexpected image number %{public}d", size);
202                 break;
203             }
204             for (auto i = 0; i < size; i++) {
205                 sptr<FormAshmem> formAshmem = parcel.ReadParcelable<FormAshmem>();
206                 if (formAshmem == nullptr) {
207                     HILOG_ERROR("null ashmem");
208                     return;
209                 }
210                 auto picName = Str16ToStr8(parcel.ReadString16());
211                 HILOG_INFO("picName:%{public}s", picName.c_str());
212                 imageDataMap[picName] = formAshmem;
213             }
214             break;
215         }
216         case FormProviderData::IMAGE_DATA_STATE_NO_OPERATION:
217             break;
218         case FormProviderData::IMAGE_DATA_STATE_REMOVED:
219             break;
220         default: {
221             HILOG_WARN("unexpected imageDateState %{public}d", imageDateState);
222             break;
223         }
224     }
225     HILOG_DEBUG("end");
226     return;
227 }
228 
ConvertRawImageData()229 bool FormJsInfo::ConvertRawImageData()
230 {
231     HILOG_DEBUG("call");
232     if (!formProviderData.ConvertRawImageData()) {
233         return false;
234     }
235     auto sharedImageMap = formProviderData.GetImageDataMap();
236     auto size = sharedImageMap.size();
237     if (size > IMAGE_DATA_THRESHOLD) {
238         HILOG_ERROR("unexpected image number %{public}zu", size);
239         return false;
240     }
241     for (const auto &entry : sharedImageMap) {
242         imageDataMap[entry.first] = entry.second.first;
243     }
244     return true;
245 }
246 
WritePkgNameMap(Parcel & parcel) const247 bool FormJsInfo::WritePkgNameMap(Parcel &parcel) const
248 {
249     HILOG_DEBUG("call");
250     std::vector<std::string> keys;
251     std::vector<std::string> values;
252 
253     for (const auto &pkgNameInfo : modulePkgNameMap) {
254         keys.emplace_back(pkgNameInfo.first);
255         values.emplace_back(pkgNameInfo.second);
256     }
257 
258     parcel.WriteStringVector(keys);
259     parcel.WriteStringVector(values);
260     return true;
261 }
262 
ReadPkgNameMap(Parcel & parcel)263 void FormJsInfo::ReadPkgNameMap(Parcel &parcel)
264 {
265     HILOG_DEBUG("call");
266     std::vector<std::string> keys;
267     std::vector<std::string> values;
268     if (!parcel.ReadStringVector(&keys)) {
269         HILOG_ERROR("ReadStringVector for keys failed");
270         return;
271     }
272     if (!parcel.ReadStringVector(&values)) {
273         HILOG_ERROR("ReadStringVector for values failed");
274         return;
275     }
276     size_t keySize = keys.size();
277     size_t valueSize = values.size();
278     if (keySize != valueSize) {
279         HILOG_ERROR("ReadFromParcel failed, invalid size");
280         return;
281     }
282 
283     std::string key;
284     std::string val;
285     for (size_t index = 0; index < keySize; index++) {
286         key = keys.at(index);
287         val = values.at(index);
288         modulePkgNameMap.emplace(key, val);
289     }
290 }
291 } // namespace AppExecFwk
292 } // namespace OHOS