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 "CloudEnhancementNapi"
17
18 #include "cloud_enhancement_napi.h"
19
20 #include <unordered_set>
21
22 #include "media_column.h"
23 #include "medialibrary_client_errno.h"
24 #include "medialibrary_errno.h"
25 #include "medialibrary_napi_log.h"
26 #include "medialibrary_tracer.h"
27 #include "userfile_client.h"
28 #include "userfile_manager_types.h"
29 #include "media_library_napi.h"
30 #include "media_file_uri.h"
31 #include "media_file_utils.h"
32 #include "result_set_utils.h"
33 #include "cloud_enhancement_task_state_napi.h"
34 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
35 #include "media_enhance_constants_c_api.h"
36 #include "media_enhance_handles.h"
37 #include "media_enhance_client_c_api.h"
38 #include "media_enhance_bundle_c_api.h"
39 #endif
40 #include "cloud_enhancement_uri.h"
41 #include "cloud_enhancement_vo.h"
42 #include "medialibrary_business_code.h"
43 #include "user_define_ipc_client.h"
44 #include "get_cloud_enhancement_pair_vo.h"
45 #include "query_cloud_enhancement_task_state_vo.h"
46
47 using namespace std;
48 using namespace OHOS::DataShare;
49 using namespace OHOS::NativeRdb;
50 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
51 using namespace OHOS::MediaEnhance;
52 #endif
53
54 namespace OHOS::Media {
55 static const string CLOUD_ENHANCEMENT_CLASS = "CloudEnhancement";
56 thread_local napi_ref CloudEnhancementNapi::constructor_ = nullptr;
57 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
58 static void* dynamicHandler = nullptr;
59 static MediaEnhanceClientHandle* clientWrapper = nullptr;
60 static mutex mtx;
61
62 using CreateMCEClient = MediaEnhanceClientHandle* (*)(MediaEnhance_TASK_TYPE taskType);
63 using DestroyMCEClient = void (*)(MediaEnhanceClientHandle* client);
64 using CreateMCEBundle = MediaEnhanceBundleHandle* (*)();
65 using DestroyMCEBundle = void (*)(MediaEnhanceBundleHandle* bundle);
66 using ClientLoadSA = int32_t (*)(MediaEnhanceClientHandle* client);
67 using ClientIsConnected = bool (*)(MediaEnhanceClientHandle* client);
68 using ClientQueryTaskState = MediaEnhanceBundleHandle* (*)(MediaEnhanceClientHandle* client, const char* taskId,
69 uint32_t taskIdLen);
70 using BundleHandleGetInt = int32_t (*)(MediaEnhanceBundleHandle* bundle, const char* key, uint32_t keyLen);
71
72
73 static CreateMCEClient createMCEClientFunc = nullptr;
74 static DestroyMCEClient destroyMCEClientFunc = nullptr;
75 static CreateMCEBundle createMCEBundleFunc = nullptr;
76 static DestroyMCEBundle destroyMCEBundleFunc = nullptr;
77 static ClientLoadSA clientLoadSaFunc = nullptr;
78 static ClientIsConnected clientIsConnectedFunc = nullptr;
79 static ClientQueryTaskState clientQueryTaskStateFunc = nullptr;
80 static BundleHandleGetInt bundleHandleGetIntFunc = nullptr;
81
InitCloudEnhancementBasicFunc(void * dynamicHandler)82 static void InitCloudEnhancementBasicFunc(void* dynamicHandler)
83 {
84 if (dynamicHandler == nullptr) {
85 NAPI_ERR_LOG("dynamicHandler is null. error:%{public}s", dlerror());
86 return;
87 }
88
89 if (createMCEClientFunc == nullptr) {
90 createMCEClientFunc = (CreateMCEClient)dlsym(dynamicHandler, "CreateMediaEnhanceClient");
91 }
92 if (createMCEClientFunc == nullptr) {
93 NAPI_ERR_LOG("CreateMediaEnhanceClient dlsym failed.error:%{public}s", dlerror());
94 return;
95 }
96
97 if (destroyMCEClientFunc == nullptr) {
98 destroyMCEClientFunc = (DestroyMCEClient)dlsym(dynamicHandler, "DestroyMediaEnhanceClient");
99 }
100 if (destroyMCEClientFunc == nullptr) {
101 NAPI_ERR_LOG("DestroyMediaEnhanceClient dlsym failed.error:%{public}s", dlerror());
102 return;
103 }
104
105 if (createMCEBundleFunc == nullptr) {
106 createMCEBundleFunc = (CreateMCEBundle)dlsym(dynamicHandler, "CreateMediaEnhanceBundle");
107 }
108 if (createMCEBundleFunc == nullptr) {
109 NAPI_ERR_LOG("CreateMediaEnhanceBundle dlsym failed.error:%{public}s", dlerror());
110 return;
111 }
112
113 if (destroyMCEBundleFunc == nullptr) {
114 destroyMCEBundleFunc = (DestroyMCEBundle)dlsym(dynamicHandler, "DestroyMediaEnhanceBundle");
115 }
116 if (destroyMCEBundleFunc == nullptr) {
117 NAPI_ERR_LOG("DestroyMediaEnhanceBundle dlsym failed.error:%{public}s", dlerror());
118 return;
119 }
120 }
121
InitCloudEnhancementExtraFunc(void * dynamicHandler)122 static void InitCloudEnhancementExtraFunc(void* dynamicHandler)
123 {
124 if (dynamicHandler == nullptr) {
125 NAPI_ERR_LOG("dynamicHandler is null. error:%{public}s", dlerror());
126 return;
127 }
128
129 if (clientLoadSaFunc == nullptr) {
130 clientLoadSaFunc = (ClientLoadSA)dlsym(dynamicHandler, "MediaEnhanceClient_LoadSA");
131 }
132 if (clientLoadSaFunc == nullptr) {
133 NAPI_ERR_LOG("MediaEnhanceClient_LoadSA dlsym failed.error:%{public}s", dlerror());
134 return;
135 }
136
137 if (clientIsConnectedFunc == nullptr) {
138 clientIsConnectedFunc = (ClientIsConnected)dlsym(dynamicHandler, "MediaEnhanceClient_IsConnected");
139 }
140 if (clientIsConnectedFunc == nullptr) {
141 NAPI_ERR_LOG("MediaEnhanceClient_IsConnected dlsym failed.error:%{public}s", dlerror());
142 return;
143 }
144
145 if (clientQueryTaskStateFunc == nullptr) {
146 clientQueryTaskStateFunc = (ClientQueryTaskState)dlsym(dynamicHandler, "MediaEnhanceClient_QueryTaskState");
147 }
148 if (clientQueryTaskStateFunc == nullptr) {
149 NAPI_ERR_LOG("MediaEnhanceClient_QueryTaskState dlsym failed. error:%{public}s", dlerror());
150 return;
151 }
152
153 if (bundleHandleGetIntFunc == nullptr) {
154 bundleHandleGetIntFunc = (BundleHandleGetInt)dlsym(dynamicHandler, "MediaEnhanceBundle_GetInt");
155 }
156 if (bundleHandleGetIntFunc == nullptr) {
157 NAPI_ERR_LOG("MediaEnhanceBundle_GetInt dlsym failed. error:%{public}s", dlerror());
158 return;
159 }
160 }
161
InitEnhancementClient()162 static void InitEnhancementClient()
163 {
164 if (createMCEClientFunc == nullptr) {
165 createMCEClientFunc = (CreateMCEClient)dlsym(dynamicHandler, "CreateMediaEnhanceClient");
166 }
167 if (createMCEClientFunc == nullptr) {
168 NAPI_ERR_LOG("CreateMediaEnhanceClient dlsym failed.error:%{public}s", dlerror());
169 return;
170 }
171 if (clientWrapper == nullptr && createMCEClientFunc != nullptr) {
172 NAPI_INFO_LOG("createMCEClientFunc by dlopen func.");
173 clientWrapper = createMCEClientFunc(MediaEnhance_TASK_TYPE::TYPE_CAMERA);
174 }
175 }
176
DestroyEnhancementClient()177 static void DestroyEnhancementClient()
178 {
179 if (destroyMCEClientFunc == nullptr) {
180 destroyMCEClientFunc = (DestroyMCEClient)dlsym(dynamicHandler, "DestroyMediaEnhanceClient");
181 }
182 if (destroyMCEClientFunc == nullptr) {
183 NAPI_ERR_LOG("DestroyMediaEnhanceClient dlsym failed.error:%{public}s", dlerror());
184 return;
185 }
186 destroyMCEClientFunc(clientWrapper);
187 clientWrapper = nullptr;
188 }
189
CreateBundle()190 static MediaEnhanceBundleHandle* CreateBundle()
191 {
192 if (createMCEBundleFunc == nullptr) {
193 createMCEBundleFunc = (CreateMCEBundle)dlsym(dynamicHandler, "CreateMediaEnhanceBundle");
194 }
195 if (createMCEBundleFunc == nullptr) {
196 NAPI_ERR_LOG("createMCEBundleFunc dlsym failed.error:%{public}s", dlerror());
197 return nullptr;
198 }
199 return createMCEBundleFunc();
200 }
201
DestroyBundle(MediaEnhanceBundleHandle * bundle)202 static void DestroyBundle(MediaEnhanceBundleHandle* bundle)
203 {
204 if (destroyMCEBundleFunc == nullptr) {
205 destroyMCEBundleFunc = (DestroyMCEBundle)dlsym(dynamicHandler,
206 "DestroyMediaEnhanceBundle");
207 }
208 if (destroyMCEBundleFunc == nullptr) {
209 NAPI_ERR_LOG("destroyMCEBundleFunc dlsym failed.error:%{public}s", dlerror());
210 return;
211 }
212 destroyMCEBundleFunc(bundle);
213 }
214
LoadSA()215 static int32_t LoadSA()
216 {
217 if (clientWrapper == nullptr) {
218 NAPI_ERR_LOG("clientWrapper is nullptr!");
219 return E_ERR;
220 }
221 if (clientLoadSaFunc == nullptr) {
222 clientLoadSaFunc = (ClientLoadSA)dlsym(dynamicHandler, "MediaEnhanceClient_LoadSA");
223 }
224 if (clientLoadSaFunc == nullptr) {
225 NAPI_ERR_LOG("MediaEnhanceClient_LoadSA dlsym failed.error:%{public}s", dlerror());
226 return E_ERR;
227 }
228 int32_t ret = clientLoadSaFunc(clientWrapper);
229 if (ret != E_OK) {
230 NAPI_ERR_LOG("Enhancement Service LoadSA failed:%{public}d", ret);
231 }
232 return ret;
233 }
234
IsConnected(MediaEnhanceClientHandle * clientWrapper)235 static bool IsConnected(MediaEnhanceClientHandle* clientWrapper)
236 {
237 if (clientWrapper == nullptr) {
238 NAPI_ERR_LOG("clientWrapper is nullptr!");
239 return E_ERR;
240 }
241 if (clientIsConnectedFunc == nullptr) {
242 clientIsConnectedFunc = (ClientIsConnected)dlsym(dynamicHandler,
243 "MediaEnhanceClient_IsConnected");
244 }
245 if (clientIsConnectedFunc == nullptr) {
246 NAPI_ERR_LOG("MediaEnhanceClient_IsConnected dlsym failed.error:%{public}s", dlerror());
247 return false;
248 }
249 return clientIsConnectedFunc(clientWrapper);
250 }
251
QueryTaskState(const string & photoId)252 static MediaEnhanceBundleHandle* QueryTaskState(const string &photoId)
253 {
254 if (clientWrapper == nullptr) {
255 NAPI_ERR_LOG("clientWrapper is nullptr!");
256 return nullptr;
257 }
258 if (clientQueryTaskStateFunc == nullptr) {
259 clientQueryTaskStateFunc = (ClientQueryTaskState)dlsym(dynamicHandler, "MediaEnhanceClient_QueryTaskState");
260 }
261 if (clientQueryTaskStateFunc == nullptr) {
262 NAPI_ERR_LOG("MediaEnhanceClient_QueryTaskState dlsym failed. error:%{public}s", dlerror());
263 return nullptr;
264 }
265 NAPI_INFO_LOG("QueryTaskState photoId: %{public}s", photoId.c_str());
266 return clientQueryTaskStateFunc(clientWrapper, photoId.c_str(), strlen(photoId.c_str()));
267 }
268
GetInt(MediaEnhanceBundleHandle * bundle,const char * key)269 static int32_t GetInt(MediaEnhanceBundleHandle* bundle, const char* key)
270 {
271 if (bundleHandleGetIntFunc == nullptr) {
272 bundleHandleGetIntFunc = (BundleHandleGetInt)dlsym(dynamicHandler, "MediaEnhanceBundle_GetInt");
273 }
274 if (bundleHandleGetIntFunc == nullptr) {
275 NAPI_ERR_LOG("MediaEnhanceBundle_GetInt dlsym failed. error:%{public}s", dlerror());
276 return E_ERR;
277 }
278 return bundleHandleGetIntFunc(bundle, key, strlen(key));
279 }
280
InitCloudEnhancementFunc()281 static void InitCloudEnhancementFunc()
282 {
283 string path = "/system/lib64/platformsdk/libmedia_cloud_enhance_plugin.z.so";
284 dynamicHandler = dlopen(path.c_str(), RTLD_NOW);
285 InitCloudEnhancementBasicFunc(dynamicHandler);
286 InitCloudEnhancementExtraFunc(dynamicHandler);
287 }
288 #endif
289
Init(napi_env env,napi_value exports)290 napi_value CloudEnhancementNapi::Init(napi_env env, napi_value exports)
291 {
292 NapiClassInfo info = { .name = CLOUD_ENHANCEMENT_CLASS,
293 .ref = &constructor_,
294 .constructor = Constructor,
295 .props = {
296 DECLARE_NAPI_STATIC_FUNCTION("getCloudEnhancementInstance", JSGetCloudEnhancementInstance),
297 DECLARE_NAPI_FUNCTION("submitCloudEnhancementTasks", JSSubmitCloudEnhancementTasks),
298 DECLARE_NAPI_FUNCTION("prioritizeCloudEnhancementTask", JSPrioritizeCloudEnhancementTask),
299 DECLARE_NAPI_FUNCTION("cancelCloudEnhancementTasks", JSCancelCloudEnhancementTasks),
300 DECLARE_NAPI_FUNCTION("cancelAllCloudEnhancementTasks", JSCancelAllCloudEnhancementTasks),
301 DECLARE_NAPI_FUNCTION("queryCloudEnhancementTaskState", JSQueryCloudEnhancementTaskState),
302 DECLARE_NAPI_FUNCTION("syncCloudEnhancementTaskStatus", JSSyncCloudEnhancementTaskStatus),
303 DECLARE_NAPI_FUNCTION("getCloudEnhancementPair", JSGetCloudEnhancementPair),
304 } };
305 MediaLibraryNapiUtils::NapiDefineClass(env, exports, info);
306 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
307 InitCloudEnhancementFunc();
308 #endif
309 return exports;
310 }
311
Constructor(napi_env env,napi_callback_info info)312 napi_value CloudEnhancementNapi::Constructor(napi_env env, napi_callback_info info)
313 {
314 if (!MediaLibraryNapiUtils::IsSystemApp()) {
315 NapiError::ThrowError(env, E_CHECK_SYSTEMAPP_FAIL,
316 "The cloud enhancement instance can be called only by system apps");
317 return nullptr;
318 }
319 napi_value newTarget = nullptr;
320 CHECK_ARGS(env, napi_get_new_target(env, info, &newTarget), JS_INNER_FAIL);
321 CHECK_COND_RET(newTarget != nullptr, nullptr, "Failed to check new.target");
322
323 size_t argc = ARGS_ONE;
324 napi_value argv[ARGS_ONE] = { 0 };
325 napi_value thisVar = nullptr;
326 CHECK_ARGS(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr), JS_INNER_FAIL);
327 CHECK_COND_WITH_MESSAGE(env, argc == ARGS_ONE, "Number of args is invalid");
328
329 unique_ptr<CloudEnhancementNapi> obj = make_unique<CloudEnhancementNapi>();
330 CHECK_COND(env, obj != nullptr, JS_INNER_FAIL);
331 CHECK_ARGS(env,
332 napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()), CloudEnhancementNapi::Destructor, nullptr,
333 nullptr),
334 JS_INNER_FAIL);
335 obj.release();
336 return thisVar;
337 }
338
Destructor(napi_env env,void * nativeObject,void * finalizeHint)339 void CloudEnhancementNapi::Destructor(napi_env env, void* nativeObject, void* finalizeHint)
340 {
341 auto* cloudEnhancement = reinterpret_cast<CloudEnhancementNapi*>(nativeObject);
342 if (cloudEnhancement == nullptr) {
343 return;
344 }
345 delete cloudEnhancement;
346 cloudEnhancement = nullptr;
347 }
348
CheckWhetherInitSuccess(napi_env env,napi_value value,bool checkIsValid)349 static bool CheckWhetherInitSuccess(napi_env env, napi_value value, bool checkIsValid)
350 {
351 napi_value propertyNames;
352 uint32_t propertyLength;
353 napi_valuetype valueType = napi_undefined;
354 NAPI_CALL_BASE(env, napi_typeof(env, value, &valueType), false);
355 if (valueType != napi_object) {
356 return false;
357 }
358
359 NAPI_CALL_BASE(env, napi_get_property_names(env, value, &propertyNames), false);
360 NAPI_CALL_BASE(env, napi_get_array_length(env, propertyNames, &propertyLength), false);
361 if (propertyLength == 0) {
362 return false;
363 }
364 if (checkIsValid && (!UserFileClient::IsValid())) {
365 NAPI_ERR_LOG("UserFileClient is not valid");
366 return false;
367 }
368 return true;
369 }
370
JSGetCloudEnhancementInstance(napi_env env,napi_callback_info info)371 napi_value CloudEnhancementNapi::JSGetCloudEnhancementInstance(napi_env env, napi_callback_info info)
372 {
373 MediaLibraryTracer tracer;
374 tracer.Start("GetCloudEnhancementInstance");
375
376 constexpr size_t ARG_CONTEXT = 1;
377 size_t argc = ARG_CONTEXT;
378 napi_value argv[ARGS_TWO] = {0};
379
380 napi_value thisVar = nullptr;
381 napi_value ctor = nullptr;
382 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
383 NAPI_CALL(env, napi_get_reference_value(env, constructor_, &ctor));
384
385 napi_value result = nullptr;
386 NAPI_CALL(env, napi_new_instance(env, ctor, argc, argv, &result));
387 if (!CheckWhetherInitSuccess(env, result, false)) {
388 NAPI_ERR_LOG("Init Cloud Enhancement Instance is failed");
389 NAPI_CALL(env, napi_get_undefined(env, &result));
390 }
391 return result;
392 }
393
InitUserFileClient(napi_env env,napi_callback_info info)394 bool CloudEnhancementNapi::InitUserFileClient(napi_env env, napi_callback_info info)
395 {
396 if (UserFileClient::IsValid()) {
397 return true;
398 }
399
400 std::unique_lock<std::mutex> helperLock(MediaLibraryNapi::sUserFileClientMutex_);
401 if (!UserFileClient::IsValid()) {
402 UserFileClient::Init(env, info);
403 }
404 helperLock.unlock();
405 return UserFileClient::IsValid();
406 }
407
ParseArgGetPhotoAsset(napi_env env,napi_value arg,int & fileId,std::string & uri,std::string & displayName)408 napi_status CloudEnhancementNapi::ParseArgGetPhotoAsset(napi_env env, napi_value arg, int &fileId, std::string &uri,
409 std::string &displayName)
410 {
411 if (arg == nullptr) {
412 NapiError::ThrowError(env, OHOS_INVALID_PARAM_CODE, "ParseArgGetPhotoAsset failed to get photoAsset");
413 return napi_invalid_arg;
414 }
415 FileAssetNapi *obj = nullptr;
416 napi_unwrap(env, arg, reinterpret_cast<void**>(&obj));
417 if (obj == nullptr) {
418 NapiError::ThrowError(env, OHOS_INVALID_PARAM_CODE, "failed to get asset napi object");
419 return napi_invalid_arg;
420 }
421 fileId = obj->GetFileId();
422 uri = obj->GetFileUri();
423 displayName = obj->GetFileDisplayName();
424 return napi_ok;
425 }
426
ParseArgsSubmitCloudEnhancementTasks(napi_env env,napi_callback_info info,unique_ptr<CloudEnhancementAsyncContext> & context)427 static napi_value ParseArgsSubmitCloudEnhancementTasks(napi_env env, napi_callback_info info,
428 unique_ptr<CloudEnhancementAsyncContext>& context)
429 {
430 CHECK_COND_WITH_MESSAGE(env,
431 MediaLibraryNapiUtils::AsyncContextGetArgs(env, info, context, ARGS_TWO, ARGS_THREE) == napi_ok,
432 "Failed to get args");
433 CHECK_COND(env, CloudEnhancementNapi::InitUserFileClient(env, info), JS_INNER_FAIL);
434
435 napi_valuetype valueType = napi_undefined;
436 CHECK_ARGS(env, napi_typeof(env, context->argv[PARAM1], &valueType), JS_INNER_FAIL);
437 CHECK_COND(env, valueType == napi_boolean, JS_INNER_FAIL);
438
439 bool hasCloudWatermark = false;
440 if (napi_get_value_bool(env, context->argv[PARAM1], &hasCloudWatermark) != napi_ok) {
441 NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID);
442 return nullptr;
443 }
444
445 int32_t triggerMode = 0;
446 if (context->argc == ARGS_THREE) {
447 CHECK_ARGS(env, napi_typeof(env, context->argv[PARAM2], &valueType), JS_INNER_FAIL);
448 CHECK_COND(env, valueType == napi_number, JS_INNER_FAIL);
449 if (napi_get_value_int32(env, context->argv[PARAM2], &triggerMode) != napi_ok) {
450 NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID);
451 return nullptr;
452 }
453 }
454
455 vector<string> uris;
456 vector<napi_value> napiValues;
457 CHECK_NULLPTR_RET(MediaLibraryNapiUtils::GetNapiValueArray(env, context->argv[PARAM0], napiValues));
458 CHECK_COND_WITH_MESSAGE(env, !napiValues.empty(), "array is empty");
459 CHECK_ARGS(env, napi_typeof(env, napiValues.front(), &valueType), JS_INNER_FAIL);
460 if (valueType == napi_object) { // array of asset object
461 CHECK_NULLPTR_RET(MediaLibraryNapiUtils::GetUriArrayFromAssets(env, napiValues, uris));
462 } else {
463 NapiError::ThrowError(env, OHOS_INVALID_PARAM_CODE, "Invalid type");
464 return nullptr;
465 }
466
467 CHECK_COND_WITH_MESSAGE(env, !uris.empty(), "Failed to check empty array");
468 for (const auto& uri : uris) {
469 CHECK_COND(env, uri.find(PhotoColumn::PHOTO_URI_PREFIX) != string::npos, JS_E_URI);
470 }
471
472 context->hasCloudWatermark_ = hasCloudWatermark;
473 context->triggerMode_ = triggerMode;
474 context->predicates.In(PhotoColumn::MEDIA_ID, uris);
475 context->uris.assign(uris.begin(), uris.end());
476 RETURN_NAPI_TRUE(env);
477 }
478
SubmitCloudEnhancementTasksExecute(napi_env env,void * data)479 static void SubmitCloudEnhancementTasksExecute(napi_env env, void* data)
480 {
481 MediaLibraryTracer tracer;
482 tracer.Start("SubmitCloudEnhancementTasksExecute");
483
484 auto* context = static_cast<CloudEnhancementAsyncContext*>(data);
485 CloudEnhancementReqBody reqBody;
486 reqBody.hasCloudWatermark = context->hasCloudWatermark_;
487 reqBody.triggerMode = context->triggerMode_;
488 reqBody.fileUris = context->uris;
489 uint32_t businessCode = static_cast<uint32_t>(MediaLibraryBusinessCode::SUBMIT_CLOUD_ENHANCEMENT_TASKS);
490 int32_t ret = IPC::UserDefineIPCClient().Call(businessCode, reqBody);
491 if (ret < 0) {
492 context->SaveError(ret);
493 NAPI_ERR_LOG("Submit cloud enhancement tasks failed, err: %{public}d", ret);
494 return;
495 }
496 NAPI_INFO_LOG("SubmitCloudEnhancementTasksExecute Success");
497 }
498
SubmitCloudEnhancementTasksCompleteCallback(napi_env env,napi_status status,void * data)499 static void SubmitCloudEnhancementTasksCompleteCallback(napi_env env, napi_status status, void* data)
500 {
501 auto* context = static_cast<CloudEnhancementAsyncContext*>(data);
502 CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
503 auto jsContext = make_unique<JSAsyncContextOutput>();
504 jsContext->status = false;
505 napi_get_undefined(env, &jsContext->data);
506 napi_get_undefined(env, &jsContext->error);
507 if (context->error == ERR_DEFAULT) {
508 jsContext->status = true;
509 } else {
510 context->HandleError(env, jsContext->error);
511 }
512
513 if (context->work != nullptr) {
514 MediaLibraryNapiUtils::InvokeJSAsyncMethod(
515 env, context->deferred, context->callbackRef, context->work, *jsContext);
516 }
517 delete context;
518 }
519
JSSubmitCloudEnhancementTasks(napi_env env,napi_callback_info info)520 napi_value CloudEnhancementNapi::JSSubmitCloudEnhancementTasks(napi_env env, napi_callback_info info)
521 {
522 if (!MediaLibraryNapiUtils::IsSystemApp()) {
523 NapiError::ThrowError(env, E_CHECK_SYSTEMAPP_FAIL, "This interface can be called only by system apps");
524 return nullptr;
525 }
526 MediaLibraryTracer tracer;
527 tracer.Start("JSSubmitCloudEnhancementTasks");
528
529 auto asyncContext = make_unique<CloudEnhancementAsyncContext>();
530 CHECK_COND_WITH_MESSAGE(env, ParseArgsSubmitCloudEnhancementTasks(env, info, asyncContext), "Failed to parse args");
531 return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "SubmitCloudEnhancementTasks",
532 SubmitCloudEnhancementTasksExecute, SubmitCloudEnhancementTasksCompleteCallback);
533 }
534
ParseArgPrioritize(napi_env env,napi_callback_info info,unique_ptr<CloudEnhancementAsyncContext> & context)535 static napi_status ParseArgPrioritize(napi_env env, napi_callback_info info,
536 unique_ptr<CloudEnhancementAsyncContext>& context)
537 {
538 napi_value thisVar = nullptr;
539 context->argc = ARGS_ONE;
540 GET_JS_ARGS(env, info, context->argc, context->argv, thisVar);
541
542 if (CloudEnhancementNapi::ParseArgGetPhotoAsset(env, context->argv[PARAM0], context->fileId, context->photoUri,
543 context->displayName) != napi_ok) {
544 NAPI_ERR_LOG("requestMedia ParseArgGetPhotoAsset error");
545 NapiError::ThrowError(env, OHOS_INVALID_PARAM_CODE, "requestMedia ParseArgGetPhotoAsset error");
546 return napi_invalid_arg;
547 }
548
549 NAPI_INFO_LOG("Parse Arg: %{public}d, %{private}s, %{public}s", context->fileId, context->photoUri.c_str(),
550 context->displayName.c_str());
551
552 return napi_ok;
553 }
554
PrioritizeCloudEnhancementTaskExecute(napi_env env,void * data)555 static void PrioritizeCloudEnhancementTaskExecute(napi_env env, void* data)
556 {
557 MediaLibraryTracer tracer;
558 tracer.Start("PrioritizeCloudEnhancementTaskExecute");
559
560 auto* context = static_cast<CloudEnhancementAsyncContext*>(data);
561 CloudEnhancementReqBody reqBody;
562 reqBody.fileUris.emplace_back(context->photoUri);
563 uint32_t businessCode = static_cast<uint32_t>(MediaLibraryBusinessCode::PRIORITIZE_CLOUD_ENHANCEMENT_TASK);
564 int32_t ret = IPC::UserDefineIPCClient().Call(businessCode, reqBody);
565 if (ret < 0) {
566 context->SaveError(ret);
567 NAPI_ERR_LOG("Prioritize cloud enhancement task failed, err: %{public}d", ret);
568 return;
569 }
570 NAPI_INFO_LOG("PrioritizeCloudEnhancementTaskExecute Success");
571 }
572
PrioritizeCloudEnhancementTaskCompleteCallback(napi_env env,napi_status status,void * data)573 static void PrioritizeCloudEnhancementTaskCompleteCallback(napi_env env, napi_status status, void* data)
574 {
575 auto* context = static_cast<CloudEnhancementAsyncContext*>(data);
576 CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
577 auto jsContext = make_unique<JSAsyncContextOutput>();
578 jsContext->status = false;
579 napi_get_undefined(env, &jsContext->data);
580 napi_get_undefined(env, &jsContext->error);
581 if (context->error == ERR_DEFAULT) {
582 jsContext->status = true;
583 } else {
584 context->HandleError(env, jsContext->error);
585 }
586
587 if (context->work != nullptr) {
588 MediaLibraryNapiUtils::InvokeJSAsyncMethod(
589 env, context->deferred, context->callbackRef, context->work, *jsContext);
590 }
591 delete context;
592 }
593
JSPrioritizeCloudEnhancementTask(napi_env env,napi_callback_info info)594 napi_value CloudEnhancementNapi::JSPrioritizeCloudEnhancementTask(napi_env env, napi_callback_info info)
595 {
596 if (!MediaLibraryNapiUtils::IsSystemApp()) {
597 NapiError::ThrowError(env, E_CHECK_SYSTEMAPP_FAIL, "This interface can be called only by system apps");
598 return nullptr;
599 }
600 MediaLibraryTracer tracer;
601 tracer.Start("JSPrioritizeCloudEnhancementTask");
602
603 auto asyncContext = make_unique<CloudEnhancementAsyncContext>();
604 CHECK_COND(env, CloudEnhancementNapi::InitUserFileClient(env, info), JS_INNER_FAIL);
605 CHECK_COND_WITH_MESSAGE(env, ParseArgPrioritize(env, info, asyncContext) == napi_ok, "Failed to parse args");
606 return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "JSPrioritizeCloudEnhancementTask",
607 PrioritizeCloudEnhancementTaskExecute, PrioritizeCloudEnhancementTaskCompleteCallback);
608 }
609
ParseArgsCancelCloudEnhancementTasks(napi_env env,napi_callback_info info,unique_ptr<CloudEnhancementAsyncContext> & context)610 static napi_value ParseArgsCancelCloudEnhancementTasks(napi_env env, napi_callback_info info,
611 unique_ptr<CloudEnhancementAsyncContext>& context)
612 {
613 CHECK_COND_WITH_MESSAGE(env,
614 MediaLibraryNapiUtils::AsyncContextGetArgs(env, info, context, ARGS_ONE, ARGS_ONE) == napi_ok,
615 "Failed to get args");
616 CHECK_COND(env, CloudEnhancementNapi::InitUserFileClient(env, info), JS_INNER_FAIL);
617
618 napi_valuetype valueType = napi_undefined;
619 CHECK_ARGS(env, napi_typeof(env, context->argv[PARAM0], &valueType), JS_INNER_FAIL);
620 CHECK_COND(env, valueType == napi_object, JS_INNER_FAIL);
621
622 vector<string> uris;
623 vector<napi_value> napiValues;
624 CHECK_NULLPTR_RET(MediaLibraryNapiUtils::GetNapiValueArray(env, context->argv[PARAM0], napiValues));
625 CHECK_COND_WITH_MESSAGE(env, !napiValues.empty(), "array is empty");
626 CHECK_ARGS(env, napi_typeof(env, napiValues.front(), &valueType), JS_INNER_FAIL);
627 if (valueType == napi_object) { // array of asset object
628 CHECK_NULLPTR_RET(MediaLibraryNapiUtils::GetUriArrayFromAssets(env, napiValues, uris));
629 } else {
630 NapiError::ThrowError(env, OHOS_INVALID_PARAM_CODE, "Invalid type");
631 return nullptr;
632 }
633
634 CHECK_COND_WITH_MESSAGE(env, !uris.empty(), "Failed to check empty array");
635 for (const auto& uri : uris) {
636 NAPI_INFO_LOG("CloudEnhancementNapi ParseArgsCancelCloudEnhancementTasks: %{public}s", uri.c_str());
637 CHECK_COND(env, uri.find(PhotoColumn::PHOTO_URI_PREFIX) != string::npos, JS_E_URI);
638 }
639
640 context->predicates.In(PhotoColumn::MEDIA_ID, uris);
641 context->uris.assign(uris.begin(), uris.end());
642 RETURN_NAPI_TRUE(env);
643 }
644
CancelCloudEnhancementTasksExecute(napi_env env,void * data)645 static void CancelCloudEnhancementTasksExecute(napi_env env, void* data)
646 {
647 MediaLibraryTracer tracer;
648 tracer.Start("CancelCloudEnhancementTasksExecute");
649
650 auto* context = static_cast<CloudEnhancementAsyncContext*>(data);
651 CloudEnhancementReqBody reqBody;
652 reqBody.hasCloudWatermark = context->hasCloudWatermark_;
653 reqBody.triggerMode = context->triggerMode_;
654 reqBody.fileUris = context->uris;
655 uint32_t businessCode = static_cast<uint32_t>(MediaLibraryBusinessCode::CANCEL_CLOUD_ENHANCEMENT_TASKS);
656 int32_t ret = IPC::UserDefineIPCClient().Call(businessCode, reqBody);
657 if (ret < 0) {
658 context->SaveError(ret);
659 NAPI_ERR_LOG("cancel cloud enhancement tasks failed, err: %{public}d", ret);
660 return;
661 }
662 NAPI_INFO_LOG("CancelCloudEnhancementTasksExecute Success");
663 }
664
CancelCloudEnhancementTasksCompleteCallback(napi_env env,napi_status status,void * data)665 static void CancelCloudEnhancementTasksCompleteCallback(napi_env env, napi_status status, void* data)
666 {
667 auto* context = static_cast<CloudEnhancementAsyncContext*>(data);
668 CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
669 auto jsContext = make_unique<JSAsyncContextOutput>();
670 jsContext->status = false;
671 napi_get_undefined(env, &jsContext->data);
672 napi_get_undefined(env, &jsContext->error);
673 if (context->error == ERR_DEFAULT) {
674 jsContext->status = true;
675 } else {
676 context->HandleError(env, jsContext->error);
677 }
678
679 if (context->work != nullptr) {
680 MediaLibraryNapiUtils::InvokeJSAsyncMethod(
681 env, context->deferred, context->callbackRef, context->work, *jsContext);
682 }
683 delete context;
684 }
685
JSCancelCloudEnhancementTasks(napi_env env,napi_callback_info info)686 napi_value CloudEnhancementNapi::JSCancelCloudEnhancementTasks(napi_env env, napi_callback_info info)
687 {
688 if (!MediaLibraryNapiUtils::IsSystemApp()) {
689 NapiError::ThrowError(env, E_CHECK_SYSTEMAPP_FAIL, "This interface can be called only by system apps");
690 return nullptr;
691 }
692 MediaLibraryTracer tracer;
693 tracer.Start("JSCancelCloudEnhancementTasks");
694
695 auto asyncContext = make_unique<CloudEnhancementAsyncContext>();
696 CHECK_COND_WITH_MESSAGE(env, ParseArgsCancelCloudEnhancementTasks(env, info, asyncContext), "Failed to parse args");
697 return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "CancelCloudEnhancementTasks",
698 CancelCloudEnhancementTasksExecute, CancelCloudEnhancementTasksCompleteCallback);
699 }
700
CancelAllCloudEnhancementTasksExecute(napi_env env,void * data)701 static void CancelAllCloudEnhancementTasksExecute(napi_env env, void* data)
702 {
703 MediaLibraryTracer tracer;
704 tracer.Start("CancelAllCloudEnhancementTasksExecute");
705
706 auto* context = static_cast<CloudEnhancementAsyncContext*>(data);
707 CloudEnhancementReqBody reqBody;
708 uint32_t businessCode = static_cast<uint32_t>(MediaLibraryBusinessCode::CANCEL_ALL_CLOUD_ENHANCEMENT_TASKS);
709 int32_t ret = IPC::UserDefineIPCClient().Call(businessCode, reqBody);
710 if (ret < 0) {
711 context->SaveError(ret);
712 NAPI_ERR_LOG("Cancel all cloud enhancement tasks failed, err: %{public}d", ret);
713 return;
714 }
715 NAPI_INFO_LOG("CancelAllCloudEnhancementTasksExecute Success");
716 }
717
CancelAllCloudEnhancementTasksCompleteCallback(napi_env env,napi_status status,void * data)718 static void CancelAllCloudEnhancementTasksCompleteCallback(napi_env env, napi_status status, void* data)
719 {
720 auto* context = static_cast<CloudEnhancementAsyncContext*>(data);
721 CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
722 auto jsContext = make_unique<JSAsyncContextOutput>();
723 jsContext->status = false;
724 napi_get_undefined(env, &jsContext->data);
725 napi_get_undefined(env, &jsContext->error);
726 if (context->error == ERR_DEFAULT) {
727 jsContext->status = true;
728 } else {
729 context->HandleError(env, jsContext->error);
730 }
731
732 if (context->work != nullptr) {
733 MediaLibraryNapiUtils::InvokeJSAsyncMethod(
734 env, context->deferred, context->callbackRef, context->work, *jsContext);
735 }
736 delete context;
737 }
738
JSCancelAllCloudEnhancementTasks(napi_env env,napi_callback_info info)739 napi_value CloudEnhancementNapi::JSCancelAllCloudEnhancementTasks(napi_env env, napi_callback_info info)
740 {
741 if (!MediaLibraryNapiUtils::IsSystemApp()) {
742 NapiError::ThrowError(env, E_CHECK_SYSTEMAPP_FAIL, "This interface can be called only by system apps");
743 return nullptr;
744 }
745 MediaLibraryTracer tracer;
746 tracer.Start("JSCancelAllCloudEnhancementTasks");
747
748 auto asyncContext = make_unique<CloudEnhancementAsyncContext>();
749 CHECK_COND_WITH_MESSAGE(env,
750 MediaLibraryNapiUtils::AsyncContextGetArgs(env, info, asyncContext, ARGS_ZERO, ARGS_ZERO) == napi_ok,
751 "Failed to parse args");
752 return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "CancelAllCloudEnhancementTasks",
753 CancelAllCloudEnhancementTasksExecute, CancelAllCloudEnhancementTasksCompleteCallback);
754 }
755
ParseArgQuery(napi_env env,napi_callback_info info,unique_ptr<CloudEnhancementAsyncContext> & context)756 static napi_status ParseArgQuery(napi_env env, napi_callback_info info,
757 unique_ptr<CloudEnhancementAsyncContext>& context)
758 {
759 napi_value thisVar = nullptr;
760 context->argc = ARGS_ONE;
761 GET_JS_ARGS(env, info, context->argc, context->argv, thisVar);
762
763 if (CloudEnhancementNapi::ParseArgGetPhotoAsset(env, context->argv[PARAM0], context->fileId, context->photoUri,
764 context->displayName) != napi_ok) {
765 NAPI_ERR_LOG("requestMedia ParseArgGetPhotoAsset error");
766 NapiError::ThrowError(env, OHOS_INVALID_PARAM_CODE, "requestMedia ParseArgGetPhotoAsset error");
767 return napi_invalid_arg;
768 }
769
770 NAPI_INFO_LOG("Parse Arg: %{public}d, %{private}s, %{public}s", context->fileId, context->photoUri.c_str(),
771 context->displayName.c_str());
772
773 return napi_ok;
774 }
775
FillTaskStageWithClientQuery(CloudEnhancementAsyncContext * context,string & photoId)776 static void FillTaskStageWithClientQuery(CloudEnhancementAsyncContext* context, string &photoId)
777 {
778 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
779 lock_guard<mutex> lock(mtx);
780 InitCloudEnhancementFunc();
781 if (dynamicHandler == nullptr) {
782 NAPI_ERR_LOG("dynamicHandler is nullptr!");
783 return;
784 }
785 InitEnhancementClient();
786 if (clientWrapper == nullptr) {
787 NAPI_ERR_LOG("clientWrapper is nullptr!");
788 return;
789 }
790 if (!IsConnected(clientWrapper)) {
791 LoadSA();
792 }
793 MediaEnhanceBundleHandle* bundle = CreateBundle();
794 bundle = QueryTaskState(photoId);
795 if (bundle == nullptr) {
796 NAPI_ERR_LOG("queryTaskState result is nullptr!");
797 DestroyEnhancementClient();
798 return;
799 }
800 int32_t currentState = GetInt(bundle, MediaEnhance_Query::CURRENT_STATE);
801 NAPI_INFO_LOG("clientQueryTaskStateFunc stage = %{public}d", currentState);
802 if (currentState == MediaEnhance_Query::EN_EXCEPTION) {
803 context->cloudEnhancementTaskStage_ = CloudEnhancementTaskStage::TASK_STAGE_EXCEPTION;
804 } else if (currentState == MediaEnhance_Query::EN_PREPARING) {
805 context->cloudEnhancementTaskStage_ = CloudEnhancementTaskStage::TASK_STAGE_PREPARING;
806 } else if (currentState == MediaEnhance_Query::EN_UPLOADING) {
807 context->cloudEnhancementTaskStage_ = CloudEnhancementTaskStage::TASK_STAGE_UPLOADING;
808 context->transferredFileSize_ = GetInt(bundle, MediaEnhance_Query::UPLOAD_PROGRESS);
809 context->totalFileSize_ = GetInt(bundle, MediaEnhance_Query::UPLOAD_SIZE);
810 } else if (currentState == MediaEnhance_Query::EN_EXECUTING) {
811 context->cloudEnhancementTaskStage_ = CloudEnhancementTaskStage::TASK_STAGE_EXECUTING;
812 context->expectedDuration_ = GetInt(bundle, MediaEnhance_Query::EXECUTE_TIME);
813 } else if (currentState == MediaEnhance_Query::EN_DOWNLOADING) {
814 context->cloudEnhancementTaskStage_ = CloudEnhancementTaskStage::TASK_STAGE_DOWNLOADING;
815 context->transferredFileSize_ = GetInt(bundle, MediaEnhance_Query::DOWNLOAD_PROGRESS);
816 context->totalFileSize_ = GetInt(bundle, MediaEnhance_Query::DOWNLOAD_SIZE);
817 }
818 DestroyBundle(bundle);
819 DestroyEnhancementClient();
820 #endif
821 }
822
QueryCloudEnhancementTaskStateExecute(napi_env env,void * data)823 static void QueryCloudEnhancementTaskStateExecute(napi_env env, void* data)
824 {
825 MediaLibraryTracer tracer;
826 tracer.Start("QueryCloudEnhancementTaskStateExecute");
827
828 auto* context = static_cast<CloudEnhancementAsyncContext*>(data);
829 QueryCloudEnhancementTaskStateReqBody reqBody;
830 QueryCloudEnhancementTaskStateRespBody respBody;
831 reqBody.photoUri = context->photoUri;
832 uint32_t businessCode = static_cast<uint32_t>(MediaLibraryBusinessCode::QUERY_CLOUD_ENHANCEMENT_TASK_STATE);
833 int32_t ret = IPC::UserDefineIPCClient().Call(businessCode, reqBody, respBody);
834 if (ret < 0) {
835 context->SaveError(JS_INNER_FAIL);
836 NAPI_ERR_LOG("Failed to query cloud enhancement task state, err: %{public}d", ret);
837 return;
838 }
839 int32_t fileId = respBody.fileId;
840 string photoId = respBody.photoId;
841 int32_t ceAvailable = respBody.ceAvailable;
842 int32_t ceErrorCode = respBody.ceErrorCode;
843 NAPI_INFO_LOG("query fileId: %{public}d, photoId: %{private}s, ceAvailable: %{public}d",
844 fileId, photoId.c_str(), ceAvailable);
845
846 if (ceAvailable == static_cast<int32_t>(CE_AVAILABLE::NOT_SUPPORT)) {
847 NAPI_ERR_LOG("photo not support cloud enhancement, fileId: %{public}d", fileId);
848 return;
849 }
850 // 任务成功或失败,不能再查云增强,否则会让云增强误报准备中
851 if (ceAvailable == static_cast<int32_t>(CE_AVAILABLE::SUCCESS)) {
852 context->cloudEnhancementTaskStage_ = CloudEnhancementTaskStage::TASK_STAGE_COMPLETED;
853 return;
854 }
855 if (ceAvailable == static_cast<int32_t>(CE_AVAILABLE::FAILED_RETRY) ||
856 ceAvailable == static_cast<int32_t>(CE_AVAILABLE::FAILED)) {
857 context->cloudEnhancementTaskStage_ = CloudEnhancementTaskStage::TASK_STAGE_FAILED;
858 context->statusCode_ = ceErrorCode;
859 NAPI_INFO_LOG("TASK_STAGE_FAILED, fileId: %{public}d, statusCode: %{public}d", fileId, ceAvailable);
860 return;
861 }
862 FillTaskStageWithClientQuery(context, photoId);
863 }
864
QueryCloudEnhancementTaskStateCompleteCallback(napi_env env,napi_status status,void * data)865 static void QueryCloudEnhancementTaskStateCompleteCallback(napi_env env, napi_status status, void* data)
866 {
867 auto* context = static_cast<CloudEnhancementAsyncContext*>(data);
868 CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
869 auto jsContext = make_unique<JSAsyncContextOutput>();
870 jsContext->status = false;
871 napi_get_undefined(env, &jsContext->data);
872 napi_get_undefined(env, &jsContext->error);
873 if (context->error == ERR_DEFAULT) {
874 napi_value cloudEnhancementTaskState =
875 CloudEnhancementTaskStateNapi::NewCloudEnhancementTaskStateNapi(env, context);
876 jsContext->data = cloudEnhancementTaskState;
877 jsContext->status = true;
878 } else {
879 context->HandleError(env, jsContext->error);
880 }
881
882 if (context->work != nullptr) {
883 MediaLibraryNapiUtils::InvokeJSAsyncMethod(
884 env, context->deferred, context->callbackRef, context->work, *jsContext);
885 }
886 delete context;
887 }
888
JSQueryCloudEnhancementTaskState(napi_env env,napi_callback_info info)889 napi_value CloudEnhancementNapi::JSQueryCloudEnhancementTaskState(napi_env env, napi_callback_info info)
890 {
891 if (!MediaLibraryNapiUtils::IsSystemApp()) {
892 NapiError::ThrowError(env, E_CHECK_SYSTEMAPP_FAIL, "This interface can be called only by system apps");
893 return nullptr;
894 }
895 MediaLibraryTracer tracer;
896 tracer.Start("JSQueryCloudEnhancementTaskState");
897
898 auto asyncContext = make_unique<CloudEnhancementAsyncContext>();
899 CHECK_COND(env, CloudEnhancementNapi::InitUserFileClient(env, info), JS_INNER_FAIL);
900 CHECK_COND_WITH_MESSAGE(env, ParseArgQuery(env, info, asyncContext) == napi_ok, "Failed to parse args");
901
902 return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "QueryCloudEnhancementTaskState",
903 QueryCloudEnhancementTaskStateExecute, QueryCloudEnhancementTaskStateCompleteCallback);
904 }
905
SyncCloudEnhancementTaskStatusExecute(napi_env env,void * data)906 static void SyncCloudEnhancementTaskStatusExecute(napi_env env, void* data)
907 {
908 MediaLibraryTracer tracer;
909 tracer.Start("SyncCloudEnhancementTaskStatusExecute");
910
911 auto* context = static_cast<CloudEnhancementAsyncContext*>(data);
912 uint32_t businessCode = static_cast<uint32_t>(MediaLibraryBusinessCode::SYNC_CLOUD_ENHANCEMENT_TASK_STATUS);
913 CloudEnhancementReqBody reqBody;
914 int32_t changeRows = IPC::UserDefineIPCClient().Call(businessCode, reqBody);
915 if (changeRows < 0) {
916 context->SaveError(changeRows);
917 NAPI_ERR_LOG("sync cloud enhancement failed, err: %{public}d", changeRows);
918 }
919 NAPI_INFO_LOG("CloudEnhancementNapi SyncCloudEnhancementTaskStatusExecute Success");
920 }
921
SyncCloudEnhancementTaskStatusCompleteCallback(napi_env env,napi_status status,void * data)922 static void SyncCloudEnhancementTaskStatusCompleteCallback(napi_env env, napi_status status, void* data)
923 {
924 auto* context = static_cast<CloudEnhancementAsyncContext*>(data);
925 CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
926 auto jsContext = make_unique<JSAsyncContextOutput>();
927 jsContext->status = false;
928 napi_get_undefined(env, &jsContext->data);
929 napi_get_undefined(env, &jsContext->error);
930 if (context->error == ERR_DEFAULT) {
931 jsContext->status = true;
932 } else {
933 context->HandleError(env, jsContext->error);
934 }
935
936 if (context->work != nullptr) {
937 MediaLibraryNapiUtils::InvokeJSAsyncMethod(
938 env, context->deferred, context->callbackRef, context->work, *jsContext);
939 }
940 delete context;
941 }
942
JSSyncCloudEnhancementTaskStatus(napi_env env,napi_callback_info info)943 napi_value CloudEnhancementNapi::JSSyncCloudEnhancementTaskStatus(napi_env env, napi_callback_info info)
944 {
945 if (!MediaLibraryNapiUtils::IsSystemApp()) {
946 NapiError::ThrowError(env, E_CHECK_SYSTEMAPP_FAIL, "This interface can be called only by system apps");
947 return nullptr;
948 }
949 MediaLibraryTracer tracer;
950 tracer.Start("JSSyncCloudEnhancementTaskStatus");
951
952 auto asyncContext = make_unique<CloudEnhancementAsyncContext>();
953 CHECK_COND_WITH_MESSAGE(env,
954 MediaLibraryNapiUtils::AsyncContextGetArgs(env, info, asyncContext, ARGS_ZERO, ARGS_ZERO) == napi_ok,
955 "Failed to parse args");
956
957 return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "SyncCloudEnhancementTaskStatus",
958 SyncCloudEnhancementTaskStatusExecute, SyncCloudEnhancementTaskStatusCompleteCallback);
959 }
960
GetPairAsset()961 bool CloudEnhancementAsyncContext::GetPairAsset()
962 {
963 if (fetchFileResult->GetCount() != 1) {
964 NAPI_ERR_LOG("Object number of fetchfileResult is not one");
965 return false;
966 }
967 fileAsset = fetchFileResult->GetFirstObject();
968 if (fileAsset == nullptr) {
969 NAPI_ERR_LOG("Fail to get fileAsset from fetchFileResult");
970 return false;
971 }
972 return true;
973 }
974
GetCloudEnhancementPairExecute(napi_env env,void * data)975 static void GetCloudEnhancementPairExecute(napi_env env, void* data)
976 {
977 MediaLibraryTracer tracer;
978 tracer.Start("GetCloudEnhancementPairExecute");
979
980 auto* context = static_cast<CloudEnhancementAsyncContext*>(data);
981 CHECK_NULL_PTR_RETURN_VOID(context, "AsyncContext is null");
982 GetCloudEnhancementPairReqBody reqBody;
983 GetCloudEnhancementPairRespBody respBody;
984 reqBody.photoUri = context->photoUri;
985 uint32_t businessCode = static_cast<uint32_t>(MediaLibraryBusinessCode::GET_CLOUD_ENHANCEMENT_PAIR);
986 int32_t ret = IPC::UserDefineIPCClient().Call(businessCode, reqBody, respBody);
987 if (ret < 0) {
988 context->SaveError(ret);
989 NAPI_ERR_LOG("Failed to get cloud enhancement pair, err: %{public}d", ret);
990 return;
991 }
992 auto resultSet = respBody.resultSet;
993 context->fetchFileResult = make_unique<FetchResult<FileAsset>>(move(resultSet));
994 if (!context->GetPairAsset()) {
995 NAPI_ERR_LOG("Fail to getPairAsset");
996 return;
997 }
998
999 NAPI_INFO_LOG("CloudEnhancementNapi GetCloudEnhancementPairExecute Success");
1000 }
1001
GetNapiPairFileAsset(napi_env env,CloudEnhancementAsyncContext * context,unique_ptr<JSAsyncContextOutput> & jsContext)1002 static void GetNapiPairFileAsset(napi_env env, CloudEnhancementAsyncContext *context,
1003 unique_ptr<JSAsyncContextOutput> &jsContext)
1004 {
1005 // Create PhotiAsset object using the contents of fileAsset
1006 if (context->fileAsset == nullptr) {
1007 NAPI_ERR_LOG("No fetch file result found!");
1008 MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_INVALID_OUTPUT,
1009 "Failed to obtain Fetch File Result");
1010 return;
1011 }
1012 if (context->fileAsset->GetPhotoEditTime() != 0) {
1013 NAPI_WARN_LOG("PhotoAsset is edited");
1014 MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_INVALID_OUTPUT,
1015 "Failed to obtain Fetch File Result");
1016 return;
1017 }
1018 context->fileAsset->SetResultNapiType(ResultNapiType::TYPE_PHOTOACCESS_HELPER);
1019 napi_value jsFileAsset = FileAssetNapi::CreateFileAsset(env, context->fileAsset);
1020 if (jsFileAsset == nullptr) {
1021 MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_INVALID_OUTPUT,
1022 "Failed to create js object for Fetch File Result");
1023 } else {
1024 jsContext->data = jsFileAsset;
1025 jsContext->status = true;
1026 napi_get_undefined(env, &jsContext->error);
1027 }
1028 }
1029
GetCloudEnhancementPairCompleteCallback(napi_env env,napi_status status,void * data)1030 static void GetCloudEnhancementPairCompleteCallback(napi_env env, napi_status status, void* data)
1031 {
1032 MediaLibraryTracer tracer;
1033 tracer.Start("GetCloudEnhancementPairCompleteCallback");
1034
1035 CloudEnhancementAsyncContext *context = static_cast<CloudEnhancementAsyncContext*>(data);
1036 CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
1037
1038 unique_ptr<JSAsyncContextOutput> jsContext = make_unique<JSAsyncContextOutput>();
1039 jsContext->status = false;
1040 napi_get_undefined(env, &jsContext->data);
1041
1042 if (context->error != ERR_DEFAULT) {
1043 context->HandleError(env, jsContext->error);
1044 } else {
1045 GetNapiPairFileAsset(env, context, jsContext);
1046 }
1047
1048 tracer.Finish();
1049 if (context->work != nullptr) {
1050 MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
1051 context->work, *jsContext);
1052 }
1053 delete context;
1054 }
1055
JSGetCloudEnhancementPair(napi_env env,napi_callback_info info)1056 napi_value CloudEnhancementNapi::JSGetCloudEnhancementPair(napi_env env, napi_callback_info info)
1057 {
1058 MediaLibraryTracer tracer;
1059 tracer.Start("JSGetCloudEnhancementPair");
1060 if (!MediaLibraryNapiUtils::IsSystemApp()) {
1061 NapiError::ThrowError(env, E_CHECK_SYSTEMAPP_FAIL, "This interface can be called only by system apps");
1062 return nullptr;
1063 }
1064 auto asyncContext = make_unique<CloudEnhancementAsyncContext>();
1065 asyncContext->resultNapiType = ResultNapiType::TYPE_PHOTOACCESS_HELPER;
1066 asyncContext->assetType = TYPE_PHOTO;
1067
1068 CHECK_COND(env, CloudEnhancementNapi::InitUserFileClient(env, info), JS_INNER_FAIL);
1069 CHECK_COND_WITH_MESSAGE(env, ParseArgQuery(env, info, asyncContext) == napi_ok, "Failed to parse args");
1070 return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "GetCloudEnhancementPair",
1071 GetCloudEnhancementPairExecute, GetCloudEnhancementPairCompleteCallback);
1072 }
1073 } // namespace OHOS::Media
1074