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