1 /*
2  * Copyright (c) 2022-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 #include "js_file_access_ext_ability.h"
17 
18 #include "ability_info.h"
19 #include "accesstoken_kit.h"
20 #include "extension_context.h"
21 #include "file_access_check_util.h"
22 #include "file_access_ext_stub_impl.h"
23 #include "file_access_extension_info.h"
24 #include "file_access_framework_errno.h"
25 #include "file_access_observer_common.h"
26 #include "file_access_service_proxy.h"
27 #include "hilog_wrapper.h"
28 #include "hitrace_meter.h"
29 #include "if_system_ability_manager.h"
30 #include "ipc_skeleton.h"
31 #include "iservice_registry.h"
32 #include "js_runtime.h"
33 #include "js_runtime_utils.h"
34 #include "n_error.h"
35 #include "napi/native_api.h"
36 #include "napi/native_node_api.h"
37 #include "napi_common_util.h"
38 #include "napi_common_want.h"
39 #include "napi_remote_object.h"
40 #include "system_ability_definition.h"
41 #include "user_access_common_utils.h"
42 #include "user_access_tracer.h"
43 
44 namespace OHOS {
45 namespace FileAccessFwk {
46 namespace {
47     constexpr size_t ARGC_ZERO = 0;
48     constexpr size_t ARGC_ONE = 1;
49     constexpr size_t ARGC_TWO = 2;
50     constexpr size_t ARGC_THREE = 3;
51     constexpr size_t ARGC_FOUR = 4;
52     constexpr size_t MAX_ARG_COUNT = 5;
53     constexpr int EXCEPTION = -1;
54     constexpr int NOEXCEPTION = -2;
55 }
56 
57 using namespace OHOS::AppExecFwk;
58 using namespace OHOS::AbilityRuntime;
59 using namespace OHOS::FileManagement::LibN;
60 using OHOS::Security::AccessToken::AccessTokenKit;
61 
Create(const std::unique_ptr<Runtime> & runtime)62 JsFileAccessExtAbility *JsFileAccessExtAbility::Create(const std::unique_ptr<Runtime> &runtime)
63 {
64     return new JsFileAccessExtAbility(static_cast<JsRuntime &>(*runtime));
65 }
66 
JsFileAccessExtAbility(JsRuntime & jsRuntime)67 JsFileAccessExtAbility::JsFileAccessExtAbility(JsRuntime &jsRuntime) : jsRuntime_(jsRuntime) {}
68 
~JsFileAccessExtAbility()69 JsFileAccessExtAbility::~JsFileAccessExtAbility()
70 {
71     jsRuntime_.FreeNativeReference(std::move(jsObj_));
72 }
73 
Init(const std::shared_ptr<AbilityLocalRecord> & record,const std::shared_ptr<OHOSApplication> & application,std::shared_ptr<AbilityHandler> & handler,const sptr<IRemoteObject> & token)74 void JsFileAccessExtAbility::Init(const std::shared_ptr<AbilityLocalRecord> &record,
75     const std::shared_ptr<OHOSApplication> &application, std::shared_ptr<AbilityHandler> &handler,
76     const sptr<IRemoteObject> &token)
77 {
78     UserAccessTracer trace;
79     trace.Start("Init");
80     FileAccessExtAbility::Init(record, application, handler, token);
81     std::string srcPath = "";
82     GetSrcPath(srcPath);
83     if (srcPath.empty()) {
84         HILOG_ERROR("Failed to get srcPath");
85         return;
86     }
87 
88     std::string moduleName(Extension::abilityInfo_->moduleName);
89     moduleName.append("::").append(abilityInfo_->name);
90     HandleScope handleScope(jsRuntime_);
91 
92     jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath,
93         abilityInfo_->compileMode == AbilityRuntime::CompileMode::ES_MODULE);
94     if (jsObj_ == nullptr) {
95         HILOG_ERROR("Failed to get jsObj_");
96         return;
97     }
98 
99     if (jsObj_->GetNapiValue() == nullptr) {
100         HILOG_ERROR("Failed to get JsFileAccessExtAbility value");
101         return;
102     }
103 }
104 
OnStart(const AAFwk::Want & want)105 void JsFileAccessExtAbility::OnStart(const AAFwk::Want &want)
106 {
107     UserAccessTracer trace;
108     trace.Start("OnStart");
109     Extension::OnStart(want);
110     HandleScope handleScope(jsRuntime_);
111     napi_env env = reinterpret_cast<napi_env>(&jsRuntime_.GetNativeEngine());
112     napi_value napiWant = OHOS::AppExecFwk::WrapWant(env, want);
113     napi_value argv[] = { napiWant };
114     CallObjectMethod("onCreate", argv, ARGC_ONE);
115 }
116 
OnConnect(const AAFwk::Want & want)117 sptr<IRemoteObject> JsFileAccessExtAbility::OnConnect(const AAFwk::Want &want)
118 {
119     UserAccessTracer trace;
120     trace.Start("OnConnect");
121     Extension::OnConnect(want);
122     sptr<FileAccessExtStubImpl> remoteObject(
123         new (std::nothrow) FileAccessExtStubImpl(std::static_pointer_cast<JsFileAccessExtAbility>(shared_from_this()),
124         reinterpret_cast<napi_env>(&jsRuntime_.GetNativeEngine())));
125     if (remoteObject == nullptr) {
126         HILOG_ERROR("No memory allocated for FileExtStubImpl");
127         return nullptr;
128     }
129 
130     return remoteObject->AsObject();
131 }
132 
CallObjectMethod(const char * name,napi_value const * argv,size_t argc)133 napi_value JsFileAccessExtAbility::CallObjectMethod(const char *name, napi_value const *argv, size_t argc)
134 {
135     UserAccessTracer trace;
136     trace.Start("CallObjectMethod");
137     if (!jsObj_) {
138         HILOG_ERROR("JsFileAccessExtAbility::CallObjectMethod jsObj Not found FileAccessExtAbility.js");
139         return nullptr;
140     }
141 
142     HandleEscape handleEscape(jsRuntime_);
143     auto &nativeEngine = jsRuntime_.GetNativeEngine();
144     auto env = reinterpret_cast<napi_env>(&nativeEngine);
145 
146     napi_value value = jsObj_->GetNapiValue();
147     if (value == nullptr) {
148         HILOG_ERROR("Failed to get FileAccessExtAbility value");
149         return nullptr;
150     }
151 
152     napi_value method = nullptr;
153     napi_get_named_property(env, value, name, &method);
154     if (method == nullptr) {
155         HILOG_ERROR("Failed to get '%{public}s' from FileAccessExtAbility object", name);
156         return nullptr;
157     }
158 
159     napi_value result = nullptr;
160     if (napi_call_function(env, value, method, argc, argv, &result) != napi_ok) {
161         HILOG_ERROR("Call function fail");
162         return nullptr;
163     }
164     return handleEscape.Escape(result);
165 }
166 
DoCallJsMethod(CallJsParam * param)167 static int DoCallJsMethod(CallJsParam *param)
168 {
169     UserAccessTracer trace;
170     trace.Start("DoCallJsMethod");
171     if (param == nullptr || param->jsRuntime == nullptr) {
172         HILOG_ERROR("failed to get jsRuntime.");
173         return EINVAL;
174     }
175     JsRuntime *jsRuntime = param->jsRuntime;
176 
177     HandleEscape handleEscape(*jsRuntime);
178     auto &nativeEngine = jsRuntime->GetNativeEngine();
179     auto env = reinterpret_cast<napi_env>(&nativeEngine);
180     size_t argc = 0;
181     napi_value argv[MAX_ARG_COUNT] = { nullptr };
182     if (param->argParser != nullptr) {
183         if (!param->argParser(env, argv, argc)) {
184             HILOG_ERROR("failed to get params.");
185             return EINVAL;
186         }
187     }
188 
189     napi_value value = nullptr;
190     auto ref = reinterpret_cast<napi_ref>(param->jsObj);
191     napi_get_reference_value(env, ref, &value);
192     if (value == nullptr) {
193         HILOG_ERROR("failed to get native value object.");
194         return EINVAL;
195     }
196     napi_value method = nullptr;
197     napi_get_named_property(env, value, param->funcName.c_str(), &method);
198     if (method == nullptr) {
199         HILOG_ERROR("failed to get %{public}s from FileExtAbility object.", param->funcName.c_str());
200         return EINVAL;
201     }
202     if (param->retParser == nullptr) {
203         HILOG_ERROR("ResultValueParser must not null.");
204         return EINVAL;
205     }
206     napi_value result = nullptr;
207     napi_call_function(env, value, method, argc, argv, &result);
208     if (result == nullptr) {
209         HILOG_ERROR("Napi call function fail.");
210         return E_GETRESULT;
211     }
212     if (!param->retParser(env, handleEscape.Escape(result))) {
213         HILOG_ERROR("Parser js result fail.");
214         return E_GETRESULT;
215     }
216     return ERR_OK;
217 }
218 
CallJsMethod(const std::string & funcName,JsRuntime & jsRuntime,NativeReference * jsObj,InputArgsParser argParser,ResultValueParser retParser)219 int JsFileAccessExtAbility::CallJsMethod(const std::string &funcName, JsRuntime &jsRuntime, NativeReference *jsObj,
220     InputArgsParser argParser, ResultValueParser retParser)
221 {
222     UserAccessTracer trace;
223     trace.Start("CallJsMethod");
224     uv_loop_s *loop = nullptr;
225     napi_status status = napi_get_uv_event_loop(reinterpret_cast<napi_env>(&jsRuntime.GetNativeEngine()), &loop);
226     if (status != napi_ok) {
227         HILOG_ERROR("failed to get uv event loop.");
228         return EINVAL;
229     }
230     auto param = std::make_shared<CallJsParam>(funcName, &jsRuntime, jsObj, argParser, retParser);
231     if (param == nullptr) {
232         HILOG_ERROR("failed to new param.");
233         return EINVAL;
234     }
235     auto work = std::make_shared<uv_work_t>();
236     if (work == nullptr) {
237         HILOG_ERROR("failed to new uv_work_t.");
238         return EINVAL;
239     }
240     work->data = reinterpret_cast<void *>(param.get());
241     int ret = uv_queue_work(
242         loop, work.get(), [](uv_work_t *work) {},
243         [](uv_work_t *work, int status) {
244             CallJsParam *param = reinterpret_cast<CallJsParam *>(work->data);
245             if (param == nullptr) {
246                 HILOG_ERROR("failed to get CallJsParam.");
247                 return;
248             }
249 
250             napi_handle_scope scope = nullptr;
251             napi_env env = reinterpret_cast<napi_env>(&(param->jsRuntime->GetNativeEngine()));
252             napi_open_handle_scope(env, &scope);
253 
254             if (DoCallJsMethod(param) != ERR_OK) {
255                 HILOG_ERROR("failed to call DoCallJsMethod.");
256             }
257 
258             std::unique_lock<std::mutex> lock(param->fileOperateMutex);
259             param->isReady = true;
260             param->fileOperateCondition.notify_one();
261             napi_close_handle_scope(env, scope);
262         });
263     if (ret != 0) {
264         HILOG_ERROR("failed to exec uv_queue_work.");
265         return EINVAL;
266     }
267     std::unique_lock<std::mutex> lock(param->fileOperateMutex);
268     param->fileOperateCondition.wait(lock, [param]() { return param->isReady; });
269     return ERR_OK;
270 }
271 
GetSrcPath(std::string & srcPath)272 void JsFileAccessExtAbility::GetSrcPath(std::string &srcPath)
273 {
274     UserAccessTracer trace;
275     trace.Start("GetSrcPath");
276     if (!Extension::abilityInfo_->isStageBasedModel) {
277         /* temporary compatibility api8 + config.json */
278         srcPath.append(Extension::abilityInfo_->package);
279         srcPath.append("/assets/js/");
280         if (!Extension::abilityInfo_->srcPath.empty()) {
281             srcPath.append(Extension::abilityInfo_->srcPath);
282         }
283         srcPath.append("/").append(Extension::abilityInfo_->name).append(".abc");
284         return;
285     }
286 
287     if (!Extension::abilityInfo_->srcEntrance.empty()) {
288         srcPath.append(Extension::abilityInfo_->moduleName + "/");
289         srcPath.append(Extension::abilityInfo_->srcEntrance);
290         srcPath.erase(srcPath.rfind('.'));
291         srcPath.append(".abc");
292     }
293 }
294 
OpenFile(const Uri & uri,int flags,int & fd)295 int JsFileAccessExtAbility::OpenFile(const Uri &uri, int flags, int &fd)
296 {
297     UserAccessTracer trace;
298     trace.Start("OpenFile");
299     auto value = std::make_shared<Value<int>>();
300     if (value == nullptr) {
301         HILOG_ERROR("OpenFile value is nullptr.");
302         return E_GETRESULT;
303     }
304 
305     auto argParser = [uri, flags](napi_env &env, napi_value argv[], size_t &argc) -> bool {
306         napi_value nativeUri = nullptr;
307         napi_create_string_utf8(env, uri.ToString().c_str(), uri.ToString().length(), &nativeUri);
308         napi_value nativeFlags = nullptr;
309         napi_create_int32(env, flags, &nativeFlags);
310         if (nativeUri == nullptr || nativeFlags == nullptr) {
311             HILOG_ERROR("create uri or flags native js value fail.");
312             return false;
313         }
314         argv[ARGC_ZERO] = nativeUri;
315         argv[ARGC_ONE] = nativeFlags;
316         argc = ARGC_TWO;
317         return true;
318     };
319     auto retParser = [value](napi_env &env, napi_value result) -> bool {
320         if (GetFdAndCodeFromJs(env, result, value) != napi_ok) {
321             HILOG_ERROR("Convert js object fail.");
322             return false;
323         }
324         return true;
325     };
326 
327     auto errCode = CallJsMethod("openFile", jsRuntime_, jsObj_.get(), argParser, retParser);
328     if (errCode != ERR_OK) {
329         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
330         return errCode;
331     }
332 
333     if (value->code != ERR_OK) {
334         HILOG_ERROR("fileio fail.");
335         return value->code;
336     }
337 
338     fd = value->data;
339     if (fd < ERR_OK) {
340         HILOG_ERROR("Failed to get file descriptor fd: %{public}d", fd);
341         return E_GETRESULT;
342     }
343     return ERR_OK;
344 }
345 
CreateFile(const Uri & parent,const std::string & displayName,Uri & newFile)346 int JsFileAccessExtAbility::CreateFile(const Uri &parent, const std::string &displayName, Uri &newFile)
347 {
348     UserAccessTracer trace;
349     trace.Start("CreateFile");
350     auto value = std::make_shared<Value<std::string>>();
351     if (!value) {
352         HILOG_ERROR("CreateFile value is nullptr.");
353         return E_GETRESULT;
354     }
355 
356     auto argParser = [parent, displayName](napi_env &env, napi_value argv[], size_t &argc) -> bool {
357         napi_value nativeParent = nullptr;
358         napi_create_string_utf8(env, parent.ToString().c_str(), parent.ToString().length(), &nativeParent);
359         napi_value nativeDisplayName = nullptr;
360         napi_create_string_utf8(env, displayName.c_str(), displayName.length(), &nativeDisplayName);
361         if (nativeParent == nullptr || nativeDisplayName == nullptr) {
362             HILOG_ERROR("create parent uri or displayName native js value fail.");
363             return false;
364         }
365         argv[ARGC_ZERO] = nativeParent;
366         argv[ARGC_ONE] = nativeDisplayName;
367         argc = ARGC_TWO;
368         return true;
369     };
370     auto retParser = [value](napi_env &env, napi_value result) -> bool {
371         if (GetUriAndCodeFromJs(env, result, value) != napi_ok) {
372             HILOG_ERROR("Convert js object fail.");
373             return false;
374         }
375         return true;
376     };
377 
378     auto errCode = CallJsMethod("createFile", jsRuntime_, jsObj_.get(), argParser, retParser);
379     if (errCode != ERR_OK) {
380         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
381         return errCode;
382     }
383 
384     if (value->code != ERR_OK) {
385         HILOG_ERROR("fileio fail.");
386         return value->code;
387     }
388 
389     if ((value->data).empty()) {
390         HILOG_ERROR("call CreateFile with return empty.");
391         return E_GETRESULT;
392     }
393 
394     newFile = Uri(value->data);
395     return ERR_OK;
396 }
397 
Mkdir(const Uri & parent,const std::string & displayName,Uri & newFile)398 int JsFileAccessExtAbility::Mkdir(const Uri &parent, const std::string &displayName, Uri &newFile)
399 {
400     UserAccessTracer trace;
401     trace.Start("Mkdir");
402     auto value = std::make_shared<Value<std::string>>();
403     if (!value) {
404         HILOG_ERROR("Mkdir value is nullptr.");
405         return E_GETRESULT;
406     }
407 
408     auto argParser = [parent, displayName](napi_env &env, napi_value *argv, size_t &argc) -> bool {
409         napi_value nativeParent = nullptr;
410         napi_create_string_utf8(env, parent.ToString().c_str(), parent.ToString().length(), &nativeParent);
411         napi_value nativeDisplayName = nullptr;
412         napi_create_string_utf8(env, displayName.c_str(), displayName.length(), &nativeDisplayName);
413         if (nativeParent == nullptr || nativeDisplayName == nullptr) {
414             HILOG_ERROR("create parent uri native js value fail.");
415             return false;
416         }
417         argv[ARGC_ZERO] = nativeParent;
418         argv[ARGC_ONE] = nativeDisplayName;
419         argc = ARGC_TWO;
420         return true;
421     };
422 
423     auto retParser = [value](napi_env &env, napi_value result) -> bool {
424         if (GetUriAndCodeFromJs(env, result, value) != napi_ok) {
425             HILOG_ERROR("Convert js object fail.");
426             return false;
427         }
428         return true;
429     };
430 
431     auto errCode = CallJsMethod("mkdir", jsRuntime_, jsObj_.get(), argParser, retParser);
432     if (errCode != ERR_OK) {
433         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
434         return errCode;
435     }
436 
437     if (value->code != ERR_OK) {
438         HILOG_ERROR("fileio fail.");
439         return value->code;
440     }
441 
442     if ((value->data).empty()) {
443         HILOG_ERROR("call Mkdir with return empty.");
444         return E_GETRESULT;
445     }
446     newFile = Uri(value->data);
447     return ERR_OK;
448 }
449 
Delete(const Uri & sourceFile)450 int JsFileAccessExtAbility::Delete(const Uri &sourceFile)
451 {
452     UserAccessTracer trace;
453     trace.Start("Delete");
454     auto ret = std::make_shared<int>();
455     if (!ret) {
456         HILOG_ERROR("Delete value is nullptr.");
457         return E_GETRESULT;
458     }
459 
460     auto argParser = [uri = sourceFile](napi_env &env, napi_value *argv, size_t &argc) -> bool {
461         napi_value nativeUri = nullptr;
462         napi_create_string_utf8(env, uri.ToString().c_str(), uri.ToString().length(), &nativeUri);
463         if (nativeUri == nullptr) {
464             HILOG_ERROR("create sourceFile uri native js value fail.");
465             return false;
466         }
467         argv[ARGC_ZERO] = nativeUri;
468         argc = ARGC_ONE;
469         return true;
470     };
471 
472     auto retParser = [ret](napi_env &env, napi_value result) -> bool {
473         if (napi_get_value_int32(env, result, ret.get()) != napi_ok) {
474             HILOG_ERROR("Convert js value fail.");
475             return false;
476         }
477         return true;
478     };
479 
480     auto errCode = CallJsMethod("delete", jsRuntime_, jsObj_.get(), argParser, retParser);
481     if (errCode != ERR_OK) {
482         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
483         return errCode;
484     }
485 
486     if (*ret != ERR_OK) {
487         HILOG_ERROR("fileio fail.");
488         return *ret;
489     }
490 
491     return ERR_OK;
492 }
493 
Move(const Uri & sourceFile,const Uri & targetParent,Uri & newFile)494 int JsFileAccessExtAbility::Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile)
495 {
496     UserAccessTracer trace;
497     trace.Start("Move");
498     auto value = std::make_shared<Value<std::string>>();
499     if (value == nullptr) {
500         HILOG_ERROR("Move value is nullptr.");
501         return E_GETRESULT;
502     }
503 
504     auto argParser = [sourceFile, targetParent](napi_env &env, napi_value *argv, size_t &argc) -> bool {
505         napi_value srcUri = nullptr;
506         napi_create_string_utf8(env, sourceFile.ToString().c_str(), sourceFile.ToString().length(), &srcUri);
507         napi_value dstUri = nullptr;
508         napi_create_string_utf8(env, targetParent.ToString().c_str(), targetParent.ToString().length(), &dstUri);
509         if (srcUri == nullptr || dstUri == nullptr) {
510             HILOG_ERROR("create sourceFile uri native js value fail.");
511             return false;
512         }
513         argv[ARGC_ZERO] = srcUri;
514         argv[ARGC_ONE] = dstUri;
515         argc = ARGC_TWO;
516         return true;
517     };
518 
519     auto retParser = [value](napi_env &env, napi_value result) -> bool {
520         if (GetUriAndCodeFromJs(env, result, value) != napi_ok) {
521             HILOG_ERROR("Convert js object fail.");
522             return false;
523         }
524         return true;
525     };
526 
527     auto errCode = CallJsMethod("move", jsRuntime_, jsObj_.get(), argParser, retParser);
528     if (errCode != ERR_OK) {
529         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
530         return errCode;
531     }
532 
533     if (value->code != ERR_OK) {
534         HILOG_ERROR("fileio fail.");
535         return value->code;
536     }
537 
538     if ((value->data).empty()) {
539         HILOG_ERROR("call move with return empty.");
540         return E_GETRESULT;
541     }
542     newFile = Uri(value->data);
543     return ERR_OK;
544 }
545 
TranslateResult(Result & result)546 static void TranslateResult(Result &result)
547 {
548     if (errCodeTable.find(result.errCode) != errCodeTable.end()) {
549         result.errCode = errCodeTable.at(result.errCode).first;
550         if (result.errMsg.empty()) {
551             result.errMsg = errCodeTable.at(result.errCode).second;
552         }
553     }
554 }
555 
GetResultByJs(napi_env & env,napi_value nativeResult,Result & result,const int & ret)556 static bool GetResultByJs(napi_env &env, napi_value nativeResult, Result &result, const int &ret)
557 {
558     UserAccessTracer trace;
559     trace.Start("GetResultsByJs");
560     if (nativeResult == nullptr) {
561         HILOG_ERROR("Convert js object fail.");
562         return false;
563     }
564 
565     if (ret == NOEXCEPTION) {
566         napi_value sourceUri = nullptr;
567         napi_get_named_property(env, nativeResult, "sourceUri", &sourceUri);
568         if (GetStringValue(env, sourceUri, result.sourceUri) != napi_ok) {
569             HILOG_ERROR("Convert sourceUri fail.");
570             return false;
571         }
572 
573         napi_value destUri = nullptr;
574         napi_get_named_property(env, nativeResult, "destUri", &destUri);
575         if (GetStringValue(env, destUri, result.destUri) != napi_ok) {
576             HILOG_ERROR("Convert destUri fail.");
577             return false;
578         }
579     }
580     if ((ret == NOEXCEPTION) || (ret == EXCEPTION)) {
581         napi_value errCode = nullptr;
582         napi_get_named_property(env, nativeResult, "errCode", &errCode);
583         if (napi_get_value_int32(env, errCode, &result.errCode) != napi_ok) {
584             HILOG_ERROR("Convert errCode fail.");
585             return false;
586         }
587     }
588     return true;
589 }
590 
ParserGetJsResult(napi_env & env,napi_value nativeValue,std::vector<Result> & result,int & copyRet)591 static bool ParserGetJsResult(napi_env &env, napi_value nativeValue, std::vector<Result> &result,
592     int &copyRet)
593 {
594     UserAccessTracer trace;
595     trace.Start("ParserGetJsResult");
596     if (nativeValue == nullptr) {
597         HILOG_ERROR("Convert js object fail.");
598         return false;
599     }
600 
601     napi_value code = nullptr;
602     napi_get_named_property(env, nativeValue, "code", &code);
603     if (napi_get_value_int32(env, code, &copyRet) != napi_ok) {
604         HILOG_ERROR("Convert js value fail.");
605         return false;
606     }
607 
608     if (copyRet == ERR_OK) {
609         return true;
610     }
611 
612     napi_value nativeArray = nullptr;
613     napi_create_array(env, &nativeArray);
614     napi_get_named_property(env, nativeValue, "results", &nativeArray);
615     if (nativeArray == nullptr) {
616         HILOG_ERROR("nativeArray is nullptr");
617         return false;
618     }
619 
620     uint32_t length = 0;
621     if (napi_get_array_length(env, nativeArray, &length) != napi_ok) {
622         HILOG_ERROR("Get nativeArray length fail");
623         return false;
624     }
625 
626     for (uint32_t i = 0; i < length; i++) {
627         napi_value nativeResult = nullptr;
628         napi_get_element(env, nativeArray, i, &nativeResult);
629         if (nativeResult == nullptr) {
630             HILOG_ERROR("get native FileInfo fail.");
631             return false;
632         }
633 
634         Result res;
635         bool ret = GetResultByJs(env, nativeResult, res, copyRet);
636         if (ret) {
637             TranslateResult(res);
638             result.push_back(res);
639         }
640     }
641 
642     return true;
643 }
644 
Copy(const Uri & sourceUri,const Uri & destUri,std::vector<Result> & copyResult,bool force)645 int JsFileAccessExtAbility::Copy(const Uri &sourceUri, const Uri &destUri, std::vector<Result> &copyResult,
646     bool force)
647 {
648     UserAccessTracer trace;
649     trace.Start("Copy");
650     auto argParser = [sourceUri, destUri, force](napi_env &env, napi_value *argv, size_t &argc) -> bool {
651         napi_value srcNativeUri = nullptr;
652         napi_create_string_utf8(env, sourceUri.ToString().c_str(), sourceUri.ToString().length(), &srcNativeUri);
653 
654         napi_value dstNativeUri = nullptr;
655         napi_create_string_utf8(env, destUri.ToString().c_str(), destUri.ToString().length(), &dstNativeUri);
656 
657         napi_value forceCopy = nullptr;
658         napi_get_boolean(env, force, &forceCopy);
659         if (srcNativeUri == nullptr || dstNativeUri == nullptr || forceCopy == nullptr) {
660             HILOG_ERROR("create arguments native js value fail.");
661             return false;
662         }
663         argv[ARGC_ZERO] = srcNativeUri;
664         argv[ARGC_ONE] = dstNativeUri;
665         argv[ARGC_TWO] = forceCopy;
666         argc = ARGC_THREE;
667         return true;
668     };
669 
670     int copyRet = EXCEPTION;
671     auto retParser = [&copyResult, &copyRet](napi_env &env, napi_value result) -> bool {
672         return ParserGetJsResult(env, result, copyResult, copyRet);
673     };
674 
675     auto errCode = CallJsMethod("copy", jsRuntime_, jsObj_.get(), argParser, retParser);
676     if (errCode != ERR_OK) {
677         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
678         Result result{ "", "", errCode, "" };
679         TranslateResult(result);
680         copyResult.push_back(result);
681         return EXCEPTION;
682     }
683 
684     return copyRet;
685 }
686 
CopyFile(const Uri & sourceUri,const Uri & destUri,const std::string & fileName,Uri & newFileUri)687 int JsFileAccessExtAbility::CopyFile(const Uri &sourceUri, const Uri &destUri, const std::string &fileName,
688     Uri &newFileUri)
689 {
690     UserAccessTracer trace;
691     trace.Start("CopyFile");
692     auto value = std::make_shared<Value<std::string>>();
693     if (value == nullptr) {
694         HILOG_ERROR("Move value is nullptr.");
695         return E_GETRESULT;
696     }
697 
698     auto argParser = [sourceUri, destUri, fileName](napi_env &env, napi_value *argv, size_t &argc) -> bool {
699         napi_value srcNativeUri = nullptr;
700         napi_create_string_utf8(env, sourceUri.ToString().c_str(), sourceUri.ToString().length(), &srcNativeUri);
701 
702         napi_value dstNativeUri = nullptr;
703         napi_create_string_utf8(env, destUri.ToString().c_str(), destUri.ToString().length(), &dstNativeUri);
704 
705         napi_value fileNativeName = nullptr;
706         napi_create_string_utf8(env, fileName.c_str(), fileName.length(), &fileNativeName);
707         if (srcNativeUri == nullptr || dstNativeUri == nullptr || fileNativeName == nullptr) {
708             HILOG_ERROR("create arguments native js value fail.");
709             return false;
710         }
711         argv[ARGC_ZERO] = srcNativeUri;
712         argv[ARGC_ONE] = dstNativeUri;
713         argv[ARGC_TWO] = fileNativeName;
714         argc = ARGC_THREE;
715         return true;
716     };
717 
718     auto retParser = [value](napi_env &env, napi_value result) -> bool {
719         if (GetUriAndCodeFromJs(env, result, value) != napi_ok) {
720             HILOG_ERROR("Convert js object fail.");
721             return false;
722         }
723         return true;
724     };
725 
726     auto errCode = CallJsMethod("copyFileByFileName", jsRuntime_, jsObj_.get(), argParser, retParser);
727     if (errCode != ERR_OK) {
728         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
729         return errCode;
730     }
731 
732     if (value->code != ERR_OK) {
733         HILOG_ERROR("fileio fail.");
734         return value->code;
735     }
736 
737     if ((value->data).empty()) {
738         HILOG_ERROR("call copyFileByFileName with return empty.");
739         return E_GETRESULT;
740     }
741     newFileUri = Uri(value->data);
742 
743     return ERR_OK;
744 }
745 
Rename(const Uri & sourceFile,const std::string & displayName,Uri & newFile)746 int JsFileAccessExtAbility::Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile)
747 {
748     UserAccessTracer trace;
749     trace.Start("Rename");
750     auto value = std::make_shared<Value<std::string>>();
751     if (value == nullptr) {
752         HILOG_ERROR("Rename value is nullptr.");
753         return E_GETRESULT;
754     }
755     auto argParser = [sourceFile, displayName](napi_env &env, napi_value *argv, size_t &argc) -> bool {
756         napi_value nativeSourceFile = nullptr;
757         napi_create_string_utf8(env, sourceFile.ToString().c_str(), sourceFile.ToString().length(), &nativeSourceFile);
758 
759         napi_value nativeDisplayName = nullptr;
760         napi_create_string_utf8(env, displayName.c_str(), displayName.length(), &nativeDisplayName);
761         if (nativeSourceFile == nullptr || nativeDisplayName == nullptr) {
762             HILOG_ERROR("create sourceFile uri or displayName native js value fail.");
763             return false;
764         }
765         argv[ARGC_ZERO] = nativeSourceFile;
766         argv[ARGC_ONE] = nativeDisplayName;
767         argc = ARGC_TWO;
768         return true;
769     };
770 
771     auto retParser = [value](napi_env &env, napi_value result) -> bool {
772         if (GetUriAndCodeFromJs(env, result, value) != napi_ok) {
773             HILOG_ERROR("Convert js object fail.");
774             return false;
775         }
776         return true;
777     };
778 
779     auto errCode = CallJsMethod("rename", jsRuntime_, jsObj_.get(), argParser, retParser);
780     if (errCode != ERR_OK) {
781         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
782         return errCode;
783     }
784 
785     if (value->code != ERR_OK) {
786         HILOG_ERROR("fileio fail.");
787         return value->code;
788     }
789 
790     if ((value->data).empty()) {
791         HILOG_ERROR("call Rename with return empty.");
792         return E_GETRESULT;
793     }
794     newFile = Uri(value->data);
795     return ERR_OK;
796 }
797 
ParserListFileJsResult(napi_env & env,napi_value nativeValue,Value<std::vector<FileInfo>> & result)798 bool JsFileAccessExtAbility::ParserListFileJsResult(napi_env &env, napi_value nativeValue,
799     Value<std::vector<FileInfo>> &result)
800 {
801     napi_value code = nullptr;
802     napi_get_named_property(env, nativeValue, "code", &code);
803     if (napi_get_value_int32(env, code, &result.code) != napi_ok) {
804         HILOG_ERROR("Convert code fail.");
805         return false;
806     }
807 
808     napi_value nativeArray = nullptr;
809     napi_create_array(env, &nativeArray);
810     napi_get_named_property(env, nativeValue, "infos", &nativeArray);
811     if (nativeArray == nullptr) {
812         HILOG_ERROR("Convert js array object fail.");
813         return false;
814     }
815 
816     uint32_t length = 0;
817     if (napi_get_array_length(env, nativeArray, &length) != napi_ok) {
818         HILOG_ERROR("Get nativeArray length fail.");
819         return false;
820     }
821     for (uint32_t i = 0; i < length; i++) {
822         napi_value nativeFileInfo = nullptr;
823         napi_get_element(env, nativeArray, i, &nativeFileInfo);
824         if (nativeFileInfo == nullptr) {
825             HILOG_ERROR("get native FileInfo fail.");
826             return false;
827         }
828 
829         FileInfo fileInfo;
830         if (GetFileInfoFromJs(env, nativeFileInfo, fileInfo) != napi_ok) {
831             HILOG_ERROR("Convert fileInfo js value fail.");
832             return false;
833         }
834 
835         result.data.emplace_back(std::move(fileInfo));
836     }
837     return true;
838 }
839 
MakeStringNativeArray(napi_env & env,std::vector<std::string> & inputArray,napi_value resultArray)840 int JsFileAccessExtAbility::MakeStringNativeArray(napi_env &env, std::vector<std::string> &inputArray,
841     napi_value resultArray)
842 {
843     if (resultArray == nullptr) {
844         HILOG_ERROR("Create NativeArray nullptr");
845         return E_GETRESULT;
846     }
847 
848     for (uint32_t i = 0; i < inputArray.size(); i++) {
849         napi_value nativeValue = nullptr;
850         napi_create_string_utf8(env, inputArray[i].c_str(), inputArray[i].length(), &nativeValue);
851         if (nativeValue == nullptr) {
852             HILOG_ERROR("Create NativeValue fail.");
853             return E_GETRESULT;
854         }
855 
856         if (napi_set_element(env, resultArray, i, nativeValue) != napi_ok) {
857             HILOG_ERROR("Add NativeValue to NativeArray fail.");
858             return E_IPCS;
859         }
860     }
861 
862     return ERR_OK;
863 }
864 
CreateNativeValue(napi_env & env,const FileFilter & filter,struct FileFilterValue & fileFilter)865 int JsFileAccessExtAbility::CreateNativeValue(napi_env &env, const FileFilter &filter,
866     struct FileFilterValue &fileFilter)
867 {
868     napi_create_array_with_length(env, filter.GetSuffix().size(), &fileFilter.suffixArray);
869     CHECK_STATUS_RETURN(fileFilter.suffixArray != nullptr, E_GETRESULT,
870         "Create Suffix native array value fail.");
871 
872     std::vector<std::string> suffixVec = filter.GetSuffix();
873     int errorCode = MakeStringNativeArray(env, suffixVec, fileFilter.suffixArray);
874     CHECK_STATUS_RETURN(errorCode == ERR_OK, errorCode,
875         "Create Suffix native array value fail, code:%{public}d.", errorCode);
876 
877     napi_create_array_with_length(env, filter.GetDisplayName().size(), &fileFilter.displayNameArray);
878     CHECK_STATUS_RETURN(fileFilter.displayNameArray != nullptr, E_GETRESULT,
879         "Create DisplayName native array value fail.");
880 
881     std::vector<std::string> displayNameVec = filter.GetDisplayName();
882     errorCode = MakeStringNativeArray(env, displayNameVec, fileFilter.displayNameArray);
883     CHECK_STATUS_RETURN(errorCode == ERR_OK, errorCode,
884         "Create DisplayName native array value fail, code:%{public}d.", errorCode);
885 
886     napi_create_array_with_length(env, filter.GetMimeType().size(), &fileFilter.mimeTypeArray);
887     CHECK_STATUS_RETURN(fileFilter.mimeTypeArray != nullptr, E_GETRESULT,
888         "Create MimeType native array value fail.");
889 
890     std::vector<std::string> mimeTypeVec = filter.GetMimeType();
891     errorCode = MakeStringNativeArray(env, mimeTypeVec, fileFilter.mimeTypeArray);
892     CHECK_STATUS_RETURN(errorCode == ERR_OK, errorCode,
893         "Create MimeType native array value fail, code:%{public}d.", errorCode);
894 
895     napi_create_int64(env, filter.GetFileSizeOver(), &fileFilter.nativeFileSizeOver);
896     CHECK_STATUS_RETURN(fileFilter.nativeFileSizeOver != nullptr, E_GETRESULT,
897         "Create NativeFileSizeOver native js value fail.");
898 
899     napi_create_double(env, filter.GetLastModifiedAfter(), &fileFilter.nativeLastModifiedAfter);
900     CHECK_STATUS_RETURN(fileFilter.nativeLastModifiedAfter != nullptr, E_GETRESULT,
901         "Create NativeLastModifiedAfter native js value fail.");
902 
903     napi_get_boolean(env, filter.GetExcludeMedia(), &fileFilter.nativeExcludeMedia);
904     CHECK_STATUS_RETURN(fileFilter.nativeExcludeMedia != nullptr, E_GETRESULT,
905         "Create NativeExcludeMedia native js value fail.");
906 
907     return ERR_OK;
908 }
909 
MakeJsNativeFileFilter(napi_env & env,const FileFilter & filter,napi_value nativeFilter)910 int JsFileAccessExtAbility::MakeJsNativeFileFilter(napi_env &env, const FileFilter &filter, napi_value nativeFilter)
911 {
912     struct FileFilterValue fileFilter;
913     int ret = CreateNativeValue(env, filter, fileFilter);
914     if (ret != ERR_OK) {
915         return ret;
916     }
917 
918     if (napi_set_named_property(env, nativeFilter, "suffix", fileFilter.suffixArray) != napi_ok) {
919         HILOG_ERROR("Set suffix property to Filter NativeValue fail.");
920         return EINVAL;
921     }
922 
923     if (napi_set_named_property(env, nativeFilter, "displayName", fileFilter.displayNameArray) != napi_ok) {
924         HILOG_ERROR("Set displayName property to Filter NativeValue fail.");
925         return EINVAL;
926     }
927 
928     if (napi_set_named_property(env, nativeFilter, "mimeType", fileFilter.mimeTypeArray) != napi_ok) {
929         HILOG_ERROR("Set mimeType property to Filter NativeValue fail.");
930         return EINVAL;
931     }
932 
933     if (napi_set_named_property(env, nativeFilter, "fileSizeOver", fileFilter.nativeFileSizeOver) != napi_ok) {
934         HILOG_ERROR("Set fileSizeOver property to Filter NativeValue fail.");
935         return EINVAL;
936     }
937 
938     if (napi_set_named_property(env, nativeFilter, "lastModifiedAfter",
939         fileFilter.nativeLastModifiedAfter) != napi_ok) {
940         HILOG_ERROR("Set lastModifiedAfter property to Filter NativeValue fail.");
941         return EINVAL;
942     }
943 
944     if (napi_set_named_property(env, nativeFilter, "excludeMedia", fileFilter.nativeExcludeMedia) != napi_ok) {
945         HILOG_ERROR("Set excludeMedia property to Filter NativeValue fail.");
946         return EINVAL;
947     }
948     return ERR_OK;
949 }
950 
BuildFileInfoNumParam(napi_env & env,FileInfoNumParam & param,napi_value * argv,size_t & argc)951 bool JsFileAccessExtAbility::BuildFileInfoNumParam(napi_env &env, FileInfoNumParam &param,
952     napi_value *argv, size_t &argc)
953 {
954     napi_value nativeSrcUri = nullptr;
955     napi_create_string_utf8(env, param.sourceFileUri.c_str(), param.sourceFileUri.length(), &nativeSrcUri);
956 
957     napi_value nativeFilter = nullptr;
958     if (param.filter.GetHasFilter()) {
959         napi_create_object(env, &nativeFilter);
960         if (nativeFilter == nullptr) {
961             HILOG_ERROR("Create js NativeValue object fail.");
962             return false;
963         }
964         int ret = MakeJsNativeFileFilter(env, param.filter, nativeFilter);
965         if (ret != ERR_OK) {
966             HILOG_ERROR("Make js nativeFilter fail.");
967             return false;
968         }
969     } else {
970         nativeFilter = nullptr;
971         napi_get_null(env, &nativeFilter);
972         if (nativeFilter == nullptr) {
973             HILOG_ERROR("Create js NativeValue null fail.");
974             return false;
975         }
976     }
977 
978     napi_value nativeRecursion = nullptr;
979     napi_get_boolean(env, param.recursion, &nativeRecursion);
980     if (nativeSrcUri == nullptr || nativeFilter == nullptr || nativeRecursion == nullptr) {
981         HILOG_ERROR("create arguments native js value fail.");
982         return false;
983     }
984     argv[ARGC_ZERO] = nativeSrcUri;
985     argv[ARGC_ONE] = nativeFilter;
986     argv[ARGC_TWO] = nativeRecursion;
987     argc = ARGC_THREE;
988     return true;
989 }
990 
ParserFileInfoNumJsResult(napi_env & env,napi_value & nativeValue,bool & success,uint32_t & counts)991 bool JsFileAccessExtAbility::ParserFileInfoNumJsResult(napi_env &env, napi_value &nativeValue, bool &success,
992     uint32_t &counts)
993 {
994     napi_value nativeSuccess = nullptr;
995     napi_get_named_property(env, nativeValue, "success", &nativeSuccess);
996     if (napi_get_value_bool(env, nativeSuccess, &success) != napi_ok) {
997         HILOG_ERROR("Convert js value fail.");
998         return false;
999     }
1000     if (!success) {
1001         return false;
1002     }
1003 
1004     napi_value nativeCounts = nullptr;
1005     napi_get_named_property(env, nativeValue, "counts", &nativeCounts);
1006     if (napi_get_value_uint32(env, nativeCounts, &counts) != napi_ok) {
1007         HILOG_ERROR("Convert js value fail.");
1008         return false;
1009     }
1010     HILOG_ERROR("left data is counts: %{public}u in storage media", counts);
1011     return true;
1012 }
1013 
GetFileInfoNum(const std::string & sourceFileUri,const FileFilter & filter,bool recursion,uint32_t & counts)1014 int JsFileAccessExtAbility::GetFileInfoNum(const std::string &sourceFileUri, const FileFilter &filter, bool recursion,
1015     uint32_t &counts)
1016 {
1017     UserAccessTracer trace;
1018     trace.Start("GetFileInfoNum");
1019     auto argParser = [sourceFileUri, filter, recursion](napi_env &env, napi_value *argv, size_t &argc) -> bool {
1020         struct FileInfoNumParam param = {
1021             sourceFileUri,
1022             filter,
1023             recursion,
1024         };
1025         return BuildFileInfoNumParam(env, param, argv, argc);
1026     };
1027 
1028     bool success = false;
1029     auto retParser = [&success, &counts](napi_env &env, napi_value result) -> bool {
1030         return ParserFileInfoNumJsResult(env, result, success, counts);
1031     };
1032 
1033     auto errCode = CallJsMethod("getFileInfoNum", jsRuntime_, jsObj_.get(), argParser, retParser);
1034     if (errCode != ERR_OK) {
1035         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
1036         return errCode;
1037     }
1038     return ERR_OK;
1039 }
1040 
BuildFilterParam(napi_env & env,const FileFilter & filter,const FilterParam & param,napi_value * argv,size_t & argc)1041 bool JsFileAccessExtAbility::BuildFilterParam(napi_env &env, const FileFilter &filter, const FilterParam &param,
1042     napi_value *argv, size_t &argc)
1043 {
1044     string uriStr = param.fileInfo.uri;
1045     napi_value uri = nullptr;
1046     napi_create_string_utf8(env, uriStr.c_str(), uriStr.length(), &uri);
1047     if (uri == nullptr) {
1048         HILOG_ERROR("Create sourceFile uri native js value fail.");
1049         return false;
1050     }
1051 
1052     napi_value nativeOffset = nullptr;
1053     napi_create_int64(env, param.offset, &nativeOffset);
1054     if (nativeOffset == nullptr) {
1055         HILOG_ERROR("Create offset native js value fail.");
1056         return false;
1057     }
1058 
1059     napi_value nativeMaxCount = nullptr;
1060     napi_create_int64(env, param.maxCount, &nativeMaxCount);
1061     if (nativeMaxCount == nullptr) {
1062         HILOG_ERROR("Create maxCount native js value fail.");
1063         return false;
1064     }
1065 
1066     napi_value nativeFilter = nullptr;
1067     if (filter.GetHasFilter()) {
1068         napi_create_object(env, &nativeFilter);
1069         if (nativeFilter == nullptr) {
1070             HILOG_ERROR("Create js NativeValue fail.");
1071             return false;
1072         }
1073         int ret = MakeJsNativeFileFilter(env, filter, nativeFilter);
1074         if (ret != ERR_OK) {
1075             HILOG_ERROR("Create js NativeValue fail.");
1076             return false;
1077         }
1078     } else {
1079         nativeFilter = nullptr;
1080         napi_get_null(env, &nativeFilter);
1081         if (nativeFilter == nullptr) {
1082             HILOG_ERROR("Create js NativeValue fail.");
1083             return false;
1084         }
1085     }
1086 
1087     argv[ARGC_ZERO] = uri;
1088     argv[ARGC_ONE] = nativeOffset;
1089     argv[ARGC_TWO] = nativeMaxCount;
1090     argv[ARGC_THREE] = nativeFilter;
1091     argc = ARGC_FOUR;
1092     return true;
1093 }
1094 
ListFile(const FileInfo & fileInfo,const int64_t offset,const int64_t maxCount,const FileFilter & filter,std::vector<FileInfo> & fileInfoVec)1095 int JsFileAccessExtAbility::ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount,
1096     const FileFilter &filter, std::vector<FileInfo> &fileInfoVec)
1097 {
1098     UserAccessTracer trace;
1099     trace.Start("ListFile");
1100     auto value = std::make_shared<Value<std::vector<FileInfo>>>();
1101     if (value == nullptr) {
1102         HILOG_ERROR("ListFile value is nullptr.");
1103         return E_GETRESULT;
1104     }
1105 
1106     auto argParser = [fileInfo, offset, maxCount, filter](napi_env &env, napi_value *argv, size_t &argc) -> bool {
1107         struct FilterParam param;
1108         param.fileInfo = fileInfo;
1109         param.offset = offset;
1110         param.maxCount = maxCount;
1111 
1112         return BuildFilterParam(env, filter, param, argv, argc);
1113     };
1114 
1115     auto retParser = [this, value](napi_env &env, napi_value result) -> bool {
1116         Value<std::vector<FileInfo>> fileInfo;
1117         bool ret = ParserListFileJsResult(env, result, fileInfo);
1118         if (!ret) {
1119             HILOG_ERROR("Parser js value fail.");
1120             return ret;
1121         }
1122 
1123         *value = std::move(fileInfo);
1124         return true;
1125     };
1126 
1127     auto errCode = CallJsMethod("listFile", jsRuntime_, jsObj_.get(), argParser, retParser);
1128     if (errCode != ERR_OK) {
1129         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
1130         return errCode;
1131     }
1132 
1133     if (value->code != ERR_OK) {
1134         HILOG_ERROR("fileio fail.");
1135         return value->code;
1136     }
1137 
1138     fileInfoVec = std::move(value->data);
1139     return ERR_OK;
1140 }
1141 
ScanFile(const FileInfo & fileInfo,const int64_t offset,const int64_t maxCount,const FileFilter & filter,std::vector<FileInfo> & fileInfoVec)1142 int JsFileAccessExtAbility::ScanFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount,
1143     const FileFilter &filter, std::vector<FileInfo> &fileInfoVec)
1144 {
1145     UserAccessTracer trace;
1146     trace.Start("ScanFile");
1147     auto value = std::make_shared<Value<std::vector<FileInfo>>>();
1148     if (value == nullptr) {
1149         HILOG_ERROR("ScanFile value is nullptr.");
1150         return E_GETRESULT;
1151     }
1152 
1153     auto argParser = [fileInfo, offset, maxCount, filter](napi_env &env, napi_value *argv, size_t &argc) -> bool {
1154         struct FilterParam param;
1155         param.fileInfo = fileInfo;
1156         param.offset = offset;
1157         param.maxCount = maxCount;
1158 
1159         return BuildFilterParam(env, filter, param, argv, argc);
1160     };
1161 
1162     auto retParser = [value](napi_env &env, napi_value result) -> bool {
1163         Value<std::vector<FileInfo>> fileInfo;
1164         bool ret = ParserListFileJsResult(env, result, fileInfo);
1165         if (!ret) {
1166             HILOG_ERROR("Parser js value fail.");
1167             return ret;
1168         }
1169 
1170         *value = std::move(fileInfo);
1171         return true;
1172     };
1173 
1174     auto errCode = CallJsMethod("scanFile", jsRuntime_, jsObj_.get(), argParser, retParser);
1175     if (errCode != ERR_OK) {
1176         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
1177         return errCode;
1178     }
1179 
1180     if (value->code != ERR_OK) {
1181         HILOG_ERROR("fileio fail.");
1182         return value->code;
1183     }
1184 
1185     fileInfoVec = std::move(value->data);
1186     return ERR_OK;
1187 }
1188 
ChangeCurrentDir(RootInfo & rootInfo)1189 void ChangeCurrentDir(RootInfo &rootInfo)
1190 {
1191     // 获取用户名
1192     std::string userName;
1193     if (!GetUserName(userName) || userName == "") {
1194         HILOG_WARN("get userName fail");
1195         return;
1196     }
1197     HILOG_DEBUG("GetuserName: %{public}s", userName.c_str());
1198     if (rootInfo.uri.rfind("file://docs/storage/Users/currentUser") == 0) {
1199         rootInfo.uri = "file://docs/storage/Users/" + userName;
1200     }
1201     if (rootInfo.relativePath.rfind("/storage/Users/currentUser") == 0) {
1202         rootInfo.relativePath = "/storage/Users/" + userName;
1203     }
1204 }
1205 
ParserGetRootsJsResult(napi_env & env,napi_value nativeValue,Value<std::vector<RootInfo>> & result)1206 bool JsFileAccessExtAbility::ParserGetRootsJsResult(napi_env &env, napi_value nativeValue,
1207     Value<std::vector<RootInfo>> &result)
1208 {
1209     napi_value code = nullptr;
1210     napi_get_named_property(env, nativeValue, "code", &code);
1211     if (napi_get_value_int32(env, code, &result.code) != napi_ok) {
1212         HILOG_ERROR("Get code fail");
1213         return false;
1214     }
1215 
1216     napi_value nativeArray = nullptr;
1217     napi_create_array(env, &nativeArray);
1218     napi_get_named_property(env, nativeValue, "roots", &nativeArray);
1219     if (nativeArray == nullptr) {
1220         HILOG_ERROR("nativeArray is nullptr");
1221         return false;
1222     }
1223 
1224     uint32_t length = 0;
1225     if (napi_get_array_length(env, nativeArray, &length) != napi_ok) {
1226         HILOG_ERROR("Get nativeArray length fail");
1227         return false;
1228     }
1229 
1230     for (uint32_t i = 0; i < length; i++) {
1231         napi_value nativeRootInfo = nullptr;
1232         napi_get_element(env, nativeArray, i, &nativeRootInfo);
1233         if (nativeRootInfo == nullptr) {
1234             HILOG_ERROR("Get native FileInfo fail.");
1235             return false;
1236         }
1237 
1238         RootInfo rootInfo;
1239         if (GetRootInfo(env, nativeRootInfo, rootInfo) != napi_ok) {
1240             HILOG_ERROR("Get native rootInfo fail.");
1241             return false;
1242         }
1243 
1244         if (IsFullMountEnable()) {
1245             ChangeCurrentDir(rootInfo);
1246         }
1247         result.data.emplace_back(std::move(rootInfo));
1248     }
1249     return true;
1250 }
1251 
GetRoots(std::vector<RootInfo> & rootInfoVec)1252 int JsFileAccessExtAbility::GetRoots(std::vector<RootInfo> &rootInfoVec)
1253 {
1254     UserAccessTracer trace;
1255     trace.Start("GetRoots");
1256     auto value = std::make_shared<Value<std::vector<RootInfo>>>();
1257     if (value == nullptr) {
1258         HILOG_ERROR("GetRoots value is nullptr.");
1259         return E_GETRESULT;
1260     }
1261 
1262     auto argParser = [](napi_env &env, napi_value *argv, size_t &argc) -> bool {
1263         argc = ARGC_ZERO;
1264         return true;
1265     };
1266 
1267     auto retParser = [value](napi_env &env, napi_value result) -> bool {
1268         Value<std::vector<RootInfo>> rootInfoVec;
1269         bool ret = ParserGetRootsJsResult(env, result, rootInfoVec);
1270         if (!ret) {
1271             HILOG_ERROR("Parser js value fail.");
1272             return ret;
1273         }
1274 
1275         *value = std::move(rootInfoVec);
1276         return true;
1277     };
1278 
1279     auto errCode = CallJsMethod("getRoots", jsRuntime_, jsObj_.get(), argParser, retParser);
1280     if (errCode != ERR_OK) {
1281         HILOG_ERROR("CallJsMethod error, code:%{public}d", errCode);
1282         return errCode;
1283     }
1284 
1285     if (value->code != ERR_OK) {
1286         HILOG_ERROR("fileio fail.");
1287         return value->code;
1288     }
1289 
1290     rootInfoVec = std::move(value->data);
1291     return ERR_OK;
1292 }
1293 
Access(const Uri & uri,bool & isExist)1294 int JsFileAccessExtAbility::Access(const Uri &uri, bool &isExist)
1295 {
1296     UserAccessTracer trace;
1297     trace.Start("Access");
1298     auto value = std::make_shared<Value<bool>>();
1299     if (value == nullptr) {
1300         HILOG_ERROR("Access value is nullptr.");
1301         return E_GETRESULT;
1302     }
1303 
1304     auto argParser = [uri](napi_env &env, napi_value *argv, size_t &argc) -> bool {
1305         napi_value nativeUri = nullptr;
1306         napi_create_string_utf8(env, uri.ToString().c_str(), uri.ToString().length(), &nativeUri);
1307         argv[ARGC_ZERO] = nativeUri;
1308         argc = ARGC_ONE;
1309         return true;
1310     };
1311 
1312     auto retParser = [value](napi_env &env, napi_value result) -> bool {
1313         napi_value isExist = nullptr;
1314         napi_get_named_property(env, result, "isExist", &isExist);
1315         if (napi_get_value_bool(env, isExist, &value->data) != napi_ok) {
1316             HILOG_ERROR("Convert js value fail.");
1317             return false;
1318         }
1319 
1320         napi_value code = nullptr;
1321         napi_get_named_property(env, result, "code", &code);
1322         if (napi_get_value_int32(env, code, &value->code) != napi_ok) {
1323             HILOG_ERROR("Convert js value fail.");
1324             return false;
1325         }
1326         return true;
1327     };
1328 
1329     auto errCode = CallJsMethod("access", jsRuntime_, jsObj_.get(), argParser, retParser);
1330     if (errCode != ERR_OK) {
1331         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
1332         return errCode;
1333     }
1334 
1335     if (value->code != ERR_OK) {
1336         HILOG_ERROR("fileio fail.");
1337         return value->code;
1338     }
1339 
1340     isExist = value->data;
1341     return ERR_OK;
1342 }
1343 
ParserQueryFileJsResult(napi_env & env,napi_value nativeValue,Value<std::vector<std::string>> & results)1344 bool JsFileAccessExtAbility::ParserQueryFileJsResult(napi_env &env, napi_value nativeValue,
1345     Value<std::vector<std::string>> &results)
1346 {
1347     napi_value code = nullptr;
1348     napi_get_named_property(env, nativeValue, "code", &code);
1349     if (napi_get_value_int32(env, code, &results.code) != napi_ok) {
1350         HILOG_ERROR("Convert code fail.");
1351         return false;
1352     }
1353 
1354     napi_value nativeArray = nullptr;
1355     napi_create_array(env, &nativeArray);
1356     napi_get_named_property(env, nativeValue, "results", &nativeArray);
1357     if (nativeArray == nullptr) {
1358         HILOG_ERROR("Convert js array object fail.");
1359         return false;
1360     }
1361 
1362     uint32_t length = 0;
1363     if (napi_get_array_length(env, nativeArray, &length) != napi_ok) {
1364         HILOG_ERROR("Get nativeArray length fail.");
1365         return false;
1366     }
1367     for (uint32_t i = 0; i < length; i++) {
1368         napi_value queryResult = nullptr;
1369         napi_get_element(env, nativeArray, i, &queryResult);
1370         if (queryResult == nullptr) {
1371             HILOG_ERROR("Get native queryResult fail.");
1372             return false;
1373         }
1374 
1375         std::string tempValue;
1376         if (GetStringValue(env, queryResult, tempValue) != napi_ok) {
1377             HILOG_ERROR("Convert js value fail.");
1378             return false;
1379         }
1380         results.data.emplace_back(std::move(tempValue));
1381     }
1382     return true;
1383 }
1384 
ConvertColumn(std::vector<std::string> & columns)1385 static void ConvertColumn(std::vector<std::string> &columns)
1386 {
1387     for (auto &column : columns) {
1388         for (auto &it : CONVERT_FILE_COLUMN) {
1389             if (column == it.first) {
1390                 column = it.second;
1391             }
1392         }
1393     }
1394 }
1395 
Query(const Uri & uri,std::vector<std::string> & columns,std::vector<std::string> & results)1396 int JsFileAccessExtAbility::Query(const Uri &uri, std::vector<std::string> &columns, std::vector<std::string> &results)
1397 {
1398     UserAccessTracer trace;
1399     trace.Start("Query");
1400     auto value = std::make_shared<Value<std::vector<std::string>>>();
1401     if (value == nullptr) {
1402         HILOG_ERROR("Query value is nullptr.");
1403         return E_GETRESULT;
1404     }
1405 
1406     ConvertColumn(columns);
1407     auto argParser = [uri, &columns](napi_env &env, napi_value *argv, size_t &argc) -> bool {
1408         if (ConstructQueryArg(env, argv, argc, uri, columns) != napi_ok) {
1409             HILOG_ERROR("Construct arg fail.");
1410             return false;
1411         }
1412         return true;
1413     };
1414 
1415     auto retParser = [value](napi_env &env, napi_value result) -> bool {
1416         Value<std::vector<std::string>> queryResult;
1417         bool ret = ParserQueryFileJsResult(env, result, queryResult);
1418         if (!ret) {
1419             HILOG_ERROR("Parser js value fail.");
1420             return ret;
1421         }
1422         value->code = queryResult.code;
1423         value->data = queryResult.data;
1424         return ret;
1425     };
1426 
1427     auto errCode = CallJsMethod("query", jsRuntime_, jsObj_.get(), argParser, retParser);
1428     if (errCode != ERR_OK) {
1429         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
1430         return errCode;
1431     }
1432 
1433     if (value->code != ERR_OK) {
1434         HILOG_ERROR("fileio fail.");
1435         return value->code;
1436     }
1437 
1438     results = std::move(value->data);
1439     return ERR_OK;
1440 }
1441 
GetFileInfoFromUri(const Uri & selectFile,FileInfo & fileInfo)1442 int JsFileAccessExtAbility::GetFileInfoFromUri(const Uri &selectFile, FileInfo &fileInfo)
1443 {
1444     UserAccessTracer trace;
1445     trace.Start("GetFileInfoFromUri");
1446     auto value = std::make_shared<Value<FileInfo>>();
1447     CHECK_STATUS_RETURN(value != nullptr, E_GETRESULT, "GetFileInfoFromUri value is nullptr.");
1448 
1449     auto argParser = [selectFile](napi_env &env, napi_value *argv, size_t &argc) -> bool {
1450         napi_value nativeUri = nullptr;
1451         napi_create_string_utf8(env, selectFile.ToString().c_str(), selectFile.ToString().length(), &nativeUri);
1452         if (nativeUri == nullptr) {
1453             HILOG_ERROR("create selectFile uri native js value fail.");
1454             return false;
1455         }
1456         argv[ARGC_ZERO] = nativeUri;
1457         argc = ARGC_ONE;
1458         return true;
1459     };
1460 
1461     auto retParser = [value](napi_env &env, napi_value result) -> bool {
1462         napi_value code = nullptr;
1463         napi_get_named_property(env, result, "code", &code);
1464         if (napi_get_value_int32(env, code, &value->code) != napi_ok) {
1465             HILOG_ERROR("Convert js value fail.");
1466             return false;
1467         }
1468 
1469         FileInfo fileInfo;
1470         napi_value nativeFileInfo = nullptr;
1471         if (napi_get_named_property(env, result, "fileInfo", &nativeFileInfo) != napi_ok) {
1472             HILOG_INFO("Convert fileInfo js value failed");
1473             return false;
1474         }
1475 
1476         if (GetFileInfoFromJs(env, nativeFileInfo, fileInfo) != napi_ok) {
1477             HILOG_ERROR("Convert fileInfo js value fail.");
1478             return false;
1479         }
1480         value->data = std::move(fileInfo);
1481         return true;
1482     };
1483 
1484     auto errCode = CallJsMethod("getFileInfoFromUri", jsRuntime_, jsObj_.get(), argParser, retParser);
1485     CHECK_STATUS_RETURN(errCode == ERR_OK, errCode, "CallJsMethod error, code:%{public}d.", errCode);
1486 
1487     CHECK_STATUS_RETURN(value->code == ERR_OK, value->code, "fileio fail.");
1488 
1489     fileInfo = std::move(value->data);
1490     return ERR_OK;
1491 }
1492 
GetFileInfoFromRelativePath(const std::string & selectFileRealtivePath,FileInfo & fileInfo)1493 int JsFileAccessExtAbility::GetFileInfoFromRelativePath(const std::string &selectFileRealtivePath, FileInfo &fileInfo)
1494 {
1495     UserAccessTracer trace;
1496     trace.Start("GetFileInfoFromRelativePath");
1497     auto value = std::make_shared<Value<FileInfo>>();
1498     CHECK_STATUS_RETURN((value != nullptr), E_GETRESULT, "GetFileInfoFromRelativePath value is nullptr.");
1499 
1500     auto argParser = [selectFileRealtivePath](napi_env &env, napi_value *argv, size_t &argc) -> bool {
1501         napi_value nativePath = nullptr;
1502         napi_create_string_utf8(env, selectFileRealtivePath.c_str(), selectFileRealtivePath.length(), &nativePath);
1503         if (nativePath == nullptr) {
1504             HILOG_ERROR("create selectFileRealtivePath native js value fail.");
1505             return false;
1506         }
1507         argv[ARGC_ZERO] = nativePath;
1508         argc = ARGC_ONE;
1509         return true;
1510     };
1511 
1512     auto retParser = [value](napi_env &env, napi_value result) -> bool {
1513         napi_value code = nullptr;
1514         napi_get_named_property(env, result, "code", &code);
1515         if (napi_get_value_int32(env, code, &value->code) != napi_ok) {
1516             HILOG_ERROR("Convert js value fail.");
1517             return false;
1518         }
1519 
1520         FileInfo fileInfo;
1521         napi_value nativeFileInfo = nullptr;
1522         if (napi_get_named_property(env, result, "fileInfo", &nativeFileInfo) != napi_ok) {
1523             HILOG_INFO("Convert fileInfo js value failed");
1524             return false;
1525         }
1526 
1527         if (GetFileInfoFromJs(env, nativeFileInfo, fileInfo) != napi_ok) {
1528             HILOG_ERROR("Convert fileInfo js value fail.");
1529             return false;
1530         }
1531         value->data = std::move(fileInfo);
1532         return true;
1533     };
1534 
1535     auto errCode = CallJsMethod("getFileInfoFromRelativePath", jsRuntime_, jsObj_.get(), argParser, retParser);
1536     CHECK_STATUS_RETURN((errCode == ERR_OK), errCode, "CallJsMethod error, code:%{public}d.", errCode);
1537 
1538     CHECK_STATUS_RETURN((value->code == ERR_OK), value->code, "fileio fail.");
1539 
1540     fileInfo = std::move(value->data);
1541     return ERR_OK;
1542 }
1543 
FuncCallback(napi_env env,napi_callback_info info)1544 napi_value JsFileAccessExtAbility::FuncCallback(napi_env env, napi_callback_info info)
1545 {
1546     UserAccessTracer trace;
1547     trace.Start("FuncCallback");
1548     if (env == nullptr) {
1549         HILOG_ERROR("NativeEngine pointer is null.");
1550         return nullptr;
1551     }
1552 
1553     if (info == nullptr) {
1554         HILOG_ERROR("invalid param.");
1555         return GetUndefinedValue(env);
1556     }
1557 
1558     size_t argc = ARGC_TWO;
1559     napi_value argv[ARGC_TWO] = { nullptr };
1560     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
1561     if (status != napi_ok) {
1562         HILOG_ERROR("napi_get_cb_info fail.");
1563         return GetUndefinedValue(env);
1564     }
1565 
1566     if (argc != ARGC_TWO) {
1567         HILOG_ERROR("invalid args.");
1568         return GetUndefinedValue(env);
1569     }
1570 
1571     std::string uriString;
1572     if (GetStringValue(env, argv[ARGC_ZERO], uriString) != napi_ok) {
1573         HILOG_ERROR("Get uri fail.");
1574         return GetUndefinedValue(env);
1575     }
1576     int32_t event = UnwrapInt32FromJS(env, argv[ARGC_ONE]);
1577 
1578     Uri uri(uriString);
1579     NotifyType notifyType = static_cast<NotifyType>(event);
1580     auto ret = Notify(uri, notifyType);
1581     if (ret != ERR_OK) {
1582         HILOG_ERROR("JsFileAccessExtAbility notify error, ret:%{public}d", ret);
1583     }
1584     return GetUndefinedValue(env);
1585 }
1586 
StartWatcher(const Uri & uri)1587 int JsFileAccessExtAbility::StartWatcher(const Uri &uri)
1588 {
1589     UserAccessTracer trace;
1590     trace.Start("StartWatcher");
1591     auto ret = std::make_shared<int>();
1592     if (ret == nullptr) {
1593         HILOG_ERROR("StartWatcher value is nullptr.");
1594         return E_GETRESULT;
1595     }
1596 
1597     auto argParser = [uri, this](napi_env &env, napi_value *argv, size_t &argc) -> bool {
1598         napi_value nativeUri = nullptr;
1599         napi_create_string_utf8(env, uri.ToString().c_str(), uri.ToString().length(), &nativeUri);
1600         if (nativeUri == nullptr) {
1601             HILOG_ERROR("create uri native js value fail.");
1602             return false;
1603         }
1604         const std::string funcName = "FuncCallback";
1605         napi_value func = nullptr;
1606         napi_create_function(env, funcName.c_str(), funcName.length(), JsFileAccessExtAbility::FuncCallback, nullptr,
1607             &func);
1608         if (func == nullptr) {
1609             HILOG_ERROR("Create function fail.");
1610             return false;
1611         }
1612         argv[ARGC_ZERO] = nativeUri;
1613         argv[ARGC_ONE] = func;
1614         argc = ARGC_TWO;
1615         return true;
1616     };
1617 
1618     auto retParser = [ret](napi_env &env, napi_value result) -> bool {
1619         if (napi_get_value_int32(env, result, ret.get()) != napi_ok) {
1620             HILOG_ERROR("Convert js value fail.");
1621             return false;
1622         }
1623         return true;
1624     };
1625 
1626     auto errCode = CallJsMethod("startWatcher", jsRuntime_, jsObj_.get(), argParser, retParser);
1627     if (errCode != ERR_OK) {
1628         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
1629         return errCode;
1630     }
1631 
1632     if (*ret != ERR_OK) {
1633         HILOG_ERROR("fileio fail.");
1634         return *ret;
1635     }
1636 
1637     return ERR_OK;
1638 }
1639 
StopWatcher(const Uri & uri)1640 int JsFileAccessExtAbility::StopWatcher(const Uri &uri)
1641 {
1642     UserAccessTracer trace;
1643     trace.Start("StopWatcher");
1644     auto ret = std::make_shared<int>();
1645     if (ret == nullptr) {
1646         HILOG_ERROR("StopWatcher value is nullptr.");
1647         return E_GETRESULT;
1648     }
1649 
1650     auto argParser = [uri](napi_env &env, napi_value *argv, size_t &argc) -> bool {
1651         napi_value nativeUri = nullptr;
1652         napi_create_string_utf8(env, uri.ToString().c_str(), uri.ToString().length(), &nativeUri);
1653         if (nativeUri == nullptr) {
1654             HILOG_ERROR("create uri native js value fail.");
1655             return false;
1656         }
1657 
1658         argv[ARGC_ZERO] = nativeUri;
1659         argc = ARGC_ONE;
1660         return true;
1661     };
1662 
1663     auto retParser = [ret](napi_env &env, napi_value result) -> bool {
1664         if (napi_get_value_int32(env, result, ret.get()) != napi_ok) {
1665             HILOG_ERROR("Convert js value fail.");
1666             return false;
1667         }
1668         return true;
1669     };
1670 
1671     auto errCode = CallJsMethod("stopWatcher", jsRuntime_, jsObj_.get(), argParser, retParser);
1672     if (errCode != ERR_OK) {
1673         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
1674         return errCode;
1675     }
1676 
1677     if (*ret != ERR_OK) {
1678         HILOG_ERROR("fileio fail.");
1679         return *ret;
1680     }
1681 
1682     return ERR_OK;
1683 }
1684 
Notify(Uri & uri,NotifyType notifyType)1685 int JsFileAccessExtAbility::Notify(Uri &uri, NotifyType notifyType)
1686 {
1687     UserAccessTracer trace;
1688     trace.Start("Notify");
1689     auto proxy = FileAccessServiceProxy::GetInstance();
1690     if (proxy == nullptr) {
1691         HILOG_ERROR("Notify get SA failed");
1692         return E_LOAD_SA;
1693     }
1694     auto ret = proxy->OnChange(uri, notifyType);
1695     if (ret != ERR_OK) {
1696         HILOG_ERROR("notify error, ret:%{public}d", ret);
1697         return ret;
1698     }
1699     return ERR_OK;
1700 }
1701 
GetFileInfoFromJs(napi_env & env,napi_value obj,FileInfo & fileInfo)1702 napi_status JsFileAccessExtAbility::GetFileInfoFromJs(napi_env &env, napi_value obj, FileInfo &fileInfo)
1703 {
1704     napi_value uri = nullptr;
1705     napi_get_named_property(env, obj, "uri", &uri);
1706     if (GetStringValue(env, uri, fileInfo.uri) != napi_ok) {
1707         HILOG_ERROR("Convert uri fail");
1708         return napi_generic_failure;
1709     }
1710 
1711     napi_value relativePath = nullptr;
1712     napi_get_named_property(env, obj, "relativePath", &relativePath);
1713     if (GetStringValue(env, relativePath, fileInfo.relativePath) != napi_ok) {
1714         HILOG_ERROR("Convert relativePath fail");
1715         return napi_generic_failure;
1716     }
1717 
1718     napi_value fileName = nullptr;
1719     napi_get_named_property(env, obj, "fileName", &fileName);
1720     if (GetStringValue(env, fileName, fileInfo.fileName) != napi_ok) {
1721         HILOG_ERROR("Convert fileName fail");
1722         return napi_generic_failure;
1723     }
1724 
1725     napi_value mode = nullptr;
1726     napi_get_named_property(env, obj, "mode", &mode);
1727     if (napi_get_value_int32(env, mode, &fileInfo.mode) != napi_ok) {
1728         HILOG_ERROR("Convert mode fail");
1729         return napi_generic_failure;
1730     }
1731 
1732     napi_value size = nullptr;
1733     napi_get_named_property(env, obj, "size", &size);
1734     if (napi_get_value_int64(env, size, &fileInfo.size) != napi_ok) {
1735         HILOG_ERROR("Convert size fail");
1736         return napi_generic_failure;
1737     }
1738 
1739     napi_value mtime = nullptr;
1740     napi_get_named_property(env, obj, "mtime", &mtime);
1741     if (napi_get_value_int64(env, mtime, &fileInfo.mtime) != napi_ok) {
1742         HILOG_ERROR("Convert mtime fail");
1743         return napi_generic_failure;
1744     }
1745 
1746     napi_value mimeType = nullptr;
1747     napi_get_named_property(env, obj, "mimeType", &mimeType);
1748     if (GetStringValue(env, mimeType, fileInfo.mimeType) != napi_ok) {
1749         HILOG_ERROR("Convert mimeType fail");
1750         return napi_generic_failure;
1751     }
1752 
1753     return napi_ok;
1754 }
1755 
GetUriAndCodeFromJs(napi_env & env,napi_value result,const std::shared_ptr<Value<std::string>> & value)1756 napi_status JsFileAccessExtAbility::GetUriAndCodeFromJs(napi_env &env, napi_value result,
1757     const std::shared_ptr<Value<std::string>> &value)
1758 {
1759     if (value == nullptr) {
1760         HILOG_ERROR("Value is null.");
1761         return napi_generic_failure;
1762     }
1763     napi_value uri = nullptr;
1764     napi_get_named_property(env, result, "uri", &uri);
1765     if (GetStringValue(env, uri, value->data) != napi_ok) {
1766         HILOG_ERROR("Convert js value fail.");
1767         return napi_generic_failure;
1768     }
1769 
1770     napi_value code = nullptr;
1771     napi_get_named_property(env, result, "code", &code);
1772     if (napi_get_value_int32(env, code, &value->code) != napi_ok) {
1773         HILOG_ERROR("Convert js value fail.");
1774         return napi_generic_failure;
1775     }
1776 
1777     return napi_ok;
1778 }
1779 
GetFdAndCodeFromJs(napi_env & env,napi_value result,const std::shared_ptr<Value<int>> & value)1780 napi_status JsFileAccessExtAbility::GetFdAndCodeFromJs(napi_env &env, napi_value result,
1781     const std::shared_ptr<Value<int>> &value)
1782 {
1783     napi_value fd = nullptr;
1784     napi_get_named_property(env, result, "fd", &fd);
1785     if (value == nullptr) {
1786         HILOG_ERROR("Value is null.");
1787         return napi_generic_failure;
1788     }
1789     if (napi_get_value_int32(env, fd, &value->data) != napi_ok) {
1790         HILOG_ERROR("Convert js value fail.");
1791         return napi_generic_failure;
1792     }
1793 
1794     napi_value code = nullptr;
1795     napi_get_named_property(env, result, "code", &code);
1796     if (napi_get_value_int32(env, code, &value->code) != napi_ok) {
1797         HILOG_ERROR("Convert js value fail.");
1798         return napi_generic_failure;
1799     }
1800 
1801     return napi_ok;
1802 }
1803 
ConstructQueryArg(napi_env & env,napi_value * argv,size_t & argc,const Uri & uri,std::vector<std::string> & columns)1804 napi_status JsFileAccessExtAbility::ConstructQueryArg(napi_env &env, napi_value *argv, size_t &argc, const Uri &uri,
1805     std::vector<std::string> &columns)
1806 {
1807     napi_value nativeUri = nullptr;
1808     napi_create_string_utf8(env, uri.ToString().c_str(), uri.ToString().length(), &nativeUri);
1809     if (nativeUri == nullptr) {
1810         HILOG_ERROR("create uri native js value fail.");
1811         return napi_generic_failure;
1812     }
1813 
1814     napi_value resultArray = nullptr;
1815     napi_create_array_with_length(env, columns.size(), &resultArray);
1816     if (resultArray == nullptr) {
1817         HILOG_ERROR("Create MimeType native array value fail.");
1818         return napi_generic_failure;
1819     }
1820     int errorCode = MakeStringNativeArray(env, columns, resultArray);
1821     if (errorCode != ERR_OK) {
1822         HILOG_ERROR("Create native array value fail, code:%{public}d.", errorCode);
1823         return napi_generic_failure;
1824     }
1825     argv[ARGC_ZERO] = nativeUri;
1826     argv[ARGC_ONE] = resultArray;
1827     argc = ARGC_TWO;
1828     return napi_ok;
1829 }
1830 
GetRootInfo(napi_env env,napi_value nativeRootInfo,RootInfo & rootInfo)1831 napi_status JsFileAccessExtAbility::GetRootInfo(napi_env env, napi_value nativeRootInfo, RootInfo &rootInfo)
1832 {
1833     napi_value deviceType = nullptr;
1834     napi_get_named_property(env, nativeRootInfo, "deviceType", &deviceType);
1835     if (napi_get_value_int32(env, deviceType, &rootInfo.deviceType) != napi_ok) {
1836         HILOG_ERROR("Get deviceType value fail.");
1837         return napi_generic_failure;
1838     }
1839 
1840     napi_value uri = nullptr;
1841     napi_get_named_property(env, nativeRootInfo, "uri", &uri);
1842     if (GetStringValue(env, uri, rootInfo.uri) != napi_ok) {
1843         HILOG_ERROR("Get uri value fail.");
1844         return napi_generic_failure;
1845     }
1846 
1847     napi_value relativePath = nullptr;
1848     napi_get_named_property(env, nativeRootInfo, "relativePath", &relativePath);
1849     if (GetStringValue(env, relativePath, rootInfo.relativePath) != napi_ok) {
1850         HILOG_ERROR("Get relativePath value fail.");
1851         return napi_generic_failure;
1852     }
1853 
1854     napi_value displayName = nullptr;
1855     napi_get_named_property(env, nativeRootInfo, "displayName", &displayName);
1856     if (GetStringValue(env, displayName, rootInfo.displayName) != napi_ok) {
1857         HILOG_ERROR("Get displayName value fail.");
1858         return napi_generic_failure;
1859     }
1860 
1861     napi_value deviceFlags = nullptr;
1862     napi_get_named_property(env, nativeRootInfo, "deviceFlags", &deviceFlags);
1863     if (napi_get_value_int32(env, deviceFlags, &rootInfo.deviceFlags) != napi_ok) {
1864         HILOG_ERROR("Get deviceFlags value fail.");
1865         return napi_generic_failure;
1866     }
1867 
1868     return napi_ok;
1869 }
1870 
MoveItem(const Uri & sourceFile,const Uri & targetParent,std::vector<Result> & moveResult,bool force)1871 int JsFileAccessExtAbility::MoveItem(const Uri &sourceFile, const Uri &targetParent,
1872                                      std::vector<Result> &moveResult, bool force)
1873 {
1874     UserAccessTracer trace;
1875     trace.Start("MoveItem");
1876     auto argParser = [sourceFile, targetParent, force](napi_env &env, napi_value *argv, size_t &argc) -> bool {
1877         HILOG_ERROR("MoveItem argParser start");
1878         napi_value srcNativeUri = nullptr;
1879         napi_create_string_utf8(env, sourceFile.ToString().c_str(), sourceFile.ToString().length(), &srcNativeUri);
1880 
1881         napi_value dstNativeUri = nullptr;
1882         napi_create_string_utf8(env, targetParent.ToString().c_str(), targetParent.ToString().length(), &dstNativeUri);
1883 
1884         napi_value forceMove = nullptr;
1885         napi_get_boolean(env, force, &forceMove);
1886         if (srcNativeUri == nullptr || dstNativeUri == nullptr || forceMove == nullptr) {
1887             HILOG_ERROR("create arguments native js value fail.");
1888             return false;
1889         }
1890         argv[ARGC_ZERO] = srcNativeUri;
1891         argv[ARGC_ONE] = dstNativeUri;
1892         argv[ARGC_TWO] = forceMove;
1893         argc = ARGC_THREE;
1894         return true;
1895     };
1896 
1897     int ret = EXCEPTION;
1898     auto retParser = [&moveResult, &ret](napi_env &env, napi_value result) -> bool {
1899         return ParserGetJsResult(env, result, moveResult, ret);
1900     };
1901 
1902     auto errCode = CallJsMethod("moveItem", jsRuntime_, jsObj_.get(), argParser, retParser);
1903     if (errCode != ERR_OK) {
1904         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
1905         Result result { "", "", errCode, ""};
1906         TranslateResult(result);
1907         moveResult.push_back(result);
1908         return EXCEPTION;
1909     }
1910 
1911     return ret;
1912 }
1913 
MoveFile(const Uri & sourceFile,const Uri & targetParent,std::string & fileName,Uri & newFile)1914 int JsFileAccessExtAbility::MoveFile(const Uri &sourceFile, const Uri &targetParent, std::string &fileName,
1915                                      Uri &newFile)
1916 {
1917     UserAccessTracer trace;
1918     trace.Start("MoveFile");
1919     auto value = std::make_shared<Value<std::string>>();
1920     if (value == nullptr) {
1921         HILOG_ERROR("MoveFile value is nullptr.");
1922         return E_GETRESULT;
1923     }
1924 
1925     auto argParser = [sourceFile, targetParent, fileName](napi_env &env, napi_value *argv, size_t &argc) -> bool {
1926         napi_value srcUri = nullptr;
1927         napi_create_string_utf8(env, sourceFile.ToString().c_str(), sourceFile.ToString().length(), &srcUri);
1928         napi_value dstUri = nullptr;
1929         napi_create_string_utf8(env, targetParent.ToString().c_str(), targetParent.ToString().length(), &dstUri);
1930         napi_value name = nullptr;
1931         napi_create_string_utf8(env, fileName.c_str(), fileName.length(), &name);
1932         if (srcUri == nullptr || dstUri == nullptr || name == nullptr) {
1933             HILOG_ERROR("create sourceFile uri native js value fail.");
1934             return false;
1935         }
1936         argv[ARGC_ZERO] = srcUri;
1937         argv[ARGC_ONE] = dstUri;
1938         argv[ARGC_TWO] = name;
1939         argc = ARGC_THREE;
1940         return true;
1941     };
1942 
1943     auto retParser = [value](napi_env &env, napi_value result) -> bool {
1944         if (GetUriAndCodeFromJs(env, result, value) != napi_ok) {
1945             HILOG_ERROR("Convert js object fail.");
1946             return false;
1947         }
1948         return true;
1949     };
1950 
1951     auto errCode = CallJsMethod("moveFile", jsRuntime_, jsObj_.get(), argParser, retParser);
1952     if (errCode != ERR_OK) {
1953         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
1954         return errCode;
1955     }
1956 
1957     if (value->code != ERR_OK) {
1958         HILOG_ERROR("fileio fail.");
1959         return value->code;
1960     }
1961 
1962     if ((value->data).empty()) {
1963         HILOG_ERROR("call move with return empty.");
1964         return E_GETRESULT;
1965     }
1966     newFile = Uri(value->data);
1967     return ERR_OK;
1968 }
1969 } // namespace FileAccessFwk
1970 } // namespace OHOS
1971