• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define MLOG_TAG "SmartAlbumNapi"
16 
17 #include "smart_album_napi.h"
18 #include "medialibrary_client_errno.h"
19 #include "medialibrary_napi_log.h"
20 #include "medialibrary_tracer.h"
21 #include "media_file_utils.h"
22 #include "userfile_client.h"
23 
24 using OHOS::HiviewDFX::HiLog;
25 using OHOS::HiviewDFX::HiLogLabel;
26 
27 namespace OHOS {
28 namespace Media {
29 using namespace std;
30 thread_local napi_ref SmartAlbumNapi::sConstructor_ = nullptr;
31 thread_local SmartAlbumAsset *SmartAlbumNapi::sAlbumData_ = nullptr;
32 using CompleteCallback = napi_async_complete_callback;
33 thread_local napi_ref SmartAlbumNapi::userFileMgrConstructor_ = nullptr;
34 constexpr int32_t INVALID_EXPIREDTIME = -1;
SmartAlbumNapi()35 SmartAlbumNapi::SmartAlbumNapi()
36     : env_(nullptr) {}
37 
38 SmartAlbumNapi::~SmartAlbumNapi() = default;
39 
SmartAlbumNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)40 void SmartAlbumNapi::SmartAlbumNapiDestructor(napi_env env, void *nativeObject, void *finalize_hint)
41 {
42     SmartAlbumNapi *album = reinterpret_cast<SmartAlbumNapi*>(nativeObject);
43     if (album != nullptr) {
44         delete album;
45         album = nullptr;
46     }
47 }
48 
Init(napi_env env,napi_value exports)49 napi_value SmartAlbumNapi::Init(napi_env env, napi_value exports)
50 {
51     napi_status status;
52     napi_value ctorObj;
53     int32_t refCount = 1;
54 
55     napi_property_descriptor album_props[] = {
56         DECLARE_NAPI_GETTER("albumId", JSGetSmartAlbumId),
57         DECLARE_NAPI_GETTER("albumUri", JSGetSmartAlbumUri),
58         DECLARE_NAPI_GETTER("albumType", JSGetSmartAlbumType),
59         DECLARE_NAPI_GETTER_SETTER("albumName", JSGetSmartAlbumName, JSSmartAlbumNameSetter),
60         DECLARE_NAPI_GETTER_SETTER("description", JSGetSmartAlbumDescription, JSSmartAlbumDescriptionSetter),
61         DECLARE_NAPI_GETTER("albumTag", JSGetSmartAlbumTag),
62         DECLARE_NAPI_GETTER("size", JSGetSmartAlbumCapacity),
63         DECLARE_NAPI_GETTER("categoryId", JSGetSmartAlbumCategoryId),
64         DECLARE_NAPI_GETTER("categoryName", JSGetSmartAlbumCategoryName),
65         DECLARE_NAPI_GETTER_SETTER("coverURI", JSGetSmartAlbumCoverUri, JSSmartAlbumCoverUriSetter),
66         DECLARE_NAPI_GETTER_SETTER("expiredTime", JSGetSmartAlbumExpiredTime, JSSmartAlbumExpiredTimeSetter),
67         DECLARE_NAPI_FUNCTION("commitModify", JSCommitModify),
68         DECLARE_NAPI_FUNCTION("addFileAssets", JSAddFileAssets),
69         DECLARE_NAPI_FUNCTION("removeFileAssets", JSRemoveFileAssets),
70         DECLARE_NAPI_FUNCTION("getFileAssets", JSGetSmartAlbumFileAssets)
71     };
72 
73     status = napi_define_class(env, SMART_ALBUM_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH,
74                                SmartAlbumNapiConstructor, nullptr,
75                                sizeof(album_props) / sizeof(album_props[PARAM0]),
76                                album_props, &ctorObj);
77     if (status == napi_ok) {
78         status = napi_create_reference(env, ctorObj, refCount, &sConstructor_);
79         if (status == napi_ok) {
80             status = napi_set_named_property(env, exports, SMART_ALBUM_NAPI_CLASS_NAME.c_str(), ctorObj);
81             if (status == napi_ok) {
82                 return exports;
83             }
84         }
85     }
86     NAPI_DEBUG_LOG("SmartAlbumNapi::Init nullptr, status: %{public}d", status);
87     return nullptr;
88 }
89 
UserFileMgrInit(napi_env env,napi_value exports)90 napi_value SmartAlbumNapi::UserFileMgrInit(napi_env env, napi_value exports)
91 {
92     NapiClassInfo info = {
93         .name = USERFILEMGR_SMART_ALBUM_NAPI_CLASS_NAME,
94         .ref = &userFileMgrConstructor_,
95         .constructor = SmartAlbumNapiConstructor,
96         .props = {
97             DECLARE_NAPI_GETTER_SETTER("albumName", JSGetSmartAlbumName, JSSmartAlbumNameSetter),
98             DECLARE_NAPI_GETTER("albumUri", JSGetSmartAlbumUri),
99             DECLARE_NAPI_GETTER("dateModified", JSGetSmartAlbumDateModified),
100             DECLARE_NAPI_GETTER("count", JSGetSmartAlbumCapacity),
101             DECLARE_NAPI_GETTER("coverUri", JSGetSmartAlbumCoverUri),
102             DECLARE_NAPI_FUNCTION("getPhotoAssets", UserFileMgrGetAssets),
103             DECLARE_NAPI_FUNCTION("delete", UserFileMgrDeleteAsset),
104             DECLARE_NAPI_FUNCTION("recover", UserFileMgrRecoverAsset),
105         }
106     };
107 
108     MediaLibraryNapiUtils::NapiDefineClass(env, exports, info);
109     return exports;
110 }
111 
SetSmartAlbumNapiProperties()112 void SmartAlbumNapi::SetSmartAlbumNapiProperties()
113 {
114     smartAlbumAssetPtr = std::shared_ptr<SmartAlbumAsset>(sAlbumData_);
115     NAPI_INFO_LOG("SetSmartAlbumNapiProperties name = %{public}s",
116         smartAlbumAssetPtr->GetAlbumName().c_str());
117 }
118 
119 // Constructor callback
SmartAlbumNapiConstructor(napi_env env,napi_callback_info info)120 napi_value SmartAlbumNapi::SmartAlbumNapiConstructor(napi_env env, napi_callback_info info)
121 {
122     napi_status status;
123     napi_value result = nullptr;
124     napi_value thisVar = nullptr;
125     napi_get_undefined(env, &result);
126     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
127     if (status == napi_ok && thisVar != nullptr) {
128         std::unique_ptr<SmartAlbumNapi> obj = std::make_unique<SmartAlbumNapi>();
129         if (obj != nullptr) {
130             obj->env_ = env;
131             if (sAlbumData_ != nullptr) {
132                 obj->SetSmartAlbumNapiProperties();
133             }
134             status = napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()),
135                                SmartAlbumNapi::SmartAlbumNapiDestructor, nullptr, nullptr);
136             if (status == napi_ok) {
137                 obj.release();
138                 return thisVar;
139             } else {
140                 NAPI_ERR_LOG("Failure wrapping js to native napi, status: %{public}d", status);
141             }
142         }
143     }
144 
145     return result;
146 }
147 
CreateSmartAlbumNapi(napi_env env,unique_ptr<SmartAlbumAsset> & albumData)148 napi_value SmartAlbumNapi::CreateSmartAlbumNapi(napi_env env, unique_ptr<SmartAlbumAsset> &albumData)
149 {
150     if (albumData == nullptr) {
151         return nullptr;
152     }
153 
154     napi_value constructor;
155     napi_ref constructorRef = (albumData->GetResultNapiType() == ResultNapiType::TYPE_MEDIALIBRARY) ?
156         (sConstructor_) : (userFileMgrConstructor_);
157     NAPI_CALL(env, napi_get_reference_value(env, constructorRef, &constructor));
158 
159     napi_value result = nullptr;
160     sAlbumData_ = albumData.release();
161     NAPI_CALL(env, napi_new_instance(env, constructor, 0, nullptr, &result));
162     sAlbumData_ = nullptr;
163     return result;
164 }
165 
GetSmartAlbumName() const166 std::string SmartAlbumNapi::GetSmartAlbumName() const
167 {
168     return smartAlbumAssetPtr->GetAlbumName();
169 }
170 
GetAlbumPrivateType() const171 int32_t SmartAlbumNapi::GetAlbumPrivateType() const
172 {
173     return smartAlbumAssetPtr->GetAlbumPrivateType();
174 }
175 
GetSmartAlbumUri() const176 std::string SmartAlbumNapi::GetSmartAlbumUri() const
177 {
178     return smartAlbumAssetPtr->GetAlbumUri();
179 }
180 
GetSmartAlbumId() const181 int32_t SmartAlbumNapi::GetSmartAlbumId() const
182 {
183     return smartAlbumAssetPtr->GetAlbumId();
184 }
GetDescription() const185 std::string SmartAlbumNapi::GetDescription() const
186 {
187     return smartAlbumAssetPtr->GetDescription();
188 }
189 
GetCoverUri() const190 std::string SmartAlbumNapi::GetCoverUri() const
191 {
192     return smartAlbumAssetPtr->GetCoverUri();
193 }
194 
GetExpiredTime() const195 int32_t SmartAlbumNapi::GetExpiredTime() const
196 {
197     return smartAlbumAssetPtr->GetExpiredTime();
198 }
199 
SetAlbumCapacity(int32_t albumCapacity)200 void SmartAlbumNapi::SetAlbumCapacity(int32_t albumCapacity)
201 {
202     smartAlbumAssetPtr->SetAlbumCapacity(albumCapacity);
203 }
204 
GetNetworkId() const205 std::string SmartAlbumNapi::GetNetworkId() const
206 {
207     return MediaFileUtils::GetNetworkIdFromUri(GetSmartAlbumUri());
208 }
209 
SetCoverUri(string & coverUri)210 void SmartAlbumNapi::SetCoverUri(string &coverUri)
211 {
212     smartAlbumAssetPtr->SetCoverUri(coverUri);
213 }
214 
SetDescription(string & description)215 void SmartAlbumNapi::SetDescription(string &description)
216 {
217     smartAlbumAssetPtr->SetDescription(description);
218 }
219 
SetExpiredTime(int32_t expiredTime)220 void SmartAlbumNapi::SetExpiredTime(int32_t expiredTime)
221 {
222     smartAlbumAssetPtr->SetExpiredTime(expiredTime);
223 }
224 
JSGetSmartAlbumId(napi_env env,napi_callback_info info)225 napi_value SmartAlbumNapi::JSGetSmartAlbumId(napi_env env, napi_callback_info info)
226 {
227     napi_status status;
228     napi_value jsResult = nullptr;
229     napi_value undefinedResult = nullptr;
230     SmartAlbumNapi* obj = nullptr;
231     int32_t id;
232     napi_value thisVar = nullptr;
233 
234     napi_get_undefined(env, &undefinedResult);
235     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
236     if ((status != napi_ok) || (thisVar == nullptr)) {
237         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
238         return undefinedResult;
239     }
240 
241     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
242     if ((status == napi_ok) && (obj != nullptr)) {
243         id = obj->GetSmartAlbumId();
244         status = napi_create_int32(env, id, &jsResult);
245         if (status == napi_ok) {
246             return jsResult;
247         }
248     }
249 
250     return undefinedResult;
251 }
252 
JSGetSmartAlbumName(napi_env env,napi_callback_info info)253 napi_value SmartAlbumNapi::JSGetSmartAlbumName(napi_env env, napi_callback_info info)
254 {
255     napi_status status;
256     napi_value jsResult = nullptr;
257     napi_value undefinedResult = nullptr;
258     SmartAlbumNapi* obj = nullptr;
259     std::string name = "";
260     napi_value thisVar = nullptr;
261     napi_get_undefined(env, &undefinedResult);
262     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
263     if ((status != napi_ok) || (thisVar == nullptr)) {
264         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
265         return undefinedResult;
266     }
267     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
268     if ((status == napi_ok) && (obj != nullptr)) {
269         name = obj->GetSmartAlbumName();
270         NAPI_DEBUG_LOG("JSGetSmartAlbumName name = %{public}s", name.c_str());
271         status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &jsResult);
272         if (status == napi_ok) {
273             return jsResult;
274         }
275     }
276 
277     return undefinedResult;
278 }
279 
JSSmartAlbumNameSetter(napi_env env,napi_callback_info info)280 napi_value SmartAlbumNapi::JSSmartAlbumNameSetter(napi_env env, napi_callback_info info)
281 {
282     napi_status status;
283     napi_value jsResult = nullptr;
284     size_t argc = ARGS_ONE;
285     napi_value argv[ARGS_ONE] = {0};
286     size_t res = 0;
287     char buffer[FILENAME_MAX];
288     SmartAlbumNapi* obj = nullptr;
289     napi_value thisVar = nullptr;
290     napi_valuetype valueType = napi_undefined;
291 
292     napi_get_undefined(env, &jsResult);
293     GET_JS_ARGS(env, info, argc, argv, thisVar);
294     NAPI_ASSERT(env, argc == ARGS_ONE, "requires 1 parameter");
295 
296     if (thisVar == nullptr || napi_typeof(env, argv[PARAM0], &valueType) != napi_ok || valueType != napi_string) {
297         NAPI_ERR_LOG("Invalid arguments type! valueType: %{public}d", valueType);
298         return jsResult;
299     }
300 
301     napi_get_value_string_utf8(env, argv[PARAM0], buffer, FILENAME_MAX, &res);
302 
303     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
304     if (status == napi_ok && obj != nullptr) {
305         obj->smartAlbumAssetPtr->SetAlbumName(std::string(buffer));
306     }
307 
308     return jsResult;
309 }
310 
JSGetSmartAlbumTag(napi_env env,napi_callback_info info)311 napi_value SmartAlbumNapi::JSGetSmartAlbumTag(napi_env env, napi_callback_info info)
312 {
313     napi_status status;
314     napi_value jsResult = nullptr;
315     napi_value undefinedResult = nullptr;
316     SmartAlbumNapi* obj = nullptr;
317     std::string albumTag = "";
318     napi_value thisVar = nullptr;
319 
320     napi_get_undefined(env, &undefinedResult);
321     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
322     if ((status != napi_ok) || (thisVar == nullptr)) {
323         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
324         return undefinedResult;
325     }
326 
327     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
328     if (status == napi_ok && obj != nullptr) {
329         albumTag = obj->smartAlbumAssetPtr->GetAlbumTag();
330         status = napi_create_string_utf8(env, albumTag.c_str(), NAPI_AUTO_LENGTH, &jsResult);
331         if (status == napi_ok) {
332             return jsResult;
333         }
334     }
335 
336     return undefinedResult;
337 }
338 
JSGetSmartAlbumCapacity(napi_env env,napi_callback_info info)339 napi_value SmartAlbumNapi::JSGetSmartAlbumCapacity(napi_env env, napi_callback_info info)
340 {
341     napi_status status;
342     napi_value jsResult = nullptr;
343     napi_value undefinedResult = nullptr;
344     SmartAlbumNapi* obj = nullptr;
345     int32_t albumCapacity;
346     napi_value thisVar = nullptr;
347 
348     napi_get_undefined(env, &undefinedResult);
349     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
350     if ((status != napi_ok) || (thisVar == nullptr)) {
351         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
352         return undefinedResult;
353     }
354 
355     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
356     if (status == napi_ok && obj != nullptr) {
357         albumCapacity = obj->smartAlbumAssetPtr->GetAlbumCapacity();
358         status = napi_create_int32(env, albumCapacity, &jsResult);
359         if (status == napi_ok) {
360             return jsResult;
361         }
362     }
363 
364     return undefinedResult;
365 }
366 
JSGetSmartAlbumCategoryId(napi_env env,napi_callback_info info)367 napi_value SmartAlbumNapi::JSGetSmartAlbumCategoryId(napi_env env, napi_callback_info info)
368 {
369     napi_status status;
370     napi_value jsResult = nullptr;
371     napi_value undefinedResult = nullptr;
372     SmartAlbumNapi* obj = nullptr;
373     int32_t categoryId;
374     napi_value thisVar = nullptr;
375 
376     napi_get_undefined(env, &undefinedResult);
377     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
378     if ((status != napi_ok) || (thisVar == nullptr)) {
379         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
380         return undefinedResult;
381     }
382 
383     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
384     if (status == napi_ok && obj != nullptr) {
385         categoryId = obj->smartAlbumAssetPtr->GetCategoryId();
386         status = napi_create_int32(env, categoryId, &jsResult);
387         if (status == napi_ok) {
388             return jsResult;
389         }
390     }
391 
392     return undefinedResult;
393 }
394 
JSGetSmartAlbumCategoryName(napi_env env,napi_callback_info info)395 napi_value SmartAlbumNapi::JSGetSmartAlbumCategoryName(napi_env env, napi_callback_info info)
396 {
397     napi_status status;
398     napi_value jsResult = nullptr;
399     napi_value undefinedResult = nullptr;
400     SmartAlbumNapi* obj = nullptr;
401     std::string categoryName = "";
402     napi_value thisVar = nullptr;
403 
404     napi_get_undefined(env, &undefinedResult);
405     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
406     if ((status != napi_ok) || (thisVar == nullptr)) {
407         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
408         return undefinedResult;
409     }
410 
411     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
412     if (status == napi_ok && obj != nullptr) {
413         categoryName = obj->smartAlbumAssetPtr->GetCategoryName();
414         status = napi_create_string_utf8(env, categoryName.c_str(), NAPI_AUTO_LENGTH, &jsResult);
415         if (status == napi_ok) {
416             return jsResult;
417         }
418     }
419 
420     return undefinedResult;
421 }
422 
JSGetSmartAlbumCoverUri(napi_env env,napi_callback_info info)423 napi_value SmartAlbumNapi::JSGetSmartAlbumCoverUri(napi_env env, napi_callback_info info)
424 {
425     napi_status status;
426     napi_value jsResult = nullptr;
427     napi_value undefinedResult = nullptr;
428     SmartAlbumNapi* obj = nullptr;
429     std::string coverUri = "";
430     napi_value thisVar = nullptr;
431 
432     napi_get_undefined(env, &undefinedResult);
433     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
434     if ((status != napi_ok) || (thisVar == nullptr)) {
435         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
436         return undefinedResult;
437     }
438 
439     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
440     if (status == napi_ok && obj != nullptr) {
441         coverUri = obj->smartAlbumAssetPtr->GetCoverUri();
442         status = napi_create_string_utf8(env, coverUri.c_str(), NAPI_AUTO_LENGTH, &jsResult);
443         if (status == napi_ok) {
444             return jsResult;
445         }
446     }
447 
448     return undefinedResult;
449 }
450 
JSSmartAlbumCoverUriSetter(napi_env env,napi_callback_info info)451 napi_value SmartAlbumNapi::JSSmartAlbumCoverUriSetter(napi_env env, napi_callback_info info)
452 {
453     napi_value jsResult = nullptr;
454     napi_get_undefined(env, &jsResult);
455     napi_value argv[ARGS_ONE] = {0};
456     size_t argc = ARGS_ONE;
457     napi_value thisVar = nullptr;
458     GET_JS_ARGS(env, info, argc, argv, thisVar);
459     NAPI_ASSERT(env, argc == ARGS_ONE, "requires 1 parameter");
460     napi_valuetype valueType = napi_undefined;
461     if (thisVar == nullptr || napi_typeof(env, argv[PARAM0], &valueType) != napi_ok || valueType != napi_string) {
462         NAPI_ERR_LOG("Invalid arguments type! valueType: %{private}d", valueType);
463         return jsResult;
464     }
465     SmartAlbumNapi* obj = nullptr;
466     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
467     if ((status != napi_ok) || (obj == nullptr)) {
468         NAPI_ERR_LOG("Unwrap object failed");
469         return jsResult;
470     }
471     size_t res = 0;
472     char buffer[FILENAME_MAX];
473     status = napi_get_value_string_utf8(env, argv[PARAM0], buffer, FILENAME_MAX, &res);
474     if (status != napi_ok) {
475         NAPI_ERR_LOG("Get coverUri value string failed");
476         return jsResult;
477     }
478     obj->smartAlbumAssetPtr->SetCoverUri(std::string(buffer));
479     return jsResult;
480 }
481 
JSGetSmartAlbumUri(napi_env env,napi_callback_info info)482 napi_value SmartAlbumNapi::JSGetSmartAlbumUri(napi_env env, napi_callback_info info)
483 {
484     napi_value undefinedResult = nullptr;
485     napi_get_undefined(env, &undefinedResult);
486     napi_status status;
487     napi_value thisVar = nullptr;
488     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
489     if ((status != napi_ok) || (thisVar == nullptr)) {
490         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
491         return undefinedResult;
492     }
493     SmartAlbumNapi* obj = nullptr;
494     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
495     if ((status != napi_ok) || (obj == nullptr)) {
496         NAPI_ERR_LOG("Unwrap object failed");
497         return undefinedResult;
498     }
499     napi_value jsResult = nullptr;
500     status = napi_create_string_utf8(env, obj->smartAlbumAssetPtr->GetAlbumUri().c_str(), NAPI_AUTO_LENGTH, &jsResult);
501     if (status != napi_ok) {
502         NAPI_ERR_LOG("Create albumUri string failed");
503         return undefinedResult;
504     }
505     return jsResult;
506 }
507 
JSGetSmartAlbumDateModified(napi_env env,napi_callback_info info)508 napi_value SmartAlbumNapi::JSGetSmartAlbumDateModified(napi_env env, napi_callback_info info)
509 {
510     napi_status status;
511     napi_value undefinedResult = nullptr;
512     napi_value thisVar = nullptr;
513 
514     napi_get_undefined(env, &undefinedResult);
515     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
516     if ((status != napi_ok) || (thisVar == nullptr)) {
517         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
518         return undefinedResult;
519     }
520     SmartAlbumNapi* obj = nullptr;
521     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
522     if ((status == napi_ok) && (obj != nullptr)) {
523         int64_t dateModified = obj->smartAlbumAssetPtr->GetAlbumDateModified();
524         napi_value jsResult = nullptr;
525         status = napi_create_int64(env, dateModified, &jsResult);
526         if (status == napi_ok) {
527             return jsResult;
528         }
529     }
530     return undefinedResult;
531 }
532 
JSGetSmartAlbumType(napi_env env,napi_callback_info info)533 napi_value SmartAlbumNapi::JSGetSmartAlbumType(napi_env env, napi_callback_info info)
534 {
535     napi_value undefinedResult = nullptr;
536     napi_get_undefined(env, &undefinedResult);
537     napi_status status;
538     napi_value thisVar = nullptr;
539     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
540     if ((status != napi_ok) || (thisVar == nullptr)) {
541         NAPI_ERR_LOG("Invalid arguments! status: %{private}d", status);
542         return undefinedResult;
543     }
544     SmartAlbumNapi* obj = nullptr;
545     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
546     if ((status != napi_ok) || (obj == nullptr)) {
547         NAPI_ERR_LOG("Unwrap object failed");
548         return undefinedResult;
549     }
550     napi_value jsResult = nullptr;
551     status = napi_create_int32(env, obj->smartAlbumAssetPtr->GetAlbumPrivateType(), &jsResult);
552     if (status != napi_ok) {
553         NAPI_ERR_LOG("Create albumPrivateType int32 failed");
554         return undefinedResult;
555     }
556     return jsResult;
557 }
558 
JSGetSmartAlbumDescription(napi_env env,napi_callback_info info)559 napi_value SmartAlbumNapi::JSGetSmartAlbumDescription(napi_env env, napi_callback_info info)
560 {
561     napi_value undefinedResult = nullptr;
562     napi_get_undefined(env, &undefinedResult);
563     napi_status status;
564     napi_value thisVar = nullptr;
565     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
566     if ((status != napi_ok) || (thisVar == nullptr)) {
567         NAPI_ERR_LOG("Invalid arguments! status: %{private}d", status);
568         return undefinedResult;
569     }
570     SmartAlbumNapi* obj = nullptr;
571     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
572     if ((status != napi_ok) || (obj == nullptr)) {
573         NAPI_ERR_LOG("Unwrap object failed");
574         return undefinedResult;
575     }
576     napi_value jsResult = nullptr;
577     status = napi_create_string_utf8(env, obj->smartAlbumAssetPtr->GetDescription().c_str(), NAPI_AUTO_LENGTH,
578         &jsResult);
579     if (status != napi_ok) {
580         NAPI_ERR_LOG("Create description string failed");
581         return undefinedResult;
582     }
583     return jsResult;
584 }
585 
JSSmartAlbumDescriptionSetter(napi_env env,napi_callback_info info)586 napi_value SmartAlbumNapi::JSSmartAlbumDescriptionSetter(napi_env env, napi_callback_info info)
587 {
588     napi_value jsResult = nullptr;
589     napi_get_undefined(env, &jsResult);
590     size_t argc = ARGS_ONE;
591     napi_value argv[ARGS_ONE] = {0};
592     napi_value thisVar = nullptr;
593     GET_JS_ARGS(env, info, argc, argv, thisVar);
594     NAPI_ASSERT(env, argc == ARGS_ONE, "requires 1 parameter");
595     napi_valuetype valueType = napi_undefined;
596     if (thisVar == nullptr || napi_typeof(env, argv[PARAM0], &valueType) != napi_ok || valueType != napi_string) {
597         NAPI_ERR_LOG("Invalid arguments type! valueType: %{private}d", valueType);
598         return jsResult;
599     }
600     SmartAlbumNapi* obj = nullptr;
601     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
602     if ((status != napi_ok) || (obj == nullptr)) {
603         NAPI_ERR_LOG("Unwrap object failed");
604         return jsResult;
605     }
606     size_t res = 0;
607     char buffer[FILENAME_MAX];
608     status = napi_get_value_string_utf8(env, argv[PARAM0], buffer, FILENAME_MAX, &res);
609     if (status != napi_ok) {
610         NAPI_ERR_LOG("Get description value string failed");
611         return jsResult;
612     }
613     obj->smartAlbumAssetPtr->SetDescription(std::string(buffer));
614     return jsResult;
615 }
616 
JSGetSmartAlbumExpiredTime(napi_env env,napi_callback_info info)617 napi_value SmartAlbumNapi::JSGetSmartAlbumExpiredTime(napi_env env, napi_callback_info info)
618 {
619     napi_value undefinedResult = nullptr;
620     napi_get_undefined(env, &undefinedResult);
621     napi_status status;
622     napi_value thisVar = nullptr;
623     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
624     if ((status != napi_ok) || (thisVar == nullptr)) {
625         NAPI_ERR_LOG("Invalid arguments! status: %{private}d", status);
626         return undefinedResult;
627     }
628     SmartAlbumNapi* obj = nullptr;
629     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
630     if ((status != napi_ok) || (obj == nullptr)) {
631         NAPI_ERR_LOG("Unwrap object failed");
632         return undefinedResult;
633     }
634     napi_value jsResult = nullptr;
635     status = napi_create_int32(env, obj->smartAlbumAssetPtr->GetExpiredTime(), &jsResult);
636     if (status != napi_ok) {
637         NAPI_ERR_LOG("Create expiredTime int32 failed");
638         return undefinedResult;
639     }
640     return jsResult;
641 }
642 
JSSmartAlbumExpiredTimeSetter(napi_env env,napi_callback_info info)643 napi_value SmartAlbumNapi::JSSmartAlbumExpiredTimeSetter(napi_env env, napi_callback_info info)
644 {
645     napi_value undefinedResult = nullptr;
646     napi_get_undefined(env, &undefinedResult);
647     size_t argc = ARGS_ONE;
648     napi_value argv[ARGS_ONE] = {0};
649     napi_value thisVar = nullptr;
650     GET_JS_ARGS(env, info, argc, argv, thisVar);
651     NAPI_ASSERT(env, argc == ARGS_ONE, "requires 1 parameter");
652     SmartAlbumNapi* obj = nullptr;
653     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
654     if ((status != napi_ok) || (obj == nullptr)) {
655         NAPI_ERR_LOG("Failed to get expiredTime obj");
656         return undefinedResult;
657     }
658     napi_valuetype valueType = napi_undefined;
659     if (napi_typeof(env, argv[PARAM0], &valueType) != napi_ok || valueType != napi_number) {
660         NAPI_ERR_LOG("Invalid arguments type! valueType: %{private}d", valueType);
661         obj->smartAlbumAssetPtr->SetExpiredTime(INVALID_EXPIREDTIME);
662         return undefinedResult;
663     }
664     int32_t expiredTime;
665     status = napi_get_value_int32(env, argv[PARAM0], &expiredTime);
666     if (status != napi_ok) {
667         NAPI_ERR_LOG("Failed to get expiredTime");
668         return undefinedResult;
669     }
670     obj->smartAlbumAssetPtr->SetExpiredTime(expiredTime);
671     return undefinedResult;
672 }
673 
CommitModifyNative(const SmartAlbumNapiAsyncContext & albumContext)674 static void CommitModifyNative(const SmartAlbumNapiAsyncContext &albumContext)
675 {
676     SmartAlbumNapiAsyncContext *context = const_cast<SmartAlbumNapiAsyncContext *>(&albumContext);
677     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
678     NAPI_DEBUG_LOG("CommitModifyNative = %{private}s", context->objectInfo->GetSmartAlbumName().c_str());
679     if (MediaFileUtils::CheckAlbumName(context->objectInfo->GetSmartAlbumName()) < 0) {
680         context->error = JS_E_DISPLAYNAME;
681         NAPI_ERR_LOG("Failed to checkDisplayName");
682         return;
683     }
684     DataShare::DataShareValuesBucket valuesBucket;
685     valuesBucket.Put(SMARTALBUM_DB_DESCRIPTION, context->objectInfo->GetDescription());
686     string coverUri = context->objectInfo->GetCoverUri();
687     if (coverUri.empty() || (coverUri.find(MEDIALIBRARY_MEDIA_PREFIX) == string::npos)) {
688         context->error = E_VIOLATION_PARAMETERS;
689         NAPI_ERR_LOG("CoverUri is invalid");
690         return;
691     }
692     valuesBucket.Put(SMARTALBUM_DB_COVER_URI, coverUri);
693     if (context->objectInfo->GetExpiredTime() < 0) {
694         context->error = E_VIOLATION_PARAMETERS;
695         NAPI_ERR_LOG("ExpiredTime is invalid");
696         return;
697     }
698     valuesBucket.Put(SMARTALBUM_DB_EXPIRED_TIME, context->objectInfo->GetExpiredTime());
699     DataShare::DataSharePredicates predicates;
700     predicates.SetWhereClause(SMARTALBUM_DB_ID + " = " + std::to_string(context->objectInfo->GetSmartAlbumId()));
701     Uri commitModifyUri(MEDIALIBRARY_DATA_URI + "/" + MEDIA_SMARTALBUMOPRN + "/" + MEDIA_SMARTALBUMOPRN_MODIFYALBUM);
702     context->changedRows = UserFileClient::Update(commitModifyUri, predicates, valuesBucket);
703     context->SaveError(context->changedRows);
704 }
705 
JSAddAssetExecute(SmartAlbumNapiAsyncContext * context)706 static void JSAddAssetExecute(SmartAlbumNapiAsyncContext *context)
707 {
708     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
709     int32_t smartAlbumId = context->objectInfo->GetSmartAlbumId();
710     if ((smartAlbumId == TRASH_ALBUM_ID_VALUES) || (smartAlbumId == FAVOURITE_ALBUM_ID_VALUES)) {
711         context->error = E_INVALID_VALUES;
712         NAPI_ERR_LOG("SmartAlbumId is invalid, smartAlbumId = %{private}d", smartAlbumId);
713         return;
714     }
715     vector<DataShare::DataShareValuesBucket> values;
716     for (int32_t id : context->assetIds) {
717         DataShare::DataShareValuesBucket valuesBucket;
718         valuesBucket.Put(SMARTALBUMMAP_DB_ALBUM_ID, smartAlbumId);
719         valuesBucket.Put(SMARTALBUMMAP_DB_CHILD_ASSET_ID, id);
720         values.push_back(valuesBucket);
721     }
722     Uri addAssetUri(MEDIALIBRARY_DATA_URI + "/" + MEDIA_SMARTALBUMMAPOPRN + "/" +
723         MEDIA_SMARTALBUMMAPOPRN_ADDSMARTALBUM);
724     context->changedRows = UserFileClient::BatchInsert(addAssetUri, values);
725     if (context->changedRows != context->assetIds.size()) {
726         context->error = E_INVALID_VALUES;
727     }
728 }
729 
JSRemoveAssetExecute(SmartAlbumNapiAsyncContext * context)730 static void JSRemoveAssetExecute(SmartAlbumNapiAsyncContext *context)
731 {
732     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
733     int32_t smartAlbumId = context->objectInfo->GetSmartAlbumId();
734     if ((smartAlbumId == TRASH_ALBUM_ID_VALUES) || (smartAlbumId == FAVOURITE_ALBUM_ID_VALUES)) {
735         NAPI_ERR_LOG("SmartAlbumId is invalid, smartAlbumId = %{private}d", smartAlbumId);
736         context->error = E_INVALID_VALUES;
737         return;
738     }
739     vector<DataShare::DataShareValuesBucket> values;
740     for (int32_t id : context->assetIds) {
741         DataShare::DataShareValuesBucket valuesBucket;
742         valuesBucket.Put(SMARTALBUMMAP_DB_ALBUM_ID, smartAlbumId);
743         valuesBucket.Put(SMARTALBUMMAP_DB_CHILD_ASSET_ID, id);
744         values.push_back(valuesBucket);
745     }
746     Uri removeAssetUri(MEDIALIBRARY_DATA_URI + "/" + MEDIA_SMARTALBUMMAPOPRN + "/" +
747         MEDIA_SMARTALBUMMAPOPRN_REMOVESMARTALBUM);
748     context->changedRows = UserFileClient::BatchInsert(removeAssetUri, values);
749     if (context->changedRows != context->assetIds.size()) {
750         context->error = E_INVALID_VALUES;
751     }
752 }
753 
JSCommitModifyCompleteCallback(napi_env env,napi_status status,SmartAlbumNapiAsyncContext * context)754 static void JSCommitModifyCompleteCallback(napi_env env, napi_status status, SmartAlbumNapiAsyncContext *context)
755 {
756     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
757     std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
758     jsContext->status = false;
759     if (context->error == ERR_DEFAULT) {
760         napi_create_int32(env, context->changedRows, &jsContext->data);
761         napi_get_undefined(env, &jsContext->error);
762         jsContext->status = true;
763     } else {
764         context->HandleError(env, jsContext->error);
765         napi_get_undefined(env, &jsContext->data);
766         MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, context->error,
767                                                      "Failed to commit smart album");
768     }
769 
770     if (context->work != nullptr) {
771         MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
772                                                    context->work, *jsContext);
773     }
774     delete context;
775 }
776 
JSAddAssetCompleteCallback(napi_env env,napi_status status,SmartAlbumNapiAsyncContext * context)777 static void JSAddAssetCompleteCallback(napi_env env, napi_status status, SmartAlbumNapiAsyncContext *context)
778 {
779     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
780     std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
781     jsContext->status = false;
782     if (context->error == ERR_DEFAULT) {
783         napi_create_int32(env, context->changedRows, &jsContext->data);
784         napi_get_undefined(env, &jsContext->error);
785         jsContext->status = true;
786     } else {
787         context->HandleError(env, jsContext->error);
788         napi_get_undefined(env, &jsContext->data);
789         MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error,  context->error,
790                                                      "Failed to add smartalbum asset");
791     }
792 
793     if (context->work != nullptr) {
794         MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
795                                                    context->work, *jsContext);
796     }
797     delete context;
798 }
799 
JSRemoveAssetCompleteCallback(napi_env env,napi_status status,SmartAlbumNapiAsyncContext * context)800 static void JSRemoveAssetCompleteCallback(napi_env env, napi_status status, SmartAlbumNapiAsyncContext *context)
801 {
802     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
803     std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
804     jsContext->status = false;
805 
806     if (context->error == ERR_DEFAULT) {
807         napi_create_int32(env, context->changedRows, &jsContext->data);
808         napi_get_undefined(env, &jsContext->error);
809         jsContext->status = true;
810     } else {
811         context->HandleError(env, jsContext->error);
812         napi_get_undefined(env, &jsContext->data);
813         MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error,  context->error,
814                                                      "Failed to remove smartalbum asset");
815     }
816 
817     if (context->work != nullptr) {
818         MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
819                                                    context->work, *jsContext);
820     }
821     delete context;
822 }
823 
ConvertCommitJSArgsToNative(napi_env env,size_t argc,const napi_value argv[],SmartAlbumNapiAsyncContext & asyncContext)824 static napi_value ConvertCommitJSArgsToNative(napi_env env, size_t argc, const napi_value argv[],
825     SmartAlbumNapiAsyncContext &asyncContext)
826 {
827     const int32_t refCount = 1;
828     napi_value result;
829     auto context = &asyncContext;
830 
831     NAPI_ASSERT(env, argv != nullptr, "Argument list is empty");
832 
833     for (size_t i = PARAM0; i < argc; i++) {
834         napi_valuetype valueType = napi_undefined;
835         napi_typeof(env, argv[i], &valueType);
836         if (i == PARAM0 && valueType == napi_function) {
837             napi_create_reference(env, argv[i], refCount, &context->callbackRef);
838         } else {
839             NAPI_ASSERT(env, false, "type mismatch");
840         }
841     }
842 
843     // Return true napi_value if params are successfully obtained
844     napi_get_boolean(env, true, &result);
845     return result;
846 }
847 
GetAssetIds(napi_env env,napi_value param,SmartAlbumNapiAsyncContext & context)848 static napi_value GetAssetIds(napi_env env, napi_value param, SmartAlbumNapiAsyncContext &context)
849 {
850     uint32_t arraySize = 0;
851     if (!MediaLibraryNapiUtils::IsArrayForNapiValue(env, param, arraySize)) {
852         NAPI_ERR_LOG("GetAssetIds get args fail, not array");
853         return nullptr;
854     }
855     string uri = "";
856     for (uint32_t i = 0; i < arraySize; i++) {
857         napi_value jsValue = nullptr;
858         int32_t result;
859         if ((napi_get_element(env, param, i, &jsValue)) != napi_ok) {
860             NAPI_ERR_LOG("GetAssetIds get args fail");
861             return nullptr;
862         }
863         if (napi_get_value_int32(env, jsValue, &result) != napi_ok) {
864             NAPI_ERR_LOG("Get ids value fail");
865             return nullptr;
866         } else {
867             if (result < 0) {
868                 NAPI_ERR_LOG("GetAssetIds < 0 is invalid , id = %{public}d", result);
869                 return nullptr;
870             }
871             context.assetIds.push_back(result);
872         }
873     }
874     napi_value res;
875     napi_get_undefined(env, &res);
876     return res;
877 }
878 
GetJSArgsForAsset(napi_env env,size_t argc,const napi_value argv[],SmartAlbumNapiAsyncContext & asyncContext)879 napi_value GetJSArgsForAsset(napi_env env, size_t argc,
880                              const napi_value argv[],
881                              SmartAlbumNapiAsyncContext &asyncContext)
882 {
883     const int32_t refCount = 1;
884     napi_value result = nullptr;
885     auto context = &asyncContext;
886 
887     NAPI_ASSERT(env, argv != nullptr, "Argument list is empty");
888 
889     for (size_t i = PARAM0; i < argc; i++) {
890         napi_valuetype valueType = napi_undefined;
891         napi_typeof(env, argv[i], &valueType);
892         if (i == PARAM0) {
893             napi_value res = GetAssetIds(env, argv[PARAM0], asyncContext);
894             if (res == nullptr) {
895                 napi_throw_error(env, std::to_string(ERR_INVALID_OUTPUT).c_str(), "Failed to obtain arguments ids");
896                 return nullptr;
897             }
898         } else if (i == PARAM1 && valueType == napi_function) {
899             napi_create_reference(env, argv[i], refCount, &context->callbackRef);
900             break;
901         } else {
902             NAPI_ASSERT(env, false, "type mismatch");
903         }
904     }
905     // Return true napi_value if params are successfully obtained
906     napi_get_boolean(env, true, &result);
907     return result;
908 }
909 
JSAddFileAssets(napi_env env,napi_callback_info info)910 napi_value SmartAlbumNapi::JSAddFileAssets(napi_env env, napi_callback_info info)
911 {
912     napi_status status;
913     napi_value result = nullptr;
914     size_t argc = ARGS_TWO;
915     napi_value argv[ARGS_TWO] = {0};
916     napi_value thisVar = nullptr;
917     napi_value resource = nullptr;
918     GET_JS_ARGS(env, info, argc, argv, thisVar);
919     NAPI_ASSERT(env, (argc == ARGS_ONE || argc == ARGS_TWO), "requires 2 parameter maximum");
920     napi_get_undefined(env, &result);
921     std::unique_ptr<SmartAlbumNapiAsyncContext> asyncContext = std::make_unique<SmartAlbumNapiAsyncContext>();
922 
923     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
924     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
925         result = GetJSArgsForAsset(env, argc, argv, *asyncContext);
926         CHECK_NULL_PTR_RETURN_UNDEFINED(env, result, result, "JSAddFileAssets fail");
927         NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
928         NAPI_CREATE_RESOURCE_NAME(env, resource, "JSAddFileAssets", asyncContext);
929 
930         asyncContext->objectPtr = asyncContext->objectInfo->smartAlbumAssetPtr;
931         CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "SmartAlbumAsset is nullptr");
932 
933         status = napi_create_async_work(
934             env, nullptr, resource, [](napi_env env, void *data) {
935                 auto context = static_cast<SmartAlbumNapiAsyncContext*>(data);
936                 JSAddAssetExecute(context);
937             },
938             reinterpret_cast<CompleteCallback>(JSAddAssetCompleteCallback),
939             static_cast<void *>(asyncContext.get()), &asyncContext->work);
940         if (status != napi_ok) {
941             napi_get_undefined(env, &result);
942         } else {
943             napi_queue_async_work(env, asyncContext->work);
944             asyncContext.release();
945         }
946     }
947 
948     return result;
949 }
950 
JSRemoveFileAssets(napi_env env,napi_callback_info info)951 napi_value SmartAlbumNapi::JSRemoveFileAssets(napi_env env, napi_callback_info info)
952 {
953     napi_status status;
954     napi_value result = nullptr;
955     size_t argc = ARGS_TWO;
956     napi_value argv[ARGS_TWO] = {0};
957     napi_value thisVar = nullptr;
958     napi_value resource = nullptr;
959     GET_JS_ARGS(env, info, argc, argv, thisVar);
960     NAPI_ASSERT(env, (argc == ARGS_ONE || argc == ARGS_TWO), "requires 2 parameter maximum");
961     napi_get_undefined(env, &result);
962     std::unique_ptr<SmartAlbumNapiAsyncContext> asyncContext = std::make_unique<SmartAlbumNapiAsyncContext>();
963 
964     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
965     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
966         result = GetJSArgsForAsset(env, argc, argv, *asyncContext);
967         CHECK_NULL_PTR_RETURN_UNDEFINED(env, result, result, "JSRemoveFileAssets fail ");
968 
969         NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
970         NAPI_CREATE_RESOURCE_NAME(env, resource, "JSRemoveFileAssets", asyncContext);
971 
972         asyncContext->objectPtr = asyncContext->objectInfo->smartAlbumAssetPtr;
973         CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "SmartAlbumAsset is nullptr");
974 
975         status = napi_create_async_work(
976             env, nullptr, resource, [](napi_env env, void *data) {
977                 auto context = static_cast<SmartAlbumNapiAsyncContext*>(data);
978                 JSRemoveAssetExecute(context);
979             },
980             reinterpret_cast<CompleteCallback>(JSRemoveAssetCompleteCallback),
981             static_cast<void *>(asyncContext.get()), &asyncContext->work);
982         if (status != napi_ok) {
983             napi_get_undefined(env, &result);
984         } else {
985             napi_queue_async_work(env, asyncContext->work);
986             asyncContext.release();
987         }
988     }
989 
990     return result;
991 }
992 
JSCommitModify(napi_env env,napi_callback_info info)993 napi_value SmartAlbumNapi::JSCommitModify(napi_env env, napi_callback_info info)
994 {
995     napi_status status;
996     napi_value result = nullptr;
997     size_t argc = ARGS_ONE;
998     napi_value argv[ARGS_ONE] = {0};
999     napi_value thisVar = nullptr;
1000     napi_value resource = nullptr;
1001     GET_JS_ARGS(env, info, argc, argv, thisVar);
1002     NAPI_ASSERT(env, (argc == ARGS_ZERO || argc == ARGS_ONE), "requires 1 parameter maximum");
1003     napi_get_undefined(env, &result);
1004     std::unique_ptr<SmartAlbumNapiAsyncContext> asyncContext = std::make_unique<SmartAlbumNapiAsyncContext>();
1005 
1006     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
1007     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1008         result = ConvertCommitJSArgsToNative(env, argc, argv, *asyncContext);
1009         CHECK_NULL_PTR_RETURN_UNDEFINED(env, result, result, "JSCommitModify fail ");
1010 
1011         NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
1012         NAPI_CREATE_RESOURCE_NAME(env, resource, "JSCommitModify", asyncContext);
1013 
1014         asyncContext->objectPtr = asyncContext->objectInfo->smartAlbumAssetPtr;
1015         CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "SmartAlbumAsset is nullptr");
1016 
1017         status = napi_create_async_work(
1018             env, nullptr, resource, [](napi_env env, void *data) {
1019                 auto context = static_cast<SmartAlbumNapiAsyncContext*>(data);
1020                 CommitModifyNative(*context);
1021             },
1022             reinterpret_cast<CompleteCallback>(JSCommitModifyCompleteCallback),
1023             static_cast<void *>(asyncContext.get()), &asyncContext->work);
1024         if (status != napi_ok) {
1025             napi_get_undefined(env, &result);
1026         } else {
1027             napi_queue_async_work(env, asyncContext->work);
1028             asyncContext.release();
1029         }
1030     }
1031 
1032     return result;
1033 }
1034 
GetFetchOptionsParam(napi_env env,napi_value arg,const SmartAlbumNapiAsyncContext & context,bool & err)1035 static void GetFetchOptionsParam(napi_env env, napi_value arg, const SmartAlbumNapiAsyncContext &context, bool &err)
1036 {
1037     SmartAlbumNapiAsyncContext *asyncContext = const_cast<SmartAlbumNapiAsyncContext *>(&context);
1038     CHECK_NULL_PTR_RETURN_VOID(asyncContext, "Async context is null");
1039     char buffer[PATH_MAX];
1040     size_t res;
1041     uint32_t len = 0;
1042     napi_value property = nullptr;
1043     napi_value stringItem = nullptr;
1044     bool present = false;
1045     bool boolResult = false;
1046 
1047     napi_has_named_property(env, arg, "selections", &present);
1048     if (present) {
1049         if (napi_get_named_property(env, arg, "selections", &property) != napi_ok
1050             || napi_get_value_string_utf8(env, property, buffer, PATH_MAX, &res) != napi_ok) {
1051             NAPI_ERR_LOG("Could not get the string argument!");
1052             err = true;
1053             return;
1054         } else {
1055             asyncContext->selection = buffer;
1056             CHECK_IF_EQUAL(memset_s(buffer, PATH_MAX, 0, sizeof(buffer)) == 0, "Memset for buffer failed");
1057         }
1058         present = false;
1059     }
1060 
1061     napi_has_named_property(env, arg, "order", &present);
1062     if (present) {
1063         if (napi_get_named_property(env, arg, "order", &property) != napi_ok
1064             || napi_get_value_string_utf8(env, property, buffer, PATH_MAX, &res) != napi_ok) {
1065             NAPI_ERR_LOG("Could not get the string argument!");
1066             err = true;
1067             return;
1068         } else {
1069             asyncContext->order = buffer;
1070             CHECK_IF_EQUAL(memset_s(buffer, PATH_MAX, 0, sizeof(buffer)) == 0, "Memset for buffer failed");
1071         }
1072         present = false;
1073     }
1074 
1075     napi_has_named_property(env, arg, "selectionArgs", &present);
1076     if (present && napi_get_named_property(env, arg, "selectionArgs", &property) == napi_ok &&
1077         napi_is_array(env, property, &boolResult) == napi_ok && boolResult) {
1078         napi_get_array_length(env, property, &len);
1079         for (size_t i = 0; i < len; i++) {
1080             napi_get_element(env, property, i, &stringItem);
1081             napi_get_value_string_utf8(env, stringItem, buffer, PATH_MAX, &res);
1082             asyncContext->selectionArgs.push_back(std::string(buffer));
1083             CHECK_IF_EQUAL(memset_s(buffer, PATH_MAX, 0, sizeof(buffer)) == 0, "Memset for buffer failed");
1084         }
1085     } else {
1086         NAPI_ERR_LOG("Could not get the string argument!");
1087         err = true;
1088     }
1089 }
1090 
ConvertJSArgsToNative(napi_env env,size_t argc,const napi_value argv[],SmartAlbumNapiAsyncContext & asyncContext)1091 static napi_value ConvertJSArgsToNative(napi_env env, size_t argc, const napi_value argv[],
1092     SmartAlbumNapiAsyncContext &asyncContext)
1093 {
1094     string str = "";
1095     std::vector<string> strArr;
1096     string order = "";
1097     bool err = false;
1098     const int32_t refCount = 1;
1099     napi_value result;
1100     auto context = &asyncContext;
1101 
1102     NAPI_ASSERT(env, argv != nullptr, "Argument list is empty");
1103 
1104     for (size_t i = PARAM0; i < argc; i++) {
1105         napi_valuetype valueType = napi_undefined;
1106         napi_typeof(env, argv[i], &valueType);
1107 
1108         if (i == PARAM0 && valueType == napi_object) {
1109             GetFetchOptionsParam(env, argv[PARAM0], asyncContext, err);
1110             if (err) {
1111                 NAPI_ASSERT(env, false, "type mismatch");
1112             }
1113         } else if (i == PARAM0 && valueType == napi_function) {
1114             napi_create_reference(env, argv[i], refCount, &context->callbackRef);
1115             break;
1116         } else if (i == PARAM1 && valueType == napi_function) {
1117             napi_create_reference(env, argv[i], refCount, &context->callbackRef);
1118             break;
1119         } else {
1120             NAPI_ASSERT(env, false, "type mismatch");
1121         }
1122     }
1123 
1124     // Return true napi_value if params are successfully obtained
1125     napi_get_boolean(env, true, &result);
1126     return result;
1127 }
1128 
UpdateSelection(SmartAlbumNapiAsyncContext * context)1129 static void UpdateSelection(SmartAlbumNapiAsyncContext *context)
1130 {
1131     if (context->resultNapiType == ResultNapiType::TYPE_USERFILE_MGR) {
1132         context->predicates.EqualTo(SMARTALBUMMAP_DB_ALBUM_ID, context->objectPtr->GetAlbumId());
1133         context->predicates.EqualTo(MEDIA_DATA_DB_TIME_PENDING, to_string(0));
1134         if (context->objectPtr->GetAlbumId() == TRASH_ALBUM_ID_VALUES) {
1135             context->predicates.NotEqualTo(MEDIA_DATA_DB_DATE_TRASHED, "0");
1136         } else {
1137             context->predicates.EqualTo(MEDIA_DATA_DB_DATE_TRASHED, "0");
1138         }
1139         MediaLibraryNapiUtils::UpdateMediaTypeSelections(context);
1140     } else {
1141         string trashPrefix;
1142         if (context->objectPtr->GetAlbumId() == TRASH_ALBUM_ID_VALUES) {
1143             trashPrefix = MEDIA_DATA_DB_DATE_TRASHED + " <> ? AND " + SMARTALBUMMAP_DB_ALBUM_ID + " = ? ";
1144         } else {
1145             trashPrefix = MEDIA_DATA_DB_DATE_TRASHED + " = ? AND " + SMARTALBUMMAP_DB_ALBUM_ID + " = ? ";
1146         }
1147         MediaLibraryNapiUtils::AppendFetchOptionSelection(context->selection, trashPrefix);
1148         context->selectionArgs.emplace_back("0");
1149         context->selectionArgs.emplace_back(std::to_string(context->objectPtr->GetAlbumId()));
1150     }
1151 }
1152 
GetFileAssetsNative(napi_env env,void * data)1153 static void GetFileAssetsNative(napi_env env, void *data)
1154 {
1155     MediaLibraryTracer tracer;
1156     tracer.Start("GetFileAssetsNative");
1157 
1158     auto context = static_cast<SmartAlbumNapiAsyncContext *>(data);
1159     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
1160 
1161     UpdateSelection(context);
1162     context->predicates.SetWhereClause(context->selection);
1163     context->predicates.SetWhereArgs(context->selectionArgs);
1164     context->predicates.SetOrder(context->order);
1165 
1166     if (context->resultNapiType == ResultNapiType::TYPE_MEDIALIBRARY) {
1167         context->fetchColumn = FILE_ASSET_COLUMNS;
1168     } else {
1169         context->fetchColumn.push_back(MEDIA_DATA_DB_ID);
1170         context->fetchColumn.push_back(MEDIA_DATA_DB_NAME);
1171         context->fetchColumn.push_back(MEDIA_DATA_DB_MEDIA_TYPE);
1172     }
1173 
1174     string queryUri = MEDIALIBRARY_DATA_ABILITY_PREFIX +
1175         (MediaFileUtils::GetNetworkIdFromUri(context->objectPtr->GetAlbumUri())) +
1176         MEDIALIBRARY_DATA_URI_IDENTIFIER + "/" + MEDIA_ALBUMOPRN_QUERYALBUM + "/" + ASSETMAP_VIEW_NAME;
1177     Uri uri(queryUri);
1178     int errCode = 0;
1179     auto resultSet = UserFileClient::Query(uri, context->predicates, context->fetchColumn, errCode);
1180     if (resultSet == nullptr) {
1181         NAPI_ERR_LOG("resultSet == nullptr, errCode is %{public}d", errCode);
1182         return;
1183     }
1184     context->fetchResult = std::make_unique<FetchResult<FileAsset>>(move(resultSet));
1185     context->fetchResult->SetNetworkId(
1186         MediaFileUtils::GetNetworkIdFromUri(context->objectPtr->GetAlbumUri()));
1187     if (context->resultNapiType == ResultNapiType::TYPE_USERFILE_MGR) {
1188         context->fetchResult->SetResultNapiType(context->resultNapiType);
1189     }
1190 }
1191 
JSGetFileAssetsCompleteCallback(napi_env env,napi_status status,void * data)1192 static void JSGetFileAssetsCompleteCallback(napi_env env, napi_status status, void *data)
1193 {
1194     MediaLibraryTracer tracer;
1195     tracer.Start("JSGetFileAssetsCompleteCallback");
1196 
1197     auto context = static_cast<SmartAlbumNapiAsyncContext *>(data);
1198     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
1199 
1200     std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
1201     jsContext->status = false;
1202 
1203     if (context->fetchResult != nullptr) {
1204         if (context->fetchResult->GetCount() < 0) {
1205             napi_get_undefined(env, &jsContext->data);
1206             MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_MEM_ALLOCATION,
1207                 "Find no data by options");
1208         } else {
1209             napi_value fetchRes = FetchFileResultNapi::CreateFetchFileResult(env, move(context->fetchResult));
1210             if (fetchRes == nullptr) {
1211                 NAPI_ERR_LOG("Failed to get file asset napi object");
1212                 napi_get_undefined(env, &jsContext->data);
1213                 MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_MEM_ALLOCATION,
1214                     "Failed to create js object for FetchFileResult");
1215             } else {
1216                 jsContext->data = fetchRes;
1217                 napi_get_undefined(env, &jsContext->error);
1218                 jsContext->status = true;
1219             }
1220         }
1221     } else {
1222         NAPI_ERR_LOG("No fetch file result found!");
1223         napi_get_undefined(env, &jsContext->data);
1224         MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_INVALID_OUTPUT,
1225                                                      "Failed to get fetchFileResult from DB");
1226     }
1227 
1228     tracer.Finish();
1229     if (context->work != nullptr) {
1230         MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
1231                                                    context->work, *jsContext);
1232     }
1233     delete context;
1234 }
1235 
JSGetSmartAlbumFileAssets(napi_env env,napi_callback_info info)1236 napi_value SmartAlbumNapi::JSGetSmartAlbumFileAssets(napi_env env, napi_callback_info info)
1237 {
1238     napi_status status;
1239     napi_value result = nullptr;
1240     constexpr int maxArgs = 2;
1241     size_t argc = maxArgs;
1242     napi_value argv[maxArgs] = {0};
1243     napi_value thisVar = nullptr;
1244 
1245     GET_JS_ARGS(env, info, argc, argv, thisVar);
1246     NAPI_ASSERT(env, ((argc == ARGS_ZERO) || (argc == ARGS_ONE) || (argc == ARGS_TWO)),
1247                 "requires 2 parameter maximum");
1248 
1249     napi_get_undefined(env, &result);
1250     std::unique_ptr<SmartAlbumNapiAsyncContext> asyncContext = std::make_unique<SmartAlbumNapiAsyncContext>();
1251     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
1252     asyncContext->resultNapiType = ResultNapiType::TYPE_MEDIALIBRARY;
1253     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1254         result = ConvertJSArgsToNative(env, argc, argv, *asyncContext);
1255         CHECK_NULL_PTR_RETURN_UNDEFINED(env, result, result, "Failed to obtain arguments");
1256 
1257         asyncContext->objectPtr = asyncContext->objectInfo->smartAlbumAssetPtr;
1258         CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "SmartAlbumAsset is nullptr");
1259 
1260         result = MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "JSGetSmartAlbumFileAssets",
1261             GetFileAssetsNative, JSGetFileAssetsCompleteCallback);
1262     }
1263 
1264     return result;
1265 }
1266 
UserFileMgrGetAssets(napi_env env,napi_callback_info info)1267 napi_value SmartAlbumNapi::UserFileMgrGetAssets(napi_env env, napi_callback_info info)
1268 {
1269     napi_value ret = nullptr;
1270     unique_ptr<SmartAlbumNapiAsyncContext> asyncContext = make_unique<SmartAlbumNapiAsyncContext>();
1271     CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext, ret, "AsyncContext context is null");
1272 
1273     asyncContext->mediaTypes.push_back(MEDIA_TYPE_IMAGE);
1274     asyncContext->mediaTypes.push_back(MEDIA_TYPE_VIDEO);
1275     CHECK_ARGS(env, MediaLibraryNapiUtils::ParseAssetFetchOptCallback(env, info, asyncContext),
1276         JS_ERR_PARAMETER_INVALID);
1277     asyncContext->resultNapiType = ResultNapiType::TYPE_USERFILE_MGR;
1278 
1279     asyncContext->objectPtr = asyncContext->objectInfo->smartAlbumAssetPtr;
1280     CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, ret, "SmartAlbumAsset is nullptr");
1281 
1282     return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "UserFileMgrGetAssets", GetFileAssetsNative,
1283         JSGetFileAssetsCompleteCallback);
1284 }
1285 
JSRecoverAssetExecute(napi_env env,void * data)1286 static void JSRecoverAssetExecute(napi_env env, void *data)
1287 {
1288     MediaLibraryTracer tracer;
1289     tracer.Start("JSRecoverAssetExecute");
1290 
1291     auto context = static_cast<SmartAlbumNapiAsyncContext *>(data);
1292     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
1293 
1294     string recoverUri = MEDIALIBRARY_DATA_URI + "/" + MEDIA_SMARTALBUMMAPOPRN + "/" +
1295         MEDIA_SMARTALBUMMAPOPRN_REMOVESMARTALBUM;
1296     Uri recoverAssetUri(recoverUri);
1297     DataShare::DataShareValuesBucket valuesBucket;
1298     valuesBucket.Put(SMARTALBUMMAP_DB_ALBUM_ID, context->objectPtr->GetAlbumId());
1299     valuesBucket.Put(SMARTALBUMMAP_DB_CHILD_ASSET_ID, stoi(MediaLibraryNapiUtils::GetFileIdFromUri(context->uri)));
1300     int retVal = UserFileClient::Insert(recoverAssetUri, valuesBucket);
1301     context->SaveError(retVal);
1302 }
1303 
JSRecoverAssetCompleteCallback(napi_env env,napi_status status,void * data)1304 static void JSRecoverAssetCompleteCallback(napi_env env, napi_status status, void *data)
1305 {
1306     MediaLibraryTracer tracer;
1307     tracer.Start("JSRecoverAssetCompleteCallback");
1308 
1309     SmartAlbumNapiAsyncContext *context = static_cast<SmartAlbumNapiAsyncContext*>(data);
1310     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
1311     unique_ptr<JSAsyncContextOutput> jsContext = make_unique<JSAsyncContextOutput>();
1312     CHECK_NULL_PTR_RETURN_VOID(jsContext, "jsContext context is null");
1313     jsContext->status = false;
1314     napi_get_undefined(env, &jsContext->data);
1315     if (context->error == ERR_DEFAULT) {
1316         jsContext->status = true;
1317         Media::MediaType mediaType = MediaLibraryNapiUtils::GetMediaTypeFromUri(context->uri);
1318         string notifyUri = MediaFileUtils::GetMediaTypeUri(mediaType);
1319         Uri modifyNotify(notifyUri);
1320         UserFileClient::NotifyChange(modifyNotify);
1321     } else {
1322         context->HandleError(env, jsContext->error);
1323     }
1324     if (context->work != nullptr) {
1325         tracer.Finish();
1326         MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
1327             context->work, *jsContext);
1328     }
1329 
1330     delete context;
1331 }
1332 
UserFileMgrRecoverAsset(napi_env env,napi_callback_info info)1333 napi_value SmartAlbumNapi::UserFileMgrRecoverAsset(napi_env env, napi_callback_info info)
1334 {
1335     napi_value ret = nullptr;
1336     unique_ptr<SmartAlbumNapiAsyncContext> asyncContext = make_unique<SmartAlbumNapiAsyncContext>();
1337     CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext, ret, "AsyncContext context is null");
1338 
1339     CHECK_ARGS(env, MediaLibraryNapiUtils::ParseArgsStringCallback(env, info, asyncContext, asyncContext->uri),
1340         JS_ERR_PARAMETER_INVALID);
1341     asyncContext->resultNapiType = ResultNapiType::TYPE_USERFILE_MGR;
1342     asyncContext->objectPtr = asyncContext->objectInfo->smartAlbumAssetPtr;
1343     CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, ret, "SmartAlbumAsset is nullptr");
1344 
1345     return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "UserFileMgrGetAssets", JSRecoverAssetExecute,
1346         JSRecoverAssetCompleteCallback);
1347 }
1348 
JSDeleteAssetExecute(napi_env env,void * data)1349 static void JSDeleteAssetExecute(napi_env env, void *data)
1350 {
1351     MediaLibraryTracer tracer;
1352     tracer.Start("JSDeleteAssetExecute");
1353 
1354     auto context = static_cast<SmartAlbumNapiAsyncContext *>(data);
1355     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
1356 
1357     string deleteUri = MEDIALIBRARY_DATA_URI + "/" + MEDIA_FILEOPRN + "/" + MEDIA_FILEOPRN_DELETEASSET;
1358     Uri deleteAssetUri(deleteUri);
1359     DataShare::DataSharePredicates predicates;
1360     predicates.EqualTo(MEDIA_DATA_DB_ID, MediaLibraryNapiUtils::GetFileIdFromUri(context->uri));
1361     int retVal = UserFileClient::Delete(deleteAssetUri, {});
1362     context->SaveError(retVal);
1363 }
1364 
JSDeleteAssetCompleteCallback(napi_env env,napi_status status,void * data)1365 static void JSDeleteAssetCompleteCallback(napi_env env, napi_status status, void *data)
1366 {
1367     MediaLibraryTracer tracer;
1368     tracer.Start("JSDeleteAssetCompleteCallback");
1369 
1370     SmartAlbumNapiAsyncContext *context = static_cast<SmartAlbumNapiAsyncContext*>(data);
1371     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
1372     unique_ptr<JSAsyncContextOutput> jsContext = make_unique<JSAsyncContextOutput>();
1373     CHECK_NULL_PTR_RETURN_VOID(jsContext, "JsContext context is null");
1374     jsContext->status = false;
1375     napi_get_undefined(env, &jsContext->data);
1376     if (context->error == ERR_DEFAULT) {
1377         jsContext->status = true;
1378         Media::MediaType mediaType = MediaLibraryNapiUtils::GetMediaTypeFromUri(context->uri);
1379         string notifyUri = MediaFileUtils::GetMediaTypeUri(mediaType);
1380         Uri modifyNotify(notifyUri);
1381         UserFileClient::NotifyChange(modifyNotify);
1382     } else {
1383         context->HandleError(env, jsContext->error);
1384     }
1385     if (context->work != nullptr) {
1386         tracer.Finish();
1387         MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
1388             context->work, *jsContext);
1389     }
1390 
1391     delete context;
1392 }
1393 
UserFileMgrDeleteAsset(napi_env env,napi_callback_info info)1394 napi_value SmartAlbumNapi::UserFileMgrDeleteAsset(napi_env env, napi_callback_info info)
1395 {
1396     napi_value ret = nullptr;
1397     unique_ptr<SmartAlbumNapiAsyncContext> asyncContext = make_unique<SmartAlbumNapiAsyncContext>();
1398     CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext, ret, "AsyncContext context is null");
1399 
1400     CHECK_ARGS(env, MediaLibraryNapiUtils::ParseArgsStringCallback(env, info, asyncContext, asyncContext->uri),
1401         JS_ERR_PARAMETER_INVALID);
1402     asyncContext->resultNapiType = ResultNapiType::TYPE_USERFILE_MGR;
1403 
1404     return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "UserFileMgrGetAssets", JSDeleteAssetExecute,
1405         JSDeleteAssetCompleteCallback);
1406 }
1407 } // namespace Media
1408 } // namespace OHOS
1409