• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 <fstream>
17 #include <iostream>
18 #include <cinttypes>
19 
20 #include "app_log_wrapper.h"
21 #include "form_provider_data.h"
22 #include "message_parcel.h"
23 #include "string_ex.h"
24 
25 namespace OHOS {
26 namespace AppExecFwk {
27 const int IMAGE_DATA_STATE_REMOVED = -1;
28 const int IMAGE_DATA_STATE_NO_OPERATION = 0;
29 const int IMAGE_DATA_STATE_ADDED = 1;
30 const std::string JSON_EMPTY_STRING = "{}";
31 
32 /**
33  * @brief Constructor.
34  */
FormProviderData()35 FormProviderData::FormProviderData()
36 {
37     jsonFormProviderData_.clear();
38 }
39 
40 /**
41  * @brief A constructor used to create a {@code FormProviderData} instance with data of
42  * the {@code nlohmann::json} type specified.
43  * @param jsonData Indicates the data to be carried in the new {@code FormProviderData} instance,
44  *             in {@code nlohmann::json} format.
45  */
FormProviderData(nlohmann::json & jsonData)46 FormProviderData::FormProviderData(nlohmann::json &jsonData)
47 {
48     jsonFormProviderData_ = jsonData;
49 }
50 
51 /**
52  * @brief A constructor used to create a {@code FormProviderData} instance with data of the {@code String} type
53  * specified.
54  * @param jsonDataString Indicates the data to be carried in the new {@code FormProviderData} instance,
55  * in JSON string format.
56  */
FormProviderData(std::string jsonDataString)57 FormProviderData::FormProviderData(std::string jsonDataString)
58 {
59     if(jsonDataString.empty()) {
60         jsonDataString = JSON_EMPTY_STRING;
61     }
62     jsonFormProviderData_ = nlohmann::json::parse(jsonDataString);
63 }
64 
65 /**
66  * @brief Updates form data in this {@code FormProviderData} object.
67  * @param jsonData Indicates the new data to use, in {@code ZSONObject} format.
68  */
UpdateData(nlohmann::json & jsonData)69 void FormProviderData::UpdateData(nlohmann::json &jsonData)
70 {
71     jsonFormProviderData_ = jsonData;
72 }
73 /**
74  * @brief Obtains the form data stored in this {@code FormProviderData} object.
75  * @return Returns json data
76  */
GetData() const77 nlohmann::json FormProviderData::GetData() const
78 {
79     return jsonFormProviderData_;
80 }
81 /**
82  * @brief Obtains the form data stored in this {@code FormProviderData} object.
83  * @return Returns json string format
84  */
GetDataString() const85 std::string FormProviderData::GetDataString() const
86 {
87     APP_LOGI("%{public}s called", __func__);
88     std::string dataStr = jsonFormProviderData_.empty() ? "" : jsonFormProviderData_.dump();
89     APP_LOGI("%{public}s, data: %{public}s", __func__, dataStr.c_str());
90     return dataStr;
91 }
92 
93 /**
94  * @brief Adds an image to this {@code FormProviderData} instance.
95  * @param picName Indicates the name of the image to add.
96  * @param data Indicates the binary data of the image content.
97  */
AddImageData(std::string picName,char * data)98 void FormProviderData::AddImageData(std::string picName, char *data)
99 {
100     if ((picName.length() == 0) || (sizeof(data) == 0)) {
101         APP_LOGE("input param is NULL!");
102         return;
103     }
104 
105     rawImageBytesMap_[picName] = data;
106 
107     imageDataState_ = IMAGE_DATA_STATE_ADDED;
108 }
109 
110 /**
111  * @brief Removes data of an image with the specified {@code picName} from this {@code FormProviderData} instance.
112  * @param picName Indicates the name of the image to remove.
113  */
RemoveImageData(std::string picName)114 void FormProviderData::RemoveImageData(std::string picName)
115 {
116     rawImageBytesMap_.erase(picName);
117 }
118 
119 /**
120  * @brief Set the form data stored from string string.
121  * @param Returns string string.
122  */
SetDataString(std::string & jsonDataString)123 void FormProviderData::SetDataString(std::string &jsonDataString)
124 {
125     APP_LOGI("%{public}s called", __func__);
126     if(jsonDataString.empty()) {
127         jsonDataString = JSON_EMPTY_STRING;
128     }
129     jsonFormProviderData_ = nlohmann::json::parse(jsonDataString);
130 }
131 /**
132  * @brief Merge new data to FormProviderData.
133  * @param addJsonData data to merge to FormProviderData
134  */
MergeData(nlohmann::json & addJsonData)135 void FormProviderData::MergeData(nlohmann::json &addJsonData)
136 {
137     APP_LOGI("%{public}s called", __func__);
138     if (addJsonData.empty()) {
139         return;
140     }
141 
142     if (jsonFormProviderData_.empty()) {
143         jsonFormProviderData_ = addJsonData;
144         return;
145     }
146 
147     for (auto && [key, value] : addJsonData.items()) {
148         jsonFormProviderData_[key] = value;
149     }
150 }
151 
152 /**
153  * @brief Obtains the imageDataMap stored in this {@code FormProviderData} object.
154  * @return Returns the map that contains shared image data.
155  */
GetImageDataMap()156 std::map<std::string, std::pair<sptr<Ashmem>, int32_t>> FormProviderData::GetImageDataMap()
157 {
158     return imageDataMap_;
159 }
160 
161 /**
162  * @brief Obtains the add/remove state stored in this {@code FormProviderData} object.
163  * @return Returns the add/remove state of shared image data.
164  */
GetImageDataState()165 int32_t FormProviderData::GetImageDataState()
166 {
167     return imageDataState_;
168 }
169 
170 /**
171  * @brief Updates imageDataState in this {@code FormProviderData} object.
172  * @param imageDataState Indicates the imageDataState to update.
173  */
SetImageDataState(int32_t imageDataState)174 void FormProviderData::SetImageDataState(int32_t imageDataState)
175 {
176     imageDataState_ = imageDataState;
177 }
178 
179 /**
180  * @brief Updates imageDataMap in this {@code FormProviderData} object.
181  * @param imageDataMap Indicates the imageDataMap to update.
182  */
SetImageDataMap(std::map<std::string,std::pair<sptr<Ashmem>,int32_t>> imageDataMap)183 void FormProviderData::SetImageDataMap(std::map<std::string, std::pair<sptr<Ashmem>, int32_t>> imageDataMap)
184 {
185     imageDataMap_ = imageDataMap;
186 }
187 
188 /**
189  * Read this {@code FormProviderData} object from a Parcel.
190  * @param parcel the parcel
191  * eturn Returns {@code true} if the marshalling is successful; returns {@code false} otherwise.
192  */
ReadFromParcel(Parcel & parcel)193 bool FormProviderData::ReadFromParcel(Parcel &parcel)
194 {
195     jsonFormProviderData_ = nlohmann::json::parse(Str16ToStr8(parcel.ReadString16()));
196 
197     imageDataState_ = parcel.ReadInt32();
198     switch (imageDataState_) {
199         case IMAGE_DATA_STATE_ADDED: {
200             int32_t imageDataNum = parcel.ReadInt32();
201             for (int32_t i = 0; i < imageDataNum; i++) {
202                 MessageParcel* messageParcel = (MessageParcel*)&parcel;
203                 sptr<Ashmem> ashmem = messageParcel->ReadAshmem();
204                 if (ashmem == nullptr) {
205                     APP_LOGE("%{public}s failed, ashmem is nullptr", __func__);
206                     return false;
207                 }
208 
209                 int32_t len = parcel.ReadInt32();
210                 std::pair<sptr<Ashmem>, int32_t> imageDataRecord = std::make_pair(ashmem, len);
211                 imageDataMap_.emplace(Str16ToStr8(parcel.ReadString16()), imageDataRecord);
212             }
213             break;
214         }
215         case IMAGE_DATA_STATE_NO_OPERATION:
216         case IMAGE_DATA_STATE_REMOVED:
217             break;
218         default:
219             APP_LOGW("%{public}s failed, unexpected imageDataState_ %{public}d", __func__, imageDataState_);
220             break;
221     }
222     return true;
223 }
224 
225 /**
226  * @brief Marshals this {@code FormProviderData} object into a {@link ohos.utils.Parcel} object.
227  * @param parcel Indicates the {@code Parcel} object for marshalling.
228  * @return Returns {@code true} if the marshalling is successful; returns {@code false} otherwise.
229  */
Marshalling(Parcel & parcel) const230 bool FormProviderData::Marshalling(Parcel &parcel) const
231 {
232     APP_LOGI("%{public}s called, jsonFormProviderData_: %{public}s", __func__, jsonFormProviderData_.dump().c_str());
233     if (!parcel.WriteString16(Str8ToStr16(jsonFormProviderData_.empty() ? JSON_EMPTY_STRING : jsonFormProviderData_.dump()))) {
234         return false;
235     }
236 
237     parcel.WriteInt32(imageDataState_);
238     switch (imageDataState_) {
239         case IMAGE_DATA_STATE_ADDED: {
240             if (rawImageBytesMap_.size() == 0) {
241                 APP_LOGE("%{public}s failed, rawImageBytesMap_ is empty", __func__);
242                 return false;
243             }
244             parcel.WriteInt32(rawImageBytesMap_.size()); // firstly write the number of shared image to add
245             for (auto &entry : rawImageBytesMap_) {
246                 if (!WriteImageDataToParcel(parcel, entry.first, entry.second)) {
247                     APP_LOGE("%{public}s failed, the picture name is %{public}s", __func__, entry.first.c_str());
248                     return false;
249                 }
250                 parcel.WriteInt32(sizeof(entry.second));
251                 parcel.WriteString16(Str8ToStr16(entry.first));
252             }
253             break;
254         }
255         case IMAGE_DATA_STATE_NO_OPERATION:
256         case IMAGE_DATA_STATE_REMOVED:
257             break;
258         default:
259             APP_LOGW("%{public}s failed, unexpected imageDataState_ %{public}d", __func__, imageDataState_);
260             break;
261     }
262     return true;
263 }
264 
265 /**
266  * @brief Unmarshals this {@code FormProviderData} object from a {@link ohos.utils.Parcel} object.
267  * @param parcel Indicates the {@code Parcel} object for unmarshalling.
268  * @return FormProviderData.
269  */
Unmarshalling(Parcel & parcel)270 FormProviderData* FormProviderData::Unmarshalling(Parcel &parcel)
271 {
272     FormProviderData *formProviderData = new (std::nothrow) FormProviderData();
273     if (formProviderData && !formProviderData->ReadFromParcel(parcel)) {
274         delete formProviderData;
275         formProviderData = nullptr;
276     }
277     std::string str = formProviderData->GetDataString();
278     APP_LOGI("%{public}s, , provider data length: %{public}zu, provider data: %{public}s", __func__, str.length(), str.c_str());
279     return formProviderData;
280 }
281 
282 /**
283  * @brief Clear imageDataMap, rawImageBytesMap_, imageDataState_ and jsonFormProviderData_.
284  */
ClearData()285 void FormProviderData::ClearData()
286 {
287     jsonFormProviderData_.clear();
288 }
289 
WriteImageDataToParcel(Parcel & parcel,std::string picName,char * data) const290 bool FormProviderData::WriteImageDataToParcel(Parcel &parcel, std::string picName, char *data) const
291 {
292     sptr<Ashmem> ashmem = Ashmem::CreateAshmem(picName.c_str(), sizeof(data));
293     if (ashmem == nullptr) {
294         APP_LOGE("create shared memory fail");
295         return false;
296     }
297 
298     bool ret = ashmem->MapReadAndWriteAshmem();
299     if (!ret) {
300         APP_LOGE("map shared memory fail");
301         return false;
302     }
303 
304     ret = ashmem->WriteToAshmem(data, sizeof(data), 0);
305     if (!ret) {
306         APP_LOGE("write image data to shared memory fail");
307         return false;
308     }
309 
310     ashmem->UnmapAshmem();
311 
312     MessageParcel* messageParcel = (MessageParcel*)&parcel;
313     ret = messageParcel->WriteAshmem(ashmem);
314 
315     ashmem->CloseAshmem(); // close ashmem after writeAshmem because writeAshmem will dup fd
316     if (!ret) {
317         APP_LOGE("writeAshmem fail, the picture name is %{public}s", picName.c_str());
318         return false;
319     }
320 
321     return true;
322 }
323 }  // namespace AppExecFwk
324 }  // namespace OHOS
325