• 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 #define LOG_TAG "UnifiedDataNapi"
16 #include "unified_data_napi.h"
17 
18 #include "application_defined_record_napi.h"
19 #include "audio_napi.h"
20 #include "file_napi.h"
21 #include "folder_napi.h"
22 #include "html_napi.h"
23 #include "image_napi.h"
24 #include "link_napi.h"
25 #include "plain_text_napi.h"
26 #include "system_defined_appitem_napi.h"
27 #include "system_defined_form_napi.h"
28 #include "system_defined_pixelmap_napi.h"
29 #include "system_defined_record_napi.h"
30 #include "text_napi.h"
31 #include "unified_data.h"
32 #include "unified_record_napi.h"
33 #include "video_napi.h"
34 
35 namespace OHOS {
36 namespace UDMF {
Constructor(napi_env env)37 napi_value UnifiedDataNapi::Constructor(napi_env env)
38 {
39     LOG_DEBUG(UDMF_KITS_NAPI, "UnifiedDataNapi");
40     napi_property_descriptor properties[] = {
41         /* UnifiedData properties */
42         DECLARE_NAPI_FUNCTION("addRecord", AddRecord),
43         DECLARE_NAPI_FUNCTION("getRecords", GetRecords),
44         DECLARE_NAPI_FUNCTION("hasType", HasType),
45         DECLARE_NAPI_FUNCTION("getTypes", GetTypes),
46         DECLARE_NAPI_GETTER_SETTER("properties", GetProperties, SetProperties),
47     };
48     size_t count = sizeof(properties) / sizeof(properties[0]);
49     return NapiDataUtils::DefineClass(env, "UnifiedData", properties, count, UnifiedDataNapi::New);
50 }
51 
New(napi_env env,napi_callback_info info)52 napi_value UnifiedDataNapi::New(napi_env env, napi_callback_info info)
53 {
54     LOG_DEBUG(UDMF_KITS_NAPI, "UnifiedDataNapi");
55     UnifiedRecordNapi *uRecord = nullptr;
56     auto ctxt = std::make_shared<ContextBase>();
57     auto input = [env, info, ctxt, &uRecord](size_t argc, napi_value *argv) {
58         if (argc == 1) {
59             ctxt->status = napi_unwrap(env, *argv, reinterpret_cast<void **>(&uRecord));
60             ASSERT_BUSINESS_ERR(ctxt, (ctxt->status == napi_ok && uRecord != nullptr && uRecord->value_ != nullptr),
61                 Status::E_INVALID_PARAMETERS, "Parameter error: parameter record type must be UnifiedRecord");
62             ctxt->status = UnifiedDataUtils::IsValidType(uRecord->value_->GetType()) ? napi_ok : napi_invalid_arg;
63             ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::E_ERROR, "invalid type!");
64         }
65     };
66 
67     // Parsing input parameters
68     ctxt->GetCbInfoSync(env, info, input);
69     ASSERT_ERR(ctxt->env, ctxt->status == napi_ok, Status::E_ERROR, ctxt->error);
70     auto *uData = new (std::nothrow) UnifiedDataNapi();
71     ASSERT_ERR(ctxt->env, uData != nullptr, Status::E_ERROR, "no memory for unified data!");
72 
73     // Create and bind UnifiedDataPropertiesNapi
74     int argc = 0;
75     napi_value argv[0] = {};
76     UnifiedDataPropertiesNapi* propertiesNapi = nullptr;
77     uData->propertyRef_ = NewWithRef(env, argc, argv, reinterpret_cast<void **>(&propertiesNapi),
78         UnifiedDataPropertiesNapi::Constructor(env));
79     if (propertiesNapi == nullptr) {
80         LOG_ERROR(UDMF_KITS_NAPI, "new UnifiedDataPropertiesNapi failed!");
81         if (uData->propertyRef_ != nullptr) {
82             napi_delete_reference(env, uData->propertyRef_);
83         }
84         delete(uData);
85         return nullptr;
86     }
87     uData->value_ = std::make_shared<UnifiedData>(propertiesNapi->value_);
88     if (uRecord) {
89         uData->value_->AddRecord(uRecord->value_);
90     }
91     ASSERT_CALL(env, napi_wrap(env, ctxt->self, uData, Destructor, nullptr, nullptr), uData);
92     return ctxt->self;
93 }
94 
Destructor(napi_env env,void * data,void * hint)95 void UnifiedDataNapi::Destructor(napi_env env, void *data, void *hint)
96 {
97     LOG_DEBUG(UDMF_KITS_NAPI, "UnifiedDataNapi finalize.");
98     auto *uData = static_cast<UnifiedDataNapi *>(data);
99     ASSERT_VOID(uData != nullptr, "finalize null!");
100     if (uData->propertyRef_ != nullptr) {
101         napi_delete_reference(env, uData->propertyRef_);
102     }
103     delete uData;
104 }
105 
NewInstance(napi_env env,std::shared_ptr<UnifiedData> in,napi_value & out)106 napi_status UnifiedDataNapi::NewInstance(napi_env env, std::shared_ptr<UnifiedData> in, napi_value &out)
107 {
108     LOG_DEBUG(UDMF_KITS_NAPI, "UnifiedDataNapi");
109     ASSERT_CALL_STATUS(env, napi_new_instance(env, Constructor(env), 0, nullptr, &out));
110 
111     UnifiedDataNapi* unifiedData = nullptr;
112     napi_status status = napi_unwrap(env, out, reinterpret_cast<void **>(&unifiedData));
113     if (status != napi_ok || unifiedData == nullptr) {
114         LOG_ERROR(UDMF_KITS_NAPI, "napi_unwrap unifiedData failed, status=%{public}d", status);
115         return status;
116     }
117     unifiedData->value_ = in;
118 
119     napi_value value;
120     status = napi_get_reference_value(env, unifiedData->propertyRef_, &value);
121     if (status != napi_ok) {
122         LOG_ERROR(UDMF_KITS_NAPI, "napi_get_reference_value propertyRef failed, status=%{public}d", status);
123         return status;
124     }
125     UnifiedDataPropertiesNapi* propertiesNapi = nullptr;
126     status = napi_unwrap(env, value, reinterpret_cast<void **>(&propertiesNapi));
127     if (status != napi_ok || propertiesNapi == nullptr) {
128         LOG_ERROR(UDMF_KITS_NAPI, "napi_unwrap propertiesNapi failed, status=%{public}d", status);
129         return status;
130     }
131     propertiesNapi->value_ = in->GetProperties();
132     return napi_ok;
133 }
134 
GetUnifiedData(napi_env env,napi_callback_info info)135 UnifiedDataNapi *UnifiedDataNapi::GetUnifiedData(napi_env env, napi_callback_info info)
136 {
137     LOG_DEBUG(UDMF_KITS_NAPI, "UnifiedDataNapi");
138     auto ctxt = std::make_shared<ContextBase>();
139     ctxt->GetCbInfoSync(env, info);
140     ASSERT_ERR(ctxt->env, ctxt->status == napi_ok, Status::E_ERROR, ctxt->error);
141     return static_cast<UnifiedDataNapi *>(ctxt->native);
142 }
143 
AddRecord(napi_env env,napi_callback_info info)144 napi_value UnifiedDataNapi::AddRecord(napi_env env, napi_callback_info info)
145 {
146     LOG_DEBUG(UDMF_KITS_NAPI, "UnifiedDataNapi");
147     UnifiedRecordNapi *uRecord = nullptr;
148     auto ctxt = std::make_shared<ContextBase>();
149     auto input = [env, info, ctxt, &uRecord](size_t argc, napi_value *argv) {
150         ASSERT_BUSINESS_ERR(ctxt, argc >= 1,
151             Status::E_INVALID_PARAMETERS, "Parameter error: Mandatory parameters are left unspecified");
152         ctxt->status = napi_unwrap(env, *argv, reinterpret_cast<void **>(&uRecord));
153         ASSERT_BUSINESS_ERR(ctxt, (ctxt->status == napi_ok && uRecord != nullptr && uRecord->value_ != nullptr),
154             Status::E_INVALID_PARAMETERS, "Parameter error: parameter record type must be UnifiedRecord");
155         ctxt->status = UnifiedDataUtils::IsValidType(uRecord->value_->GetType()) ? napi_ok : napi_invalid_arg;
156         ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::E_ERROR, "invalid type!");
157     };
158     ctxt->GetCbInfoSync(env, info, input);
159     ASSERT_ERR(ctxt->env, ctxt->status == napi_ok, Status::E_ERROR, ctxt->error);
160     auto *uData = static_cast<UnifiedDataNapi *>(ctxt->native);
161     ASSERT_ERR(
162         ctxt->env, (uData != nullptr && uData->value_ != nullptr), Status::E_ERROR, "invalid object!");
163     uData->value_->AddRecord(uRecord->value_);
164     return nullptr;
165 }
166 
GetRecords(napi_env env,napi_callback_info info)167 napi_value UnifiedDataNapi::GetRecords(napi_env env, napi_callback_info info)
168 {
169     LOG_DEBUG(UDMF_KITS_NAPI, "UnifiedDataNapi");
170     auto ctxt = std::make_shared<ContextBase>();
171     auto uData = GetUnifiedData(env, info);
172     ASSERT_ERR(
173         ctxt->env, (uData != nullptr && uData->value_ != nullptr), Status::E_ERROR, "invalid object!");
174     std::vector<std::shared_ptr<UnifiedRecord>> records = uData->value_->GetRecords();
175     napi_status status = napi_create_array_with_length(env, records.size(), &ctxt->output);
176     ASSERT_ERR(ctxt->env, status == napi_ok, Status::E_ERROR, "init array failed!");
177     int index = 0;
178     for (const std::shared_ptr<UnifiedRecord> &recordPtr : records) {
179         napi_value recordNapi = nullptr;
180         GetRecord(env, recordPtr, recordNapi);
181         ctxt->status = napi_set_element(env, ctxt->output, index++, recordNapi);
182         ASSERT_ERR(ctxt->env, ctxt->status == napi_ok, Status::E_ERROR, "set element failed!");
183     }
184     return ctxt->output;
185 }
186 
GetRecord(napi_env env,std::shared_ptr<UnifiedRecord> in,napi_value & out)187 void UnifiedDataNapi::GetRecord(napi_env env, std::shared_ptr<UnifiedRecord> in, napi_value &out)
188 {
189     switch (in->GetType()) {
190         case TEXT: {
191             TextNapi::NewInstance(env, in, out);
192             break;
193         }
194         case PLAIN_TEXT: {
195             PlainTextNapi::NewInstance(env, in, out);
196             break;
197         }
198         case HTML: {
199             HtmlNapi::NewInstance(env, in, out);
200             break;
201         }
202         case HYPERLINK: {
203             LinkNapi::NewInstance(env, in, out);
204             break;
205         }
206         case FILE: {
207             FileNapi::NewInstance(env, in, out);
208             break;
209         }
210         case IMAGE: {
211             ImageNapi::NewInstance(env, in, out);
212             break;
213         }
214         case VIDEO: {
215             VideoNapi::NewInstance(env, in, out);
216             break;
217         }
218         case AUDIO: {
219             AudioNapi::NewInstance(env, in, out);
220             break;
221         }
222         case FOLDER: {
223             FolderNapi::NewInstance(env, in, out);
224             break;
225         }
226         case SYSTEM_DEFINED_RECORD: {
227             SystemDefinedRecordNapi::NewInstance(env, in, out);
228             break;
229         }
230         case SYSTEM_DEFINED_APP_ITEM: {
231             SystemDefinedAppItemNapi::NewInstance(env, in, out);
232             break;
233         }
234         case SYSTEM_DEFINED_FORM: {
235             SystemDefinedFormNapi::NewInstance(env, in, out);
236             break;
237         }
238         case SYSTEM_DEFINED_PIXEL_MAP: {
239             auto value = in->GetValue();
240             if (std::get_if<std::shared_ptr<OHOS::Media::PixelMap>>(&value)) {
241                 UnifiedRecordNapi::NewInstance(env, in, out);
242             } else {
243                 SystemDefinedPixelMapNapi::NewInstance(env, in, out);
244             }
245             break;
246         }
247         case APPLICATION_DEFINED_RECORD: {
248             ApplicationDefinedRecordNapi::NewInstance(env, in, out);
249             break;
250         }
251         default:
252             UnifiedRecordNapi::NewInstance(env, in, out);
253             LOG_INFO(UDMF_KITS_NAPI, "GetRecord default");
254             break;
255     }
256 }
257 
HasType(napi_env env,napi_callback_info info)258 napi_value UnifiedDataNapi::HasType(napi_env env, napi_callback_info info)
259 {
260     LOG_DEBUG(UDMF_KITS_NAPI, "UnifiedDataNapi");
261     std::string type;
262     auto ctxt = std::make_shared<ContextBase>();
263     auto input = [env, info, ctxt, &type](size_t argc, napi_value *argv) {
264         ASSERT_BUSINESS_ERR(ctxt, argc >= 1,
265             Status::E_INVALID_PARAMETERS, "Parameter error: Mandatory parameters are left unspecified");
266         ctxt->status = NapiDataUtils::GetValue(env, argv[0], type);
267         ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok,
268             Status::E_INVALID_PARAMETERS, "Parameter error: parameter type type must be string");
269     };
270     ctxt->GetCbInfoSync(env, info, input);
271     ASSERT_ERR(ctxt->env, ctxt->status == napi_ok, Status::E_ERROR, ctxt->error);
272     auto *uData = static_cast<UnifiedDataNapi *>(ctxt->native);
273     ASSERT_ERR(
274         ctxt->env, (uData != nullptr && uData->value_ != nullptr), Status::E_ERROR, "invalid object!");
275     bool ret = uData->value_->HasHigherFileType(type);
276     napi_value result = nullptr;
277     napi_get_boolean(env, ret, &result);
278     return result;
279 }
280 
GetTypes(napi_env env,napi_callback_info info)281 napi_value UnifiedDataNapi::GetTypes(napi_env env, napi_callback_info info)
282 {
283     LOG_DEBUG(UDMF_KITS_NAPI, "UnifiedDataNapi");
284     auto uData = GetUnifiedData(env, info);
285     ASSERT_ERR(env, (uData != nullptr && uData->value_ != nullptr), Status::E_ERROR, "invalid object!");
286 
287     std::vector<std::string> Types = uData->value_->GetTypesLabels();
288     napi_value nTypes = nullptr;
289     napi_status status = napi_create_array(env, &nTypes);
290     ASSERT_ERR(env, status == napi_ok, Status::E_ERROR, "create array fail!");
291 
292     size_t index = 0;
293     napi_value value = nullptr;
294     for (auto type : Types) {
295         napi_create_string_utf8(env, type.c_str(), NAPI_AUTO_LENGTH, &value);
296         napi_set_element(env, nTypes, index, value);
297         index++;
298     }
299     return nTypes;
300 }
301 
GetProperties(napi_env env,napi_callback_info info)302 napi_value UnifiedDataNapi::GetProperties(napi_env env, napi_callback_info info)
303 {
304     LOG_DEBUG(UDMF_KITS_NAPI, "UnifiedDataNapi");
305     napi_value value;
306     auto uData = GetUnifiedData(env, info);
307     ASSERT_ERR(env, (uData != nullptr && uData->value_ != nullptr), Status::E_ERROR, "invalid object!");
308     ASSERT_ERR(env, (uData != nullptr && uData->propertyRef_ != nullptr), Status::E_ERROR, "invalid properties!");
309     NAPI_CALL(env, napi_get_reference_value(env, uData->propertyRef_, &value));
310     return value;
311 }
312 
GetPropertiesNapi(napi_env env)313 UnifiedDataPropertiesNapi* UnifiedDataNapi::GetPropertiesNapi(napi_env env)
314 {
315     napi_value value;
316     NAPI_CALL(env, napi_get_reference_value(env, propertyRef_, &value));
317     UnifiedDataPropertiesNapi* out = nullptr;
318     napi_status status = napi_unwrap(env, value, reinterpret_cast<void**>(&out));
319     ASSERT_ERR(env, status == napi_ok && out != nullptr, Status::E_ERROR, "napi_unwrap failed");
320     return out;
321 }
322 
SetProperties(napi_env env,napi_callback_info info)323 napi_value UnifiedDataNapi::SetProperties(napi_env env, napi_callback_info info)
324 {
325     LOG_DEBUG(UDMF_KITS_NAPI, "UnifiedDataNapi");
326     auto ctxt = std::make_shared<ContextBase>();
327     auto input = [env, ctxt](size_t argc, napi_value* argv) {
328         ASSERT_BUSINESS_ERR(ctxt, argc >= 1,
329             Status::E_INVALID_PARAMETERS, "Parameter error: Mandatory parameters are left unspecified");
330         UnifiedDataPropertiesNapi* propertiesNapi = nullptr;
331         ctxt->status = Unwrap(env, argv[0], reinterpret_cast<void**>(&propertiesNapi),
332             UnifiedDataPropertiesNapi::Constructor(env));
333         ASSERT_BUSINESS_ERR(ctxt, propertiesNapi != nullptr,
334             Status::E_INVALID_PARAMETERS, "Parameter error: parameter properties type must be UnifiedDataProperties");
335 
336         auto uData = static_cast<UnifiedDataNapi*>(ctxt->native);
337         if (uData->propertyRef_ != nullptr) {
338             napi_delete_reference(env, uData->propertyRef_);
339         }
340         ctxt->status = napi_create_reference(env, argv[0], 1, &uData->propertyRef_);
341         ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok,
342             Status::E_ERROR, "napi_create_reference to properties failed!");
343         uData->value_->SetProperties(propertiesNapi->value_);
344     };
345     ctxt->GetCbInfoSync(env, info, input);
346     ASSERT_ERR(ctxt->env, ctxt->status == napi_ok, Status::E_ERROR, ctxt->error);
347     return ctxt->self;
348 }
349 
NewWithRef(napi_env env,size_t argc,napi_value * argv,void ** out,napi_value constructor)350 napi_ref UnifiedDataNapi::NewWithRef(napi_env env, size_t argc, napi_value *argv, void **out, napi_value constructor)
351 {
352     napi_value object = nullptr;
353     napi_status status = napi_new_instance(env, constructor, argc, argv, &object);
354     ASSERT_ERR(env, status == napi_ok && object != nullptr, Status::E_ERROR, "napi_new_instance failed");
355 
356     status = napi_unwrap(env, object, out);
357     ASSERT_ERR(env, status == napi_ok && out != nullptr, Status::E_ERROR, "napi_unwrap failed");
358 
359     napi_ref ref = nullptr;
360     status = napi_create_reference(env, object, 1, &ref);
361     ASSERT_ERR(env, status == napi_ok && ref != nullptr, Status::E_ERROR, "napi_create_reference failed");
362     return ref;
363 }
364 
Unwrap(napi_env env,napi_value in,void ** out,napi_value constructor)365 napi_status UnifiedDataNapi::Unwrap(napi_env env, napi_value in, void **out, napi_value constructor)
366 {
367     if (constructor != nullptr) {
368         bool isInstance = false;
369         napi_instanceof(env, in, constructor, &isInstance);
370         if (!isInstance) {
371             LOG_ERROR(UDMF_KITS_NAPI, "not a instance of *");
372             return napi_invalid_arg;
373         }
374     }
375     return napi_unwrap(env, in, out);
376 }
377 } // namespace UDMF
378 } // namespace OHOS