• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <variant>
21 
22 #include "html.h"
23 #include "image.h"
24 #include "link.h"
25 #include "summary_napi.h"
26 #include "system_defined_form.h"
27 #include "system_defined_pixelmap.h"
28 #include "text.h"
29 #include "plain_text.h"
30 #include "udmf_client.h"
31 #include "application_defined_record.h"
32 #include "async_task_params.h"
33 #include "data_params_conversion.h"
34 #include "get_data_params_napi.h"
35 #include "udmf_async_client.h"
36 #include "unified_data.h"
37 #include "unified_data_napi.h"
38 #include "unified_types.h"
39 #include "video.h"
40 #include "native_engine/native_engine.h"
41 #include "frameworks/bridge/common/utils/engine_helper.h"
42 #include "frameworks/bridge/common/utils/utils.h"
43 #include "frameworks/bridge/js_frontend/engine/common/js_engine.h"
44 #include "js_native_api_types.h"
45 
46 #include "base/image/file_uri_helper.h"
47 #include "base/utils/utils.h"
48 #include "core/common/udmf/unified_data.h"
49 #include "ndk_data_conversion.h"
50 namespace OHOS::Ace {
GetInstance()51 UdmfClient* UdmfClient::GetInstance()
52 {
53     static UdmfClientImpl instance;
54     return &instance;
55 }
56 
CreateUnifiedData()57 RefPtr<UnifiedData> UdmfClientImpl::CreateUnifiedData()
58 {
59     return AceType::DynamicCast<UnifiedData>(AceType::MakeRefPtr<UnifiedDataImpl>());
60 }
61 
TransformUnifiedData(napi_value napiValue)62 RefPtr<UnifiedData> UdmfClientImpl::TransformUnifiedData(napi_value napiValue)
63 {
64     auto engine = EngineHelper::GetCurrentEngine();
65     CHECK_NULL_RETURN(engine, nullptr);
66     NativeEngine* nativeEngine = engine->GetNativeEngine();
67     napi_env env = reinterpret_cast<napi_env>(nativeEngine);
68     void* native = nullptr;
69     napi_unwrap(env, napiValue, &native);
70     auto* unifiedData = reinterpret_cast<UDMF::UnifiedDataNapi*>(native);
71     CHECK_NULL_RETURN(unifiedData, nullptr);
72     CHECK_NULL_RETURN(unifiedData->value_, nullptr);
73     auto udData = AceType::MakeRefPtr<UnifiedDataImpl>();
74     udData->SetUnifiedData(unifiedData->value_);
75     return udData;
76 }
77 
TransformUdmfUnifiedData(RefPtr<UnifiedData> & UnifiedData)78 napi_value UdmfClientImpl::TransformUdmfUnifiedData(RefPtr<UnifiedData>& UnifiedData)
79 {
80     auto engine = EngineHelper::GetCurrentEngine();
81     CHECK_NULL_RETURN(engine, nullptr);
82     NativeEngine* nativeEngine = engine->GetNativeEngine();
83     napi_env env = reinterpret_cast<napi_env>(nativeEngine);
84     auto unifiedData = AceType::DynamicCast<UnifiedDataImpl>(UnifiedData)->GetUnifiedData();
85     CHECK_NULL_RETURN(unifiedData, nullptr);
86     napi_value dataVal = nullptr;
87     UDMF::UnifiedDataNapi::NewInstance(env, unifiedData, dataVal);
88     CHECK_NULL_RETURN(dataVal, nullptr);
89     return dataVal;
90 }
91 
TransformUnifiedDataPtr(RefPtr<UnifiedData> & unifiedDataImpl)92 void* UdmfClientImpl::TransformUnifiedDataPtr(RefPtr<UnifiedData>& unifiedDataImpl)
93 {
94     CHECK_NULL_RETURN(unifiedDataImpl, nullptr);
95     std::shared_ptr<UDMF::UnifiedData> unifiedData =
96         AceType::DynamicCast<UnifiedDataImpl>(unifiedDataImpl)->GetUnifiedData();
97     CHECK_NULL_RETURN(unifiedData, nullptr);
98     return unifiedData.get();
99 }
100 
TransformUnifiedDataForNative(void * rawData)101 RefPtr<UnifiedData> UdmfClientImpl::TransformUnifiedDataForNative(void* rawData)
102 {
103     CHECK_NULL_RETURN(rawData, nullptr);
104     auto udData = AceType::MakeRefPtr<UnifiedDataImpl>();
105     auto udmfData = static_cast<OH_UdmfData*>(rawData);
106     CHECK_NULL_RETURN(udmfData, nullptr);
107     auto unifiedData = std::make_shared<UDMF::UnifiedData>();
108     auto status = OHOS::UDMF::NdkDataConversion::GetNativeUnifiedData(udmfData, unifiedData);
109     if (status) {
110         return nullptr;
111     }
112 
113     udData->SetUnifiedData(unifiedData);
114     return udData;
115 }
116 
TransformSummary(std::map<std::string,int64_t> & summary)117 napi_value UdmfClientImpl::TransformSummary(std::map<std::string, int64_t>& summary)
118 {
119     auto engine = EngineHelper::GetCurrentEngine();
120     CHECK_NULL_RETURN(engine, nullptr);
121     NativeEngine* nativeEngine = engine->GetNativeEngine();
122     napi_env env = reinterpret_cast<napi_env>(nativeEngine);
123     std::shared_ptr<UDMF::Summary> udmfSummary = std::make_shared<UDMF::Summary>();
124     CHECK_NULL_RETURN(udmfSummary, nullptr);
125     udmfSummary->totalSize = 0;
126     for (auto element : summary) {
127         udmfSummary->totalSize += element.second;
128     }
129     udmfSummary->summary = std::move(summary);
130     napi_value dataVal = nullptr;
131     UDMF::SummaryNapi::NewInstance(env, udmfSummary, dataVal);
132     CHECK_NULL_RETURN(dataVal, nullptr);
133     return dataVal;
134 }
135 
SetData(const RefPtr<UnifiedData> & unifiedData,std::string & key)136 int32_t UdmfClientImpl::SetData(const RefPtr<UnifiedData>& unifiedData, std::string& key)
137 {
138     auto& client = UDMF::UdmfClient::GetInstance();
139     UDMF::CustomOption udCustomOption;
140     udCustomOption.intention = UDMF::Intention::UD_INTENTION_DRAG;
141     auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
142     CHECK_NULL_RETURN(udData, UDMF::E_ERROR);
143     int32_t ret = client.SetData(udCustomOption, *udData->GetUnifiedData(), key);
144     return ret;
145 }
146 
GetData(const RefPtr<UnifiedData> & unifiedData,const std::string & key)147 int32_t UdmfClientImpl::GetData(const RefPtr<UnifiedData>& unifiedData, const std::string& key)
148 {
149     auto& client = UDMF::UdmfClient::GetInstance();
150     UDMF::QueryOption queryOption;
151     queryOption.key = key;
152     auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
153     CHECK_NULL_RETURN(udData, UDMF::E_ERROR);
154     int ret = client.GetData(queryOption, *udData->GetUnifiedData());
155     return ret;
156 }
157 
StartAsyncDataRetrieval(napi_env env,napi_value napiValue,const std::string & key)158 int32_t UdmfClientImpl::StartAsyncDataRetrieval(napi_env env, napi_value napiValue, const std::string& key)
159 {
160     UDMF::GetDataParams getDataParams;
161     getDataParams.query.key = key;
162     getDataParams.query.intention = UDMF::Intention::UD_INTENTION_DRAG;
163     auto status = UDMF::GetDataParamsNapi::Convert2NativeValue(env, napiValue, getDataParams, key);
164     if (!status) {
165         return -1;
166     }
167     return static_cast<int32_t>(UDMF::UdmfAsyncClient::GetInstance().StartAsyncDataRetrieval(getDataParams));
168 }
169 
Cancel(const std::string & key)170 int32_t UdmfClientImpl::Cancel(const std::string& key)
171 {
172     return static_cast<int32_t>(UDMF::UdmfAsyncClient::GetInstance().Cancel(key));
173 }
174 
GetSummary(std::string & key,std::map<std::string,int64_t> & summaryMap)175 int32_t UdmfClientImpl::GetSummary(std::string& key, std::map<std::string, int64_t>& summaryMap)
176 {
177     auto& client = UDMF::UdmfClient::GetInstance();
178     UDMF::Summary summary;
179     UDMF::QueryOption queryOption;
180     queryOption.key = key;
181     int32_t ret = client.GetSummary(queryOption, summary);
182     summaryMap = summary.summary;
183     return ret;
184 }
185 
GetRemoteStatus(std::string & key)186 bool UdmfClientImpl::GetRemoteStatus(std::string& key)
187 {
188     auto& client = UDMF::UdmfClient::GetInstance();
189     bool isRemoteData = false;
190     UDMF::QueryOption queryOption;
191     queryOption.key = key;
192     int32_t ret = client.IsRemoteData(queryOption, isRemoteData);
193     if (ret != 0) {
194         // if ret is not 0, udmf client has not been sync, so return true to use remote getData.
195         return true;
196     }
197     return isRemoteData;
198 }
199 
GetSize()200 int64_t UnifiedDataImpl::GetSize()
201 {
202     CHECK_NULL_RETURN(unifiedData_, 0);
203     return unifiedData_->GetRecords().size();
204 }
205 
GetUnifiedData()206 std::shared_ptr<UDMF::UnifiedData> UnifiedDataImpl::GetUnifiedData()
207 {
208     if (unifiedData_ == nullptr) {
209         unifiedData_ = std::make_shared<UDMF::UnifiedData>();
210     }
211     return unifiedData_;
212 }
213 
SetUnifiedData(std::shared_ptr<UDMF::UnifiedData> unifiedData)214 void UnifiedDataImpl::SetUnifiedData(std::shared_ptr<UDMF::UnifiedData> unifiedData)
215 {
216     unifiedData_ = unifiedData;
217 }
218 
AddFormRecord(const RefPtr<UnifiedData> & unifiedData,int32_t formId,const RequestFormInfo & cardInfo)219 void UdmfClientImpl::AddFormRecord(
220     const RefPtr<UnifiedData>& unifiedData, int32_t formId, const RequestFormInfo& cardInfo)
221 {
222     auto formRecord = std::make_shared<UDMF::SystemDefinedForm>();
223     formRecord->SetFormId(formId);
224     formRecord->SetFormName(cardInfo.cardName);
225     formRecord->SetBundleName(cardInfo.bundleName);
226     formRecord->SetAbilityName(cardInfo.abilityName);
227     formRecord->SetModule(cardInfo.moduleName);
228     formRecord->SetType(UDMF::UDType::SYSTEM_DEFINED_FORM);
229 
230     auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
231     CHECK_NULL_VOID(udData);
232     CHECK_NULL_VOID(udData->GetUnifiedData());
233     udData->GetUnifiedData()->AddRecord(formRecord);
234 }
235 
AddLinkRecord(const RefPtr<UnifiedData> & unifiedData,const std::string & url,const std::string & description)236 void UdmfClientImpl::AddLinkRecord(
237     const RefPtr<UnifiedData>& unifiedData, const std::string& url, const std::string& description)
238 {
239     auto record = std::make_shared<UDMF::Link>(url, description);
240 
241     auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
242     CHECK_NULL_VOID(udData);
243     CHECK_NULL_VOID(udData->GetUnifiedData());
244     udData->GetUnifiedData()->AddRecord(record);
245 }
246 
GetLinkRecord(const RefPtr<UnifiedData> & unifiedData,std::string & url,std::string & description)247 void UdmfClientImpl::GetLinkRecord(
248     const RefPtr<UnifiedData>& unifiedData, std::string& url, std::string& description)
249 {
250     auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
251     CHECK_NULL_VOID(udData);
252     CHECK_NULL_VOID(udData->GetUnifiedData());
253     auto records = udData->GetUnifiedData()->GetRecords();
254     for (auto record : records) {
255         UDMF::UDType type = record->GetType();
256         if (type == UDMF::UDType::HYPERLINK) {
257             UDMF::Link* link = reinterpret_cast<UDMF::Link*>(record.get());
258             url = link->GetUrl();
259             description = link->GetDescription();
260             return;
261         }
262     }
263 }
264 
AddHtmlRecord(const RefPtr<UnifiedData> & unifiedData,const std::string & htmlContent,const std::string & plainContent)265 void UdmfClientImpl::AddHtmlRecord(
266     const RefPtr<UnifiedData>& unifiedData, const std::string& htmlContent, const std::string& plainContent)
267 {
268     auto htmlRecord = std::make_shared<UDMF::Html>(htmlContent, plainContent);
269 
270     auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
271     CHECK_NULL_VOID(udData);
272     CHECK_NULL_VOID(udData->GetUnifiedData());
273     if (!plainContent.empty() || !htmlContent.empty()) {
274         udData->GetUnifiedData()->AddRecord(htmlRecord);
275     }
276 }
277 
GetHtmlRecord(const RefPtr<UnifiedData> & unifiedData,std::string & htmlContent,std::string & plainContent)278 void UdmfClientImpl::GetHtmlRecord(
279     const RefPtr<UnifiedData>& unifiedData, std::string& htmlContent, std::string& plainContent)
280 {
281     auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
282     CHECK_NULL_VOID(udData);
283     CHECK_NULL_VOID(udData->GetUnifiedData());
284     auto records = udData->GetUnifiedData()->GetRecords();
285     for (auto record : records) {
286         UDMF::UDType type = record->GetType();
287         if (type == UDMF::UDType::HTML) {
288             UDMF::Html* html = reinterpret_cast<UDMF::Html*>(record.get());
289             plainContent = html->GetPlainContent();
290             htmlContent = html->GetHtmlContent();
291             return;
292         }
293     }
294 }
295 
AddPixelMapRecord(const RefPtr<UnifiedData> & unifiedData,std::vector<uint8_t> & data,PixelMapRecordDetails & details)296 void UdmfClientImpl::AddPixelMapRecord(const RefPtr<UnifiedData>& unifiedData, std::vector<uint8_t>& data,
297     PixelMapRecordDetails& details)
298 {
299     auto record = std::make_shared<UDMF::SystemDefinedPixelMap>(data);
300     UDMF::UDDetails uDetails = {
301         { "width", details.width },
302         { "height", details.height },
303         { "pixel-format", static_cast<int32_t>(details.pixelFormat) },
304         { "alpha-type", static_cast<int32_t>(details.alphaType) } };
305     record->SetDetails(uDetails);
306     auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
307     CHECK_NULL_VOID(udData);
308     CHECK_NULL_VOID(udData->GetUnifiedData());
309     udData->GetUnifiedData()->AddRecord(record);
310 }
311 
AddImageRecord(const RefPtr<UnifiedData> & unifiedData,const std::string & uri)312 void UdmfClientImpl::AddImageRecord(const RefPtr<UnifiedData>& unifiedData, const std::string& uri)
313 {
314     auto record = std::make_shared<UDMF::Image>(uri);
315 
316     auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
317     CHECK_NULL_VOID(udData);
318     CHECK_NULL_VOID(udData->GetUnifiedData());
319     udData->GetUnifiedData()->AddRecord(record);
320 }
321 
AddPlainTextRecord(const RefPtr<UnifiedData> & unifiedData,const std::string & selectedStr)322 void UdmfClientImpl::AddPlainTextRecord(const RefPtr<UnifiedData>& unifiedData, const std::string& selectedStr)
323 {
324     auto record = std::make_shared<UDMF::PlainText>(selectedStr, "");
325 
326     auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
327     CHECK_NULL_VOID(udData);
328     CHECK_NULL_VOID(udData->GetUnifiedData());
329     udData->GetUnifiedData()->AddRecord(record);
330 }
331 
GetSinglePlainTextRecord(const RefPtr<UnifiedData> & unifiedData)332 std::string UdmfClientImpl::GetSinglePlainTextRecord(const RefPtr<UnifiedData>& unifiedData)
333 {
334     std::string str = "";
335     auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
336     CHECK_NULL_RETURN(udData, str);
337     CHECK_NULL_RETURN(udData->GetUnifiedData(), str);
338     auto records = udData->GetUnifiedData()->GetRecords();
339     if (records.size() >= 1 && records[0]->GetType() == UDMF::UDType::PLAIN_TEXT) {
340         UDMF::PlainText* plainText = reinterpret_cast<UDMF::PlainText*>(records[0].get());
341         str = plainText->GetContent();
342     }
343     return str;
344 }
345 
AddFileUriRecord(const RefPtr<UnifiedData> & unifiedData,std::vector<std::string> & uri)346 bool UdmfClientImpl::AddFileUriRecord(const RefPtr<UnifiedData>& unifiedData, std::vector<std::string>& uri)
347 {
348     auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
349     CHECK_NULL_RETURN(udData, false);
350     CHECK_NULL_RETURN(udData->GetUnifiedData(), false);
351 
352     for (std::string u : uri) {
353         LOGI("DragDrop event AddFileUriRecord, uri:%{public}s", u.c_str());
354         auto record = std::make_shared<UDMF::Image>(u);
355         udData->GetUnifiedData()->AddRecord(record);
356     }
357 
358     return true;
359 }
360 
GetFileUriRecord(const RefPtr<UnifiedData> & unifiedData,std::vector<std::string> & uri)361 bool UdmfClientImpl::GetFileUriRecord(const RefPtr<UnifiedData>& unifiedData, std::vector<std::string>& uri)
362 {
363     auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
364     CHECK_NULL_RETURN(udData, false);
365     CHECK_NULL_RETURN(udData->GetUnifiedData(), false);
366     auto records = udData->GetUnifiedData()->GetRecords();
367 
368     for (auto record : records) {
369         UDMF::UDType type = record->GetType();
370         if (type == UDMF::UDType::IMAGE || type == UDMF::UDType::AUDIO ||
371             type == UDMF::UDType::VIDEO || type == UDMF::UDType::FILE) {
372             UDMF::File* file = reinterpret_cast<UDMF::File*>(record.get());
373             if (file) {
374                 uri.emplace_back(file->GetUri());
375                 LOGI("DragDrop event GetFileUri, uri:%{public}s", file->GetUri().c_str());
376             } else {
377                 LOGE("DragDrop event GetFileUri file is null");
378             }
379         }
380     }
381     return true;
382 }
383 
GetPlainTextRecords(const RefPtr<UnifiedData> & unifiedData)384 std::vector<std::string> UdmfClientImpl::GetPlainTextRecords(const RefPtr<UnifiedData>& unifiedData)
385 {
386     std::vector<std::string> textRecords;
387     auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
388     CHECK_NULL_RETURN(udData, textRecords);
389     CHECK_NULL_RETURN(udData->GetUnifiedData(), textRecords);
390     auto records = udData->GetUnifiedData()->GetRecords();
391     for (const auto& record : records) {
392         UDMF::UDType type = record->GetType();
393         if (type == UDMF::UDType::PLAIN_TEXT) {
394             UDMF::PlainText* plainText = reinterpret_cast<UDMF::PlainText*>(record.get());
395             std::string str = plainText->GetContent();
396             textRecords.emplace_back(str);
397         }
398     }
399     return textRecords;
400 }
401 
GetVideoRecordUri(const RefPtr<UnifiedData> & unifiedData,std::string & uri)402 int32_t UdmfClientImpl::GetVideoRecordUri(const RefPtr<UnifiedData>& unifiedData, std::string& uri)
403 {
404     auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
405     CHECK_NULL_RETURN(udData, UDMF::E_ERROR);
406     CHECK_NULL_RETURN(udData->GetUnifiedData(), UDMF::E_ERROR);
407     auto records = udData->GetUnifiedData()->GetRecords();
408     if (records.size() == 0) {
409         return UDMF::E_ERROR;
410     }
411     auto video = static_cast<UDMF::Video*>(records[0].get());
412     uri = video->GetUri();
413     return 0;
414 }
415 
GetErrorInfo(int32_t errorCode)416 std::pair<int32_t, std::string> UdmfClientImpl::GetErrorInfo(int32_t errorCode)
417 {
418     switch (errorCode) {
419         case UDMF::E_NOT_FOUND:
420             return { ERROR_CODE_DRAG_DATA_NOT_FOUND, "GetData failed, data not found." };
421         default:
422             return { ERROR_CODE_DRAG_DATA_ERROR, "GetData failed, data error." };
423     }
424 }
425 
AddSpanStringRecord(const RefPtr<UnifiedData> & unifiedData,std::vector<uint8_t> & data)426 void UdmfClientImpl::AddSpanStringRecord(
427     const RefPtr<UnifiedData>& unifiedData, std::vector<uint8_t>& data)
428 {
429     auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
430     CHECK_NULL_VOID(udData);
431     CHECK_NULL_VOID(udData->GetUnifiedData());
432     auto record = std::make_shared<UDMF::ApplicationDefinedRecord>("OPENHARMONY_STYLED_STRING_UDMF", data);
433     udData->GetUnifiedData()->AddRecord(record);
434 }
435 
GetSpanStringRecord(const RefPtr<UnifiedData> & unifiedData)436 std::vector<uint8_t> UdmfClientImpl::GetSpanStringRecord(const RefPtr<UnifiedData>& unifiedData)
437 {
438     std::vector<uint8_t> arr;
439     auto udData = AceType::DynamicCast<UnifiedDataImpl>(unifiedData);
440     CHECK_NULL_RETURN(udData, arr);
441     CHECK_NULL_RETURN(udData->GetUnifiedData(), arr);
442     auto records = udData->GetUnifiedData()->GetRecords();
443     for (auto record: records) {
444         UDMF::UDType type = record->GetType();
445         if (type == UDMF::UDType::APPLICATION_DEFINED_RECORD) {
446             UDMF::ApplicationDefinedRecord* app = reinterpret_cast<UDMF::ApplicationDefinedRecord*>(record.get());
447             if (app->GetApplicationDefinedType() == "OPENHARMONY_STYLED_STRING_UDMF") {
448                 arr = app->GetRawData();
449                 return arr;
450             }
451         }
452     }
453     return arr;
454 }
455 } // namespace OHOS::Ace
456