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