• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
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_service_proxy.h"
22 #include "file_access_ext_stub_impl.h"
23 #include "file_access_observer_common.h"
24 #include "file_access_extension_info.h"
25 #include "file_access_framework_errno.h"
26 #include "hilog_wrapper.h"
27 #include "hitrace_meter.h"
28 #include "if_system_ability_manager.h"
29 #include "ipc_skeleton.h"
30 #include "iservice_registry.h"
31 #include "js_runtime.h"
32 #include "js_runtime_utils.h"
33 #include "napi/native_api.h"
34 #include "napi/native_node_api.h"
35 #include "napi_common_util.h"
36 #include "napi_common_want.h"
37 #include "napi_remote_object.h"
38 #include "system_ability_definition.h"
39 #include "n_error.h"
40 #include "user_access_tracer.h"
41 
42 namespace OHOS {
43 namespace FileAccessFwk {
44 namespace {
45     constexpr size_t ARGC_ZERO = 0;
46     constexpr size_t ARGC_ONE = 1;
47     constexpr size_t ARGC_TWO = 2;
48     constexpr size_t ARGC_THREE = 3;
49     constexpr size_t ARGC_FOUR = 4;
50     constexpr size_t MAX_ARG_COUNT = 5;
51     constexpr int COPY_EXCEPTION = -1;
52     constexpr int COPY_NOEXCEPTION = -2;
53 }
54 
55 using namespace OHOS::AppExecFwk;
56 using namespace OHOS::AbilityRuntime;
57 using namespace OHOS::FileManagement::LibN;
58 using OHOS::Security::AccessToken::AccessTokenKit;
59 
60 struct FilterParam {
61     FileInfo fileInfo;
62     int64_t offset;
63     int64_t maxCount;
64 };
65 
Create(const std::unique_ptr<Runtime> & runtime)66 JsFileAccessExtAbility* JsFileAccessExtAbility::Create(const std::unique_ptr<Runtime> &runtime)
67 {
68     return new JsFileAccessExtAbility(static_cast<JsRuntime&>(*runtime));
69 }
70 
JsFileAccessExtAbility(JsRuntime & jsRuntime)71 JsFileAccessExtAbility::JsFileAccessExtAbility(JsRuntime &jsRuntime) : jsRuntime_(jsRuntime) {}
72 
~JsFileAccessExtAbility()73 JsFileAccessExtAbility::~JsFileAccessExtAbility()
74 {
75     jsRuntime_.FreeNativeReference(std::move(jsObj_));
76 }
77 
Init(const std::shared_ptr<AbilityLocalRecord> & record,const std::shared_ptr<OHOSApplication> & application,std::shared_ptr<AbilityHandler> & handler,const sptr<IRemoteObject> & token)78 void JsFileAccessExtAbility::Init(const std::shared_ptr<AbilityLocalRecord> &record,
79     const std::shared_ptr<OHOSApplication> &application, std::shared_ptr<AbilityHandler> &handler,
80     const sptr<IRemoteObject> &token)
81 {
82     UserAccessTracer trace;
83     trace.Start("Init");
84     FileAccessExtAbility::Init(record, application, handler, token);
85     std::string srcPath = "";
86     GetSrcPath(srcPath);
87     if (srcPath.empty()) {
88         HILOG_ERROR("Failed to get srcPath");
89         return;
90     }
91 
92     std::string moduleName(Extension::abilityInfo_->moduleName);
93     moduleName.append("::").append(abilityInfo_->name);
94     HandleScope handleScope(jsRuntime_);
95 
96     jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath,
97         abilityInfo_->compileMode == AbilityRuntime::CompileMode::ES_MODULE);
98     if (jsObj_ == nullptr) {
99         HILOG_ERROR("Failed to get jsObj_");
100         return;
101     }
102 
103     NativeObject* obj = ConvertNativeValueTo<NativeObject>(jsObj_->Get());
104     if (obj == nullptr) {
105         HILOG_ERROR("Failed to get JsFileAccessExtAbility object");
106         return;
107     }
108 }
109 
OnStart(const AAFwk::Want & want)110 void JsFileAccessExtAbility::OnStart(const AAFwk::Want &want)
111 {
112     UserAccessTracer trace;
113     trace.Start("OnStart");
114     Extension::OnStart(want);
115     HandleScope handleScope(jsRuntime_);
116     napi_env env = reinterpret_cast<napi_env>(&jsRuntime_.GetNativeEngine());
117     napi_value napiWant = OHOS::AppExecFwk::WrapWant(env, want);
118     NativeValue* nativeWant = reinterpret_cast<NativeValue*>(napiWant);
119     NativeValue* argv[] = {nativeWant};
120     CallObjectMethod("onCreate", argv, ARGC_ONE);
121 }
122 
OnConnect(const AAFwk::Want & want)123 sptr<IRemoteObject> JsFileAccessExtAbility::OnConnect(const AAFwk::Want &want)
124 {
125     UserAccessTracer trace;
126     trace.Start("OnConnect");
127     Extension::OnConnect(want);
128     sptr<FileAccessExtStubImpl> remoteObject(new (std::nothrow) FileAccessExtStubImpl(
129         std::static_pointer_cast<JsFileAccessExtAbility>(shared_from_this()),
130         reinterpret_cast<napi_env>(&jsRuntime_.GetNativeEngine())));
131     if (remoteObject == nullptr) {
132         HILOG_ERROR("No memory allocated for FileExtStubImpl");
133         return nullptr;
134     }
135 
136     return remoteObject->AsObject();
137 }
138 
CallObjectMethod(const char * name,NativeValue * const * argv,size_t argc)139 NativeValue* JsFileAccessExtAbility::CallObjectMethod(const char* name, NativeValue* const* argv, size_t argc)
140 {
141     UserAccessTracer trace;
142     trace.Start("CallObjectMethod");
143     if (!jsObj_) {
144         HILOG_ERROR("JsFileAccessExtAbility::CallObjectMethod jsObj Not found FileAccessExtAbility.js");
145         return nullptr;
146     }
147 
148     HandleEscape handleEscape(jsRuntime_);
149     auto& nativeEngine = jsRuntime_.GetNativeEngine();
150 
151     NativeValue* value = jsObj_->Get();
152     if (value == nullptr) {
153         HILOG_ERROR("Failed to get FileAccessExtAbility value");
154         return nullptr;
155     }
156 
157     NativeObject* obj = ConvertNativeValueTo<NativeObject>(value);
158     if (obj == nullptr) {
159         HILOG_ERROR("Failed to get FileAccessExtAbility object");
160         return nullptr;
161     }
162 
163     NativeValue* method = obj->GetProperty(name);
164     if (method == nullptr) {
165         HILOG_ERROR("Failed to get '%{public}s' from FileAccessExtAbility object", name);
166         return nullptr;
167     }
168 
169     return handleEscape.Escape(nativeEngine.CallFunction(value, method, argv, argc));
170 }
171 
DoCallJsMethod(CallJsParam * param)172 static int DoCallJsMethod(CallJsParam *param)
173 {
174     UserAccessTracer trace;
175     trace.Start("DoCallJsMethod");
176     JsRuntime *jsRuntime = param->jsRuntime;
177     if (jsRuntime == nullptr) {
178         HILOG_ERROR("failed to get jsRuntime.");
179         return EINVAL;
180     }
181     HandleEscape handleEscape(*jsRuntime);
182     auto& nativeEngine = jsRuntime->GetNativeEngine();
183     size_t argc = 0;
184     NativeValue *argv[MAX_ARG_COUNT] = { nullptr };
185     if (param->argParser != nullptr) {
186         if (!param->argParser(nativeEngine, argv, argc)) {
187             HILOG_ERROR("failed to get params.");
188             return EINVAL;
189         }
190     }
191     NativeValue *value = param->jsObj->Get();
192     if (value == nullptr) {
193         HILOG_ERROR("failed to get native value object.");
194         return EINVAL;
195     }
196     NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
197     if (obj == nullptr) {
198         HILOG_ERROR("failed to get FileExtAbility object.");
199         return EINVAL;
200     }
201     NativeValue *method = obj->GetProperty(param->funcName.c_str());
202     if (method == nullptr) {
203         HILOG_ERROR("failed to get %{public}s from FileExtAbility object.", param->funcName.c_str());
204         return EINVAL;
205     }
206     if (param->retParser == nullptr) {
207         HILOG_ERROR("ResultValueParser must not null.");
208         return EINVAL;
209     }
210     if (!param->retParser(nativeEngine, handleEscape.Escape(nativeEngine.CallFunction(value, method, argv, argc)))) {
211         HILOG_INFO("Parser js result fail.");
212         return E_GETRESULT;
213     }
214     return ERR_OK;
215 }
216 
CallJsMethod(const std::string & funcName,JsRuntime & jsRuntime,NativeReference * jsObj,InputArgsParser argParser,ResultValueParser retParser)217 int JsFileAccessExtAbility::CallJsMethod(const std::string &funcName, JsRuntime &jsRuntime, NativeReference *jsObj,
218     InputArgsParser argParser, ResultValueParser retParser)
219 {
220     UserAccessTracer trace;
221     trace.Start("CallJsMethod");
222     uv_loop_s *loop = nullptr;
223     napi_status status = napi_get_uv_event_loop(reinterpret_cast<napi_env>(&jsRuntime.GetNativeEngine()), &loop);
224     if (status != napi_ok) {
225         HILOG_ERROR("failed to get uv event loop.");
226         return EINVAL;
227     }
228     auto param = std::make_shared<CallJsParam>(funcName, &jsRuntime, jsObj, argParser, retParser);
229     if (param == nullptr) {
230         HILOG_ERROR("failed to new param.");
231         return EINVAL;
232     }
233     auto work = std::make_shared<uv_work_t>();
234     if (work == nullptr) {
235         HILOG_ERROR("failed to new uv_work_t.");
236         return EINVAL;
237     }
238     work->data = reinterpret_cast<void *>(param.get());
239     int ret = uv_queue_work(loop, work.get(), [](uv_work_t *work) {}, [](uv_work_t *work, int status) {
240         CallJsParam *param = reinterpret_cast<CallJsParam *>(work->data);
241         napi_handle_scope scope = nullptr;
242         napi_env env = reinterpret_cast<napi_env>(&(param->jsRuntime->GetNativeEngine()));
243         napi_open_handle_scope(env, &scope);
244         do {
245             if (param == nullptr) {
246                 HILOG_ERROR("failed to get CallJsParam.");
247                 break;
248             }
249             if (DoCallJsMethod(param) != ERR_OK) {
250                 HILOG_ERROR("failed to call DoCallJsMethod.");
251             }
252         } while (false);
253         std::unique_lock<std::mutex> lock(param->fileOperateMutex);
254         param->isReady = true;
255         param->fileOperateCondition.notify_one();
256         napi_close_handle_scope(env, scope);
257     });
258     if (ret != 0) {
259         HILOG_ERROR("failed to exec uv_queue_work.");
260         return EINVAL;
261     }
262     std::unique_lock<std::mutex> lock(param->fileOperateMutex);
263     param->fileOperateCondition.wait(lock, [param]() { return param->isReady; });
264     return ERR_OK;
265 }
266 
GetSrcPath(std::string & srcPath)267 void JsFileAccessExtAbility::GetSrcPath(std::string &srcPath)
268 {
269     UserAccessTracer trace;
270     trace.Start("GetSrcPath");
271     if (!Extension::abilityInfo_->isStageBasedModel) {
272         /* temporary compatibility api8 + config.json */
273         srcPath.append(Extension::abilityInfo_->package);
274         srcPath.append("/assets/js/");
275         if (!Extension::abilityInfo_->srcPath.empty()) {
276             srcPath.append(Extension::abilityInfo_->srcPath);
277         }
278         srcPath.append("/").append(Extension::abilityInfo_->name).append(".abc");
279         return;
280     }
281 
282     if (!Extension::abilityInfo_->srcEntrance.empty()) {
283         srcPath.append(Extension::abilityInfo_->moduleName + "/");
284         srcPath.append(Extension::abilityInfo_->srcEntrance);
285         srcPath.erase(srcPath.rfind('.'));
286         srcPath.append(".abc");
287     }
288 }
289 
290 template <typename T>
291 struct Value {
292     T data;
293     int code {ERR_OK};
294 };
295 
OpenFile(const Uri & uri,int flags,int & fd)296 int JsFileAccessExtAbility::OpenFile(const Uri &uri, int flags, int &fd)
297 {
298     UserAccessTracer trace;
299     trace.Start("OpenFile");
300     auto value = std::make_shared<Value<int>>();
301     if (value == nullptr) {
302         HILOG_ERROR("OpenFile value is nullptr.");
303         return E_GETRESULT;
304     }
305 
306     auto argParser = [uri, flags](NativeEngine &engine, NativeValue *argv[], size_t &argc) -> bool {
307         NativeValue *nativeUri = engine.CreateString(uri.ToString().c_str(), uri.ToString().length());
308         NativeValue *nativeFlags = engine.CreateNumber((int32_t)flags);
309         if (nativeUri == nullptr || nativeFlags == nullptr) {
310             HILOG_ERROR("create uri or flags native js value fail.");
311             return false;
312         }
313         argv[ARGC_ZERO] = nativeUri;
314         argv[ARGC_ONE] = nativeFlags;
315         argc = ARGC_TWO;
316         return true;
317     };
318     auto retParser = [value](NativeEngine &engine, NativeValue *result) -> bool {
319         NativeObject *obj = ConvertNativeValueTo<NativeObject>(result);
320         if (obj == nullptr) {
321             HILOG_ERROR("Convert js object fail.");
322             return false;
323         }
324 
325         bool ret = ConvertFromJsValue(engine, obj->GetProperty("fd"), value->data);
326         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("code"), value->code);
327         if (!ret) {
328             HILOG_ERROR("Convert js value fail.");
329         }
330         return ret;
331     };
332 
333     auto errCode = CallJsMethod("openFile", jsRuntime_, jsObj_.get(), argParser, retParser);
334     if (errCode != ERR_OK) {
335         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
336         return errCode;
337     }
338 
339     if (value->code != ERR_OK) {
340         HILOG_ERROR("fileio fail.");
341         return value->code;
342     }
343 
344     fd = value->data;
345     if (fd < ERR_OK) {
346         HILOG_ERROR("Failed to get file descriptor fd: %{public}d", fd);
347         return E_GETRESULT;
348     }
349     return ERR_OK;
350 }
351 
CreateFile(const Uri & parent,const std::string & displayName,Uri & newFile)352 int JsFileAccessExtAbility::CreateFile(const Uri &parent, const std::string &displayName, Uri &newFile)
353 {
354     UserAccessTracer trace;
355     trace.Start("CreateFile");
356     auto value = std::make_shared<Value<std::string>>();
357     if (!value) {
358         HILOG_ERROR("CreateFile value is nullptr.");
359         return E_GETRESULT;
360     }
361 
362     auto argParser = [parent, displayName](NativeEngine &engine, NativeValue *argv[], size_t &argc) -> bool {
363         NativeValue *nativeParent = engine.CreateString(parent.ToString().c_str(), parent.ToString().length());
364         NativeValue *nativeDisplayName = engine.CreateString(displayName.c_str(), displayName.length());
365         if (nativeParent == nullptr || nativeDisplayName == nullptr) {
366             HILOG_ERROR("create parent uri or displayName native js value fail.");
367             return false;
368         }
369         argv[ARGC_ZERO] = nativeParent;
370         argv[ARGC_ONE] = nativeDisplayName;
371         argc = ARGC_TWO;
372         return true;
373     };
374     auto retParser = [value](NativeEngine &engine, NativeValue *result) -> bool {
375         NativeObject *obj = ConvertNativeValueTo<NativeObject>(result);
376         if (obj == nullptr) {
377             HILOG_ERROR("Convert js object fail.");
378             return false;
379         }
380 
381         bool ret = ConvertFromJsValue(engine, obj->GetProperty("uri"), value->data);
382         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("code"), value->code);
383         if (!ret) {
384             HILOG_ERROR("Convert js value fail.");
385         }
386         return ret;
387     };
388 
389     auto errCode = CallJsMethod("createFile", jsRuntime_, jsObj_.get(), argParser, retParser);
390     if (errCode != ERR_OK) {
391         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
392         return errCode;
393     }
394 
395     if (value->code != ERR_OK) {
396         HILOG_ERROR("fileio fail.");
397         return value->code;
398     }
399 
400     if ((value->data).empty()) {
401         HILOG_ERROR("call CreateFile with return empty.");
402         return E_GETRESULT;
403     }
404 
405     newFile = Uri(value->data);
406     return ERR_OK;
407 }
408 
Mkdir(const Uri & parent,const std::string & displayName,Uri & newFile)409 int JsFileAccessExtAbility::Mkdir(const Uri &parent, const std::string &displayName, Uri &newFile)
410 {
411     UserAccessTracer trace;
412     trace.Start("Mkdir");
413     auto value = std::make_shared<Value<std::string>>();
414     if (!value) {
415         HILOG_ERROR("Mkdir value is nullptr.");
416         return E_GETRESULT;
417     }
418 
419     auto argParser = [parent, displayName](NativeEngine &engine, NativeValue *argv[], size_t &argc) -> bool {
420         NativeValue *nativeParent = engine.CreateString(parent.ToString().c_str(), parent.ToString().length());
421         NativeValue *nativeDisplayName = engine.CreateString(displayName.c_str(), displayName.length());
422         if (nativeParent == nullptr || nativeDisplayName == nullptr) {
423             HILOG_ERROR("create parent uri native js value fail.");
424             return false;
425         }
426         argv[ARGC_ZERO] = nativeParent;
427         argv[ARGC_ONE] = nativeDisplayName;
428         argc = ARGC_TWO;
429         return true;
430     };
431     auto retParser = [value](NativeEngine &engine, NativeValue *result) -> bool {
432         NativeObject *obj = ConvertNativeValueTo<NativeObject>(result);
433         if (obj == nullptr) {
434             HILOG_ERROR("Convert js object fail.");
435             return false;
436         }
437 
438         bool ret = ConvertFromJsValue(engine, obj->GetProperty("uri"), value->data);
439         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("code"), value->code);
440         if (!ret) {
441             HILOG_ERROR("Convert js value fail.");
442         }
443 
444         return ret;
445     };
446 
447     auto errCode = CallJsMethod("mkdir", jsRuntime_, jsObj_.get(), argParser, retParser);
448     if (errCode != ERR_OK) {
449         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
450         return errCode;
451     }
452 
453     if (value->code != ERR_OK) {
454         HILOG_ERROR("fileio fail.");
455         return value->code;
456     }
457 
458     if ((value->data).empty()) {
459         HILOG_ERROR("call Mkdir with return empty.");
460         return E_GETRESULT;
461     }
462     newFile = Uri(value->data);
463     return ERR_OK;
464 }
465 
Delete(const Uri & sourceFile)466 int JsFileAccessExtAbility::Delete(const Uri &sourceFile)
467 {
468     UserAccessTracer trace;
469     trace.Start("Delete");
470     auto ret = std::make_shared<int>();
471     if (!ret) {
472         HILOG_ERROR("Delete value is nullptr.");
473         return E_GETRESULT;
474     }
475 
476     auto argParser = [uri = sourceFile](NativeEngine &engine, NativeValue *argv[], size_t &argc) -> bool {
477         NativeValue *nativeUri = engine.CreateString(uri.ToString().c_str(), uri.ToString().length());
478         if (nativeUri == nullptr) {
479             HILOG_ERROR("create sourceFile uri native js value fail.");
480             return false;
481         }
482         argv[ARGC_ZERO] = nativeUri;
483         argc = ARGC_ONE;
484         return true;
485     };
486     auto retParser = [ret](NativeEngine &engine, NativeValue *result) -> bool {
487         bool res = ConvertFromJsValue(engine, result, *ret);
488         if (!res) {
489             HILOG_ERROR("Convert js value fail.");
490         }
491         return res;
492     };
493 
494     auto errCode = CallJsMethod("delete", jsRuntime_, jsObj_.get(), argParser, retParser);
495     if (errCode != ERR_OK) {
496         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
497         return errCode;
498     }
499 
500     if (*ret != ERR_OK) {
501         HILOG_ERROR("fileio fail.");
502         return *ret;
503     }
504 
505     return ERR_OK;
506 }
507 
Move(const Uri & sourceFile,const Uri & targetParent,Uri & newFile)508 int JsFileAccessExtAbility::Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile)
509 {
510     UserAccessTracer trace;
511     trace.Start("Move");
512     auto value = std::make_shared<Value<std::string>>();
513     if (value == nullptr) {
514         HILOG_ERROR("Move value is nullptr.");
515         return E_GETRESULT;
516     }
517 
518     auto argParser = [sourceFile, targetParent](NativeEngine &engine, NativeValue* argv[], size_t &argc) -> bool {
519         NativeValue *srcUri = engine.CreateString(sourceFile.ToString().c_str(),
520             sourceFile.ToString().length());
521         NativeValue *dstUri = engine.CreateString(targetParent.ToString().c_str(), targetParent.ToString().length());
522         if (srcUri == nullptr || dstUri == nullptr) {
523             HILOG_ERROR("create sourceFile uri native js value fail.");
524             return false;
525         }
526         argv[ARGC_ZERO] = srcUri;
527         argv[ARGC_ONE] = dstUri;
528         argc = ARGC_TWO;
529         return true;
530     };
531     auto retParser = [value](NativeEngine &engine, NativeValue *result) -> bool {
532         NativeObject *obj = ConvertNativeValueTo<NativeObject>(result);
533         if (obj == nullptr) {
534             HILOG_ERROR("Convert js object fail.");
535             return false;
536         }
537 
538         bool ret = ConvertFromJsValue(engine, obj->GetProperty("uri"), value->data);
539         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("code"), value->code);
540         if (!ret) {
541             HILOG_ERROR("Convert js value fail.");
542         }
543         return ret;
544     };
545 
546     auto errCode = CallJsMethod("move", jsRuntime_, jsObj_.get(), argParser, retParser);
547     if (errCode != ERR_OK) {
548         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
549         return errCode;
550     }
551 
552     if (value->code != ERR_OK) {
553         HILOG_ERROR("fileio fail.");
554         return value->code;
555     }
556 
557     if ((value->data).empty()) {
558         HILOG_ERROR("call move with return empty.");
559         return E_GETRESULT;
560     }
561     newFile = Uri(value->data);
562     return ERR_OK;
563 }
564 
TranslateCopyResult(CopyResult & copyResult)565 static void TranslateCopyResult(CopyResult &copyResult)
566 {
567     if (errCodeTable.find(copyResult.errCode) != errCodeTable.end()) {
568         copyResult.errCode = errCodeTable.at(copyResult.errCode).first;
569         if (copyResult.errMsg.empty()) {
570             copyResult.errMsg = errCodeTable.at(copyResult.errCode).second;
571         }
572     }
573 }
574 
GetResultByJs(NativeEngine & engine,NativeValue * nativeCopyResult,CopyResult & result,int & copyRet)575 static bool GetResultByJs(NativeEngine &engine, NativeValue *nativeCopyResult, CopyResult &result, int &copyRet)
576 {
577     UserAccessTracer trace;
578     trace.Start("GetResultsByJs");
579     NativeObject *obj = ConvertNativeValueTo<NativeObject>(nativeCopyResult);
580     if (obj == nullptr) {
581         HILOG_ERROR("Convert js object fail.");
582         return false;
583     }
584 
585     bool ret = true;
586     if (copyRet == COPY_NOEXCEPTION) {
587         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("sourceUri"), result.sourceUri);
588         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("destUri"), result.destUri);
589     }
590     if ((copyRet == COPY_NOEXCEPTION) || (copyRet == COPY_EXCEPTION)) {
591         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("errCode"), result.errCode);
592     }
593     if (!ret) {
594         HILOG_ERROR("Convert js value fail.");
595     }
596     return ret;
597 }
598 
ParserGetJsCopyResult(NativeEngine & engine,NativeValue * nativeValue,std::vector<CopyResult> & copyResult,int & copyRet)599 static bool ParserGetJsCopyResult(NativeEngine &engine, NativeValue *nativeValue,
600     std::vector<CopyResult> &copyResult, int &copyRet)
601 {
602     UserAccessTracer trace;
603     trace.Start("ParserGetJsCopyResult");
604     NativeObject *obj = ConvertNativeValueTo<NativeObject>(nativeValue);
605     if (obj == nullptr) {
606         HILOG_ERROR("Convert js object fail.");
607         return false;
608     }
609 
610     bool ret = ConvertFromJsValue(engine, obj->GetProperty("code"), copyRet);
611     if (!ret) {
612         HILOG_ERROR("Convert js value fail.");
613         return false;
614     }
615     if (copyRet == ERR_OK) {
616         return true;
617     }
618 
619     NativeArray *nativeArray = ConvertNativeValueTo<NativeArray>(obj->GetProperty("results"));
620     if (nativeArray == nullptr) {
621         HILOG_ERROR("nativeArray is nullptr");
622         return false;
623     }
624 
625     for (uint32_t i = 0; i < nativeArray->GetLength(); i++) {
626         NativeValue *nativeCopyResult = nativeArray->GetElement(i);
627         if (nativeCopyResult == nullptr) {
628             HILOG_ERROR("get native FileInfo fail.");
629             return false;
630         }
631 
632         CopyResult result;
633         ret = GetResultByJs(engine, nativeCopyResult, result, copyRet);
634         if (ret) {
635             TranslateCopyResult(result);
636             copyResult.push_back(result);
637         }
638     }
639 
640     return true;
641 }
642 
Copy(const Uri & sourceUri,const Uri & destUri,std::vector<CopyResult> & copyResult,bool force)643 int JsFileAccessExtAbility::Copy(const Uri &sourceUri, const Uri &destUri, std::vector<CopyResult> &copyResult,
644     bool force)
645 {
646     UserAccessTracer trace;
647     trace.Start("Copy");
648     auto argParser = [sourceUri, destUri, force](NativeEngine &engine, NativeValue* argv[], size_t &argc) -> bool {
649         NativeValue *srcNativeUri = engine.CreateString(sourceUri.ToString().c_str(),
650             sourceUri.ToString().length());
651         NativeValue *dstNativeUri = engine.CreateString(destUri.ToString().c_str(), destUri.ToString().length());
652         NativeValue *forceCopy = engine.CreateBoolean(force);
653         if (srcNativeUri == nullptr || dstNativeUri == nullptr || forceCopy == nullptr) {
654             HILOG_ERROR("create arguments native js value fail.");
655             return false;
656         }
657         argv[ARGC_ZERO] = srcNativeUri;
658         argv[ARGC_ONE] = dstNativeUri;
659         argv[ARGC_TWO] = forceCopy;
660         argc = ARGC_THREE;
661         return true;
662     };
663 
664     int copyRet = COPY_EXCEPTION;
665     auto retParser = [&copyResult, &copyRet](NativeEngine &engine, NativeValue *result) -> bool {
666         return ParserGetJsCopyResult(engine, result, copyResult, copyRet);
667     };
668 
669     auto errCode = CallJsMethod("copy", jsRuntime_, jsObj_.get(), argParser, retParser);
670     if (errCode != ERR_OK) {
671         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
672         CopyResult result { "", "", errCode, ""};
673         TranslateCopyResult(result);
674         copyResult.push_back(result);
675         return COPY_EXCEPTION;
676     }
677 
678     return copyRet;
679 }
680 
Rename(const Uri & sourceFile,const std::string & displayName,Uri & newFile)681 int JsFileAccessExtAbility::Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile)
682 {
683     UserAccessTracer trace;
684     trace.Start("Rename");
685     auto value = std::make_shared<Value<std::string>>();
686     if (value == nullptr) {
687         HILOG_ERROR("Rename value is nullptr.");
688         return E_GETRESULT;
689     }
690     auto argParser = [sourceFile, displayName](NativeEngine &engine, NativeValue *argv[], size_t &argc) -> bool {
691         NativeValue *nativeSourceFile = engine.CreateString(sourceFile.ToString().c_str(),
692             sourceFile.ToString().length());
693         NativeValue *nativeDisplayName = engine.CreateString(displayName.c_str(), displayName.length());
694         if (nativeSourceFile == nullptr || nativeDisplayName == nullptr) {
695             HILOG_ERROR("create sourceFile uri or displayName native js value fail.");
696             return false;
697         }
698         argv[ARGC_ZERO] = nativeSourceFile;
699         argv[ARGC_ONE] = nativeDisplayName;
700         argc = ARGC_TWO;
701         return true;
702     };
703     auto retParser = [value](NativeEngine &engine, NativeValue *result) -> bool {
704         NativeObject *obj = ConvertNativeValueTo<NativeObject>(result);
705         if (obj == nullptr) {
706             HILOG_ERROR("Convert js object fail.");
707             return false;
708         }
709 
710         bool ret = ConvertFromJsValue(engine, obj->GetProperty("uri"), value->data);
711         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("code"), value->code);
712         if (!ret) {
713             HILOG_ERROR("Convert js value fail.");
714         }
715         return ret;
716     };
717 
718     auto errCode = CallJsMethod("rename", jsRuntime_, jsObj_.get(), argParser, retParser);
719     if (errCode != ERR_OK) {
720         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
721         return errCode;
722     }
723 
724     if (value->code != ERR_OK) {
725         HILOG_ERROR("fileio fail.");
726         return value->code;
727     }
728 
729     if ((value->data).empty()) {
730         HILOG_ERROR("call Rename with return empty.");
731         return E_GETRESULT;
732     }
733     newFile = Uri(value->data);
734     return ERR_OK;
735 }
736 
737 
ParserListFileJsResult(NativeEngine & engine,NativeValue * nativeValue,Value<std::vector<FileInfo>> & result)738 static bool ParserListFileJsResult(NativeEngine &engine, NativeValue *nativeValue, Value<std::vector<FileInfo>> &result)
739 {
740     NativeObject *obj = ConvertNativeValueTo<NativeObject>(nativeValue);
741     if (obj == nullptr) {
742         HILOG_ERROR("Convert js object fail.");
743         return false;
744     }
745 
746     bool ret = ConvertFromJsValue(engine, obj->GetProperty("code"), result.code);
747     NativeArray *nativeArray = ConvertNativeValueTo<NativeArray>(obj->GetProperty("infos"));
748     if (nativeArray == nullptr) {
749         HILOG_ERROR("Convert js array object fail.");
750         return false;
751     }
752 
753     for (uint32_t i = 0; i < nativeArray->GetLength(); i++) {
754         NativeValue *nativeFileInfo = nativeArray->GetElement(i);
755         if (nativeFileInfo == nullptr) {
756             HILOG_ERROR("get native FileInfo fail.");
757             return false;
758         }
759 
760         obj = ConvertNativeValueTo<NativeObject>(nativeFileInfo);
761         if (obj == nullptr) {
762             HILOG_ERROR("Convert js object fail.");
763             return false;
764         }
765 
766         FileInfo fileInfo;
767         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("uri"), fileInfo.uri);
768         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("relativePath"), fileInfo.relativePath);
769         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("fileName"), fileInfo.fileName);
770         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("mode"), fileInfo.mode);
771         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("size"), fileInfo.size);
772         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("mtime"), fileInfo.mtime);
773         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("mimeType"), fileInfo.mimeType);
774         if (!ret) {
775             HILOG_ERROR("Convert js value fail.");
776             return ret;
777         }
778 
779         result.data.emplace_back(std::move(fileInfo));
780     }
781     return true;
782 }
783 
MakeStringNativeArray(NativeEngine & engine,std::vector<std::string> & inputArray,NativeValue * resultArray)784 static int MakeStringNativeArray(NativeEngine &engine, std::vector<std::string> &inputArray, NativeValue *resultArray)
785 {
786     NativeArray *nativeArray = ConvertNativeValueTo<NativeArray>(resultArray);
787     if (nativeArray == nullptr) {
788         HILOG_ERROR("Create NativeArray nullptr");
789         return E_GETRESULT;
790     }
791 
792     bool ret = false;
793     for (uint32_t i = 0; i < inputArray.size(); i++) {
794         NativeValue* nativeValue = engine.CreateString(inputArray[i].c_str(), inputArray[i].length());
795         if (nativeValue == nullptr) {
796             HILOG_ERROR("Create NativeValue fail.");
797             return E_GETRESULT;
798         }
799 
800         ret = nativeArray->SetElement(i, nativeValue);
801         if (!ret) {
802             HILOG_ERROR("Add NativeValue to NativeArray fail.");
803             return E_IPCS;
804         }
805     }
806 
807     return ERR_OK;
808 }
809 
MakeJsNativeFileFilter(NativeEngine & engine,const FileFilter & filter,NativeValue * nativeFilter)810 static int MakeJsNativeFileFilter(NativeEngine &engine, const FileFilter &filter, NativeValue *nativeFilter)
811 {
812     NativeValue *suffixArray = engine.CreateArray(filter.GetSuffix().size());
813     if (suffixArray == nullptr) {
814         HILOG_ERROR("Create Suffix native array value fail.");
815         return E_GETRESULT;
816     }
817 
818     std::vector<std::string> suffixVec = filter.GetSuffix();
819     int errorCode = MakeStringNativeArray(engine, suffixVec, suffixArray);
820     if (errorCode != ERR_OK) {
821         HILOG_ERROR("Create Suffix native array value fail, code:%{public}d.", errorCode);
822         return errorCode;
823     }
824 
825     NativeValue *displayNameArray = engine.CreateArray(filter.GetDisplayName().size());
826     if (displayNameArray == nullptr) {
827         HILOG_ERROR("Create DisplayName native array value fail.");
828         return E_GETRESULT;
829     }
830 
831     std::vector<std::string> displayNameVec = filter.GetDisplayName();
832     errorCode = MakeStringNativeArray(engine, displayNameVec, displayNameArray);
833     if (errorCode != ERR_OK) {
834         HILOG_ERROR("Create DisplayName native array value fail, code:%{public}d.", errorCode);
835         return errorCode;
836     }
837 
838     NativeValue *mimeTypeArray = engine.CreateArray(filter.GetMimeType().size());
839     if (mimeTypeArray == nullptr) {
840         HILOG_ERROR("Create MimeType native array value fail.");
841         return E_GETRESULT;
842     }
843 
844     std::vector<std::string> mimeTypeVec = filter.GetMimeType();
845     errorCode = MakeStringNativeArray(engine, mimeTypeVec, mimeTypeArray);
846     if (errorCode != ERR_OK) {
847         HILOG_ERROR("Create MimeType native array value fail, code:%{public}d.", errorCode);
848         return errorCode;
849     }
850 
851     NativeValue *nativeFileSizeOver = engine.CreateNumber(filter.GetFileSizeOver());
852     if (nativeFileSizeOver == nullptr) {
853         HILOG_ERROR("Create NativeFileSizeOver native js value fail.");
854         return E_GETRESULT;
855     }
856 
857     NativeValue *nativeLastModifiedAfter = engine.CreateNumber(filter.GetLastModifiedAfter());
858     if (nativeLastModifiedAfter == nullptr) {
859         HILOG_ERROR("Create NativeLastModifiedAfter native js value fail.");
860         return E_GETRESULT;
861     }
862 
863     NativeValue *nativeExcludeMedia = engine.CreateBoolean(filter.GetExcludeMedia());
864     if (nativeExcludeMedia == nullptr) {
865         HILOG_ERROR("Create NativeExcludeMedia native js value fail.");
866         return E_GETRESULT;
867     }
868 
869     NativeObject *objFilter = ConvertNativeValueTo<NativeObject>(nativeFilter);
870     if (objFilter == nullptr) {
871         HILOG_ERROR("Convert js object fail.");
872         return E_GETRESULT;
873     }
874     bool ret = objFilter->SetProperty("suffix", suffixArray);
875     ret = ret && objFilter->SetProperty("displayName", displayNameArray);
876     ret = ret && objFilter->SetProperty("mimeType", mimeTypeArray);
877     ret = ret && objFilter->SetProperty("fileSizeOver", nativeFileSizeOver);
878     ret = ret && objFilter->SetProperty("lastModifiedAfter", nativeLastModifiedAfter);
879     ret = ret && objFilter->SetProperty("excludeMedia", nativeExcludeMedia);
880     if (!ret) {
881         HILOG_ERROR("Set property to Filter NativeValue fail.");
882         return EINVAL;
883     }
884 
885     return ERR_OK;
886 }
887 
BuildFilterParam(NativeEngine & engine,const FileFilter & filter,const FilterParam & param,NativeValue * argv[],size_t & argc)888 static bool BuildFilterParam(NativeEngine &engine, const FileFilter &filter, const FilterParam &param,
889     NativeValue *argv[], size_t &argc)
890 {
891     string uriStr = param.fileInfo.uri;
892     NativeValue *uri = engine.CreateString(uriStr.c_str(), uriStr.length());
893     if (uri == nullptr) {
894         HILOG_ERROR("Create sourceFile uri native js value fail.");
895         return false;
896     }
897 
898     NativeValue *nativeOffset = engine.CreateNumber(param.offset);
899     if (nativeOffset == nullptr) {
900         HILOG_ERROR("Create offset native js value fail.");
901         return false;
902     }
903 
904     NativeValue *nativeMaxCount = engine.CreateNumber(param.maxCount);
905     if (nativeMaxCount == nullptr) {
906         HILOG_ERROR("Create maxCount native js value fail.");
907         return false;
908     }
909 
910     NativeValue *nativeFilter = nullptr;
911     if (filter.GetHasFilter()) {
912         nativeFilter = engine.CreateObject();
913         if (nativeFilter == nullptr) {
914             HILOG_ERROR("Create js NativeValue fail.");
915             return false;
916         }
917         int ret = MakeJsNativeFileFilter(engine, filter, nativeFilter);
918         if (ret != ERR_OK) {
919             HILOG_ERROR("Create js NativeValue fail.");
920             return false;
921         }
922     } else {
923         nativeFilter = engine.CreateNull();
924         if (nativeFilter == nullptr) {
925             HILOG_ERROR("Create js NativeValue fail.");
926             return false;
927         }
928     }
929 
930     argv[ARGC_ZERO] = uri;
931     argv[ARGC_ONE] = nativeOffset;
932     argv[ARGC_TWO] = nativeMaxCount;
933     argv[ARGC_THREE] = nativeFilter;
934     argc = ARGC_FOUR;
935 
936     return true;
937 }
938 
ListFile(const FileInfo & fileInfo,const int64_t offset,const int64_t maxCount,const FileFilter & filter,std::vector<FileInfo> & fileInfoVec)939 int JsFileAccessExtAbility::ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount,
940     const FileFilter &filter, std::vector<FileInfo> &fileInfoVec)
941 {
942     UserAccessTracer trace;
943     trace.Start("ListFile");
944     auto value = std::make_shared<Value<std::vector<FileInfo>>>();
945     if (value == nullptr) {
946         HILOG_ERROR("ListFile value is nullptr.");
947         return E_GETRESULT;
948     }
949 
950     auto argParser =
951         [fileInfo, offset, maxCount, filter](NativeEngine &engine, NativeValue *argv[], size_t &argc) -> bool {
952         struct FilterParam param;
953         param.fileInfo = fileInfo;
954         param.offset = offset;
955         param.maxCount = maxCount;
956 
957         return BuildFilterParam(engine, filter, param, argv, argc);
958     };
959     auto retParser = [value](NativeEngine &engine, NativeValue *result) -> bool {
960         Value<std::vector<FileInfo>> fileInfo;
961         bool ret = ParserListFileJsResult(engine, result, fileInfo);
962         if (!ret) {
963             HILOG_ERROR("Parser js value fail.");
964             return ret;
965         }
966 
967         *value = std::move(fileInfo);
968         return true;
969     };
970 
971     auto errCode = CallJsMethod("listFile", jsRuntime_, jsObj_.get(), argParser, retParser);
972     if (errCode != ERR_OK) {
973         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
974         return errCode;
975     }
976 
977     if (value->code != ERR_OK) {
978         HILOG_ERROR("fileio fail.");
979         return value->code;
980     }
981 
982     fileInfoVec = std::move(value->data);
983     return ERR_OK;
984 }
985 
ScanFile(const FileInfo & fileInfo,const int64_t offset,const int64_t maxCount,const FileFilter & filter,std::vector<FileInfo> & fileInfoVec)986 int JsFileAccessExtAbility::ScanFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount,
987     const FileFilter &filter, std::vector<FileInfo> &fileInfoVec)
988 {
989     UserAccessTracer trace;
990     trace.Start("ScanFile");
991     auto value = std::make_shared<Value<std::vector<FileInfo>>>();
992     if (value == nullptr) {
993         HILOG_ERROR("ScanFile value is nullptr.");
994         return E_GETRESULT;
995     }
996 
997     auto argParser =
998         [fileInfo, offset, maxCount, filter](NativeEngine &engine, NativeValue *argv[], size_t &argc) -> bool {
999         struct FilterParam param;
1000         param.fileInfo = fileInfo;
1001         param.offset = offset;
1002         param.maxCount = maxCount;
1003 
1004         return BuildFilterParam(engine, filter, param, argv, argc);
1005     };
1006 
1007     auto retParser = [value](NativeEngine &engine, NativeValue *result) -> bool {
1008         Value<std::vector<FileInfo>> fileInfo;
1009         bool ret = ParserListFileJsResult(engine, result, fileInfo);
1010         if (!ret) {
1011             HILOG_ERROR("Parser js value fail.");
1012             return ret;
1013         }
1014 
1015         *value = std::move(fileInfo);
1016         return true;
1017     };
1018 
1019     auto errCode = CallJsMethod("scanFile", jsRuntime_, jsObj_.get(), argParser, retParser);
1020     if (errCode != ERR_OK) {
1021         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
1022         return errCode;
1023     }
1024 
1025     if (value->code != ERR_OK) {
1026         HILOG_ERROR("fileio fail.");
1027         return value->code;
1028     }
1029 
1030     fileInfoVec = std::move(value->data);
1031     return ERR_OK;
1032 }
1033 
ParserGetRootsJsResult(NativeEngine & engine,NativeValue * nativeValue,Value<std::vector<RootInfo>> & result)1034 static bool ParserGetRootsJsResult(NativeEngine &engine, NativeValue *nativeValue, Value<std::vector<RootInfo>> &result)
1035 {
1036     NativeObject *obj = ConvertNativeValueTo<NativeObject>(nativeValue);
1037     if (obj == nullptr) {
1038         HILOG_ERROR("Convert js object fail.");
1039         return false;
1040     }
1041 
1042     bool ret = ConvertFromJsValue(engine, obj->GetProperty("code"), result.code);
1043     NativeArray *nativeArray = ConvertNativeValueTo<NativeArray>(obj->GetProperty("roots"));
1044     if (nativeArray == nullptr) {
1045         HILOG_ERROR("nativeArray is nullptr");
1046         return false;
1047     }
1048 
1049     for (uint32_t i = 0; i < nativeArray->GetLength(); i++) {
1050         NativeValue *nativeRootInfo = nativeArray->GetElement(i);
1051         if (nativeRootInfo == nullptr) {
1052             HILOG_ERROR("get native FileInfo fail.");
1053             return false;
1054         }
1055 
1056         obj = ConvertNativeValueTo<NativeObject>(nativeRootInfo);
1057         if (obj == nullptr) {
1058             HILOG_ERROR("Convert js object fail.");
1059             return false;
1060         }
1061 
1062         RootInfo rootInfo;
1063         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("deviceType"), rootInfo.deviceType);
1064         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("uri"), rootInfo.uri);
1065         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("relativePath"), rootInfo.relativePath);
1066         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("displayName"), rootInfo.displayName);
1067         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("deviceFlags"), rootInfo.deviceFlags);
1068         if (!ret) {
1069             HILOG_ERROR("Convert js value fail.");
1070             return ret;
1071         }
1072 
1073         result.data.emplace_back(std::move(rootInfo));
1074     }
1075 
1076     return true;
1077 }
1078 
GetRoots(std::vector<RootInfo> & rootInfoVec)1079 int JsFileAccessExtAbility::GetRoots(std::vector<RootInfo> &rootInfoVec)
1080 {
1081     UserAccessTracer trace;
1082     trace.Start("GetRoots");
1083     auto value = std::make_shared<Value<std::vector<RootInfo>>>();
1084     if (value == nullptr) {
1085         HILOG_ERROR("GetRoots value is nullptr.");
1086         return E_GETRESULT;
1087     }
1088 
1089     auto argParser = [](NativeEngine &engine, NativeValue *argv[], size_t &argc) -> bool {
1090         argc = ARGC_ZERO;
1091         return true;
1092     };
1093     auto retParser = [value](NativeEngine &engine, NativeValue *result) -> bool {
1094         Value<std::vector<RootInfo>> rootInfoVec;
1095         bool ret = ParserGetRootsJsResult(engine, result, rootInfoVec);
1096         if (!ret) {
1097             HILOG_ERROR("Parser js value fail.");
1098             return ret;
1099         }
1100 
1101         *value = std::move(rootInfoVec);
1102         return true;
1103     };
1104 
1105     auto errCode = CallJsMethod("getRoots", jsRuntime_, jsObj_.get(), argParser, retParser);
1106     if (errCode != ERR_OK) {
1107         HILOG_ERROR("CallJsMethod error, code:%{public}d", errCode);
1108         return errCode;
1109     }
1110 
1111     if (value->code != ERR_OK) {
1112         HILOG_ERROR("fileio fail.");
1113         return value->code;
1114     }
1115 
1116     rootInfoVec = std::move(value->data);
1117     return ERR_OK;
1118 }
1119 
Access(const Uri & uri,bool & isExist)1120 int JsFileAccessExtAbility::Access(const Uri &uri, bool &isExist)
1121 {
1122     UserAccessTracer trace;
1123     trace.Start("Access");
1124     auto value = std::make_shared<Value<bool>>();
1125     if (value == nullptr) {
1126         HILOG_ERROR("Access value is nullptr.");
1127         return E_GETRESULT;
1128     }
1129 
1130     auto argParser = [uri](NativeEngine &engine, NativeValue *argv[], size_t &argc) -> bool {
1131         NativeValue *nativeUri = engine.CreateString(uri.ToString().c_str(), uri.ToString().length());
1132         argv[ARGC_ZERO] = nativeUri;
1133         argc = ARGC_ONE;
1134         return true;
1135     };
1136     auto retParser = [value](NativeEngine &engine, NativeValue *result) -> bool {
1137         NativeObject *obj = ConvertNativeValueTo<NativeObject>(result);
1138         if (obj == nullptr) {
1139             HILOG_ERROR("Convert js object fail.");
1140             return E_GETRESULT;
1141         }
1142 
1143         bool ret = ConvertFromJsValue(engine, obj->GetProperty("isExist"), value->data);
1144         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("code"), value->code);
1145         if (!ret) {
1146             HILOG_ERROR("Convert js value fail.");
1147         }
1148         return ret;
1149     };
1150 
1151     auto errCode = CallJsMethod("access", jsRuntime_, jsObj_.get(), argParser, retParser);
1152     if (errCode != ERR_OK) {
1153         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
1154         return errCode;
1155     }
1156 
1157     if (value->code != ERR_OK) {
1158         HILOG_ERROR("fileio fail.");
1159         return value->code;
1160     }
1161 
1162     isExist = value->data;
1163     return ERR_OK;
1164 }
1165 
ParserQueryFileJsResult(NativeEngine & engine,NativeValue * nativeValue,Value<std::vector<std::string>> & results)1166 static bool ParserQueryFileJsResult(NativeEngine &engine, NativeValue *nativeValue,
1167     Value<std::vector<std::string>> &results)
1168 {
1169     NativeObject *obj = ConvertNativeValueTo<NativeObject>(nativeValue);
1170     if (obj == nullptr) {
1171         HILOG_ERROR("Convert js object fail.");
1172         return false;
1173     }
1174 
1175     bool ret = ConvertFromJsValue(engine, obj->GetProperty("code"), results.code);
1176     if (!ret) {
1177         HILOG_ERROR("Convert the code of js value fail.");
1178         return ret;
1179     }
1180 
1181     NativeArray *nativeArray = ConvertNativeValueTo<NativeArray>(obj->GetProperty("results"));
1182     if (nativeArray == nullptr) {
1183         HILOG_ERROR("Convert js array object fail.");
1184         return false;
1185     }
1186 
1187     for (uint32_t i = 0; i < nativeArray->GetLength(); i++) {
1188         NativeValue *queryResult = nativeArray->GetElement(i);
1189         if (queryResult == nullptr) {
1190             HILOG_ERROR("get native queryResult fail.");
1191             return false;
1192         }
1193         std::string tempValue;
1194         ret = ConvertFromJsValue(engine, queryResult, tempValue);
1195         if (!ret) {
1196             HILOG_ERROR("Convert js value fail.");
1197             return ret;
1198         }
1199         results.data.emplace_back(std::move(tempValue));
1200     }
1201     return true;
1202 }
1203 
ConvertColumn(std::vector<std::string> & columns)1204 static void ConvertColumn(std::vector<std::string> &columns)
1205 {
1206     for (auto &column : columns) {
1207         for (auto &it : CONVERT_FILE_COLUMN) {
1208             if (column == it.first) {
1209                 column = it.second;
1210             }
1211         }
1212     }
1213 }
1214 
Query(const Uri & uri,std::vector<std::string> & columns,std::vector<std::string> & results)1215 int JsFileAccessExtAbility::Query(const Uri &uri, std::vector<std::string> &columns, std::vector<std::string> &results)
1216 {
1217     UserAccessTracer trace;
1218     trace.Start("Query");
1219     auto value = std::make_shared<Value<std::vector<std::string>>>();
1220     if (value == nullptr) {
1221         HILOG_ERROR("Query value is nullptr.");
1222         return E_GETRESULT;
1223     }
1224 
1225     ConvertColumn(columns);
1226     auto argParser = [uri, &columns](NativeEngine &engine, NativeValue *argv[], size_t &argc) -> bool {
1227         NativeValue *nativeUri = engine.CreateString(uri.ToString().c_str(), uri.ToString().length());
1228         if (nativeUri == nullptr) {
1229             HILOG_ERROR("create uri native js value fail.");
1230             return false;
1231         }
1232         NativeValue *resultArray = engine.CreateArray(columns.size());
1233         if (resultArray == nullptr) {
1234             HILOG_ERROR("Create MimeType native array value fail.");
1235             return false;
1236         }
1237         int errorCode = MakeStringNativeArray(engine, columns, resultArray);
1238         if (errorCode != ERR_OK) {
1239             HILOG_ERROR("Create native array value fail, code:%{public}d.", errorCode);
1240             return false;
1241         }
1242         argv[ARGC_ZERO] = nativeUri;
1243         argv[ARGC_ONE] = resultArray;
1244         argc = ARGC_TWO;
1245         return true;
1246     };
1247     auto retParser = [value](NativeEngine &engine, NativeValue *result) -> bool {
1248         Value<std::vector<std::string>> queryResult;
1249         bool ret = ParserQueryFileJsResult(engine, result, queryResult);
1250         if (!ret) {
1251             HILOG_ERROR("Parser js value fail.");
1252             return ret;
1253         }
1254         value->code = queryResult.code;
1255         value->data = queryResult.data;
1256         return ret;
1257     };
1258 
1259     auto errCode = CallJsMethod("query", jsRuntime_, jsObj_.get(), argParser, retParser);
1260     if (errCode != ERR_OK) {
1261         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
1262         return errCode;
1263     }
1264 
1265     if (value->code != ERR_OK) {
1266         HILOG_ERROR("fileio fail.");
1267         return value->code;
1268     }
1269 
1270     results = std::move(value->data);
1271     return ERR_OK;
1272 }
1273 
GetFileInfoFromUri(const Uri & selectFile,FileInfo & fileInfo)1274 int JsFileAccessExtAbility::GetFileInfoFromUri(const Uri &selectFile, FileInfo &fileInfo)
1275 {
1276     UserAccessTracer trace;
1277     trace.Start("GetFileInfoFromUri");
1278     auto value = std::make_shared<Value<FileInfo>>();
1279     if (value == nullptr) {
1280         HILOG_ERROR("GetFileInfoFromUri value is nullptr.");
1281         return E_GETRESULT;
1282     }
1283 
1284     auto argParser = [selectFile](NativeEngine &engine, NativeValue *argv[], size_t &argc) -> bool {
1285         NativeValue *nativeUri = engine.CreateString(selectFile.ToString().c_str(), selectFile.ToString().length());
1286         if (nativeUri == nullptr) {
1287             HILOG_ERROR("create selectFile uri native js value fail.");
1288             return false;
1289         }
1290         argv[ARGC_ZERO] = nativeUri;
1291         argc = ARGC_ONE;
1292         return true;
1293     };
1294     auto retParser = [value](NativeEngine &engine, NativeValue *result) -> bool {
1295         NativeObject *obj = ConvertNativeValueTo<NativeObject>(result);
1296         if (obj == nullptr) {
1297             HILOG_ERROR("Convert js object fail.");
1298             return false;
1299         }
1300         bool ret = ConvertFromJsValue(engine, obj->GetProperty("code"), value->code);
1301         if (!ret) {
1302             HILOG_ERROR("Convert js value fail.");
1303             return false;
1304         }
1305 
1306         obj = ConvertNativeValueTo<NativeObject>(obj->GetProperty("fileInfo"));
1307         if (obj == nullptr) {
1308             HILOG_ERROR("Convert js-fileInfo object fail.");
1309             return false;
1310         }
1311 
1312         FileInfo fileInfo;
1313         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("uri"), fileInfo.uri);
1314         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("relativePath"), fileInfo.relativePath);
1315         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("fileName"), fileInfo.fileName);
1316         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("mode"), fileInfo.mode);
1317         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("size"), fileInfo.size);
1318         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("mtime"), fileInfo.mtime);
1319         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("mimeType"), fileInfo.mimeType);
1320         if (!ret) {
1321             HILOG_ERROR("Convert js value fail.");
1322             return false;
1323         }
1324         value->data = std::move(fileInfo);
1325         return ret;
1326     };
1327 
1328     auto errCode = CallJsMethod("getFileInfoFromUri", jsRuntime_, jsObj_.get(), argParser, retParser);
1329     if (errCode != ERR_OK) {
1330         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
1331         return errCode;
1332     }
1333 
1334     if (value->code != ERR_OK) {
1335         HILOG_ERROR("fileio fail.");
1336         return value->code;
1337     }
1338 
1339     fileInfo = std::move(value->data);
1340     return ERR_OK;
1341 }
1342 
GetFileInfoFromRelativePath(const std::string & selectFileRealtivePath,FileInfo & fileInfo)1343 int JsFileAccessExtAbility::GetFileInfoFromRelativePath(const std::string &selectFileRealtivePath, FileInfo &fileInfo)
1344 {
1345     UserAccessTracer trace;
1346     trace.Start("GetFileInfoFromRelativePath");
1347     auto value = std::make_shared<Value<FileInfo>>();
1348     if (value == nullptr) {
1349         HILOG_ERROR("GetFileInfoFromRelativePath value is nullptr.");
1350         return E_GETRESULT;
1351     }
1352 
1353     auto argParser = [selectFileRealtivePath](NativeEngine &engine, NativeValue *argv[], size_t &argc) -> bool {
1354         NativeValue *nativePath = engine.CreateString(selectFileRealtivePath.c_str(), selectFileRealtivePath.length());
1355         if (nativePath == nullptr) {
1356             HILOG_ERROR("create selectFileRealtivePath native js value fail.");
1357             return false;
1358         }
1359         argv[ARGC_ZERO] = nativePath;
1360         argc = ARGC_ONE;
1361         return true;
1362     };
1363     auto retParser = [value](NativeEngine &engine, NativeValue *result) -> bool {
1364         NativeObject *obj = ConvertNativeValueTo<NativeObject>(result);
1365         if (obj == nullptr) {
1366             HILOG_ERROR("Convert js object fail.");
1367             return false;
1368         }
1369         bool ret = ConvertFromJsValue(engine, obj->GetProperty("code"), value->code);
1370         if (!ret) {
1371             HILOG_ERROR("Convert js value fail.");
1372             return false;
1373         }
1374 
1375         obj = ConvertNativeValueTo<NativeObject>(obj->GetProperty("fileInfo"));
1376         if (obj == nullptr) {
1377             HILOG_ERROR("Convert js-fileInfo object fail.");
1378             return false;
1379         }
1380 
1381         FileInfo fileInfo;
1382         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("uri"), fileInfo.uri);
1383         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("relativePath"), fileInfo.relativePath);
1384         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("fileName"), fileInfo.fileName);
1385         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("mode"), fileInfo.mode);
1386         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("size"), fileInfo.size);
1387         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("mtime"), fileInfo.mtime);
1388         ret = ret && ConvertFromJsValue(engine, obj->GetProperty("mimeType"), fileInfo.mimeType);
1389         if (!ret) {
1390             HILOG_ERROR("Convert js value fail.");
1391             return false;
1392         }
1393         value->data = std::move(fileInfo);
1394         return ret;
1395     };
1396 
1397     auto errCode = CallJsMethod("getFileInfoFromRelativePath", jsRuntime_, jsObj_.get(), argParser, retParser);
1398     if (errCode != ERR_OK) {
1399         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
1400         return errCode;
1401     }
1402 
1403     if (value->code != ERR_OK) {
1404         HILOG_ERROR("fileio fail.");
1405         return value->code;
1406     }
1407 
1408     fileInfo = std::move(value->data);
1409     return ERR_OK;
1410 }
1411 
FuncCallback(NativeEngine * engine,NativeCallbackInfo * info)1412 NativeValue* JsFileAccessExtAbility::FuncCallback(NativeEngine* engine, NativeCallbackInfo* info)
1413 {
1414     UserAccessTracer trace;
1415     trace.Start("FuncCallback");
1416     if (engine == nullptr) {
1417         HILOG_ERROR("NativeEngine pointer is null.");
1418         return nullptr;
1419     }
1420 
1421     if (info == nullptr) {
1422         HILOG_ERROR("invalid param.");
1423         return engine->CreateUndefined();
1424     }
1425 
1426     if (info->argc != ARGC_TWO) {
1427         HILOG_ERROR("invalid args.");
1428         return engine->CreateUndefined();
1429     }
1430 
1431     if (info->functionInfo == nullptr || info->functionInfo->data == nullptr) {
1432         HILOG_ERROR("invalid object.");
1433         return engine->CreateUndefined();
1434     }
1435 
1436     std::string uriString = UnwrapStringFromJS(reinterpret_cast<napi_env>(engine),
1437         reinterpret_cast<napi_value>(info->argv[ARGC_ZERO]));
1438     int32_t event = UnwrapInt32FromJS(reinterpret_cast<napi_env>(engine),
1439         reinterpret_cast<napi_value>(info->argv[ARGC_ONE]));
1440 
1441     Uri uri(uriString);
1442     NotifyType notifyType = static_cast<NotifyType>(event);
1443     auto ret = Notify(uri, notifyType);
1444     if (ret != ERR_OK) {
1445         HILOG_ERROR("JsFileAccessExtAbility notify error, ret:%{public}d", ret);
1446     }
1447     return engine->CreateUndefined();
1448 }
1449 
StartWatcher(const Uri & uri)1450 int JsFileAccessExtAbility::StartWatcher(const Uri &uri)
1451 {
1452     UserAccessTracer trace;
1453     trace.Start("StartWatcher");
1454     auto ret = std::make_shared<int>();
1455     if (ret == nullptr) {
1456         HILOG_ERROR("StartWatcher value is nullptr.");
1457         return E_GETRESULT;
1458     }
1459 
1460     auto argParser = [uri, this](NativeEngine &engine, NativeValue *argv[], size_t &argc) -> bool {
1461         NativeValue *nativeUri = engine.CreateString(uri.ToString().c_str(), uri.ToString().length());
1462         if (nativeUri == nullptr) {
1463             HILOG_ERROR("create uri native js value fail.");
1464             return false;
1465         }
1466         const std::string funcName = "FuncCallback";
1467         NativeValue* func = engine.CreateFunction(funcName.c_str(), funcName.length(),
1468             JsFileAccessExtAbility::FuncCallback, this);
1469         argv[ARGC_ZERO] = nativeUri;
1470         argv[ARGC_ONE] = func;
1471         argc = ARGC_TWO;
1472         return true;
1473     };
1474 
1475     auto retParser = [ret](NativeEngine &engine, NativeValue *result) -> bool {
1476         bool res = ConvertFromJsValue(engine, result, *ret);
1477         if (!res) {
1478             HILOG_ERROR("Convert js value fail.");
1479         }
1480         return res;
1481     };
1482 
1483     auto errCode = CallJsMethod("startWatcher", jsRuntime_, jsObj_.get(), argParser, retParser);
1484     if (errCode != ERR_OK) {
1485         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
1486         return errCode;
1487     }
1488 
1489     if (*ret != ERR_OK) {
1490         HILOG_ERROR("fileio fail.");
1491         return *ret;
1492     }
1493 
1494     return ERR_OK;
1495 }
1496 
StopWatcher(const Uri & uri,bool isUnregisterAll)1497 int JsFileAccessExtAbility::StopWatcher(const Uri &uri, bool isUnregisterAll)
1498 {
1499     UserAccessTracer trace;
1500     trace.Start("StopWatcher");
1501     auto ret = std::make_shared<int>();
1502     if (ret == nullptr) {
1503         HILOG_ERROR("StopWatcher value is nullptr.");
1504         return E_GETRESULT;
1505     }
1506 
1507     auto argParser = [uri, isUnregisterAll](NativeEngine &engine, NativeValue *argv[], size_t &argc) -> bool {
1508         NativeValue *nativeUri = engine.CreateString(uri.ToString().c_str(), uri.ToString().length());
1509         if (nativeUri == nullptr) {
1510             HILOG_ERROR("create uri native js value fail.");
1511             return false;
1512         }
1513         NativeValue *isCleanAll = engine.CreateBoolean(isUnregisterAll);
1514         argv[ARGC_ZERO] = nativeUri;
1515         argv[ARGC_ONE] = isCleanAll;
1516         argc = ARGC_TWO;
1517         return true;
1518     };
1519 
1520     auto retParser = [ret](NativeEngine &engine, NativeValue *result) -> bool {
1521         bool res = ConvertFromJsValue(engine, result, *ret);
1522         if (!res) {
1523             HILOG_ERROR("Convert js value fail.");
1524         }
1525         return res;
1526     };
1527 
1528     auto errCode = CallJsMethod("stopWatcher", jsRuntime_, jsObj_.get(), argParser, retParser);
1529     if (errCode != ERR_OK) {
1530         HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode);
1531         return errCode;
1532     }
1533 
1534     if (*ret != ERR_OK) {
1535         HILOG_ERROR("fileio fail.");
1536         return *ret;
1537     }
1538 
1539     return ERR_OK;
1540 }
1541 
Notify(Uri & uri,NotifyType notifyType)1542 int JsFileAccessExtAbility::Notify(Uri &uri, NotifyType notifyType)
1543 {
1544     UserAccessTracer trace;
1545     trace.Start("Notify");
1546     auto proxy = FileAccessServiceProxy::GetInstance();
1547     if (proxy == nullptr) {
1548         HILOG_ERROR("Notify get SA failed");
1549         return E_LOAD_SA;
1550     }
1551     auto ret = proxy->OnChange(uri, notifyType);
1552     if (ret != ERR_OK) {
1553         HILOG_ERROR("notify error, ret:%{public}d", ret);
1554         return ret;
1555     }
1556     return ERR_OK;
1557 }
1558 } // namespace FileAccessFwk
1559 } // namespace OHOS
1560