diff --git a/frameworks/innerkits/file_access/include/file_access_ext_ability.h b/frameworks/innerkits/file_access/include/file_access_ext_ability.h index ffc0b19dcfde2d51daf8109641b1509aaa8d9ccf..19929cd55b2bb741e2dad0767c5b8851ed3985e3 100644 --- a/frameworks/innerkits/file_access/include/file_access_ext_ability.h +++ b/frameworks/innerkits/file_access/include/file_access_ext_ability.h @@ -46,9 +46,9 @@ public: virtual int Delete(const Uri &sourceFile); virtual int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile); virtual int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile); - - virtual std::vector ListFile(const Uri &sourceFile); - virtual std::vector GetRoots(); + virtual int ListFile(const FileInfo &fileInfo, std::vector &fileInfoVec, + int64_t offset, int64_t maxCount); + virtual int GetRoots(std::vector &deviceInfoVec); virtual int IsFileExist(const Uri &uri, bool &isExist); virtual int RegisterNotify(sptr ¬ify); virtual int UnregisterNotify(sptr ¬ify); diff --git a/frameworks/innerkits/file_access/include/file_access_ext_proxy.h b/frameworks/innerkits/file_access/include/file_access_ext_proxy.h index ff4e0872773e9f0b1ed44fa934051c29a7054388..2fcf8b25ea2f40bbda8d263275bee8ca1fa5f971 100644 --- a/frameworks/innerkits/file_access/include/file_access_ext_proxy.h +++ b/frameworks/innerkits/file_access/include/file_access_ext_proxy.h @@ -42,9 +42,10 @@ public: virtual int Delete(const Uri &sourceFile) override; virtual int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) override; virtual int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) override; - - virtual std::vector ListFile(const Uri &sourceFile) override; - virtual std::vector GetRoots() override; + virtual int ListFile(const FileInfo &fileInfo, std::vector &fileInfoVec, int64_t offset, + int64_t maxCount) override; + virtual int ListFile(const FileInfo &fileInfo, ShmParam &shmParam) override; + virtual int GetRoots(std::vector &deviceInfoVec) override; virtual int IsFileExist(const Uri &uri, bool &isExist) override; virtual int RegisterNotify(sptr ¬ify) override; virtual int UnregisterNotify(sptr ¬ify) override; diff --git a/frameworks/innerkits/file_access/include/file_access_ext_stub_impl.h b/frameworks/innerkits/file_access/include/file_access_ext_stub_impl.h index d72745dd30eea65f13052bb68d59b0f6e2427700..b60de057da9be36f69095c07bad295ef0a4c03b7 100644 --- a/frameworks/innerkits/file_access/include/file_access_ext_stub_impl.h +++ b/frameworks/innerkits/file_access/include/file_access_ext_stub_impl.h @@ -40,8 +40,9 @@ public: int Delete(const Uri &sourceFile) override; int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) override; int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) override; - std::vector ListFile(const Uri &sourceFileUri) override; - std::vector GetRoots() override; + virtual int ListFile(const FileInfo &fileInfo, std::vector &fileInfoVec, + int64_t offset, int64_t maxCount) override; + virtual int GetRoots(std::vector &deviceInfoVec) override; int IsFileExist(const Uri &uri, bool &isExist) override; int RegisterNotify(sptr ¬ify) override; int UnregisterNotify(sptr ¬ify) override; diff --git a/frameworks/innerkits/file_access/include/file_access_extension_info.h b/frameworks/innerkits/file_access/include/file_access_extension_info.h index ab4719dbb241a0b4666e5f57b476693e4a05b255..ef0297f6a9f458ffe3c36a1bf8fc6e814e39bd66 100644 --- a/frameworks/innerkits/file_access/include/file_access_extension_info.h +++ b/frameworks/innerkits/file_access/include/file_access_extension_info.h @@ -17,13 +17,25 @@ #define FILE_ACCESS_EXTENSION_INFO_H #include +#include +#include +#include +#include #include +#include +#include +#include +#include "hilog_wrapper.h" #include "parcel.h" #include "uri.h" namespace OHOS { namespace FileAccessFwk { +namespace { + constexpr int MULTIPLE_COUNT = 1000; +} + enum DeviceType { DEVICE_LOCAL_DISK = 1, // Local c,d... disk DEVICE_SHARED_DISK, // Multi-user shared disk @@ -34,23 +46,38 @@ enum DeviceType { DEVICE_EXTERNAL_CLOUD // Cloud disk device }; +struct FileInfoData { + char uri[4096] = {0}; + char fileName[256] = {0}; + char mode[32] = {0}; + int64_t size {0}; + int64_t mtime {0}; + char mimeType[64] = {0}; +}; + struct FileInfo : public virtual OHOS::Parcelable { public: - Uri uri = Uri(""); + std::string uri; std::string fileName; std::string mode; int64_t size {0}; int64_t mtime {0}; std::string mimeType; - bool ReadFromParcel(Parcel &parcel) + FileInfo &operator=(const FileInfo &other) { - std::unique_ptr uriInfo(parcel.ReadParcelable()); - if (uriInfo == nullptr) { - return false; - } - uri = *uriInfo; + uri = other.uri; + fileName = other.fileName; + mode = other.mode; + size = other.size; + mtime = other.mtime; + mimeType = other.mimeType; + return *this; + } + bool ReadFromParcel(Parcel &parcel) + { + uri = parcel.ReadString(); fileName = parcel.ReadString(); mode = parcel.ReadString(); size = parcel.ReadInt64(); @@ -61,7 +88,7 @@ public: virtual bool Marshalling(Parcel &parcel) const override { - if (!parcel.WriteParcelable(&uri)) { + if (!parcel.WriteString(uri)) { return false; } if (!parcel.WriteString(fileName)) { @@ -155,12 +182,246 @@ public: } }; +class ShmParam : public virtual OHOS::Parcelable { +public: + int64_t key {-1}; + int64_t offset {0}; + int64_t maxNum {100}; + int64_t numCount {0}; + + ShmParam() = default; + ~ShmParam() = default; + + bool InitBuff() + { + struct timespec time = {0, 0}; + clock_gettime(CLOCK_REALTIME, &time); + std::stringstream secNs; + secNs << (time.tv_sec * MULTIPLE_COUNT * MULTIPLE_COUNT * MULTIPLE_COUNT + time.tv_nsec); + auto hash_id = std::hash()(secNs.str()); + auto key_id = static_cast(hash_id); + memSize = sizeof(FileInfoData) * maxNum; + if (key > 0) { + return true; + } + + int shmid = shmget(key_id, memSize, 0777U | IPC_CREAT | IPC_EXCL); + if (shmid < 0) { + HILOG_ERROR("shmget error"); + return false; + } + + FileInfoData* fileInfo = (FileInfoData*)shmat(shmid, 0, 0); + if (fileInfo == nullptr) { + HILOG_ERROR("shmat error"); + return false; + } + + if (memset_s(fileInfo, memSize, 0, memSize) != EOK) { + HILOG_ERROR("memory alloc error"); + return false; + } + + if (shmdt(fileInfo) < 0) { + HILOG_ERROR("shmdt error"); + return false; + } + + key = static_cast(key_id); + return true; + } + + bool ReleaseBuff() + { + if (key < 0) { + HILOG_ERROR("key invalid"); + return false; + } + + int shmid = shmget(key, memSize, 0777U | IPC_CREAT); + if (shmid < 0) { + HILOG_ERROR("shmget error"); + return false; + } + + FileInfoData* fileInfo = (FileInfoData*)shmat(shmid, 0, 0); + if (fileInfo == nullptr) { + HILOG_ERROR("shmat error"); + return false; + } + + if (memset_s(fileInfo, memSize, 0, memSize) != EOK) { + HILOG_ERROR("memory alloc error"); + return false; + } + + if (shmdt(fileInfo) < 0) { + HILOG_ERROR("shmdt error"); + return false; + } + + if (shmctl(shmid, IPC_RMID, 0) != EOK) { + return false; + } + + key = -1; + offset = 0; + numCount = 0; + memSize = 0; + return true; + } + + bool WriteBuff(std::string uri, std::vector &fileInfoVec) + { + if (key == -1 || memSize == 0) { + return false; + } + + numCount = 0; + int64_t count { fileInfoVec.size() }; + if (count == 0) { + return true; + } + + auto key_id = static_cast(key); + int shmid = shmget(key_id, memSize, 0777U | IPC_CREAT); + if (shmid < 0) { + HILOG_ERROR("shmget error"); + return false; + } + + FileInfoData* fileInfoTmp = (FileInfoData*)shmat(shmid, 0, 0); + if (fileInfoTmp == nullptr) { + HILOG_ERROR("shmat error"); + return false; + } + + if (memset_s(fileInfoTmp, memSize, 0, memSize) != EOK) { + HILOG_ERROR("memory alloc error"); + return false; + } + + for (int64_t i = 0; i < count; ++i) { + memcpy(fileInfoTmp[i].uri, fileInfoVec[i].uri.c_str(), strlen(fileInfoVec[i].uri.c_str()) + 1); + memcpy(fileInfoTmp[i].fileName, fileInfoVec[i].fileName.c_str(), + strlen(fileInfoVec[i].fileName.c_str()) + 1); + memcpy(fileInfoTmp[i].mode, fileInfoVec[i].mode.c_str(), strlen(fileInfoVec[i].mode.c_str()) + 1); + fileInfoTmp[i].size = fileInfoVec[i].size; + fileInfoTmp[i].mtime = fileInfoVec[i].mtime; + memcpy(fileInfoTmp[i].mimeType, fileInfoVec[i].mimeType.c_str(), + strlen(fileInfoVec[i].mimeType.c_str()) + 1); + } + + if (shmdt(fileInfoTmp) < 0) { + HILOG_ERROR("shmdt error"); + return false; + } + numCount = count; + offset = offset + numCount; + + return true; + } + + bool ReadBuff(int64_t pos, FileInfo &fileInfo) + { + if (pos >= numCount || pos < 0) { + HILOG_ERROR("argument invalid"); + return false; + } + + int shmid = shmget(key, memSize, 0644U | IPC_CREAT); + if (shmid < 0) { + HILOG_ERROR("shmget error"); + return false; + } + + FileInfoData* fileInfoTmp = (FileInfoData*)shmat(shmid, 0, 0); + if (fileInfoTmp == nullptr) { + HILOG_ERROR("shmat error"); + return false; + } + + fileInfo.uri = fileInfoTmp[pos].uri; + fileInfo.fileName = fileInfoTmp[pos].fileName; + fileInfo.mode = fileInfoTmp[pos].mode; + fileInfo.size = fileInfoTmp[pos].size; + fileInfo.mtime = fileInfoTmp[pos].mtime; + fileInfo.mimeType = fileInfoTmp[pos].mimeType; + + return true; + } + + ShmParam &operator=(const ShmParam &other) + { + key = other.key; + offset = other.offset; + maxNum = other.maxNum; + numCount = other.numCount; + memSize = other.memSize; + return *this; + } + + bool ReadFromParcel(Parcel &parcel) + { + key = parcel.ReadInt64(); + offset = parcel.ReadInt64(); + maxNum = parcel.ReadInt64(); + numCount = parcel.ReadInt64(); + memSize = parcel.ReadInt64(); + return true; + } + + virtual bool Marshalling(Parcel &parcel) const override + { + if (!parcel.WriteInt64(key)) { + return false; + } + + if (!parcel.WriteInt64(offset)) { + return false; + } + + if (!parcel.WriteInt64(maxNum)) { + return false; + } + + if (!parcel.WriteInt64(numCount)) { + return false; + } + + if (!parcel.WriteInt64(memSize)) { + return false; + } + + return true; + } + + static ShmParam *Unmarshalling(Parcel &parcel) + { + ShmParam *param = new (std::nothrow) ShmParam(); + if (param == nullptr) { + return nullptr; + } + + if (!param->ReadFromParcel(parcel)) { + delete param; + param = nullptr; + } + + return param; + } + +private: + int64_t memSize {0}; +}; + const uint32_t FLAG_SUPPORTS_THUMBNAIL = 1; const uint32_t FLAG_SUPPORTS_WRITE = 1 << 1; const uint32_t FLAG_SUPPORTS_READ = 1 << 2; const uint32_t FLAG_SUPPORTS_DELETE = 1 << 3; const uint32_t FLAG_SUPPORTS_RENAME = 1 << 4; const uint32_t FLAG_SUPPORTS_MOVE = 1 << 5; + } // namespace FileAccessFwk } // namespace OHOS #endif // FILE_ACCESS_EXTENSION_INFO_H \ No newline at end of file diff --git a/frameworks/innerkits/file_access/include/file_access_helper.h b/frameworks/innerkits/file_access/include/file_access_helper.h index 436ea33345714e1e457524e0d1f0bd0f062629f9..34c7fef2bc8afe380c9866080f4aec1b7855db75 100644 --- a/frameworks/innerkits/file_access/include/file_access_helper.h +++ b/frameworks/innerkits/file_access/include/file_access_helper.h @@ -47,8 +47,7 @@ struct ConnectInfo { class FileAccessHelper final : public std::enable_shared_from_this { public: ~FileAccessHelper() = default; - // get all ability want info - static std::vector GetRegisterFileAccessExtAbilityInfo(); + static int GetRegisterFileAccessExtAbilityInfo(std::vector &wantVec); // create and connect all ability static std::shared_ptr Creator(const std::shared_ptr &context); // create and connect with want, if created, only connect with want @@ -65,8 +64,8 @@ public: int Delete(Uri &selectFile); int Move(Uri &sourceFile, Uri &targetParent, Uri &newFile); int Rename(Uri &sourceFile, const std::string &displayName, Uri &newFile); - std::vector ListFile(Uri &sourceFile); - std::vector GetRoots(); + int ListFile(const FileInfo &fileInfo, ShmParam &shmParam); + int GetRoots(std::vector &deviceInfoVec); int On(std::shared_ptr &callback); int Off(); private: diff --git a/frameworks/innerkits/file_access/include/ifile_access_ext_base.h b/frameworks/innerkits/file_access/include/ifile_access_ext_base.h index 63ab8bfd778b3b407d03ecc51e7bbb2fffdb8d41..4c7e6dc35b162a6b23a8ec3cafaff40dcd3f4100 100644 --- a/frameworks/innerkits/file_access/include/ifile_access_ext_base.h +++ b/frameworks/innerkits/file_access/include/ifile_access_ext_base.h @@ -52,12 +52,16 @@ public: virtual int Delete(const Uri &sourceFile) = 0; virtual int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) = 0; virtual int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) = 0; - - virtual std::vector ListFile(const Uri &sourceFile) = 0; - virtual std::vector GetRoots() = 0; + virtual int ListFile(const FileInfo &fileInfo, std::vector &fileInfoVec, + int64_t offset, int64_t maxCount) = 0; + virtual int GetRoots(std::vector &deviceInfoVec) = 0; virtual int IsFileExist(const Uri &uri, bool &isExist) = 0; virtual int RegisterNotify(sptr ¬ify) = 0; virtual int UnregisterNotify(sptr ¬ify) = 0; + virtual int ListFile(const FileInfo &fileInfo, ShmParam &shmParam) + { + return 0; + }; }; } // namespace FileAccessFwk } // namespace OHOS diff --git a/frameworks/innerkits/file_access/include/js_file_access_ext_ability.h b/frameworks/innerkits/file_access/include/js_file_access_ext_ability.h index 66d4a8f27976fa1f008d04a2fb808dad4907553e..bbc51e4a44bb4c1958c60104f2c0b74c9276e9e4 100644 --- a/frameworks/innerkits/file_access/include/js_file_access_ext_ability.h +++ b/frameworks/innerkits/file_access/include/js_file_access_ext_ability.h @@ -66,8 +66,9 @@ public: int Delete(const Uri &sourceFile) override; int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) override; int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) override; - std::vector ListFile(const Uri &sourceFile) override; - std::vector GetRoots() override; + int ListFile(const FileInfo &fileInfo, std::vector &fileInfoVec, + int64_t offset, int64_t maxCount) override; + int GetRoots(std::vector &deviceInfoVec) override; int IsFileExist(const Uri &uri, bool &isExist) override; private: diff --git a/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp b/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp index 638d2efcba16da873f16229db66e0484e022f6c8..75bb65410b4287fe95228a28a5aa34bc3e4f3675 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp @@ -97,18 +97,18 @@ int FileAccessExtAbility::Rename(const Uri &sourceFile, const std::string &displ return ERR_OPERATION_NOT_SUPPORT; } -std::vector FileAccessExtAbility::ListFile(const Uri &sourceFile) +int FileAccessExtAbility::ListFile(const FileInfo &fileInfo, + std::vector &fileInfoVec, + int64_t offset, int64_t maxCount) { - std::vector vec; HILOG_ERROR("FileAccessExtAbility::ListFile Undefined operation"); - return vec; + return ERR_OPERATION_NOT_SUPPORT; } -std::vector FileAccessExtAbility::GetRoots() +int FileAccessExtAbility::GetRoots(std::vector &deviceInfoVec) { - std::vector vec; HILOG_ERROR("FileAccessExtAbility::GetRoots Undefined operation"); - return vec; + return ERR_OPERATION_NOT_SUPPORT; } int FileAccessExtAbility::IsFileExist(const Uri &uri, bool &isExist) diff --git a/frameworks/innerkits/file_access/src/file_access_ext_proxy.cpp b/frameworks/innerkits/file_access/src/file_access_ext_proxy.cpp index 1f5d7370e635d45cb9b199d12b293a5937745a43..7dc5c3d67ecf4dc4847701302cbfee34093a3059 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_proxy.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_proxy.cpp @@ -327,7 +327,15 @@ int FileAccessExtProxy::Rename(const Uri &sourceFile, const std::string &display return ret; } -std::vector FileAccessExtProxy::ListFile(const Uri &sourceFile) +int FileAccessExtProxy::ListFile(const FileInfo &fileInfo, + std::vector &fileInfoVec, + int64_t offset, + int64_t maxCount) +{ + return ERR_OK; +} + +int FileAccessExtProxy::ListFile(const FileInfo &fileInfo, ShmParam &shmParam) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "ListFile"); std::vector vec; @@ -335,13 +343,19 @@ std::vector FileAccessExtProxy::ListFile(const Uri &sourceFile) if (!data.WriteInterfaceToken(FileAccessExtProxy::GetDescriptor())) { HILOG_ERROR("WriteInterfaceToken failed"); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return vec; + return ERR_IPC_ERROR; } - if (!data.WriteParcelable(&sourceFile)) { - HILOG_ERROR("fail to WriteParcelable sourceFileUri"); + if (!data.WriteParcelable(&fileInfo)) { + HILOG_ERROR("fail to WriteParcelable fileInfo"); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return vec; + return ERR_IPC_ERROR; + } + + if (!data.WriteParcelable(&shmParam)) { + HILOG_ERROR("fail to WriteParcelable shmParam"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ERR_IPC_ERROR; } MessageParcel reply; @@ -350,31 +364,24 @@ std::vector FileAccessExtProxy::ListFile(const Uri &sourceFile) if (err != NO_ERROR) { HILOG_ERROR("fail to SendRequest. err: %{public}d", err); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return vec; + return err; } - vec.clear(); - int64_t count = reply.ReadInt64(); - for (int32_t i = 0; i < count; i++) { - std::unique_ptr fileInfo(reply.ReadParcelable()); - if (fileInfo != nullptr) { - vec.push_back(*fileInfo); - } - } + ShmParam* shmParamTmp = reply.ReadParcelable(); + shmParam = *shmParamTmp; FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return vec; + return ERR_OK; } -std::vector FileAccessExtProxy::GetRoots() +int FileAccessExtProxy::GetRoots(std::vector &deviceInfoVec) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "GetRoots"); - std::vector vec; MessageParcel data; if (!data.WriteInterfaceToken(FileAccessExtProxy::GetDescriptor())) { HILOG_ERROR("WriteInterfaceToken failed"); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return vec; + return ERR_IPC_ERROR; } MessageParcel reply; @@ -383,20 +390,20 @@ std::vector FileAccessExtProxy::GetRoots() if (err != NO_ERROR) { HILOG_ERROR("fail to SendRequest. err: %{public}d", err); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return vec; + return ERR_IPC_ERROR; } - vec.clear(); + deviceInfoVec.clear(); uint64_t count = reply.ReadUint64(); for (uint64_t i = 0; i < count; i++) { std::unique_ptr deviceInfo(reply.ReadParcelable()); if (deviceInfo != nullptr) { - vec.push_back(*deviceInfo); + deviceInfoVec.push_back(*deviceInfo); } } FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return vec; + return ERR_OK; } int FileAccessExtProxy::IsFileExist(const Uri &uri, bool &isExist) diff --git a/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp b/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp index 2884e2e72b0547774719c3af54c2594a92f9a93e..afe8a99a36816610f900a482f72d42d6c38e5e3e 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp @@ -337,27 +337,37 @@ ErrCode FileAccessExtStub::CmdRename(MessageParcel &data, MessageParcel &reply) ErrCode FileAccessExtStub::CmdListFile(MessageParcel &data, MessageParcel &reply) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "CmdListFile"); - std::shared_ptr uri(data.ReadParcelable()); - if (uri == nullptr) { + std::shared_ptr fileInfo(data.ReadParcelable()); + if (fileInfo == nullptr) { HILOG_ERROR("parameter ListFile uri is nullptr"); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return ERR_INVALID_URI; + return ERR_IPC_ERROR; } - std::vector vec = ListFile(*uri); - uint64_t count {vec.size()}; - if (!reply.WriteUint64(count)) { - HILOG_ERROR("parameter ListFile fail to WriteInt32 count"); + std::shared_ptr shmParam(data.ReadParcelable()); + if (shmParam == nullptr) { + HILOG_ERROR("parameter ListFile uri is nullptr"); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return ERR_IPC_ERROR; } - for (uint64_t i = 0; i < count; i++) { - if (!reply.WriteParcelable(&vec[i])) { - HILOG_ERROR("parameter ListFile fail to WriteParcelable vec"); - FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return ERR_IPC_ERROR; - } + std::vector vec; + int ret = ListFile(*fileInfo, vec, shmParam->offset, shmParam->maxNum); + if (ret != ERR_OK) { + HILOG_ERROR("parameter ListFile ret err"); + return ERR_IPC_ERROR; + } + + bool res = shmParam->WriteBuff(fileInfo->uri.c_str(), vec); + if (!res) { + HILOG_ERROR("parameter ListFile WriteBuff ret err"); + return ERR_SHM_FAIL; + } + + if (!reply.WriteParcelable(&(*shmParam))) { + HILOG_ERROR("parameter ListFile fail to WriteParcelable shmParam"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ERR_IPC_ERROR; } FinishTrace(HITRACE_TAG_FILEMANAGEMENT); @@ -367,7 +377,14 @@ ErrCode FileAccessExtStub::CmdListFile(MessageParcel &data, MessageParcel &reply ErrCode FileAccessExtStub::CmdGetRoots(MessageParcel &data, MessageParcel &reply) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "CmdGetRoots"); - std::vector vec = GetRoots(); + std::vector vec; + int ret = GetRoots(vec); + if (ret != ERR_OK) { + HILOG_ERROR("parameter GetRoots fail"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ret; + } + uint64_t count {vec.size()}; if (!reply.WriteUint64(count)) { HILOG_ERROR("parameter GetRoots fail to WriteInt32 count"); diff --git a/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp b/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp index 473747d38d0fb97823178257c63f15ce5e9c34b9..78169ea71533996bd743f299115d50bb3b507780 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp @@ -110,34 +110,35 @@ int FileAccessExtStubImpl::Rename(const Uri &sourceFile, const std::string &disp return ret; } -std::vector FileAccessExtStubImpl::ListFile(const Uri &sourceFile) +int FileAccessExtStubImpl::ListFile(const FileInfo &fileInfo, + std::vector &fileInfoVec, + int64_t offset, + int64_t maxCount) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "ListFile"); - std::vector vec; if (extension_ == nullptr) { HILOG_ERROR("ListFile get extension failed."); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return vec; + return ERR_IPC_ERROR; } - vec = extension_->ListFile(sourceFile); + int ret = extension_->ListFile(fileInfo, fileInfoVec, offset, maxCount); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return vec; + return ret; } -std::vector FileAccessExtStubImpl::GetRoots() +int FileAccessExtStubImpl::GetRoots(std::vector &deviceInfoVec) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "GetRoots"); - std::vector vec; if (extension_ == nullptr) { HILOG_ERROR("GetRoots get extension failed."); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return vec; + return ERR_IPC_ERROR; } - vec = extension_->GetRoots(); + int ret = extension_->GetRoots(deviceInfoVec); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return vec; + return ret; } int FileAccessExtStubImpl::IsFileExist(const Uri &uri, bool &isExist) diff --git a/frameworks/innerkits/file_access/src/file_access_helper.cpp b/frameworks/innerkits/file_access/src/file_access_helper.cpp index f2758f315f5beb032a766320592cb82da847b677..0e58947983c14689802be3841e417d8fed0febbc 100644 --- a/frameworks/innerkits/file_access/src/file_access_helper.cpp +++ b/frameworks/innerkits/file_access/src/file_access_helper.cpp @@ -150,7 +150,7 @@ std::string FileAccessHelper::GetKeyOfWantsMap(const AAFwk::Want &want) } } HILOG_ERROR("GetKeyOfWantsMap called return nullptr"); - return ""; + return nullptr; } void FileAccessHelper::InsertConnectInfo(const std::string &key, @@ -538,38 +538,42 @@ int FileAccessHelper::Rename(Uri &sourceFile, const std::string &displayName, Ur return index; } -std::vector FileAccessHelper::ListFile(Uri &sourceFile) +int FileAccessHelper::ListFile(const FileInfo &fileInfo, ShmParam &shmParam) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "ListFile"); - std::vector results; + Uri sourceFile(fileInfo.uri); if (!CheckUri(sourceFile)) { HILOG_ERROR("sourceFile format check error."); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return results; + return ERR_INVALID_URI; } sptr fileExtProxy = GetProxyByUri(sourceFile); if (fileExtProxy == nullptr) { HILOG_ERROR("failed with invalid fileAccessExtProxy"); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return results; + return ERR_IPC_ERROR; } - results = fileExtProxy->ListFile(sourceFile); + int ret = fileExtProxy->ListFile(fileInfo, shmParam); + if (ret != ERR_OK) { + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ret; + } FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return results; + return ERR_OK; } -std::vector FileAccessHelper::GetRoots() +int FileAccessHelper::GetRoots(std::vector &deviceInfoVec) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "GetRoots"); - std::vector rootsInfo; if (!GetProxy()) { HILOG_ERROR("failed with invalid fileAccessExtProxy"); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return rootsInfo; + return ERR_IPC_ERROR; } + deviceInfoVec.clear(); for (auto iter = cMap_.begin(); iter != cMap_.end(); ++iter) { auto connectInfo = iter->second; auto fileAccessExtProxy = connectInfo->fileAccessExtConnection->GetFileExtProxy(); @@ -577,34 +581,37 @@ std::vector FileAccessHelper::GetRoots() if (fileAccessExtProxy) { AddFileAccessDeathRecipient(fileAccessExtProxy->AsObject()); } - results = fileAccessExtProxy->GetRoots(); - rootsInfo.insert(rootsInfo.end(), results.begin(), results.end()); + int ret = fileAccessExtProxy->GetRoots(results); + if (ret != ERR_OK) { + return ret; + } + deviceInfoVec.insert(deviceInfoVec.end(), results.begin(), results.end()); } - return rootsInfo; + return ERR_OK; } -std::vector FileAccessHelper::GetRegisterFileAccessExtAbilityInfo() +int FileAccessHelper::GetRegisterFileAccessExtAbilityInfo(std::vector &wantVec) { - std::vector wants; std::vector extensionInfos; sptr bm = FileAccessHelper::GetBundleMgrProxy(); bool ret = bm->QueryExtensionAbilityInfos( AppExecFwk::ExtensionAbilityType::FILEACCESS_EXTENSION, DEFAULT_USERID, extensionInfos); if (!ret) { HILOG_ERROR("FileAccessHelper::GetRegisterFileAccessExtAbilityInfo QueryExtensionAbilityInfos error"); - return wants; + return ERR_INVALID_PARAM; } + wantVec.clear(); FileAccessHelper::wantsMap_.clear(); for (size_t i = 0; i < extensionInfos.size(); i++) { AAFwk::Want want; want.SetElementName(extensionInfos[i].bundleName, extensionInfos[i].name); FileAccessHelper::wantsMap_.insert(std::pair(extensionInfos[i].bundleName, want)); - wants.push_back(want); + wantVec.push_back(want); } - return wants; + return ERR_OK; } int FileAccessHelper::IsFileExist(Uri &uri, bool &isExist) diff --git a/frameworks/innerkits/file_access/src/js_file_access_ext_ability.cpp b/frameworks/innerkits/file_access/src/js_file_access_ext_ability.cpp index a6e31e74b47789998d60a0d457b663a5d19fb464..fb975fd5ca51abced19c9ddc9a0342450fad231a 100644 --- a/frameworks/innerkits/file_access/src/js_file_access_ext_ability.cpp +++ b/frameworks/innerkits/file_access/src/js_file_access_ext_ability.cpp @@ -635,18 +635,37 @@ int JsFileAccessExtAbility::Rename(const Uri &sourceFile, const std::string &dis return errCode; } -std::vector JsFileAccessExtAbility::ListFile(const Uri &sourceFile) +int JsFileAccessExtAbility::ListFile(const FileInfo &fileInfo, + std::vector &fileInfoVec, + int64_t offset, + int64_t maxCount) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "ListFile"); + std::string sourceFile = fileInfo.uri; auto value = std::make_shared>>(); - auto argParser = [sourceFile](NativeEngine &engine, NativeValue *argv[], size_t &argc) -> bool { - NativeValue *uri = engine.CreateString(sourceFile.ToString().c_str(), sourceFile.ToString().length()); + auto argParser = [sourceFile, offset, maxCount](NativeEngine &engine, NativeValue *argv[], size_t &argc) -> bool { + NativeValue *uri = engine.CreateString(sourceFile.c_str(), sourceFile.length()); if (uri == nullptr) { HILOG_ERROR("create sourceFile uri native js value fail."); return false; } + + NativeValue *nativeOffset = engine.CreateNumber(offset); + if (nativeOffset == nullptr) { + HILOG_ERROR("create nativeMaxNum native js value fail."); + return false; + } + + NativeValue *nativeMaxCount = engine.CreateNumber(maxCount); + if (nativeMaxCount == nullptr) { + HILOG_ERROR("create nativeMaxNum native js value fail."); + return false; + } + argv[ARGC_ZERO] = uri; - argc = ARGC_ONE; + argv[ARGC_ONE] = nativeOffset; + argv[ARGC_TWO] = nativeMaxCount; + argc = ARGC_THREE; return true; }; auto retParser = [value](NativeEngine &engine, NativeValue *result) -> bool { @@ -657,9 +676,7 @@ std::vector JsFileAccessExtAbility::ListFile(const Uri &sourceFile) NativeValue *nativeFileInfo = nativeArray->GetElement(i); obj = ConvertNativeValueTo(nativeFileInfo); FileInfo fileInfo; - std::string uri; - ret = ret && ConvertFromJsValue(engine, obj->GetProperty("uri"), uri); - fileInfo.uri = Uri(uri); + ret = ret && ConvertFromJsValue(engine, obj->GetProperty("uri"), fileInfo.uri); ret = ret && ConvertFromJsValue(engine, obj->GetProperty("fileName"), fileInfo.fileName); ret = ret && ConvertFromJsValue(engine, obj->GetProperty("mode"), fileInfo.mode); ret = ret && ConvertFromJsValue(engine, obj->GetProperty("size"), fileInfo.size); @@ -669,6 +686,7 @@ std::vector JsFileAccessExtAbility::ListFile(const Uri &sourceFile) HILOG_ERROR("Convert js value fail."); return ret; } + (value->data).emplace_back(std::move(fileInfo)); } return true; @@ -677,17 +695,20 @@ std::vector JsFileAccessExtAbility::ListFile(const Uri &sourceFile) auto errCode = CallJsMethod("listFile", jsRuntime_, jsObj_.get(), argParser, retParser); if (errCode != ERR_OK) { HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode); + return errCode; } if (value->code != ERR_OK) { HILOG_ERROR("fileio fail."); + return ERR_FILEIO_FAIL; } + fileInfoVec = value->data; FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return value->data; + return ERR_OK; } -std::vector JsFileAccessExtAbility::GetRoots() +int JsFileAccessExtAbility::GetRoots(std::vector &deviceInfoVec) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "GetRoots"); auto value = std::make_shared>>(); @@ -722,14 +743,17 @@ std::vector JsFileAccessExtAbility::GetRoots() auto errCode = CallJsMethod("getRoots", jsRuntime_, jsObj_.get(), argParser, retParser); if (errCode != ERR_OK) { HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode); + return errCode; } if (value->code != ERR_OK) { HILOG_ERROR("fileio fail."); + return ERR_FILEIO_FAIL; } + deviceInfoVec = value->data; FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return value->data; + return ERR_OK; } int JsFileAccessExtAbility::IsFileExist(const Uri &uri, bool &isExist) diff --git a/frameworks/innerkits/file_access/src/napi_common_fileaccess.cpp b/frameworks/innerkits/file_access/src/napi_common_fileaccess.cpp index b34865aa73a9d6142bbcce44e927711916ad12bd..6438f40dc1f5d79a645e4bb92f925657d9d0b61e 100644 --- a/frameworks/innerkits/file_access/src/napi_common_fileaccess.cpp +++ b/frameworks/innerkits/file_access/src/napi_common_fileaccess.cpp @@ -113,7 +113,7 @@ napi_value WrapFileInfo(napi_env env, const FileInfo &fileInfo) NAPI_CALL(env, napi_create_object(env, &jsObject)); - jsValue = OHOS::AppExecFwk::WrapStringToJS(env, fileInfo.uri.ToString()); + jsValue = OHOS::AppExecFwk::WrapStringToJS(env, fileInfo.uri); SetPropertyValueByPropertyName(env, jsObject, "uri", jsValue); jsValue = OHOS::AppExecFwk::WrapStringToJS(env, fileInfo.fileName); @@ -142,7 +142,7 @@ bool UnwrapFileInfo(napi_env env, napi_value param, FileInfo &fileInfo) std::string natValueString(""); if (OHOS::AppExecFwk::UnwrapStringByPropertyName(env, param, "uri", natValueString)) { - fileInfo.uri = Uri(natValueString); + fileInfo.uri = natValueString; } if (OHOS::AppExecFwk::UnwrapStringByPropertyName(env, param, "fileName", natValueString)) { diff --git a/interfaces/kits/napi/file_access_module/BUILD.gn b/interfaces/kits/napi/file_access_module/BUILD.gn index 3e556e1254b5c01ed2636b7ef3378259167d49ca..b0b76b0801105e2ac622369fb65b1a92ad442bdb 100644 --- a/interfaces/kits/napi/file_access_module/BUILD.gn +++ b/interfaces/kits/napi/file_access_module/BUILD.gn @@ -22,16 +22,22 @@ ohos_shared_library("fileaccess") { include_dirs = [ "./", - "${BASE_DIR}/utils", "${BASE_DIR}/interfaces/kits/napi/common", + "${BASE_DIR}/interfaces/kits/napi/file_access_module/file_info", + "${BASE_DIR}/interfaces/kits/napi/file_access_module/root_info", + "${BASE_DIR}/utils", "//foundation/distributeddatamgr/distributedfile/utils/filemgmt_libn/include", ] sources = [ "${BASE_DIR}/interfaces/kits/napi/common/file_extension_info_napi.cpp", + "file_info/napi_file_info_exporter.cpp", + "file_info/napi_file_iterator_exporter.cpp", "napi_fileaccess_helper.cpp", "napi_notify_callback.cpp", "native_fileaccess_module.cpp", + "root_info/napi_root_info_exporter.cpp", + "root_info/napi_root_iterator_exporter.cpp", ] deps = [ diff --git a/interfaces/kits/napi/file_access_module/file_info/file_info_entity.h b/interfaces/kits/napi/file_access_module/file_info/file_info_entity.h new file mode 100644 index 0000000000000000000000000000000000000000..e668b1f6c32a8f10bf46481e33ff4199a398a1e5 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/file_info/file_info_entity.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILE_INFO_ENTITY_H +#define FILE_INFO_ENTITY_H + +#include "file_access_extension_info.h" +#include "file_access_helper.h" + +namespace OHOS { +namespace FileAccessFwk { +struct FileInfoEntity { + FileAccessHelper *fileAccessHelper { nullptr }; + FileInfo fileInfo {}; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // FILE_INFO_ENTITY_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/file_info/file_iterator_entity.h b/interfaces/kits/napi/file_access_module/file_info/file_iterator_entity.h new file mode 100644 index 0000000000000000000000000000000000000000..05c33bb2039da72d1b104044001feff89e88387c --- /dev/null +++ b/interfaces/kits/napi/file_access_module/file_info/file_iterator_entity.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILE_ITERATOR_ENTITY_H +#define FILE_ITERATOR_ENTITY_H + +#include + +#include "file_access_extension_info.h" +#include "file_access_helper.h" +#include "hilog_wrapper.h" + +namespace OHOS { +namespace FileAccessFwk { +struct FileIteratorEntity { + FileAccessHelper *fileAccessHelper { nullptr }; + std::mutex entityOperateMutex; + FileInfo fileInfo {}; + ShmParam shmParam {}; + int64_t pos { 0 }; + + ~FileIteratorEntity() + { + shmParam.ReleaseBuff(); + } +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // FILE_ITERATOR_ENTITY_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/file_info/napi_file_info_exporter.cpp b/interfaces/kits/napi/file_access_module/file_info/napi_file_info_exporter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..32fe248c560eb84cfc7f25289a8ca37c9dee9416 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/file_info/napi_file_info_exporter.cpp @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "napi_file_info_exporter.h" + +#include +#include + +#include "file_access_framework_errno.h" +#include "file_info_entity.h" +#include "file_iterator_entity.h" +#include "hilog_wrapper.h" +#include "napi_file_iterator_exporter.h" + +namespace OHOS { +namespace FileAccessFwk { +bool NapiFileInfoExporter::Export() +{ + std::vector props = { + NVal::DeclareNapiFunction("listFile", ListFile), + NVal::DeclareNapiGetter("uri", GetUri), + NVal::DeclareNapiGetter("fileName", GetFileName), + NVal::DeclareNapiGetter("mode", GetMode), + NVal::DeclareNapiGetter("size", GetSize), + NVal::DeclareNapiGetter("mtime", GetMtime), + NVal::DeclareNapiGetter("mimeType", GetMimeType), + }; + + std::string className = GetClassName(); + bool succ = false; + napi_value classValue = nullptr; + std::tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, + NapiFileInfoExporter::Constructor, std::move(props)); + if (!succ) { + HILOG_ERROR("Failed to define class NapiFileInfoExporter"); + NError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to define class NapiFileInfoExporter"); + return false; + } + + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + HILOG_ERROR("Failed to save class NapiFileInfoExporter"); + NError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to save class NapiFileInfoExporter"); + return false; + } + + return exports_.AddProp(className, classValue); +} + +napi_value NapiFileInfoExporter::Constructor(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto fileInfoEntity = std::make_unique(); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), std::move(fileInfoEntity))) { + NError(EIO).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj FileInfoEntity"); + return nullptr; + } + return funcArg.GetThisVar(); +} + +napi_value NapiFileInfoExporter::ListFile(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto fileInfoEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (fileInfoEntity == nullptr) { + NError(ERR_INVALID_PARAM).ThrowErr(env, "Cannot get entity of FileInfoEntity"); + return nullptr; + } + + bool isDir = false; + if (fileInfoEntity->fileInfo.mode == "folder") { + isDir = true; + } else if (fileInfoEntity->fileInfo.mode == "file") { + isDir = false; + } else { + mode_t mode; + std::stringstream(fileInfoEntity->fileInfo.mode) >> mode; + isDir = (S_ISDIR(mode) == 1); + } + + if (!isDir) { + HILOG_ERROR("current FileInfo is not dir"); + return nullptr; + } + + if (fileInfoEntity->fileAccessHelper == nullptr) { + NError(ERR_INVALID_PARAM).ThrowErr(env, "fileAccessHelper is null."); + return nullptr; + } + + ShmParam shmParam; + HILOG_ERROR("NapiFileInfoExporter::ListFile uri:%{public}s", fileInfoEntity->fileInfo.uri.c_str()); + if (!shmParam.InitBuff()) { + NError(ERR_SHM_FAIL).ThrowErr(env, "ShmParam InitBuff fail."); + return nullptr; + } + + auto ret = fileInfoEntity->fileAccessHelper->ListFile(fileInfoEntity->fileInfo, shmParam); + if (ret != ERR_OK) { + NError(ret).ThrowErr(env, "exec ListFile fail"); + return nullptr; + } + + auto objFileIteratorExporter = NClass::InstantiateClass(env, NapiFileIteratorExporter::className_, {}); + if (objFileIteratorExporter == nullptr) { + NError(ERR_INVALID_PARAM).ThrowErr(env, "Cannot instantiate class NapiFileIteratorExporter"); + return nullptr; + } + + auto fileIteratorEntity = NClass::GetEntityOf(env, objFileIteratorExporter); + if (fileIteratorEntity == nullptr) { + NError(ERR_INVALID_PARAM).ThrowErr(env, "Cannot get the entity of FileIteratorEntity"); + return nullptr; + } + + { + std::lock_guard lock(fileIteratorEntity->entityOperateMutex); + fileIteratorEntity->fileAccessHelper = fileInfoEntity->fileAccessHelper; + fileIteratorEntity->fileInfo = fileInfoEntity->fileInfo; + fileIteratorEntity->shmParam = std::move(shmParam); + fileIteratorEntity->pos = 0; + } + + return NVal(env, objFileIteratorExporter).val_; +} + +static FileInfoEntity *GetFileInfoEntity(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto fileInfoEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (fileInfoEntity == nullptr) { + NError(EIO).ThrowErr(env, "Cannot get entity of FileInfoEntity"); + return nullptr; + } + return fileInfoEntity; +} + +napi_value NapiFileInfoExporter::GetUri(napi_env env, napi_callback_info info) +{ + auto fileInfoEntity = GetFileInfoEntity(env, info); + if (fileInfoEntity == nullptr) { + HILOG_ERROR("Failed to get entity of FileInfoEntity"); + return NVal::CreateUndefined(env).val_; + } + return NVal::CreateUTF8String(env, fileInfoEntity->fileInfo.uri).val_; +} + +napi_value NapiFileInfoExporter::GetFileName(napi_env env, napi_callback_info info) +{ + auto fileInfoEntity = GetFileInfoEntity(env, info); + if (fileInfoEntity == nullptr) { + HILOG_ERROR("Failed to get entity of FileInfoEntity"); + return NVal::CreateUndefined(env).val_; + } + return NVal::CreateUTF8String(env, fileInfoEntity->fileInfo.fileName).val_; +} + +napi_value NapiFileInfoExporter::GetMode(napi_env env, napi_callback_info info) +{ + auto fileInfoEntity = GetFileInfoEntity(env, info); + if (fileInfoEntity == nullptr) { + HILOG_ERROR("Failed to get entity of FileInfoEntity"); + return NVal::CreateUndefined(env).val_; + } + return NVal::CreateUTF8String(env, fileInfoEntity->fileInfo.mode).val_; +} + +napi_value NapiFileInfoExporter::GetSize(napi_env env, napi_callback_info info) +{ + auto fileInfoEntity = GetFileInfoEntity(env, info); + if (fileInfoEntity == nullptr) { + HILOG_ERROR("Failed to get entity of FileInfoEntity"); + return NVal::CreateUndefined(env).val_; + } + return NVal::CreateInt64(env, fileInfoEntity->fileInfo.size).val_; +} + +napi_value NapiFileInfoExporter::GetMtime(napi_env env, napi_callback_info info) +{ + auto fileInfoEntity = GetFileInfoEntity(env, info); + if (fileInfoEntity == nullptr) { + HILOG_ERROR("Failed to get entity of FileInfoEntity"); + return NVal::CreateUndefined(env).val_; + } + return NVal::CreateInt64(env, fileInfoEntity->fileInfo.mtime).val_; +} + +napi_value NapiFileInfoExporter::GetMimeType(napi_env env, napi_callback_info info) +{ + auto fileInfoEntity = GetFileInfoEntity(env, info); + if (fileInfoEntity == nullptr) { + HILOG_ERROR("Failed to get entity of FileInfoEntity"); + return NVal::CreateUndefined(env).val_; + } + return NVal::CreateUTF8String(env, fileInfoEntity->fileInfo.mimeType).val_; +} + +std::string NapiFileInfoExporter::GetClassName() +{ + return NapiFileInfoExporter::className_; +} +} // namespace FileAccessFwk +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/file_info/napi_file_info_exporter.h b/interfaces/kits/napi/file_access_module/file_info/napi_file_info_exporter.h new file mode 100644 index 0000000000000000000000000000000000000000..57264e33d493a45673c46849e4f7f53233e7dfe3 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/file_info/napi_file_info_exporter.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NAPI_FILE_INFO_EXPORTER_H +#define NAPI_FILE_INFO_EXPORTER_H + +#include + +#include "file_access_extension_info.h" +#include "file_access_helper.h" +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileAccessFwk { +using namespace FileManagement::LibN; + +class NapiFileInfoExporter final : public NExporter { +public: + inline static const std::string className_ = "NapiFileInfoExporter"; + + NapiFileInfoExporter(napi_env env, napi_value exports) : NExporter(env, exports) {}; + ~NapiFileInfoExporter() = default; + + static napi_value Constructor(napi_env env, napi_callback_info info); + static napi_value ListFile(napi_env env, napi_callback_info info); + static napi_value GetUri(napi_env env, napi_callback_info info); + static napi_value GetFileName(napi_env env, napi_callback_info info); + static napi_value GetMode(napi_env env, napi_callback_info info); + static napi_value GetSize(napi_env env, napi_callback_info info); + static napi_value GetMtime(napi_env env, napi_callback_info info); + static napi_value GetMimeType(napi_env env, napi_callback_info info); + + bool Export() override; + std::string GetClassName() override; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // NAPI_FILE_INFO_EXPORTER_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/file_info/napi_file_iterator_exporter.cpp b/interfaces/kits/napi/file_access_module/file_info/napi_file_iterator_exporter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..07af1cac3f3c8d6cfc2fa6337cd08a040592f85b --- /dev/null +++ b/interfaces/kits/napi/file_access_module/file_info/napi_file_iterator_exporter.cpp @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "napi_file_iterator_exporter.h" + +#include +#include + +#include "file_info_entity.h" +#include "file_iterator_entity.h" +#include "hilog_wrapper.h" +#include "napi_file_info_exporter.h" + +namespace OHOS { +namespace FileAccessFwk { +bool NapiFileIteratorExporter::Export() +{ + std::vector props = { + NVal::DeclareNapiFunction("next", Next), + }; + + std::string className = GetClassName(); + bool succ = false; + napi_value classValue = nullptr; + std::tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, + NapiFileIteratorExporter::Constructor, std::move(props)); + if (!succ) { + NError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to define class NapiFileIteratorExporter"); + return false; + } + + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + NError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to save class NapiFileIteratorExporter"); + return false; + } + + return exports_.AddProp(className, classValue); +} + +napi_value NapiFileIteratorExporter::Constructor(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto fileIteratorEntity = std::make_unique(); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), std::move(fileIteratorEntity))) { + NError(EIO).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj FileIteratorEntity"); + return nullptr; + } + return funcArg.GetThisVar(); +} + +napi_value NapiFileIteratorExporter::Next(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto fileIteratorEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (fileIteratorEntity == nullptr) { + NError(EINVAL).ThrowErr(env, "Cannot get entity of FileIteratorEntity"); + return nullptr; + } + + bool isDir = false; + if (fileIteratorEntity->fileInfo.mode == "folder") { + isDir = true; + } else if (fileIteratorEntity->fileInfo.mode == "file") { + isDir = false; + } else { + mode_t mode; + std::stringstream(fileIteratorEntity->fileInfo.mode) >> mode; + isDir = (S_ISDIR(mode) == 1); + } + + if (!isDir) { + HILOG_ERROR("current FileInfo is not dir."); + return nullptr; + } + + auto objFileInfoExporter = NClass::InstantiateClass(env, NapiFileInfoExporter::className_, {}); + if (objFileInfoExporter == nullptr) { + NError(EINVAL).ThrowErr(env, "Cannot instantiate class NapiFileInfoExporter"); + return nullptr; + } + + auto fileInfoEntity = NClass::GetEntityOf(env, objFileInfoExporter); + if (fileInfoEntity == nullptr) { + NError(EINVAL).ThrowErr(env, "Cannot get the entity of FileInfoEntity"); + return nullptr; + } + + if (fileIteratorEntity->fileAccessHelper == nullptr) { + NError(ERR_INVALID_PARAM).ThrowErr(env, "fileAccessHelper is null."); + return nullptr; + } + + bool done = true; + { + std::lock_guard lock(fileIteratorEntity->entityOperateMutex); + if (fileIteratorEntity->shmParam.numCount == 0) { + auto retNVal = NVal::CreateObject(env); + retNVal.AddProp("value", nullptr); + retNVal.AddProp("done", NVal::CreateBool(env, done).val_); + return retNVal.val_; + } + + if (fileIteratorEntity->pos >= fileIteratorEntity->shmParam.numCount) { + NError(ERR_INVALID_PARAM).ThrowErr(env, "out of index."); + return nullptr; + } + + fileInfoEntity->fileAccessHelper = fileIteratorEntity->fileAccessHelper; + auto ret = fileIteratorEntity->shmParam.ReadBuff(fileIteratorEntity->pos, fileInfoEntity->fileInfo); + if (!ret) { + NError(ERR_INVALID_PARAM).ThrowErr(env, "read FileInfo from ShmParam error."); + return nullptr; + } + + fileIteratorEntity->pos++; + if (fileIteratorEntity->pos == fileIteratorEntity->shmParam.numCount) { + int ret = fileIteratorEntity->fileAccessHelper->ListFile(fileIteratorEntity->fileInfo, + fileIteratorEntity->shmParam); + if (ret != ERR_OK) { + NError(ret).ThrowErr(env, "exec ListFile fail."); + return nullptr; + } + + fileIteratorEntity->pos = 0; + } + done = (fileIteratorEntity->pos == fileIteratorEntity->shmParam.numCount); + } + + auto retNVal = NVal::CreateObject(env); + retNVal.AddProp("value", objFileInfoExporter); + retNVal.AddProp("done", NVal::CreateBool(env, done).val_); + return retNVal.val_; +} + +std::string NapiFileIteratorExporter::GetClassName() +{ + return NapiFileIteratorExporter::className_; +} +} // namespace FileAccessFwk +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/file_info/napi_file_iterator_exporter.h b/interfaces/kits/napi/file_access_module/file_info/napi_file_iterator_exporter.h new file mode 100644 index 0000000000000000000000000000000000000000..e1b51314bcce9ca4b510166e1bcab8624e08a740 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/file_info/napi_file_iterator_exporter.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NAPI_FILE_ITERATOR_EXPORTER_H +#define NAPI_FILE_ITERATOR_EXPORTER_H + +#include + +#include "file_access_extension_info.h" +#include "file_access_helper.h" +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileAccessFwk { +using namespace FileManagement::LibN; + +class NapiFileIteratorExporter final : public NExporter { +public: + inline static const std::string className_ = "NapiFileIteratorExporter"; + + NapiFileIteratorExporter(napi_env env, napi_value exports) : NExporter(env, exports) {}; + ~NapiFileIteratorExporter() = default; + + static napi_value Constructor(napi_env env, napi_callback_info info); + static napi_value Next(napi_env env, napi_callback_info info); + + bool Export() override; + std::string GetClassName() override; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // NAPI_FILE_ITERATOR_EXPORTER_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.cpp b/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.cpp index dd5ae325397fd4987770022560ead0ebac9f07b9..9e5027a02a25df4c6e75245037f8539e2469d665 100644 --- a/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.cpp +++ b/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.cpp @@ -27,7 +27,9 @@ #include "napi_common_fileaccess.h" #include "napi_error.h" #include "napi_notify_callback.h" +#include "napi_root_iterator_exporter.h" #include "n_val.h" +#include "root_iterator_entity.h" #include "securec.h" #include "uri.h" @@ -174,8 +176,8 @@ napi_value NAPI_GetRegisterFileAccessExtAbilityInfo(napi_env env, napi_callback_ auto result = std::make_shared>(); auto cbExec = [result]() -> NError { - *result = FileAccessHelper::GetRegisterFileAccessExtAbilityInfo(); - return NError(ERRNO_NOERR); + int ret = FileAccessHelper::GetRegisterFileAccessExtAbilityInfo(*result); + return NError(ret); }; auto cbComplete = [result](napi_env env, NError err) -> NVal { if (err) { @@ -206,7 +208,7 @@ napi_value FileAccessHelperInit(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("delete", NAPI_Delete), DECLARE_NAPI_FUNCTION("move", NAPI_Move), DECLARE_NAPI_FUNCTION("rename", NAPI_Rename), - DECLARE_NAPI_FUNCTION("listFile", NAPI_ListFile), + // DECLARE_NAPI_FUNCTION("listFile", NAPI_ListFile), DECLARE_NAPI_FUNCTION("getRoots", NAPI_GetRoots), DECLARE_NAPI_FUNCTION("isFileExist", NAPI_IsFileExist), DECLARE_NAPI_FUNCTION("on", NAPI_On), @@ -587,56 +589,6 @@ napi_value NAPI_Rename(napi_env env, napi_callback_info info) return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_; } -napi_value NAPI_ListFile(napi_env env, napi_callback_info info) -{ - NFuncArg funcArg(env, info); - if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { - NapiError(ERR_PARAM_NUMBER).ThrowErr(env); - return nullptr; - } - - bool succ = false; - std::unique_ptr uri; - std::tie(succ, uri, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); - if (!succ) { - NapiError(ERR_INVALID_PARAM).ThrowErr(env); - return nullptr; - } - - FileAccessHelper *fileAccessHelper = GetFileAccessHelper(env, funcArg.GetThisVar()); - if (fileAccessHelper == nullptr) { - return nullptr; - } - - auto result = std::make_shared>(); - string uriString(uri.get()); - auto cbExec = [uriString, result, fileAccessHelper]() -> NError { - OHOS::Uri uri(uriString); - *result = fileAccessHelper->ListFile(uri); - return NError(ERRNO_NOERR); - }; - auto cbComplete = [result](napi_env env, NError err) -> NVal { - if (err) { - return { env, err.GetNapiErr(env) }; - } - napi_value jsArray = WrapArrayFileInfoToJS(env, *result); - return {env, jsArray}; - }; - - const std::string procedureName = "listFile"; - NVal thisVar(env, funcArg.GetThisVar()); - if (funcArg.GetArgc() == NARG_CNT::ONE) { - return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_; - } - - NVal cb(env, funcArg[NARG_POS::SECOND]); - if (!cb.TypeIs(napi_function)) { - NapiError(ERR_INVALID_PARAM).ThrowErr(env); - return nullptr; - } - return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_; -} - napi_value NAPI_GetRoots(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); @@ -652,30 +604,47 @@ napi_value NAPI_GetRoots(napi_env env, napi_callback_info info) auto result = std::make_shared>(); auto cbExec = [result, fileAccessHelper]() -> NError { - *result = fileAccessHelper->GetRoots(); - return NError(ERRNO_NOERR); + int ret = fileAccessHelper->GetRoots(*result); + return NError(ret); }; - auto cbComplete = [result](napi_env env, NError err) -> NVal { - if (err) { - return { env, err.GetNapiErr(env) }; + auto cbComplete = [fileAccessHelper, result](napi_env env, NError err) -> NVal { + auto objRootIterator = NClass::InstantiateClass(env, NapiRootIteratorExporter::className_, {}); + if (!objRootIterator) { + auto errGen = []() -> std::tuple { + return { ERR_INVALID_PARAM, "Cannot instantiate class NapiRootIteratorExporter" }; + }; + return { env, NError(errGen).GetNapiErr(env) }; } - napi_value jsArray = WrapArrayDeviceInfoToJS(env, *result); - return {env, jsArray}; + + auto rootIteratorEntity = NClass::GetEntityOf(env, objRootIterator); + if (!rootIteratorEntity) { + auto errGen = []() -> std::tuple { + return { ERR_INVALID_PARAM, "Cannot get the entity of RootIteratorEntity" }; + }; + return { env, NError(errGen).GetNapiErr(env) }; + } + + { + std::lock_guard lock(rootIteratorEntity->entityOperateMutex); + rootIteratorEntity->fileAccessHelper = fileAccessHelper; + rootIteratorEntity->devVec = std::move(*result); + rootIteratorEntity->pos = 0; + } + return { env, objRootIterator }; }; const std::string procedureName = "getRoots"; NVal thisVar(env, funcArg.GetThisVar()); - if (funcArg.GetArgc() == NARG_CNT::ZERO) { return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_; } NVal cb(env, funcArg[NARG_POS::FIRST]); - if (!cb.TypeIs(napi_function)) { - NapiError(ERR_INVALID_PARAM).ThrowErr(env); - return nullptr; + if (cb.TypeIs(napi_function)) { + return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_; } - return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_; + NapiError(ERR_INVALID_PARAM).ThrowErr(env); + return nullptr; } napi_value NAPI_IsFileExist(napi_env env, napi_callback_info info) diff --git a/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.h b/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.h index b0ec4e817304f096f8bc30f4a32babee59ccc152..a1d7416e4f1875d3dd59da845fe079cc5e248290 100644 --- a/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.h +++ b/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.h @@ -30,11 +30,10 @@ namespace FileAccessFwk { napi_value NAPI_Delete(napi_env env, napi_callback_info info); napi_value NAPI_Move(napi_env env, napi_callback_info info); napi_value NAPI_Rename(napi_env env, napi_callback_info info); - napi_value NAPI_ListFile(napi_env env, napi_callback_info info); napi_value NAPI_GetRoots(napi_env env, napi_callback_info info); napi_value NAPI_IsFileExist(napi_env env, napi_callback_info info); napi_value NAPI_On(napi_env env, napi_callback_info info); napi_value NAPI_Off(napi_env env, napi_callback_info info); -} } // namespace FileAccessFwk +} // namespace OHOS #endif // NAPI_FILEACCESS_HELPER_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/napi_notify_callback.h b/interfaces/kits/napi/file_access_module/napi_notify_callback.h index 5dec5b4f3dbac336ae9b782c84c11bb26c1a3337..2f89b00623c39153eb63eed7bf4740f9329543f8 100644 --- a/interfaces/kits/napi/file_access_module/napi_notify_callback.h +++ b/interfaces/kits/napi/file_access_module/napi_notify_callback.h @@ -44,6 +44,6 @@ private: napi_env env_; uv_loop_s *loop_ = nullptr; }; -} // FileAccessFwk -} // OHOS +} // namespace FileAccessFwk +} // namespace OHOS #endif // NAPI_NOTIFY_CALLBACK_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/native_fileaccess_module.cpp b/interfaces/kits/napi/file_access_module/native_fileaccess_module.cpp index 19127d0ae1f51a51764174a3c2c8e7903fb6ee40..e4c941468def5b44123c6b06c861a6b066930814 100644 --- a/interfaces/kits/napi/file_access_module/native_fileaccess_module.cpp +++ b/interfaces/kits/napi/file_access_module/native_fileaccess_module.cpp @@ -13,14 +13,22 @@ * limitations under the License. */ +#include +#include + +#include "filemgmt_libn.h" #include "file_extension_info_napi.h" #include "hilog_wrapper.h" #include "napi_fileaccess_helper.h" -#include "napi/native_api.h" -#include "napi/native_node_api.h" +#include "napi_file_info_exporter.h" +#include "napi_file_iterator_exporter.h" +#include "napi_root_info_exporter.h" +#include "napi_root_iterator_exporter.h" namespace OHOS { namespace FileAccessFwk { +using namespace FileManagement::LibN; + EXTERN_C_START /* * The module initialization. @@ -33,6 +41,21 @@ static napi_value Init(napi_env env, napi_value exports) InitDeviceType(env, exports); InitFileInfo(env, exports); InitDeviceInfo(env, exports); + + std::vector> products; + products.emplace_back(std::make_unique(env, exports)); + products.emplace_back(std::make_unique(env, exports)); + products.emplace_back(std::make_unique(env, exports)); + products.emplace_back(std::make_unique(env, exports)); + for (auto &&product : products) { + if (!product->Export()) { + HILOG_ERROR("INNER BUG. Failed to export class %{public}s", product->GetClassName().c_str()); + return nullptr; + } else { + HILOG_ERROR("Class %{public}s has been exported", product->GetClassName().c_str()); + } + } + return exports; } EXTERN_C_END diff --git a/interfaces/kits/napi/file_access_module/root_info/napi_root_info_exporter.cpp b/interfaces/kits/napi/file_access_module/root_info/napi_root_info_exporter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0bd8ed1d6f5862b24ea75be0e6cbff3c1a1f24f4 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/root_info/napi_root_info_exporter.cpp @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NAPI_FILEACCESS_HELPER_H +#define NAPI_FILEACCESS_HELPER_H + +#include "napi_root_info_exporter.h" + +#include + +#include "file_access_framework_errno.h" +#include "file_iterator_entity.h" +#include "hilog_wrapper.h" +#include "napi_file_iterator_exporter.h" +#include "root_info_entity.h" + +namespace OHOS { +namespace FileAccessFwk { +bool NapiRootInfoExporter::Export() +{ + std::vector props = { + NVal::DeclareNapiFunction("listFile", ListFile), + NVal::DeclareNapiGetter("uri", GetUri), + NVal::DeclareNapiGetter("displayName", GetDisplayName), + NVal::DeclareNapiGetter("deviceId", GetDeviceId), + NVal::DeclareNapiGetter("flags", GetFlags), + NVal::DeclareNapiGetter("type", GetType) + }; + + std::string className = GetClassName(); + bool succ = false; + napi_value classValue = nullptr; + std::tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, + NapiRootInfoExporter::Constructor, std::move(props)); + if (!succ) { + HILOG_ERROR("Failed to define class NapiRootInfoExporter"); + NError(ERR_INVALID_PARAM).ThrowErr(exports_.env_, "INNER BUG. Failed to define class NapiRootInfoExporter"); + return false; + } + + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + HILOG_ERROR("Failed to save class NapiRootInfoExporter"); + NError(ERR_INVALID_PARAM).ThrowErr(exports_.env_, "INNER BUG. Failed to save class NapiRootInfoExporter"); + return false; + } + + return exports_.AddProp(className, classValue); +} + +napi_value NapiRootInfoExporter::Constructor(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto rootInfoEntity = std::make_unique(); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), std::move(rootInfoEntity))) { + NError(ERR_INVALID_PARAM).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj RootInfoEntity"); + return nullptr; + } + return funcArg.GetThisVar(); +} + +napi_value NapiRootInfoExporter::ListFile(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto rootEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (rootEntity == nullptr) { + NError(ERR_INVALID_PARAM).ThrowErr(env, "Cannot get entity of FileInfoEntity"); + return nullptr; + } + + if (rootEntity->fileAccessHelper == nullptr) { + NError(ERR_INVALID_PARAM).ThrowErr(env, "fileAccessHelper is null."); + return nullptr; + } + + FileInfo fileInfo; + fileInfo.uri = rootEntity->deviceInfo.uri.ToString(); + fileInfo.mode = "16877"; + ShmParam shmParam; + if (!shmParam.InitBuff()) { + NError(ERR_SHM_FAIL).ThrowErr(env, "shmParam InitBuff fail."); + return nullptr; + } + + auto ret = rootEntity->fileAccessHelper->ListFile(fileInfo, shmParam); + if (ret != ERR_OK) { + NError(ret).ThrowErr(env, "exec ListFile fail."); + return nullptr; + } + + napi_value objFileIteratorExporter = NClass::InstantiateClass(env, NapiFileIteratorExporter::className_, {}); + if (objFileIteratorExporter == nullptr) { + NError(ERR_INVALID_PARAM).ThrowErr(env, "Cannot instantiate class NapiFileIteratorExporter"); + return nullptr; + } + + auto fileIteratorEntity = NClass::GetEntityOf(env, objFileIteratorExporter); + if (fileIteratorEntity == nullptr) { + NError(ERR_INVALID_PARAM).ThrowErr(env, "Cannot get the entity of FileIteratorEntity"); + return nullptr; + } + + HILOG_INFO("-------> FileInfo count:%{public}" PRId64, shmParam.numCount); + { + std::lock_guard lock(fileIteratorEntity->entityOperateMutex); + fileIteratorEntity->fileAccessHelper = rootEntity->fileAccessHelper; + fileIteratorEntity->fileInfo = std::move(fileInfo); + fileIteratorEntity->shmParam = std::move(shmParam); + fileIteratorEntity->pos = 0; + } + + return NVal(env, objFileIteratorExporter).val_; +} + +napi_value NapiRootInfoExporter::GetUri(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto rootInfoEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (rootInfoEntity == nullptr) { + NError(ERR_INVALID_PARAM).ThrowErr(env, "Cannot get entity of RootInfoEntity"); + return nullptr; + } + + return NVal::CreateUTF8String(env, rootInfoEntity->deviceInfo.uri.ToString()).val_; +} + +napi_value NapiRootInfoExporter::GetDisplayName(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto rootInfoEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (rootInfoEntity == nullptr) { + NError(ERR_INVALID_PARAM).ThrowErr(env, "Cannot get entity of RootInfoEntity"); + return nullptr; + } + + return NVal::CreateUTF8String(env, rootInfoEntity->deviceInfo.displayName).val_; +} + +napi_value NapiRootInfoExporter::GetDeviceId(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto rootInfoEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (rootInfoEntity == nullptr) { + NError(ERR_INVALID_PARAM).ThrowErr(env, "Cannot get entity of RootInfoEntity"); + return nullptr; + } + + return NVal::CreateUTF8String(env, rootInfoEntity->deviceInfo.deviceId).val_; +} + +napi_value NapiRootInfoExporter::GetFlags(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto rootInfoEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (rootInfoEntity == nullptr) { + NError(ERR_INVALID_PARAM).ThrowErr(env, "Cannot get entity of RootInfoEntity"); + return nullptr; + } + + return NVal::CreateInt64(env, rootInfoEntity->deviceInfo.flags).val_; +} + +napi_value NapiRootInfoExporter::GetType(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto rootInfoEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (rootInfoEntity == nullptr) { + NError(ERR_INVALID_PARAM).ThrowErr(env, "Cannot get entity of RootInfoEntity"); + return nullptr; + } + + return NVal::CreateInt64(env, (int64_t)(rootInfoEntity->deviceInfo.type)).val_; +} + +std::string NapiRootInfoExporter::GetClassName() +{ + return NapiRootInfoExporter::className_; +} +} // namespace FileAccessFwk +} // namespace OHOS +#endif // NAPI_FILEACCESS_HELPER_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/root_info/napi_root_info_exporter.h b/interfaces/kits/napi/file_access_module/root_info/napi_root_info_exporter.h new file mode 100644 index 0000000000000000000000000000000000000000..c6d9cc87e0762a0d47961f97207080e09c04d250 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/root_info/napi_root_info_exporter.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NAPI_ROOT_INFO_EXPORTER_H +#define NAPI_ROOT_INFO_EXPORTER_H + +#include + +#include "file_access_extension_info.h" +#include "file_access_helper.h" +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileAccessFwk { +using namespace FileManagement::LibN; + +class NapiRootInfoExporter final : public NExporter { +public: + inline static const std::string className_ = "NapiRootInfoExporter"; + + NapiRootInfoExporter(napi_env env, napi_value exports) : NExporter(env, exports) {}; + ~NapiRootInfoExporter() = default; + + static napi_value Constructor(napi_env env, napi_callback_info info); + static napi_value ListFile(napi_env env, napi_callback_info info); + static napi_value GetUri(napi_env env, napi_callback_info info); + static napi_value GetDisplayName(napi_env env, napi_callback_info info); + static napi_value GetDeviceId(napi_env env, napi_callback_info info); + static napi_value GetFlags(napi_env env, napi_callback_info info); + static napi_value GetType(napi_env env, napi_callback_info info); + + bool Export() override; + std::string GetClassName() override; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // NAPI_ROOT_INFO_EXPORTER_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/root_info/napi_root_iterator_exporter.cpp b/interfaces/kits/napi/file_access_module/root_info/napi_root_iterator_exporter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6faa04e3a60fa2d817dee6de5dc97bfcf71691de --- /dev/null +++ b/interfaces/kits/napi/file_access_module/root_info/napi_root_iterator_exporter.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "napi_root_iterator_exporter.h" + +#include "hilog_wrapper.h" +#include "napi_root_info_exporter.h" +#include "root_info_entity.h" +#include "root_iterator_entity.h" + +namespace OHOS { +namespace FileAccessFwk { +bool NapiRootIteratorExporter::Export() +{ + std::vector props = { + NVal::DeclareNapiFunction("next", Next), + }; + + std::string className = GetClassName(); + bool succ = false; + napi_value classValue = nullptr; + std::tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, + NapiRootIteratorExporter::Constructor, std::move(props)); + if (!succ) { + NError(EIO).ThrowErr(exports_.env_, + "INNER BUG. Failed to define class NapNapiRootIteratorExporteriRootIterator"); + return false; + } + + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + NError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to save class NapiRootIteratorExporter"); + return false; + } + + return exports_.AddProp(className, classValue); +} + +napi_value NapiRootIteratorExporter::Constructor(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto rootIteratorEntity = std::make_unique(); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), std::move(rootIteratorEntity))) { + NError(EIO).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj FileIteratorEntity"); + return nullptr; + } + return funcArg.GetThisVar(); +} + +napi_value NapiRootIteratorExporter::Next(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + napi_value thisVar = funcArg.GetThisVar(); + auto iterEntity = NClass::GetEntityOf(env, thisVar); + if (iterEntity == nullptr) { + NError(EIO).ThrowErr(env, "Cannot get entity of RootIteratorEntity"); + return nullptr; + } + + napi_value objRootExporter = NClass::InstantiateClass(env, NapiRootInfoExporter::className_, {}); + if (objRootExporter == nullptr) { + NError(EINVAL).ThrowErr(env, "Cannot instantiate class NapiRootInfoExporter"); + return nullptr; + } + + auto rootEntity = NClass::GetEntityOf(env, objRootExporter); + if (rootEntity == nullptr) { + NError(EINVAL).ThrowErr(env, "Cannot get the entity of RootInfoEntity"); + return nullptr; + } + + bool done = true; + { + std::lock_guard lock(iterEntity->entityOperateMutex); + auto len = (int32_t)iterEntity->devVec.size(); + rootEntity->fileAccessHelper = iterEntity->fileAccessHelper; + if (iterEntity->pos < len) { + rootEntity->deviceInfo = iterEntity->devVec[iterEntity->pos]; + iterEntity->pos++; + done = (iterEntity->pos == len); + } else { + rootEntity = nullptr; + objRootExporter = nullptr; + } + } + + auto retNVal = NVal::CreateObject(env); + retNVal.AddProp("value", objRootExporter); + retNVal.AddProp("done", NVal::CreateBool(env, done).val_); + return retNVal.val_; +} + +std::string NapiRootIteratorExporter::GetClassName() +{ + return NapiRootIteratorExporter::className_; +} +} // namespace FileAccessFwk +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/root_info/napi_root_iterator_exporter.h b/interfaces/kits/napi/file_access_module/root_info/napi_root_iterator_exporter.h new file mode 100644 index 0000000000000000000000000000000000000000..9902d7d103ee56d1c564139d935f52cf4d73b524 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/root_info/napi_root_iterator_exporter.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NAPI_ROOT_ITERATOR_H +#define NAPI_ROOT_ITERATOR_H + +#include + +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileAccessFwk { +using namespace FileManagement::LibN; +class NapiRootIteratorExporter final : public NExporter { +public: + inline static const std::string className_ = "NapiRootIteratorExporter"; + + NapiRootIteratorExporter(napi_env env, napi_value exports) : NExporter(env, exports) {}; + ~NapiRootIteratorExporter() = default; + + static napi_value Constructor(napi_env env, napi_callback_info info); + static napi_value Next(napi_env env, napi_callback_info info); + + bool Export() override; + std::string GetClassName() override; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // NAPI_ROOT_ITERATOR_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/root_info/root_info_entity.h b/interfaces/kits/napi/file_access_module/root_info/root_info_entity.h new file mode 100644 index 0000000000000000000000000000000000000000..30828220f47f1a7350c42f85a19eb224dd668394 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/root_info/root_info_entity.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ROOT_INFO_ENTITY_H +#define ROOT_INFO_ENTITY_H + +#include "file_access_extension_info.h" +#include "file_access_helper.h" + +namespace OHOS { +namespace FileAccessFwk { +struct RootInfoEntity { + FileAccessHelper *fileAccessHelper { nullptr }; + DeviceInfo deviceInfo {}; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // ROOT_INFO_ENTITY_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/root_info/root_iterator_entity.h b/interfaces/kits/napi/file_access_module/root_info/root_iterator_entity.h new file mode 100644 index 0000000000000000000000000000000000000000..9452fb2d7090e4d894a4f151c7311a5eee226cfe --- /dev/null +++ b/interfaces/kits/napi/file_access_module/root_info/root_iterator_entity.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ROOT_ITERATOR_ENTITY_H +#define ROOT_ITERATOR_ENTITY_H + +#include +#include + +#include "file_access_extension_info.h" +#include "file_access_helper.h" + +namespace OHOS { +namespace FileAccessFwk { +struct RootIteratorEntity { + FileAccessHelper *fileAccessHelper { nullptr }; + std::vector devVec {}; + std::mutex entityOperateMutex; + int64_t pos { 0 }; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // ROOT_ITERATOR_ENTITY_H \ No newline at end of file diff --git a/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/FileExtensionAbility.ts b/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/FileExtensionAbility.ts index 96e5f95184ebd321bc667fcc0cbf2be7a90dadaa..c4feefcec43ba41de7d74b8aab815e2a770eba8d 100644 --- a/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/FileExtensionAbility.ts +++ b/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/FileExtensionAbility.ts @@ -445,7 +445,7 @@ export default class FileExtAbility extends Extension { }; } - listFile(sourceFileUri) { + listFile(sourceFileUri, offset, count) { if (!this.checkUri(sourceFileUri)) { return { infos: [], @@ -457,10 +457,15 @@ export default class FileExtAbility extends Extension { let path = this.getPath(sourceFileUri); let dir = fileio.opendirSync(path); let hasNextFile = true; + let i = 0; while (hasNextFile) { try { let dirent = dir.readSync(); let stat = fileio.statSync(path + '/' + dirent.name); + if (offset > i) { + i ++; + continue; + } infos.push({ uri: this.genNewFileUri(sourceFileUri, dirent.name), fileName: dirent.name, @@ -469,6 +474,11 @@ export default class FileExtAbility extends Extension { mtime: stat.mtime, mimeType: '', }); + i ++; + if (i == (offset + count)) { + hasNextFile = false; + break; + } } catch (e) { hasNextFile = false; } diff --git a/utils/file_access_framework_errno.h b/utils/file_access_framework_errno.h index d45271e89f266eb0976348e78e5cc56e415708c2..ee4e40630282951cdbe7051b88c0b3949648fa51 100644 --- a/utils/file_access_framework_errno.h +++ b/utils/file_access_framework_errno.h @@ -39,7 +39,8 @@ enum { ERR_INVALID_NOTIFY, // invalid notify ERR_REMOVE_NOTIFY_FAIL, // remove notify fail ERR_NOTIFY_NOT_EXIST, // the notify is not exist - ERR_NOTIFY_FAIL // notify client fail + ERR_NOTIFY_FAIL, // notify client fail + ERR_SHM_FAIL // shm fail }; } // namespace FileAccessFwk } // namespace OHOS