• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "file_access_helper.h"
17 
18 #include "bundle_constants.h"
19 #include "bundle_mgr_proxy.h"
20 #include "file_access_framework_errno.h"
21 #include "hilog_wrapper.h"
22 #include "hitrace_meter.h"
23 #include "if_system_ability_manager.h"
24 #include "ifile_access_ext_base.h"
25 #include "ipc_skeleton.h"
26 #include "iservice_registry.h"
27 #include "system_ability_definition.h"
28 
29 namespace OHOS {
30 namespace FileAccessFwk {
31 std::vector<AAFwk::Want> FileAccessHelper::wants_;
32 
GetUserId()33 static int GetUserId()
34 {
35     int uid = IPCSkeleton::GetCallingUid();
36     int userId = uid / AppExecFwk::Constants::BASE_USER_RANGE;
37     return userId;
38 }
39 
GetBundleNameFromPath(const std::string & path,std::string & bundleName)40 static bool GetBundleNameFromPath(const std::string &path, std::string &bundleName)
41 {
42     if (path.size() == 0) {
43         HILOG_ERROR("Uri path error.");
44         return false;
45     }
46 
47     if (path.front() != '/') {
48         HILOG_ERROR("Uri path format error.");
49         return false;
50     }
51 
52     auto tmpPath = path.substr(1);
53     auto index = tmpPath.find_first_of("/");
54     bundleName = tmpPath.substr(0, index);
55     if (bundleName.compare(MEDIA_BNUDLE_NAME_ALIAS) == 0) {
56         bundleName = MEDIA_BNUDLE_NAME;
57     }
58     return true;
59 }
60 
CheckUri(Uri & uri)61 static bool CheckUri(Uri &uri)
62 {
63     HILOG_DEBUG("Uri : %{public}s.", uri.ToString().c_str());
64     std::string schemeStr = std::string(uri.GetScheme());
65     if (schemeStr.compare(SCHEME_NAME) != 0) {
66         HILOG_ERROR("Uri scheme error.");
67         return false;
68     }
69     return true;
70 }
71 
GetBundleMgrProxy()72 sptr<AppExecFwk::IBundleMgr> FileAccessHelper::GetBundleMgrProxy()
73 {
74     sptr<ISystemAbilityManager> systemAbilityManager =
75         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
76     if (!systemAbilityManager) {
77         return nullptr;
78     }
79 
80     sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
81     if (!remoteObject) {
82         return nullptr;
83     }
84 
85     return iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
86 }
87 
FileAccessHelper(const std::shared_ptr<OHOS::AbilityRuntime::Context> & context,const std::unordered_map<std::string,std::shared_ptr<ConnectInfo>> & cMap)88 FileAccessHelper::FileAccessHelper(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context,
89     const std::unordered_map<std::string, std::shared_ptr<ConnectInfo>> &cMap)
90 {
91     token_ = context->GetToken();
92     cMap_ = cMap;
93 }
94 
FileAccessHelper(const sptr<IRemoteObject> & token,const std::unordered_map<std::string,std::shared_ptr<ConnectInfo>> & cMap)95 FileAccessHelper::FileAccessHelper(const sptr<IRemoteObject> &token,
96     const std::unordered_map<std::string, std::shared_ptr<ConnectInfo>> &cMap)
97 {
98     token_ = token;
99     cMap_ = cMap;
100 }
101 
AddFileAccessDeathRecipient(const sptr<IRemoteObject> & token)102 void FileAccessHelper::AddFileAccessDeathRecipient(const sptr<IRemoteObject> &token)
103 {
104     if (token != nullptr && callerDeathRecipient_ != nullptr) {
105         token->RemoveDeathRecipient(callerDeathRecipient_);
106     }
107     if (callerDeathRecipient_ == nullptr) {
108         callerDeathRecipient_ =
109             new FileAccessDeathRecipient(std::bind(&FileAccessHelper::OnSchedulerDied, this, std::placeholders::_1));
110     }
111     if (token != nullptr) {
112         token->AddDeathRecipient(callerDeathRecipient_);
113     }
114 }
115 
OnSchedulerDied(const wptr<IRemoteObject> & remote)116 void FileAccessHelper::OnSchedulerDied(const wptr<IRemoteObject> &remote)
117 {
118     auto object = remote.promote();
119     object = nullptr;
120 }
121 
GetConnectInfo(const std::string & bundleName)122 std::shared_ptr<ConnectInfo> FileAccessHelper::GetConnectInfo(const std::string &bundleName)
123 {
124     auto iterator = cMap_.find(bundleName);
125     if (iterator != cMap_.end()) {
126         return iterator->second;
127     }
128     HILOG_ERROR("GetConnectInfo called with bundleName return nullptr");
129     return nullptr;
130 }
131 
GetKeyOfWants(const AAFwk::Want & want)132 std::string FileAccessHelper::GetKeyOfWants(const AAFwk::Want &want)
133 {
134     auto elementTmp = want.GetElement();
135     for (auto iter = FileAccessHelper::wants_.begin(); iter != FileAccessHelper::wants_.end(); ++iter) {
136         auto element = iter->GetElement();
137         if (element.GetBundleName() == elementTmp.GetBundleName() &&
138             element.GetAbilityName() == elementTmp.GetAbilityName()) {
139             return element.GetBundleName();
140         }
141     }
142     HILOG_ERROR("GetKeyOfWants did not find a want message to match");
143     return "";
144 }
145 
Creator(const std::shared_ptr<OHOS::AbilityRuntime::Context> & context)146 std::pair<std::shared_ptr<FileAccessHelper>, int> FileAccessHelper::Creator(
147     const std::shared_ptr<OHOS::AbilityRuntime::Context> &context)
148 {
149     if (context == nullptr) {
150         HILOG_ERROR("FileAccessHelper::Creator failed, context == nullptr");
151         return {nullptr, EINVAL};
152     }
153 
154     sptr<AppExecFwk::IBundleMgr> bm = FileAccessHelper::GetBundleMgrProxy();
155     FileAccessHelper::wants_.clear();
156     std::unordered_map<std::string, std::shared_ptr<ConnectInfo>> cMap;
157     std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
158     bool ret = bm->QueryExtensionAbilityInfos(
159         AppExecFwk::ExtensionAbilityType::FILEACCESS_EXTENSION, GetUserId(), extensionInfos);
160     if (!ret) {
161         HILOG_ERROR("FileAccessHelper::Creator QueryExtensionAbilityInfos failed");
162         return {nullptr, E_GETINFO};
163     }
164 
165     for (size_t i = 0; i < extensionInfos.size(); i++) {
166         AAFwk::Want wantTem;
167         wantTem.SetElementName(extensionInfos[i].bundleName, extensionInfos[i].name);
168         sptr<FileAccessExtConnection> fileAccessExtConnection = new(std::nothrow) FileAccessExtConnection();
169         if (fileAccessExtConnection == nullptr) {
170             HILOG_ERROR("new fileAccessExtConnection fail");
171             return {nullptr, E_GETRESULT};
172         }
173 
174         if (!fileAccessExtConnection->IsExtAbilityConnected()) {
175             fileAccessExtConnection->ConnectFileExtAbility(wantTem, context->GetToken());
176         }
177 
178         sptr<IFileAccessExtBase> fileExtProxy = fileAccessExtConnection->GetFileExtProxy();
179         if (fileExtProxy == nullptr) {
180             HILOG_ERROR("Creator get invalid fileExtProxy");
181             return {nullptr, E_CONNECT};
182         }
183 
184         std::shared_ptr<ConnectInfo> connectInfo = std::make_shared<ConnectInfo>();
185         if (connectInfo == nullptr) {
186             HILOG_ERROR("Creator, connectInfo == nullptr");
187             return {nullptr, E_GETRESULT};
188         }
189         FileAccessHelper::wants_.push_back(wantTem);
190 
191         connectInfo->want = wantTem;
192         connectInfo->fileAccessExtConnection = fileAccessExtConnection;
193         cMap.emplace(extensionInfos[i].bundleName, connectInfo);
194     }
195     FileAccessHelper *ptrFileAccessHelper = new (std::nothrow) FileAccessHelper(context, cMap);
196     if (ptrFileAccessHelper == nullptr) {
197         HILOG_ERROR("FileAccessHelper::Creator failed, create FileAccessHelper failed");
198         return {nullptr, E_GETRESULT};
199     }
200 
201     return {std::shared_ptr<FileAccessHelper>(ptrFileAccessHelper), ERR_OK};
202 }
203 
Creator(const std::shared_ptr<OHOS::AbilityRuntime::Context> & context,const std::vector<AAFwk::Want> & wants)204 std::pair<std::shared_ptr<FileAccessHelper>, int> FileAccessHelper::Creator(
205     const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, const std::vector<AAFwk::Want> &wants)
206 {
207     if (context == nullptr) {
208         HILOG_ERROR("FileAccessHelper::Creator failed, context == nullptr");
209         return {nullptr, EINVAL};
210     }
211 
212     if (wants.size() == 0) {
213         HILOG_ERROR("FileAccessHelper::Creator failed, wants is empty");
214         return {nullptr, EINVAL};
215     }
216 
217     if (GetRegisteredFileAccessExtAbilityInfo(FileAccessHelper::wants_) != ERR_OK) {
218         HILOG_ERROR("GetRegisteredFileAccessExtAbilityInfo failed");
219         return {nullptr, E_GETINFO};
220     }
221 
222     std::unordered_map<std::string, std::shared_ptr<ConnectInfo>> cMap;
223     for (size_t i = 0; i < wants.size(); i++) {
224         sptr<FileAccessExtConnection> fileAccessExtConnection = new(std::nothrow) FileAccessExtConnection();
225         if (fileAccessExtConnection == nullptr) {
226             HILOG_ERROR("new fileAccessExtConnection fail");
227             return {nullptr, E_GETRESULT};
228         }
229 
230         if (!fileAccessExtConnection->IsExtAbilityConnected()) {
231             fileAccessExtConnection->ConnectFileExtAbility(wants[i], context->GetToken());
232         }
233 
234         sptr<IFileAccessExtBase> fileExtProxy = fileAccessExtConnection->GetFileExtProxy();
235         if (fileExtProxy == nullptr) {
236             HILOG_ERROR("Creator get invalid fileExtProxy");
237             return {nullptr, E_CONNECT};
238         }
239 
240         std::shared_ptr<ConnectInfo> connectInfo = std::make_shared<ConnectInfo>();
241         if (connectInfo == nullptr) {
242             HILOG_ERROR("Creator, connectInfo == nullptr");
243             return {nullptr, E_GETRESULT};
244         }
245 
246         connectInfo->want = wants[i];
247         connectInfo->fileAccessExtConnection = fileAccessExtConnection;
248         string bundleName = FileAccessHelper::GetKeyOfWants(wants[i]);
249         if (bundleName.length() == 0) {
250             HILOG_ERROR("Creator GetKeyOfWants bundleName not found");
251             return {nullptr, E_GETRESULT};
252         }
253         cMap.insert(std::pair<std::string, std::shared_ptr<ConnectInfo>>(bundleName, connectInfo));
254     }
255     FileAccessHelper *ptrFileAccessHelper = new (std::nothrow) FileAccessHelper(context, cMap);
256     if (ptrFileAccessHelper == nullptr) {
257         HILOG_ERROR("Creator failed, create FileAccessHelper failed");
258         return {nullptr, E_GETRESULT};
259     }
260 
261     return {std::shared_ptr<FileAccessHelper>(ptrFileAccessHelper), ERR_OK};
262 }
263 
Creator(const sptr<IRemoteObject> & token,const std::vector<AAFwk::Want> & wants)264 std::shared_ptr<FileAccessHelper> FileAccessHelper::Creator(const sptr<IRemoteObject> &token,
265     const std::vector<AAFwk::Want> &wants)
266 {
267     if (token == nullptr) {
268         HILOG_ERROR("FileAccessHelper::Creator failed, token == nullptr");
269         return nullptr;
270     }
271 
272     if (wants.size() == 0) {
273         HILOG_ERROR("FileAccessHelper::Creator failed, wants is empty");
274         return nullptr;
275     }
276 
277     if (GetRegisteredFileAccessExtAbilityInfo(FileAccessHelper::wants_) != ERR_OK) {
278         HILOG_ERROR("GetRegisteredFileAccessExtAbilityInfo failed");
279         return nullptr;
280     }
281 
282     std::unordered_map<std::string, std::shared_ptr<ConnectInfo>> cMap;
283     for (size_t i = 0; i < wants.size(); i++) {
284         sptr<FileAccessExtConnection> fileAccessExtConnection = new(std::nothrow) FileAccessExtConnection();
285         if (fileAccessExtConnection == nullptr) {
286             HILOG_ERROR("new fileAccessExtConnection fail");
287             return nullptr;
288         }
289 
290         if (!fileAccessExtConnection->IsExtAbilityConnected()) {
291             fileAccessExtConnection->ConnectFileExtAbility(wants[i], token);
292         }
293 
294         sptr<IFileAccessExtBase> fileExtProxy = fileAccessExtConnection->GetFileExtProxy();
295         if (fileExtProxy == nullptr) {
296             HILOG_ERROR("Creator get invalid fileExtProxy");
297             return nullptr;
298         }
299 
300         std::shared_ptr<ConnectInfo> connectInfo = std::make_shared<ConnectInfo>();
301         if (connectInfo == nullptr) {
302             HILOG_ERROR("Creator, connectInfo == nullptr");
303             return nullptr;
304         }
305 
306         connectInfo->want = wants[i];
307         connectInfo->fileAccessExtConnection = fileAccessExtConnection;
308         string bundleName = FileAccessHelper::GetKeyOfWants(wants[i]);
309         if (bundleName.length() == 0) {
310             HILOG_ERROR("Creator GetKeyOfWants bundleName not found");
311             return nullptr;
312         }
313         cMap.insert(std::pair<std::string, std::shared_ptr<ConnectInfo>>(bundleName, connectInfo));
314     }
315     FileAccessHelper *ptrFileAccessHelper = new (std::nothrow) FileAccessHelper(token, cMap);
316     if (ptrFileAccessHelper == nullptr) {
317         HILOG_ERROR("Creator failed, create FileAccessHelper failed");
318         return nullptr;
319     }
320 
321     return std::shared_ptr<FileAccessHelper>(ptrFileAccessHelper);
322 }
323 
Release()324 bool FileAccessHelper::Release()
325 {
326     for (auto iter = cMap_.begin(); iter != cMap_.end(); iter++) {
327         if (iter->second->fileAccessExtConnection->IsExtAbilityConnected()) {
328             iter->second->fileAccessExtConnection->DisconnectFileExtAbility();
329         }
330     }
331     cMap_.clear();
332     token_ = nullptr;
333     FileAccessHelper::wants_.clear();
334     return true;
335 }
336 
GetProxyByUri(Uri & uri)337 sptr<IFileAccessExtBase> FileAccessHelper::GetProxyByUri(Uri &uri)
338 {
339     std::string bundleName;
340     if (!GetBundleNameFromPath(uri.GetPath(), bundleName)) {
341         HILOG_ERROR("Get BundleName failed.");
342         return nullptr;
343     }
344 
345     auto connectInfo = GetConnectInfo(bundleName);
346     if (connectInfo == nullptr) {
347         HILOG_ERROR("GetProxyByUri failed with invalid connectInfo");
348         return nullptr;
349     }
350 
351     if (!connectInfo->fileAccessExtConnection->IsExtAbilityConnected()) {
352         connectInfo->fileAccessExtConnection->ConnectFileExtAbility(connectInfo->want, token_);
353     }
354 
355     auto fileAccessExtProxy = connectInfo->fileAccessExtConnection->GetFileExtProxy();
356     if (fileAccessExtProxy) {
357         AddFileAccessDeathRecipient(fileAccessExtProxy->AsObject());
358     }
359 
360     if (fileAccessExtProxy == nullptr) {
361         HILOG_ERROR("GetProxyByUri failed with invalid fileAccessExtProxy");
362         return nullptr;
363     }
364 
365     return fileAccessExtProxy;
366 }
367 
GetProxy()368 bool FileAccessHelper::GetProxy()
369 {
370     for (auto iter = cMap_.begin(); iter != cMap_.end(); ++iter) {
371         auto connectInfo = iter->second;
372         if (!connectInfo->fileAccessExtConnection->IsExtAbilityConnected()) {
373             connectInfo->fileAccessExtConnection->ConnectFileExtAbility(connectInfo->want, token_);
374         }
375 
376         auto fileAccessExtProxy = connectInfo->fileAccessExtConnection->GetFileExtProxy();
377         if (fileAccessExtProxy) {
378             AddFileAccessDeathRecipient(fileAccessExtProxy->AsObject());
379         }
380 
381         if (fileAccessExtProxy == nullptr) {
382             HILOG_ERROR("GetProxy failed with invalid fileAccessExtProxy");
383             return false;
384         }
385     }
386     return true;
387 }
388 
OpenFile(Uri & uri,int flags,int & fd)389 int FileAccessHelper::OpenFile(Uri &uri, int flags, int &fd)
390 {
391     StartTrace(HITRACE_TAG_FILEMANAGEMENT, "OpenFile");
392 
393     if (!CheckUri(uri)) {
394         HILOG_ERROR("Uri format check error.");
395         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
396         return E_URIS;
397     }
398 
399     if (flags != READ && flags != WRITE && flags != WRITE_READ) {
400         HILOG_ERROR("flags type error.");
401         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
402         return EINVAL;
403     }
404 
405     sptr<IFileAccessExtBase> fileExtProxy = GetProxyByUri(uri);
406     if (fileExtProxy == nullptr) {
407         HILOG_ERROR("failed with invalid fileAccessExtProxy");
408         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
409         return E_IPCS;
410     }
411 
412     int ret = fileExtProxy->OpenFile(uri, flags, fd);
413     if (ret != ERR_OK) {
414         HILOG_ERROR("OpenFile get result error, code:%{public}d", ret);
415         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
416         return ret;
417     }
418 
419     FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
420     return ERR_OK;
421 }
422 
CreateFile(Uri & parent,const std::string & displayName,Uri & newFile)423 int FileAccessHelper::CreateFile(Uri &parent, const std::string &displayName, Uri &newFile)
424 {
425     StartTrace(HITRACE_TAG_FILEMANAGEMENT, "CreateFile");
426     if (!CheckUri(parent)) {
427         HILOG_ERROR("Uri format check error.");
428         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
429         return E_URIS;
430     }
431 
432     sptr<IFileAccessExtBase> fileExtProxy = GetProxyByUri(parent);
433     if (fileExtProxy == nullptr) {
434         HILOG_ERROR("failed with invalid fileAccessExtProxy");
435         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
436         return E_IPCS;
437     }
438 
439     int ret = fileExtProxy->CreateFile(parent, displayName, newFile);
440     if (ret != ERR_OK) {
441         HILOG_ERROR("CreateFile get result error, code:%{public}d", ret);
442         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
443         return ret;
444     }
445 
446     FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
447     return ERR_OK;
448 }
449 
Mkdir(Uri & parent,const std::string & displayName,Uri & newDir)450 int FileAccessHelper::Mkdir(Uri &parent, const std::string &displayName, Uri &newDir)
451 {
452     StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Mkdir");
453     if (!CheckUri(parent)) {
454         HILOG_ERROR("Uri format check error.");
455         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
456         return E_URIS;
457     }
458 
459     sptr<IFileAccessExtBase> fileExtProxy = GetProxyByUri(parent);
460     if (fileExtProxy == nullptr) {
461         HILOG_ERROR("failed with invalid fileAccessExtProxy");
462         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
463         return E_IPCS;
464     }
465 
466     int ret = fileExtProxy->Mkdir(parent, displayName, newDir);
467     if (ret != ERR_OK) {
468         HILOG_ERROR("Mkdir get result error, code:%{public}d", ret);
469         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
470         return ret;
471     }
472 
473     FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
474     return ERR_OK;
475 }
476 
Delete(Uri & selectFile)477 int FileAccessHelper::Delete(Uri &selectFile)
478 {
479     StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Delete");
480     if (!CheckUri(selectFile)) {
481         HILOG_ERROR("Uri format check error.");
482         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
483         return E_URIS;
484     }
485 
486     sptr<IFileAccessExtBase> fileExtProxy = GetProxyByUri(selectFile);
487     if (fileExtProxy == nullptr) {
488         HILOG_ERROR("failed with invalid fileAccessExtProxy");
489         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
490         return E_IPCS;
491     }
492 
493     int ret = fileExtProxy->Delete(selectFile);
494     if (ret != ERR_OK) {
495         HILOG_ERROR("Delete get result error, code:%{public}d", ret);
496         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
497         return ret;
498     }
499 
500     FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
501     return ERR_OK;
502 }
503 
Move(Uri & sourceFile,Uri & targetParent,Uri & newFile)504 int FileAccessHelper::Move(Uri &sourceFile, Uri &targetParent, Uri &newFile)
505 {
506     StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Move");
507     Uri sourceFileUri(sourceFile.ToString());
508     Uri targetParentUri(targetParent.ToString());
509     if (!CheckUri(sourceFile)) {
510         HILOG_ERROR("sourceFile format check error.");
511         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
512         return E_URIS;
513     }
514 
515     if (!CheckUri(targetParent)) {
516         HILOG_ERROR("targetParent format check error.");
517         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
518         return E_URIS;
519     }
520 
521     if (sourceFileUri.GetScheme() != targetParentUri.GetScheme()) {
522         HILOG_WARN("Operation failed, move not supported");
523         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
524         return EPERM;
525     }
526 
527     sptr<IFileAccessExtBase> fileExtProxy = GetProxyByUri(sourceFile);
528     if (fileExtProxy == nullptr) {
529         HILOG_ERROR("failed with invalid fileAccessExtProxy");
530         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
531         return E_IPCS;
532     }
533 
534     int ret = fileExtProxy->Move(sourceFile, targetParent, newFile);
535     if (ret != ERR_OK) {
536         HILOG_ERROR("Move get result error, code:%{public}d", ret);
537         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
538         return ret;
539     }
540 
541     FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
542     return ERR_OK;
543 }
544 
Rename(Uri & sourceFile,const std::string & displayName,Uri & newFile)545 int FileAccessHelper::Rename(Uri &sourceFile, const std::string &displayName, Uri &newFile)
546 {
547     StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Rename");
548     if (!CheckUri(sourceFile)) {
549         HILOG_ERROR("sourceFile format check error.");
550         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
551         return E_URIS;
552     }
553 
554     sptr<IFileAccessExtBase> fileExtProxy = GetProxyByUri(sourceFile);
555     if (fileExtProxy == nullptr) {
556         HILOG_ERROR("failed with invalid fileAccessExtProxy");
557         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
558         return E_IPCS;
559     }
560 
561     int ret = fileExtProxy->Rename(sourceFile, displayName, newFile);
562     if (ret != ERR_OK) {
563         HILOG_ERROR("Rename get result error, code:%{public}d", ret);
564         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
565         return ret;
566     }
567 
568     FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
569     return ERR_OK;
570 }
571 
ListFile(const FileInfo & fileInfo,const int64_t offset,const int64_t maxCount,const FileFilter & filter,std::vector<FileInfo> & fileInfoVec)572 int FileAccessHelper::ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount,
573     const FileFilter &filter, std::vector<FileInfo> &fileInfoVec)
574 {
575     StartTrace(HITRACE_TAG_FILEMANAGEMENT, "ListFile");
576     Uri sourceFile(fileInfo.uri);
577     if (!CheckUri(sourceFile)) {
578         HILOG_ERROR("sourceFile format check error.");
579         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
580         return E_URIS;
581     }
582 
583     sptr<IFileAccessExtBase> fileExtProxy = GetProxyByUri(sourceFile);
584     if (fileExtProxy == nullptr) {
585         HILOG_ERROR("failed with invalid fileAccessExtProxy");
586         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
587         return E_IPCS;
588     }
589 
590     int ret = fileExtProxy->ListFile(fileInfo, offset, maxCount, filter, fileInfoVec);
591     if (ret != ERR_OK) {
592         HILOG_ERROR("ListFile get result error, code:%{public}d", ret);
593         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
594         return ret;
595     }
596 
597     FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
598     return ERR_OK;
599 }
600 
ScanFile(const FileInfo & fileInfo,const int64_t offset,const int64_t maxCount,const FileFilter & filter,std::vector<FileInfo> & fileInfoVec)601 int FileAccessHelper::ScanFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount,
602     const FileFilter &filter, std::vector<FileInfo> &fileInfoVec)
603 {
604     StartTrace(HITRACE_TAG_FILEMANAGEMENT, "ScanFile");
605     Uri sourceFile(fileInfo.uri);
606     if (!CheckUri(sourceFile)) {
607         HILOG_ERROR("sourceFile format check error.");
608         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
609         return E_URIS;
610     }
611 
612     sptr<IFileAccessExtBase> fileExtProxy = GetProxyByUri(sourceFile);
613     if (fileExtProxy == nullptr) {
614         HILOG_ERROR("failed with invalid fileAccessExtProxy");
615         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
616         return E_IPCS;
617     }
618 
619     int ret = fileExtProxy->ScanFile(fileInfo, offset, maxCount, filter, fileInfoVec);
620     if (ret != ERR_OK) {
621         HILOG_ERROR("ScanFile get result error, code:%{public}d", ret);
622         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
623         return ret;
624     }
625 
626     FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
627     return ERR_OK;
628 }
629 
GetRoots(std::vector<RootInfo> & rootInfoVec)630 int FileAccessHelper::GetRoots(std::vector<RootInfo> &rootInfoVec)
631 {
632     StartTrace(HITRACE_TAG_FILEMANAGEMENT, "GetRoots");
633     if (!GetProxy()) {
634         HILOG_ERROR("failed with invalid fileAccessExtProxy");
635         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
636         return E_IPCS;
637     }
638 
639     int ret = ERR_OK;
640     for (auto iter = cMap_.begin(); iter != cMap_.end(); ++iter) {
641         auto connectInfo = iter->second;
642         auto fileAccessExtProxy = connectInfo->fileAccessExtConnection->GetFileExtProxy();
643         std::vector<RootInfo> results;
644         if (fileAccessExtProxy) {
645             AddFileAccessDeathRecipient(fileAccessExtProxy->AsObject());
646         } else {
647             HILOG_ERROR("GetFileExtProxy return nullptr, bundle name is %{public}s", iter->first.c_str());
648             continue;
649         }
650 
651         ret = fileAccessExtProxy->GetRoots(results);
652         if (ret != ERR_OK) {
653             HILOG_ERROR("getRoots get fail ret:%{public}d", ret);
654             FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
655             return ret;
656         }
657 
658         rootInfoVec.insert(rootInfoVec.end(), results.begin(), results.end());
659     }
660 
661     FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
662     return ERR_OK;
663 }
664 
GetRegisteredFileAccessExtAbilityInfo(std::vector<AAFwk::Want> & wantVec)665 int FileAccessHelper::GetRegisteredFileAccessExtAbilityInfo(std::vector<AAFwk::Want> &wantVec)
666 {
667     StartTrace(HITRACE_TAG_FILEMANAGEMENT, "GetRegisteredFileAccessExtAbilityInfo");
668     std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
669     sptr<AppExecFwk::IBundleMgr> bm = FileAccessHelper::GetBundleMgrProxy();
670     if (bm == nullptr) {
671         HILOG_ERROR("GetBundleMgrProxy nullptr.");
672         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
673         return E_GETINFO;
674     }
675     bool ret = bm->QueryExtensionAbilityInfos(
676         AppExecFwk::ExtensionAbilityType::FILEACCESS_EXTENSION, GetUserId(), extensionInfos);
677     if (!ret) {
678         HILOG_ERROR("FileAccessHelper::GetRegisteredFileAccessExtAbilityInfo QueryExtensionAbilityInfos error");
679         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
680         return E_GETINFO;
681     }
682 
683     wantVec.clear();
684     for (size_t i = 0; i < extensionInfos.size(); i++) {
685         AAFwk::Want want;
686         want.SetElementName(extensionInfos[i].bundleName, extensionInfos[i].name);
687         wantVec.push_back(want);
688     }
689 
690     FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
691     return ERR_OK;
692 }
693 
Access(Uri & uri,bool & isExist)694 int FileAccessHelper::Access(Uri &uri, bool &isExist)
695 {
696     StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Access");
697     if (!CheckUri(uri)) {
698         HILOG_ERROR("uri format check error.");
699         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
700         return E_URIS;
701     }
702 
703     sptr<IFileAccessExtBase> fileExtProxy = GetProxyByUri(uri);
704     if (fileExtProxy == nullptr) {
705         HILOG_ERROR("failed with invalid fileAccessExtProxy");
706         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
707         return E_IPCS;
708     }
709 
710     int ret = fileExtProxy->Access(uri, isExist);
711     if (ret != ERR_OK) {
712         HILOG_ERROR("Access get result error, code:%{public}d", ret);
713         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
714         return ret;
715     }
716 
717     FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
718     return ERR_OK;
719 }
720 
UriToFileInfo(Uri & selectFile,FileInfo & fileInfo)721 int FileAccessHelper::UriToFileInfo(Uri &selectFile, FileInfo &fileInfo)
722 {
723     StartTrace(HITRACE_TAG_FILEMANAGEMENT, "UriToFileInfo");
724     if (!CheckUri(selectFile)) {
725         HILOG_ERROR("selectFile uri format check error.");
726         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
727         return E_URIS;
728     }
729 
730     sptr<IFileAccessExtBase> fileExtProxy = GetProxyByUri(selectFile);
731     if (fileExtProxy == nullptr) {
732         HILOG_ERROR("failed with invalid fileAccessExtProxy");
733         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
734         return E_IPCS;
735     }
736 
737     int ret = fileExtProxy->UriToFileInfo(selectFile, fileInfo);
738     if (ret != ERR_OK) {
739         HILOG_ERROR("UriToFileInfo get result error, code:%{public}d", ret);
740         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
741         return ret;
742     }
743 
744     FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
745     return ERR_OK;
746 }
747 
On(std::shared_ptr<INotifyCallback> & callback)748 int FileAccessHelper::On(std::shared_ptr<INotifyCallback> &callback)
749 {
750     StartTrace(HITRACE_TAG_FILEMANAGEMENT, "On");
751     if (callback == nullptr) {
752         HILOG_ERROR("failed with invalid callback");
753         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
754         return EINVAL;
755     }
756 
757     if (!GetProxy()) {
758         HILOG_ERROR("failed with invalid fileAccessExtProxy");
759         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
760         return E_IPCS;
761     }
762 
763     std::lock_guard<std::mutex> lock(notifyAgentMutex_);
764     if (notifyAgent_ == nullptr) {
765         notifyAgent_ = new(std::nothrow) FileAccessNotifyAgent(callback);
766         if (notifyAgent_ == nullptr) {
767             HILOG_ERROR("new FileAccessNotifyAgent fail");
768             FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
769             return EINVAL;
770         }
771     }
772 
773     int errorCode = ERR_OK;
774     for (auto iter = cMap_.begin(); iter != cMap_.end(); ++iter) {
775         auto connectInfo = iter->second;
776         auto fileAccessExtProxy = connectInfo->fileAccessExtConnection->GetFileExtProxy();
777         if (fileAccessExtProxy == nullptr) {
778             HILOG_ERROR("fileAccessExtProxy RegisterNotify fail");
779             FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
780             return E_IPCS;
781         }
782 
783         errorCode = fileAccessExtProxy->RegisterNotify(notifyAgent_);
784         if (errorCode != ERR_OK) {
785             HILOG_ERROR("fileAccessExtProxy RegisterNotify fail, bundleName:%{public}s, ret:%{public}d.",
786                 connectInfo->want.GetElement().GetBundleName().c_str(), errorCode);
787             FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
788             return errorCode;
789         }
790     }
791 
792     FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
793     return ERR_OK;
794 }
795 
Off()796 int FileAccessHelper::Off()
797 {
798     StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Off");
799     std::lock_guard<std::mutex> lock(notifyAgentMutex_);
800     if (notifyAgent_ == nullptr) {
801         HILOG_ERROR("not registered notify");
802         FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
803         return E_NOTIFY;
804     }
805 
806     int errorCode = ERR_OK;
807     for (auto [key, value] : cMap_) {
808         auto connectInfo = value;
809         auto fileAccessExtProxy = connectInfo->fileAccessExtConnection->GetFileExtProxy();
810         if (fileAccessExtProxy == nullptr) {
811             HILOG_INFO("fileAccessExtProxy UnregisterNotify fail, bundleName:%{public}s",
812                 connectInfo->want.GetElement().GetBundleName().c_str());
813             continue;
814         }
815 
816         errorCode = fileAccessExtProxy->UnregisterNotify(notifyAgent_);
817         if (errorCode != ERR_OK) {
818             HILOG_ERROR("fileAccessExtProxy UnregisterNotify fail, bundleName:%{public}s, ret:%{public}d.",
819                 connectInfo->want.GetElement().GetBundleName().c_str(), errorCode);
820             FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
821             return errorCode;
822         }
823     }
824 
825     notifyAgent_.clear();
826     FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
827     return ERR_OK;
828 }
829 
OnRemoteDied(const wptr<IRemoteObject> & remote)830 void FileAccessDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
831 {
832     if (handler_) {
833         handler_(remote);
834     }
835 }
836 
FileAccessDeathRecipient(RemoteDiedHandler handler)837 FileAccessDeathRecipient::FileAccessDeathRecipient(RemoteDiedHandler handler) : handler_(handler)
838 {
839 }
840 
~FileAccessDeathRecipient()841 FileAccessDeathRecipient::~FileAccessDeathRecipient()
842 {
843 }
844 } // namespace FileAccessFwk
845 } // namespace OHOS