1 /*
2 * Copyright (c) 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 "udmf_impl.h"
17
18 #include <memory>
19 #include <unordered_map>
20
21 #include "html.h"
22 #include "image.h"
23 #include "link.h"
24 #include "summary_napi.h"
25 #include "system_defined_form.h"
26 #include "system_defined_pixelmap.h"
27 #include "text.h"
28 #include "plain_text.h"
29 #include "udmf_client.h"
30 #include "unified_data.h"
31 #include "unified_data_napi.h"
32 #include "unified_types.h"
33 #include "video.h"
34 #include "native_engine/native_engine.h"
35 #include "frameworks/bridge/common/utils/engine_helper.h"
36 #include "frameworks/bridge/common/utils/utils.h"
37 #include "frameworks/bridge/js_frontend/engine/common/js_engine.h"
38 #include "js_native_api_types.h"
39
40 #include "base/image/file_uri_helper.h"
41 #include "base/utils/utils.h"
42 #include "core/common/udmf/unified_data.h"
43 namespace OHOS::Ace {
GetInstance()44 UdmfClient* UdmfClient::GetInstance()
45 {
46 static UdmfClientImpl instance;
47 return &instance;
48 }
49
CreateUnifiedData()50 RefPtr<UnifiedData> UdmfClientImpl::CreateUnifiedData()
51 {
52 return AceType::DynamicCast<UnifiedData>(AceType::MakeRefPtr<UnifiedDataImpl>());
53 }
54
TransformUnifiedData(napi_value napiValue)55 RefPtr<UnifiedData> UdmfClientImpl::TransformUnifiedData(napi_value napiValue)
56 {
57 auto engine = EngineHelper::GetCurrentEngine();
58 CHECK_NULL_RETURN(engine, nullptr);
59 NativeEngine* nativeEngine = engine->GetNativeEngine();
60 napi_env env = reinterpret_cast<napi_env>(nativeEngine);
61 void* native = nullptr;
62 napi_unwrap(env, napiValue, &native);
63 auto* unifiedData = reinterpret_cast<UDMF::UnifiedDataNapi*>(native);
64 CHECK_NULL_RETURN(unifiedData, nullptr);
65 CHECK_NULL_RETURN(unifiedData->value_, nullptr);
66 auto udData = AceType::MakeRefPtr<UnifiedDataImpl>();
67 udData->SetUnifiedData(unifiedData->value_);
68 return udData;
69 }
70
TransformUdmfUnifiedData(RefPtr<UnifiedData> & UnifiedData)71 napi_value UdmfClientImpl::TransformUdmfUnifiedData(RefPtr<UnifiedData>& UnifiedData)
72 {
73 auto engine = EngineHelper::GetCurrentEngine();
74 CHECK_NULL_RETURN(engine, nullptr);
75 NativeEngine* nativeEngine = engine->GetNativeEngine();
76 napi_env env = reinterpret_cast<napi_env>(nativeEngine);
77 auto unifiedData = AceType::DynamicCast<UnifiedDataImpl>(UnifiedData)->GetUnifiedData();
78 CHECK_NULL_RETURN(unifiedData, nullptr);
79 napi_value dataVal = nullptr;
80 UDMF::UnifiedDataNapi::NewInstance(env, unifiedData, dataVal);
81 CHECK_NULL_RETURN(dataVal, nullptr);
82 return dataVal;
83 }
84
TransformSummary(std::map<std::string,int64_t> & summary)85 napi_value UdmfClientImpl::TransformSummary(std::map<std::string, int64_t>& summary)
86 {
87 auto engine = EngineHelper::GetCurrentEngine();
88 CHECK_NULL_RETURN(engine, nullptr);
89 NativeEngine* nativeEngine = engine->GetNativeEngine();
90 napi_env env = reinterpret_cast<napi_env>(nativeEngine);
91 std::shared_ptr<UDMF::Summary> udmfSummary = std::make_shared<UDMF::Summary>();
92 CHECK_NULL_RETURN(udmfSummary, nullptr);
93 udmfSummary->totalSize = 0;
94 for (auto element : summary) {
95 udmfSummary->totalSize += element.second;
96 }
97 udmfSummary->summary = std::move(summary);
98 napi_value dataVal = nullptr;
99 UDMF::SummaryNapi::NewInstance(env, udmfSummary, dataVal);
100 CHECK_NULL_RETURN(dataVal, nullptr);
101 return dataVal;
102 }
103
SetData(const RefPtr<UnifiedData> & unifiedData,std::string & key)104 int32_t UdmfClientImpl::SetData(const RefPtr<UnifiedData>& unifiedData, std::string& key)
105 {
106 auto client = UDMF::UdmfClient::GetInstance();
107 UDMF::CustomOption udCustomOption;
108 udCustomOption.intention = UDMF::Intention::UD_INTENTION_DRAG;
109 auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
110 CHECK_NULL_RETURN(udData, UDMF::E_ERROR);
111 int32_t ret = client.SetData(udCustomOption, *udData->GetUnifiedData(), key);
112 return ret;
113 }
114
GetData(const RefPtr<UnifiedData> & unifiedData,const std::string & key)115 int32_t UdmfClientImpl::GetData(const RefPtr<UnifiedData>& unifiedData, const std::string& key)
116 {
117 auto client = UDMF::UdmfClient::GetInstance();
118 UDMF::QueryOption queryOption;
119 queryOption.key = key;
120 auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
121 CHECK_NULL_RETURN(udData, UDMF::E_ERROR);
122 int ret = client.GetData(queryOption, *udData->GetUnifiedData());
123 return ret;
124 }
125
GetSummary(std::string & key,std::map<std::string,int64_t> & summaryMap)126 int32_t UdmfClientImpl::GetSummary(std::string& key, std::map<std::string, int64_t>& summaryMap)
127 {
128 auto client = UDMF::UdmfClient::GetInstance();
129 UDMF::Summary summary;
130 UDMF::QueryOption queryOption;
131 queryOption.key = key;
132 int32_t ret = client.GetSummary(queryOption, summary);
133 summaryMap = summary.summary;
134 return ret;
135 }
136
GetSize()137 int64_t UnifiedDataImpl::GetSize()
138 {
139 CHECK_NULL_RETURN(unifiedData_, 0);
140 return unifiedData_->GetRecords().size();
141 }
142
GetUnifiedData()143 std::shared_ptr<UDMF::UnifiedData> UnifiedDataImpl::GetUnifiedData()
144 {
145 if (unifiedData_ == nullptr) {
146 unifiedData_ = std::make_shared<UDMF::UnifiedData>();
147 }
148 return unifiedData_;
149 }
150
SetUnifiedData(std::shared_ptr<UDMF::UnifiedData> unifiedData)151 void UnifiedDataImpl::SetUnifiedData(std::shared_ptr<UDMF::UnifiedData> unifiedData)
152 {
153 unifiedData_ = unifiedData;
154 }
155
AddFormRecord(const RefPtr<UnifiedData> & unifiedData,int32_t formId,const RequestFormInfo & cardInfo)156 void UdmfClientImpl::AddFormRecord(
157 const RefPtr<UnifiedData>& unifiedData, int32_t formId, const RequestFormInfo& cardInfo)
158 {
159 auto formRecord = std::make_shared<UDMF::SystemDefinedForm>();
160 formRecord->SetFormId(formId);
161 formRecord->SetFormName(cardInfo.cardName);
162 formRecord->SetBundleName(cardInfo.bundleName);
163 formRecord->SetAbilityName(cardInfo.abilityName);
164 formRecord->SetModule(cardInfo.moduleName);
165 formRecord->SetType(UDMF::UDType::SYSTEM_DEFINED_FORM);
166
167 auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
168 CHECK_NULL_VOID(udData);
169 CHECK_NULL_VOID(udData->GetUnifiedData());
170 udData->GetUnifiedData()->AddRecord(formRecord);
171 }
172
AddLinkRecord(const RefPtr<UnifiedData> & unifiedData,const std::string & url,const std::string & description)173 void UdmfClientImpl::AddLinkRecord(
174 const RefPtr<UnifiedData>& unifiedData, const std::string& url, const std::string& description)
175 {
176 auto record = std::make_shared<UDMF::Link>(url, description);
177
178 auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
179 CHECK_NULL_VOID(udData);
180 CHECK_NULL_VOID(udData->GetUnifiedData());
181 udData->GetUnifiedData()->AddRecord(record);
182 }
183
GetLinkRecord(const RefPtr<UnifiedData> & unifiedData,std::string & url,std::string & description)184 void UdmfClientImpl::GetLinkRecord(
185 const RefPtr<UnifiedData>& unifiedData, std::string& url, std::string& description)
186 {
187 auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
188 CHECK_NULL_VOID(udData);
189 CHECK_NULL_VOID(udData->GetUnifiedData());
190 auto records = udData->GetUnifiedData()->GetRecords();
191 for (auto record : records) {
192 UDMF::UDType type = record->GetType();
193 if (type == UDMF::UDType::HYPERLINK) {
194 UDMF::Link* link = reinterpret_cast<UDMF::Link*>(record.get());
195 url = link->GetUrl();
196 description = link->GetDescription();
197 return;
198 }
199 }
200 }
201
AddHtmlRecord(const RefPtr<UnifiedData> & unifiedData,const std::string & htmlContent,const std::string & plainContent)202 void UdmfClientImpl::AddHtmlRecord(
203 const RefPtr<UnifiedData>& unifiedData, const std::string& htmlContent, const std::string& plainContent)
204 {
205 auto htmlRecord = std::make_shared<UDMF::Html>(htmlContent, plainContent);
206
207 auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
208 CHECK_NULL_VOID(udData);
209 CHECK_NULL_VOID(udData->GetUnifiedData());
210 if (!plainContent.empty() || !htmlContent.empty()) {
211 udData->GetUnifiedData()->AddRecord(htmlRecord);
212 }
213 }
214
GetHtmlRecord(const RefPtr<UnifiedData> & unifiedData,std::string & htmlContent,std::string & plainContent)215 void UdmfClientImpl::GetHtmlRecord(
216 const RefPtr<UnifiedData>& unifiedData, std::string& htmlContent, std::string& plainContent)
217 {
218 auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
219 CHECK_NULL_VOID(udData);
220 CHECK_NULL_VOID(udData->GetUnifiedData());
221 auto records = udData->GetUnifiedData()->GetRecords();
222 for (auto record : records) {
223 UDMF::UDType type = record->GetType();
224 if (type == UDMF::UDType::HTML) {
225 UDMF::Html* html = reinterpret_cast<UDMF::Html*>(record.get());
226 plainContent = html->GetPlainContent();
227 htmlContent = html->GetHtmlContent();
228 return;
229 }
230 }
231 }
232
AddPixelMapRecord(const RefPtr<UnifiedData> & unifiedData,std::vector<uint8_t> & data,PixelMapRecordDetails & details)233 void UdmfClientImpl::AddPixelMapRecord(const RefPtr<UnifiedData>& unifiedData, std::vector<uint8_t>& data,
234 PixelMapRecordDetails& details)
235 {
236 auto record = std::make_shared<UDMF::SystemDefinedPixelMap>(data);
237 UDMF::UDDetails uDetails = {
238 { "width", details.width },
239 { "height", details.height },
240 { "pixel-format", static_cast<int32_t>(details.pixelFormat) },
241 { "alpha-type", static_cast<int32_t>(details.alphaType) } };
242 record->SetDetails(uDetails);
243 auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
244 CHECK_NULL_VOID(udData);
245 CHECK_NULL_VOID(udData->GetUnifiedData());
246 udData->GetUnifiedData()->AddRecord(record);
247 }
248
AddImageRecord(const RefPtr<UnifiedData> & unifiedData,const std::string & uri)249 void UdmfClientImpl::AddImageRecord(const RefPtr<UnifiedData>& unifiedData, const std::string& uri)
250 {
251 auto record = std::make_shared<UDMF::Image>(uri);
252
253 auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
254 CHECK_NULL_VOID(udData);
255 CHECK_NULL_VOID(udData->GetUnifiedData());
256 udData->GetUnifiedData()->AddRecord(record);
257 }
258
AddPlainTextRecord(const RefPtr<UnifiedData> & unifiedData,const std::string & selectedStr)259 void UdmfClientImpl::AddPlainTextRecord(const RefPtr<UnifiedData>& unifiedData, const std::string& selectedStr)
260 {
261 auto record = std::make_shared<UDMF::PlainText>(selectedStr, "");
262
263 auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
264 CHECK_NULL_VOID(udData);
265 CHECK_NULL_VOID(udData->GetUnifiedData());
266 udData->GetUnifiedData()->AddRecord(record);
267 }
268
GetSinglePlainTextRecord(const RefPtr<UnifiedData> & unifiedData)269 std::string UdmfClientImpl::GetSinglePlainTextRecord(const RefPtr<UnifiedData>& unifiedData)
270 {
271 std::string str = "";
272 auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
273 CHECK_NULL_RETURN(udData, str);
274 CHECK_NULL_RETURN(udData->GetUnifiedData(), str);
275 auto records = udData->GetUnifiedData()->GetRecords();
276 if (records.size() >= 1 && records[0]->GetType() == UDMF::UDType::PLAIN_TEXT) {
277 UDMF::PlainText* plainText = reinterpret_cast<UDMF::PlainText*>(records[0].get());
278 str = plainText->GetContent();
279 }
280 return str;
281 }
282
AddFileUriRecord(const RefPtr<UnifiedData> & unifiedData,std::vector<std::string> & uri)283 bool UdmfClientImpl::AddFileUriRecord(const RefPtr<UnifiedData>& unifiedData, std::vector<std::string>& uri)
284 {
285 auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
286 CHECK_NULL_RETURN(udData, false);
287 CHECK_NULL_RETURN(udData->GetUnifiedData(), false);
288
289 for (std::string u : uri) {
290 LOGI("DragDrop event AddFileUriRecord, uri:%{public}s", u.c_str());
291 auto record = std::make_shared<UDMF::Image>(u);
292 udData->GetUnifiedData()->AddRecord(record);
293 }
294
295 return true;
296 }
297
GetFileUriRecord(const RefPtr<UnifiedData> & unifiedData,std::vector<std::string> & uri)298 bool UdmfClientImpl::GetFileUriRecord(const RefPtr<UnifiedData>& unifiedData, std::vector<std::string>& uri)
299 {
300 auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
301 CHECK_NULL_RETURN(udData, false);
302 CHECK_NULL_RETURN(udData->GetUnifiedData(), false);
303 auto records = udData->GetUnifiedData()->GetRecords();
304
305 for (auto record : records) {
306 UDMF::UDType type = record->GetType();
307 if (type == UDMF::UDType::IMAGE || type == UDMF::UDType::AUDIO ||
308 type == UDMF::UDType::VIDEO || type == UDMF::UDType::FILE) {
309 UDMF::File* file = reinterpret_cast<UDMF::File*>(record.get());
310 if (file) {
311 uri.emplace_back(file->GetUri());
312 LOGI("DragDrop event GetFileUri, uri:%{public}s", file->GetUri().c_str());
313 } else {
314 LOGE("DragDrop event GetFileUri file is null");
315 }
316 }
317 }
318 return true;
319 }
320
GetPlainTextRecords(const RefPtr<UnifiedData> & unifiedData)321 std::vector<std::string> UdmfClientImpl::GetPlainTextRecords(const RefPtr<UnifiedData>& unifiedData)
322 {
323 std::vector<std::string> textRecords;
324 auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
325 CHECK_NULL_RETURN(udData, textRecords);
326 CHECK_NULL_RETURN(udData->GetUnifiedData(), textRecords);
327 auto records = udData->GetUnifiedData()->GetRecords();
328 for (const auto& record : records) {
329 UDMF::UDType type = record->GetType();
330 if (type == UDMF::UDType::PLAIN_TEXT) {
331 UDMF::PlainText* plainText = reinterpret_cast<UDMF::PlainText*>(record.get());
332 std::string str = plainText->GetContent();
333 textRecords.emplace_back(str);
334 }
335 }
336 return textRecords;
337 }
338
GetVideoRecordUri(const RefPtr<UnifiedData> & unifiedData,std::string & uri)339 int32_t UdmfClientImpl::GetVideoRecordUri(const RefPtr<UnifiedData>& unifiedData, std::string& uri)
340 {
341 auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
342 CHECK_NULL_RETURN(udData, UDMF::E_ERROR);
343 CHECK_NULL_RETURN(udData->GetUnifiedData(), UDMF::E_ERROR);
344 auto records = udData->GetUnifiedData()->GetRecords();
345 if (records.size() == 0) {
346 return UDMF::E_ERROR;
347 }
348 auto video = static_cast<UDMF::Video*>(records[0].get());
349 uri = video->GetUri();
350 return 0;
351 }
352
GetErrorInfo(int32_t errorCode)353 std::pair<int32_t, std::string> UdmfClientImpl::GetErrorInfo(int32_t errorCode)
354 {
355 switch (errorCode) {
356 case UDMF::E_NOT_FOUND:
357 return { ERROR_CODE_DRAG_DATA_NOT_FOUND, "GetData failed, data not found." };
358 default:
359 return { ERROR_CODE_DRAG_DATA_ERROR, "GetData failed, data error." };
360 }
361 }
362 } // namespace OHOS::Ace
363