• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 #define MLOG_TAG "CloudMediaAssetManagerNapi"
17 
18 #include "cloud_media_asset_manager_napi.h"
19 
20 #include "media_column.h"
21 #include "medialibrary_client_errno.h"
22 #include "medialibrary_errno.h"
23 #include "medialibrary_napi_log.h"
24 #include "medialibrary_tracer.h"
25 #include "userfile_client.h"
26 #include "userfile_manager_types.h"
27 #include "media_library_napi.h"
28 #include "media_file_uri.h"
29 #include "media_file_utils.h"
30 #include "result_set_utils.h"
31 #include "cloud_media_asset_types.h"
32 #include "cloud_media_asset_status_napi.h"
33 #include "cloud_media_asset_uri.h"
34 #include "start_download_cloud_media_vo.h"
35 #include "retain_cloud_media_asset_vo.h"
36 #include "medialibrary_business_code.h"
37 #include "user_define_ipc_client.h"
38 #include "medialibrary_business_code.h"
39 #include "get_cloudmedia_asset_status_vo.h"
40 #include "user_define_ipc_client.h"
41 
42 using namespace std;
43 namespace OHOS::Media {
44 static const string CLOUD_MEDIA_ASSET_MANAGER_CLASS = "CloudMediaAssetManager";
45 thread_local napi_ref CloudMediaAssetManagerNapi::constructor_ = nullptr;
46 const size_t TYPE_SIZE = 6;
47 const int32_t INDEX_ZERO = 0;
48 const int32_t INDEX_ONE = 1;
49 const int32_t INDEX_TWO = 2;
50 const int32_t INDEX_THREE = 3;
51 const int32_t INDEX_FOUR = 4;
52 const int32_t INDEX_FIVE = 5;
53 
Init(napi_env env,napi_value exports)54 napi_value CloudMediaAssetManagerNapi::Init(napi_env env, napi_value exports)
55 {
56     NapiClassInfo info = {
57         .name = CLOUD_MEDIA_ASSET_MANAGER_CLASS,
58         .ref = &constructor_,
59         .constructor = Constructor,
60         .props = {
61             DECLARE_NAPI_STATIC_FUNCTION("getCloudMediaAssetManagerInstance", JSGetCloudMediaAssetManagerInstance),
62             DECLARE_NAPI_FUNCTION("startDownloadCloudMedia", JSStartDownloadCloudMedia),
63             DECLARE_NAPI_FUNCTION("pauseDownloadCloudMedia", JSPauseDownloadCloudMedia),
64             DECLARE_NAPI_FUNCTION("cancelDownloadCloudMedia", JSCancelDownloadCloudMedia),
65             DECLARE_NAPI_FUNCTION("retainCloudMediaAsset", JSRetainCloudMediaAsset),
66             DECLARE_NAPI_FUNCTION("getCloudMediaAssetStatus", JSGetCloudMediaAssetStatus),
67         } };
68     MediaLibraryNapiUtils::NapiDefineClass(env, exports, info);
69     return exports;
70 }
71 
Constructor(napi_env env,napi_callback_info info)72 napi_value CloudMediaAssetManagerNapi::Constructor(napi_env env, napi_callback_info info)
73 {
74     if (!MediaLibraryNapiUtils::IsSystemApp()) {
75         NapiError::ThrowError(env, E_CHECK_SYSTEMAPP_FAIL,
76             "The cloud media asset manager instance can be called only by system apps");
77         return nullptr;
78     }
79     napi_value newTarget = nullptr;
80     CHECK_ARGS(env, napi_get_new_target(env, info, &newTarget), JS_INNER_FAIL);
81     CHECK_COND_RET(newTarget != nullptr, nullptr, "Failed to check new.target");
82 
83     size_t argc = ARGS_ONE;
84     napi_value argv[ARGS_ONE] = { 0 };
85     napi_value thisVar = nullptr;
86     CHECK_ARGS(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr), JS_INNER_FAIL);
87     CHECK_COND_WITH_MESSAGE(env, argc == ARGS_ONE, "Number of args is invalid");
88     if (!InitUserFileClient(env, info)) {
89         NAPI_ERR_LOG("Failed to init UserFileClient");
90         return nullptr;
91     }
92 
93     unique_ptr<CloudMediaAssetManagerNapi> obj = make_unique<CloudMediaAssetManagerNapi>();
94     CHECK_COND(env, obj != nullptr, JS_INNER_FAIL);
95     CHECK_ARGS(env,
96         napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()), CloudMediaAssetManagerNapi::Destructor, nullptr,
97             nullptr),
98         JS_INNER_FAIL);
99     obj.release();
100     return thisVar;
101 }
102 
Destructor(napi_env env,void * nativeObject,void * finalizeHint)103 void CloudMediaAssetManagerNapi::Destructor(napi_env env, void* nativeObject, void* finalizeHint)
104 {
105     auto* cloudMediaAssetManager = reinterpret_cast<CloudMediaAssetManagerNapi*>(nativeObject);
106     if (cloudMediaAssetManager == nullptr) {
107         NAPI_ERR_LOG("cloudMediaAssetManager is nullptr");
108         return;
109     }
110     delete cloudMediaAssetManager;
111     cloudMediaAssetManager = nullptr;
112 }
113 
CheckWhetherInitSuccess(napi_env env,napi_value value,bool checkIsValid)114 static bool CheckWhetherInitSuccess(napi_env env, napi_value value, bool checkIsValid)
115 {
116     napi_value propertyNames;
117     uint32_t propertyLength;
118     napi_valuetype valueType = napi_undefined;
119     NAPI_CALL_BASE(env, napi_typeof(env, value, &valueType), false);
120     if (valueType != napi_object) {
121         NAPI_ERR_LOG("valueType is not valid");
122         return false;
123     }
124 
125     NAPI_CALL_BASE(env, napi_get_property_names(env, value, &propertyNames), false);
126     NAPI_CALL_BASE(env, napi_get_array_length(env, propertyNames, &propertyLength), false);
127     if (propertyLength == 0) {
128         NAPI_ERR_LOG("propertyLength is 0");
129         return false;
130     }
131     if (checkIsValid && (!UserFileClient::IsValid())) {
132         NAPI_ERR_LOG("UserFileClient is not valid");
133         return false;
134     }
135     return true;
136 }
137 
JSGetCloudMediaAssetManagerInstance(napi_env env,napi_callback_info info)138 napi_value CloudMediaAssetManagerNapi::JSGetCloudMediaAssetManagerInstance(napi_env env, napi_callback_info info)
139 {
140     MediaLibraryTracer tracer;
141     tracer.Start("GetCloudMediaAssetManagerInstance");
142 
143     constexpr size_t ARG_CONTEXT = 1;
144     size_t argc = ARG_CONTEXT;
145     napi_value argv[ARGS_TWO] = {0};
146 
147     napi_value thisVar = nullptr;
148     napi_value ctor = nullptr;
149     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
150     NAPI_CALL(env, napi_get_reference_value(env, constructor_, &ctor));
151 
152     napi_value result = nullptr;
153     NAPI_CALL(env, napi_new_instance(env, ctor, argc, argv, &result));
154     if (!CheckWhetherInitSuccess(env, result, false)) {
155         NAPI_ERR_LOG("Init Cloud Media Asset Manager Instance is failed");
156         NAPI_CALL(env, napi_get_undefined(env, &result));
157     }
158     return result;
159 }
160 
InitUserFileClient(napi_env env,napi_callback_info info)161 bool CloudMediaAssetManagerNapi::InitUserFileClient(napi_env env, napi_callback_info info)
162 {
163     if (UserFileClient::IsValid()) {
164         return true;
165     }
166 
167     std::unique_lock<std::mutex> helperLock(MediaLibraryNapi::sUserFileClientMutex_);
168     if (!UserFileClient::IsValid()) {
169         UserFileClient::Init(env, info);
170     }
171     helperLock.unlock();
172     return UserFileClient::IsValid();
173 }
174 
ParseArgCloudMediaDownloadType(napi_env env,napi_callback_info info,unique_ptr<CloudMediaAssetAsyncContext> & context)175 static napi_status ParseArgCloudMediaDownloadType(napi_env env, napi_callback_info info,
176     unique_ptr<CloudMediaAssetAsyncContext>& context)
177 {
178     CHECK_STATUS_RET(MediaLibraryNapiUtils::AsyncContextGetArgs(env, info, context, ARGS_ONE, ARGS_ONE),
179         "Failed to get args");
180     napi_valuetype valueType = napi_undefined;
181     CHECK_STATUS_RET(napi_typeof(env, context->argv[ARGS_ZERO], &valueType), "Failed to get type");
182     CHECK_COND_RET(valueType == napi_number, napi_number_expected, "Type is not as expected number");
183     CHECK_STATUS_RET(napi_get_value_int32(env, context->argv[ARGS_ZERO], &context->cloudMediaDownloadType),
184         "Failed to get int32 value");
185     return napi_ok;
186 }
187 
ParseArgCloudMediaRetainType(napi_env env,napi_callback_info info,unique_ptr<CloudMediaAssetAsyncContext> & context)188 static napi_status ParseArgCloudMediaRetainType(napi_env env, napi_callback_info info,
189     unique_ptr<CloudMediaAssetAsyncContext>& context)
190 {
191     CHECK_STATUS_RET(MediaLibraryNapiUtils::AsyncContextGetArgs(env, info, context, ARGS_ONE, ARGS_ONE),
192         "Failed to get args");
193     napi_valuetype valueType = napi_undefined;
194     CHECK_STATUS_RET(napi_typeof(env, context->argv[ARGS_ZERO], &valueType), "Failed to get type");
195     CHECK_COND_RET(valueType == napi_number, napi_number_expected, "Type is not as expected number");
196     CHECK_STATUS_RET(napi_get_value_int32(env, context->argv[ARGS_ZERO], &context->cloudMediaRetainType),
197         "Failed to get int32 value");
198     return napi_ok;
199 }
200 
StartDownloadCloudMediaExecute(napi_env env,void * data)201 static void StartDownloadCloudMediaExecute(napi_env env, void* data)
202 {
203     MediaLibraryTracer tracer;
204     tracer.Start("StartDownloadCloudMediaExecute");
205     NAPI_INFO_LOG("enter StartDownloadCloudMediaExecute");
206 
207     auto* context = static_cast<CloudMediaAssetAsyncContext*>(data);
208     StartDownloadCloudMediaReqBody reqBody;
209     uint32_t businessCode = static_cast<uint32_t>(MediaLibraryBusinessCode::START_DOWNLOAD_CLOUDMEDIA);
210     reqBody.cloudMediaType = context->cloudMediaDownloadType;
211     NAPI_INFO_LOG("before IPC::UserDefineIPCClient().Call, retain type: %{public}d", reqBody.cloudMediaType);
212     int32_t ret = IPC::UserDefineIPCClient().Call(businessCode, reqBody);
213     NAPI_INFO_LOG("after IPC::UserDefineIPCClient().Call, retain type: %{public}d", reqBody.cloudMediaType);
214     if (ret < 0) {
215         context->SaveError(ret);
216         NAPI_ERR_LOG("Start download cloud media failed, err: %{public}d", ret);
217     }
218 }
219 
StartDownloadCloudMediaCompleteCallback(napi_env env,napi_status status,void * data)220 static void StartDownloadCloudMediaCompleteCallback(napi_env env, napi_status status, void* data)
221 {
222     auto* context = static_cast<CloudMediaAssetAsyncContext*>(data);
223     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
224     auto jsContext = make_unique<JSAsyncContextOutput>();
225     jsContext->status = false;
226     napi_get_undefined(env, &jsContext->data);
227     napi_get_undefined(env, &jsContext->error);
228     if (context->error == ERR_DEFAULT) {
229         jsContext->status = true;
230     } else {
231         context->HandleError(env, jsContext->error);
232     }
233 
234     if (context->work != nullptr) {
235         MediaLibraryNapiUtils::InvokeJSAsyncMethod(
236             env, context->deferred, context->callbackRef, context->work, *jsContext);
237     }
238     delete context;
239 }
240 
JSStartDownloadCloudMedia(napi_env env,napi_callback_info info)241 napi_value CloudMediaAssetManagerNapi::JSStartDownloadCloudMedia(napi_env env, napi_callback_info info)
242 {
243     if (!MediaLibraryNapiUtils::IsSystemApp()) {
244         NapiError::ThrowError(env, E_CHECK_SYSTEMAPP_FAIL, "This interface can be called only by system apps");
245         return nullptr;
246     }
247     MediaLibraryTracer tracer;
248     tracer.Start("JSStartDownloadCloudMedia");
249 
250     auto asyncContext = make_unique<CloudMediaAssetAsyncContext>();
251     CHECK_COND_WITH_MESSAGE(env, ParseArgCloudMediaDownloadType(env, info, asyncContext) == napi_ok,
252         "Failed to parse args");
253     return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "StartDownloadCloudMedia",
254         StartDownloadCloudMediaExecute, StartDownloadCloudMediaCompleteCallback);
255 }
256 
PauseDownloadCloudMediaExecute(napi_env env,void * data)257 static void PauseDownloadCloudMediaExecute(napi_env env, void* data)
258 {
259     MediaLibraryTracer tracer;
260     tracer.Start("PauseDownloadCloudMediaExecute");
261     NAPI_INFO_LOG("enter PauseDownloadCloudMediaExecute");
262 
263     auto* context = static_cast<CloudMediaAssetAsyncContext*>(data);
264     uint32_t businessCode = static_cast<uint32_t>(MediaLibraryBusinessCode::PAUSE_DOWNLOAD_CLOUDMEDIA);
265     NAPI_INFO_LOG("before IPC::UserDefineIPCClient().Call");
266     int32_t ret = IPC::UserDefineIPCClient().Call(businessCode);
267     NAPI_INFO_LOG("after IPC::UserDefineIPCClient().Call");
268     if (ret < 0) {
269         context->SaveError(ret);
270         NAPI_ERR_LOG("Pause download cloud media failed, err: %{public}d", ret);
271     }
272 }
273 
PauseDownloadCloudMediaCompleteCallback(napi_env env,napi_status status,void * data)274 static void PauseDownloadCloudMediaCompleteCallback(napi_env env, napi_status status, void* data)
275 {
276     auto* context = static_cast<CloudMediaAssetAsyncContext*>(data);
277     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
278     auto jsContext = make_unique<JSAsyncContextOutput>();
279     jsContext->status = false;
280     napi_get_undefined(env, &jsContext->data);
281     napi_get_undefined(env, &jsContext->error);
282     if (context->error == ERR_DEFAULT) {
283         jsContext->status = true;
284     } else {
285         context->HandleError(env, jsContext->error);
286     }
287 
288     if (context->work != nullptr) {
289         MediaLibraryNapiUtils::InvokeJSAsyncMethod(
290             env, context->deferred, context->callbackRef, context->work, *jsContext);
291     }
292     delete context;
293 }
294 
JSPauseDownloadCloudMedia(napi_env env,napi_callback_info info)295 napi_value CloudMediaAssetManagerNapi::JSPauseDownloadCloudMedia(napi_env env, napi_callback_info info)
296 {
297     if (!MediaLibraryNapiUtils::IsSystemApp()) {
298         NapiError::ThrowError(env, E_CHECK_SYSTEMAPP_FAIL, "This interface can be called only by system apps");
299         return nullptr;
300     }
301     MediaLibraryTracer tracer;
302     tracer.Start("JSPauseDownloadCloudMedia");
303 
304     auto asyncContext = make_unique<CloudMediaAssetAsyncContext>();
305     return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "PauseDownloadCloudMedia",
306         PauseDownloadCloudMediaExecute, PauseDownloadCloudMediaCompleteCallback);
307 }
308 
CancelDownloadCloudMediaExecute(napi_env env,void * data)309 static void CancelDownloadCloudMediaExecute(napi_env env, void* data)
310 {
311     MediaLibraryTracer tracer;
312     tracer.Start("CancelDownloadCloudMediaExecute");
313     NAPI_INFO_LOG("enter CancelDownloadCloudMediaExecute");
314 
315     auto* context = static_cast<CloudMediaAssetAsyncContext*>(data);
316     uint32_t businessCode = static_cast<uint32_t>(MediaLibraryBusinessCode::CANCEL_DOWNLOAD_CLOUDMEDIA);
317     NAPI_INFO_LOG("before IPC::UserDefineIPCClient().Call");
318     int32_t ret = IPC::UserDefineIPCClient().Call(businessCode);
319     NAPI_INFO_LOG("after IPC::UserDefineIPCClient().Call");
320     if (ret < 0) {
321         context->SaveError(ret);
322         NAPI_ERR_LOG("Cancel download cloud media failed, err: %{public}d", ret);
323     }
324 }
325 
CancelDownloadCloudMediaCompleteCallback(napi_env env,napi_status status,void * data)326 static void CancelDownloadCloudMediaCompleteCallback(napi_env env, napi_status status, void* data)
327 {
328     auto* context = static_cast<CloudMediaAssetAsyncContext*>(data);
329     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
330     auto jsContext = make_unique<JSAsyncContextOutput>();
331     jsContext->status = false;
332     napi_get_undefined(env, &jsContext->data);
333     napi_get_undefined(env, &jsContext->error);
334     if (context->error == ERR_DEFAULT) {
335         jsContext->status = true;
336     } else {
337         context->HandleError(env, jsContext->error);
338     }
339 
340     if (context->work != nullptr) {
341         MediaLibraryNapiUtils::InvokeJSAsyncMethod(
342             env, context->deferred, context->callbackRef, context->work, *jsContext);
343     }
344     delete context;
345 }
346 
JSCancelDownloadCloudMedia(napi_env env,napi_callback_info info)347 napi_value CloudMediaAssetManagerNapi::JSCancelDownloadCloudMedia(napi_env env, napi_callback_info info)
348 {
349     if (!MediaLibraryNapiUtils::IsSystemApp()) {
350         NapiError::ThrowError(env, E_CHECK_SYSTEMAPP_FAIL, "This interface can be called only by system apps");
351         return nullptr;
352     }
353     MediaLibraryTracer tracer;
354     tracer.Start("JSCancelDownloadCloudMedia");
355 
356     auto asyncContext = make_unique<CloudMediaAssetAsyncContext>();
357     return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "CancelDownloadCloudMedia",
358         CancelDownloadCloudMediaExecute, CancelDownloadCloudMediaCompleteCallback);
359 }
360 
RetainCloudMediaAssetExecute(napi_env env,void * data)361 static void RetainCloudMediaAssetExecute(napi_env env, void* data)
362 {
363     MediaLibraryTracer tracer;
364     tracer.Start("RetainCloudMediaAssetExecute");
365     NAPI_INFO_LOG("enter RetainCloudMediaAssetExecute");
366 
367     auto* context = static_cast<CloudMediaAssetAsyncContext*>(data);
368     RetainCloudMediaAssetReqBody reqBody;
369     uint32_t businessCode = static_cast<uint32_t>(MediaLibraryBusinessCode::RETAIN_CLOUDMEDIA_ASSET);
370     reqBody.cloudMediaRetainType = context->cloudMediaRetainType;
371     NAPI_INFO_LOG("before IPC::UserDefineIPCClient().Call");
372     int32_t ret = IPC::UserDefineIPCClient().Call(businessCode, reqBody);
373     NAPI_INFO_LOG("after IPC::UserDefineIPCClient().Call");
374     if (ret < 0) {
375         context->SaveError(ret);
376         NAPI_ERR_LOG("Retain cloud media asset failed, err: %{public}d", ret);
377     }
378 }
379 
RetainCloudMediaAssetCompleteCallback(napi_env env,napi_status status,void * data)380 static void RetainCloudMediaAssetCompleteCallback(napi_env env, napi_status status, void* data)
381 {
382     auto* context = static_cast<CloudMediaAssetAsyncContext*>(data);
383     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
384     auto jsContext = make_unique<JSAsyncContextOutput>();
385     jsContext->status = false;
386     napi_get_undefined(env, &jsContext->data);
387     napi_get_undefined(env, &jsContext->error);
388     if (context->error == ERR_DEFAULT) {
389         jsContext->status = true;
390     } else {
391         context->HandleError(env, jsContext->error);
392     }
393 
394     if (context->work != nullptr) {
395         MediaLibraryNapiUtils::InvokeJSAsyncMethod(
396             env, context->deferred, context->callbackRef, context->work, *jsContext);
397     }
398     delete context;
399 }
400 
JSRetainCloudMediaAsset(napi_env env,napi_callback_info info)401 napi_value CloudMediaAssetManagerNapi::JSRetainCloudMediaAsset(napi_env env, napi_callback_info info)
402 {
403     if (!MediaLibraryNapiUtils::IsSystemApp()) {
404         NapiError::ThrowError(env, E_CHECK_SYSTEMAPP_FAIL, "This interface can be called only by system apps");
405         return nullptr;
406     }
407     MediaLibraryTracer tracer;
408     tracer.Start("JSRetainCloudMediaAsset");
409 
410     auto asyncContext = make_unique<CloudMediaAssetAsyncContext>();
411     CHECK_COND_WITH_MESSAGE(env, ParseArgCloudMediaRetainType(env, info, asyncContext) == napi_ok,
412         "Failed to parse args");
413     return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "RetainCloudMediaAsset",
414         RetainCloudMediaAssetExecute, RetainCloudMediaAssetCompleteCallback);
415 }
416 
CanConvertToInt32(const std::string & str)417 static bool CanConvertToInt32(const std::string &str)
418 {
419     std::istringstream stringStream(str);
420     int32_t num = 0;
421     stringStream >> num;
422     return stringStream.eof() && !stringStream.fail();
423 }
424 
SplitUriString(const std::string & str,std::vector<std::string> & type)425 static bool SplitUriString(const std::string& str, std::vector<std::string> &type)
426 {
427     std::stringstream ss(str);
428     std::string item;
429     while (std::getline(ss, item, ',')) {
430         if (item.empty()) {
431             return false;
432         }
433         type.emplace_back(item);
434     }
435     return type.size() == TYPE_SIZE;
436 }
437 
GetCloudMediaAssetStatusExecute(napi_env env,void * data)438 static void GetCloudMediaAssetStatusExecute(napi_env env, void* data)
439 {
440     MediaLibraryTracer tracer;
441     tracer.Start("GetCloudMediaAssetStatusExecute");
442     NAPI_INFO_LOG("enter GetCloudMediaAssetStatusExecute");
443 
444     auto* context = static_cast<CloudMediaAssetAsyncContext*>(data);
445     GetCloudMediaAssetStatusReqBody reqBody;
446     GetCloudMediaAssetStatusReqBody respBody;
447     uint32_t businessCode = static_cast<uint32_t>(MediaLibraryBusinessCode::QUERY_GET_CLOUDMEDIA_ASSET_STATUS);
448     int32_t ret = IPC::UserDefineIPCClient().Call(businessCode, reqBody, respBody);
449     if (ret != 0) {
450         context->SaveError(ret);
451         NAPI_ERR_LOG("Get cloud media asset status failed, err: %{public}d", ret);
452         return;
453     }
454 
455     NAPI_INFO_LOG("Get cloud media asset, res: %{public}s.", respBody.status.c_str());
456     std::vector<std::string> type;
457     if (!SplitUriString(respBody.status, type)) {
458         NAPI_ERR_LOG("GetType failed");
459         return;
460     }
461     if (!CanConvertToInt32(type[INDEX_ZERO]) || !CanConvertToInt32(type[INDEX_FIVE])) {
462         NAPI_ERR_LOG("GetType failed");
463         return;
464     }
465     context->cloudMediaAssetTaskStatus_ = static_cast<CloudMediaAssetTaskStatus>(std::stoi(type[INDEX_ZERO]));
466     context->cloudMediaTaskPauseCause_ = static_cast<CloudMediaTaskPauseCause>(std::stoi(type[INDEX_FIVE]));
467     std::string taskInfo = "totalcount: " + type[INDEX_ONE] + "," +
468                            "totalSize: " + type[INDEX_TWO] + "," +
469                            "remainCount: " + type[INDEX_THREE] + "," +
470                            "remainSize: " + type[INDEX_FOUR];
471     context->taskInfo_ = taskInfo;
472 }
473 
GetCloudMediaAssetStatusCompleteCallback(napi_env env,napi_status status,void * data)474 static void GetCloudMediaAssetStatusCompleteCallback(napi_env env, napi_status status, void* data)
475 {
476     auto* context = static_cast<CloudMediaAssetAsyncContext*>(data);
477     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
478     auto jsContext = make_unique<JSAsyncContextOutput>();
479     jsContext->status = false;
480     napi_get_undefined(env, &jsContext->data);
481     napi_get_undefined(env, &jsContext->error);
482     if (context->error == ERR_DEFAULT) {
483         napi_value cloudMediaAssetStatus = CloudMediaAssetStatusNapi::NewCloudMediaAssetStatusNapi(env, context);
484         jsContext->data = cloudMediaAssetStatus;
485         jsContext->status = true;
486     } else {
487         context->HandleError(env, jsContext->error);
488     }
489 
490     if (context->work != nullptr) {
491         MediaLibraryNapiUtils::InvokeJSAsyncMethod(
492             env, context->deferred, context->callbackRef, context->work, *jsContext);
493     }
494     delete context;
495 }
496 
JSGetCloudMediaAssetStatus(napi_env env,napi_callback_info info)497 napi_value CloudMediaAssetManagerNapi::JSGetCloudMediaAssetStatus(napi_env env, napi_callback_info info)
498 {
499     if (!MediaLibraryNapiUtils::IsSystemApp()) {
500         NapiError::ThrowError(env, E_CHECK_SYSTEMAPP_FAIL, "This interface can be called only by system apps");
501         return nullptr;
502     }
503     MediaLibraryTracer tracer;
504     tracer.Start("JSGetCloudMediaAssetStatus");
505 
506     auto asyncContext = make_unique<CloudMediaAssetAsyncContext>();
507     return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "GetCloudMediaAssetStatus",
508         GetCloudMediaAssetStatusExecute, GetCloudMediaAssetStatusCompleteCallback);
509 }
510 } // namespace OHOS::Media