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