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 ©Result)
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 ©Ret)
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> ©Result, int ©Ret)
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> ©Result,
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 = [©Result, ©Ret](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 ¶m,
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