From 26b99ca431a1d6841002469f2bacb7edea04906d Mon Sep 17 00:00:00 2001 From: yangbo Date: Thu, 30 Mar 2023 09:43:47 +0000 Subject: [PATCH 1/2] use getContext(this) get context Signed-off-by: yangbo --- interfaces/kits/picker/picker.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/interfaces/kits/picker/picker.js b/interfaces/kits/picker/picker.js index 085eeeac..57b56d36 100644 --- a/interfaces/kits/picker/picker.js +++ b/interfaces/kits/picker/picker.js @@ -97,7 +97,8 @@ async function photoPickerSelect() { console.log("[picker] config: " + JSON.stringify(config)); try { - let result = await globalThis.abilityContext.startAbilityForResult(config, {windowMode: 1}); + let context = getContext(this); + let result = await context.startAbilityForResult(config, {windowMode: 1}); console.log("[picker] result: " + JSON.stringify(result)); let uris = result.want.parameters["select-item-list"]; let isOrigin = result.want.parameters["isOriginal"]; @@ -140,7 +141,8 @@ async function documentPickerSelect() { console.log("[picker] config: " + JSON.stringify(config)); try { - let result = await globalThis.abilityContext.startAbilityForResult(config, {windowMode: 1}); + let context = getContext(this); + let result = await context.startAbilityForResult(config, {windowMode: 1}); console.log("[picker] result: " + JSON.stringify(result)); let uris = result.want.parameters.select_item_list; if (result.resultCode == -1) { @@ -189,7 +191,8 @@ async function documentPickerSave() { console.log("[picker] config: " + JSON.stringify(config)); try { - let result = await globalThis.abilityContext.startAbilityForResult(config, {windowMode: 1}); + let context = getContext(this); + let result = await context.startAbilityForResult(config, {windowMode: 1}); console.log("[picker] result: " + JSON.stringify(result)); let uris = result.want["parameters"].pick_path_return; if (result.resultCode == -1) { @@ -231,7 +234,8 @@ async function audioPickerSelect() { console.log("[picker] config: " + JSON.stringify(config)); try { - let result = await globalThis.abilityContext.startAbilityForResult(config, {windowMode: 1}); + let context = getContext(this); + let result = await context.startAbilityForResult(config, {windowMode: 1}); console.log("[picker] result: " + JSON.stringify(result)); let uris = result.want.parameters.select_item_list; if (result.resultCode == -1) { -- Gitee From fb24fed95556e87fbee53d72f9bfb4b8a623b3f1 Mon Sep 17 00:00:00 2001 From: caochuan Date: Tue, 14 Feb 2023 11:00:22 +0800 Subject: [PATCH 2/2] feat: add query interface for FAF Signed-off-by: caochuan --- .../napi/common/file_extension_info_napi.cpp | 19 ++++ .../js/napi/common/file_extension_info_napi.h | 1 + .../napi_fileaccess_helper.cpp | 54 +++++++++ .../napi_fileaccess_helper.h | 1 + .../native_fileaccess_module.cpp | 1 + .../include/file_access_ext_ability.h | 1 + .../include/file_access_ext_proxy.h | 1 + .../include/file_access_ext_stub.h | 1 + .../include/file_access_ext_stub_impl.h | 1 + .../include/file_access_extension_info.h | 29 +++++ .../file_access/include/file_access_helper.h | 1 + .../include/ifile_access_ext_base.h | 2 + .../include/js_file_access_ext_ability.h | 1 + .../src/file_access_ext_ability.cpp | 6 + .../file_access/src/file_access_ext_proxy.cpp | 75 +++++++++++++ .../file_access/src/file_access_ext_stub.cpp | 48 ++++++++ .../src/file_access_ext_stub_impl.cpp | 14 +++ .../file_access/src/file_access_helper.cpp | 106 ++++++++++++++++++ .../src/js_file_access_ext_ability.cpp | 99 ++++++++++++++++ .../FileExtensionAbility.ts | 76 +++++++++++++ 20 files changed, 537 insertions(+) diff --git a/frameworks/js/napi/common/file_extension_info_napi.cpp b/frameworks/js/napi/common/file_extension_info_napi.cpp index f97a6c34..489e6540 100644 --- a/frameworks/js/napi/common/file_extension_info_napi.cpp +++ b/frameworks/js/napi/common/file_extension_info_napi.cpp @@ -184,5 +184,24 @@ void InitOpenFlags(napi_env env, napi_value exports) napi_define_properties(env, obj, sizeof(desc) / sizeof(desc[0]), desc); napi_set_named_property(env, exports, propertyName, obj); } + +void InitQueryFlags(napi_env env, napi_value exports) +{ + char propertyName[] = "FileKey"; + napi_property_descriptor desc[] = { + DECLARE_NAPI_STATIC_PROPERTY("DISPLAY_NAME", NVal::CreateUTF8String(env, DISPLAY_NAME).val_), + DECLARE_NAPI_STATIC_PROPERTY("DATE_ADDED", NVal::CreateUTF8String(env, DATE_ADDED).val_), + DECLARE_NAPI_STATIC_PROPERTY("DATE_MODIFIED", NVal::CreateUTF8String(env, DATE_MODIFIED).val_), + DECLARE_NAPI_STATIC_PROPERTY("RELATIVE_PATH", NVal::CreateUTF8String(env, RELATIVE_PATH).val_), + DECLARE_NAPI_STATIC_PROPERTY("FILE_SIZE", NVal::CreateUTF8String(env, FILE_SIZE).val_), + DECLARE_NAPI_STATIC_PROPERTY("WIDTH", NVal::CreateUTF8String(env, WIDTH).val_), + DECLARE_NAPI_STATIC_PROPERTY("HEIGHT", NVal::CreateUTF8String(env, HEIGHT).val_), + DECLARE_NAPI_STATIC_PROPERTY("DURATION", NVal::CreateUTF8String(env, DURATION).val_), + }; + napi_value obj = nullptr; + napi_create_object(env, &obj); + napi_define_properties(env, obj, sizeof(desc) / sizeof(desc[0]), desc); + napi_set_named_property(env, exports, propertyName, obj); +} } // namespace FileAccessFwk } // namespace OHOS \ No newline at end of file diff --git a/frameworks/js/napi/common/file_extension_info_napi.h b/frameworks/js/napi/common/file_extension_info_napi.h index 08c2f501..bb517469 100644 --- a/frameworks/js/napi/common/file_extension_info_napi.h +++ b/frameworks/js/napi/common/file_extension_info_napi.h @@ -27,6 +27,7 @@ void InitDeviceType(napi_env env, napi_value exports); void InitFileInfo(napi_env env, napi_value exports); void InitRootInfo(napi_env env, napi_value exports); void InitOpenFlags(napi_env env, napi_value exports); +void InitQueryFlags(napi_env env, napi_value exports); } // namespace FileAccessFwk } // namespace OHOS #endif // FILE_EXTENSION_INFO_NAPI_H \ No newline at end of file diff --git a/frameworks/js/napi/file_access_module/napi_fileaccess_helper.cpp b/frameworks/js/napi/file_access_module/napi_fileaccess_helper.cpp index 6eae3349..db5cc631 100644 --- a/frameworks/js/napi/file_access_module/napi_fileaccess_helper.cpp +++ b/frameworks/js/napi/file_access_module/napi_fileaccess_helper.cpp @@ -230,6 +230,7 @@ napi_value FileAccessHelperInit(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("createFile", NAPI_CreateFile), DECLARE_NAPI_FUNCTION("delete", NAPI_Delete), DECLARE_NAPI_FUNCTION("move", NAPI_Move), + DECLARE_NAPI_FUNCTION("query", NAPI_Query), DECLARE_NAPI_FUNCTION("rename", NAPI_Rename), DECLARE_NAPI_FUNCTION("getRoots", NAPI_GetRoots), DECLARE_NAPI_FUNCTION("access", NAPI_Access), @@ -591,6 +592,59 @@ napi_value NAPI_Move(napi_env env, napi_callback_info info) return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_; } +napi_value NAPI_Query(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::THREE)) { + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + bool succ = false; + std::unique_ptr uri; + std::unique_ptr metaJson; + std::tie(succ, uri, metaJson) = GetReadArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); + if (!succ) { + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + FileAccessHelper *fileAccessHelper = GetFileAccessHelper(env, funcArg.GetThisVar()); + if (fileAccessHelper == nullptr) { + return nullptr; + } + + std::string uriString(uri.get()); + std::string metaJsonString(metaJson.get()); + auto metaJsonPtr = std::make_shared(metaJsonString); + auto cbExec = [uriString, metaJsonPtr, fileAccessHelper]() -> NError { + OHOS::Uri uri(uriString); + int ret = fileAccessHelper->Query(uri, *metaJsonPtr); + return NError(ret); + }; + + auto cbComplete = [metaJsonPtr](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return { NVal::CreateUTF8String(env, *metaJsonPtr) }; + }; + + const std::string procedureName = "query"; + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::TWO) { + return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_; + } + + NVal cb(env, funcArg[NARG_POS::THIRD]); + if (!cb.TypeIs(napi_function)) { + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_; +} + napi_value NAPI_Rename(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); diff --git a/frameworks/js/napi/file_access_module/napi_fileaccess_helper.h b/frameworks/js/napi/file_access_module/napi_fileaccess_helper.h index 41a80d25..df17ae86 100644 --- a/frameworks/js/napi/file_access_module/napi_fileaccess_helper.h +++ b/frameworks/js/napi/file_access_module/napi_fileaccess_helper.h @@ -29,6 +29,7 @@ namespace FileAccessFwk { napi_value NAPI_Mkdir(napi_env env, napi_callback_info info); 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_Query(napi_env env, napi_callback_info info); napi_value NAPI_Rename(napi_env env, napi_callback_info info); napi_value NAPI_GetRoots(napi_env env, napi_callback_info info); napi_value NAPI_Access(napi_env env, napi_callback_info info); diff --git a/frameworks/js/napi/file_access_module/native_fileaccess_module.cpp b/frameworks/js/napi/file_access_module/native_fileaccess_module.cpp index 0b0ca6d1..752d3427 100644 --- a/frameworks/js/napi/file_access_module/native_fileaccess_module.cpp +++ b/frameworks/js/napi/file_access_module/native_fileaccess_module.cpp @@ -43,6 +43,7 @@ static napi_value Init(napi_env env, napi_value exports) InitFileInfo(env, exports); InitRootInfo(env, exports); InitOpenFlags(env, exports); + InitQueryFlags(env, exports); std::vector> products; products.emplace_back(std::make_unique(env, exports)); diff --git a/interfaces/inner_api/file_access/include/file_access_ext_ability.h b/interfaces/inner_api/file_access/include/file_access_ext_ability.h index 0cba3acf..6c3bf384 100644 --- a/interfaces/inner_api/file_access/include/file_access_ext_ability.h +++ b/interfaces/inner_api/file_access/include/file_access_ext_ability.h @@ -55,6 +55,7 @@ public: virtual int ScanFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, const FileFilter &filter, std::vector &fileInfoVec); virtual int GetThumbnail(const Uri &uri, const Size &size, std::unique_ptr &pixelMap); + virtual int Query(const Uri &uri, std::vector &columns, std::vector &results); virtual int GetFileInfoFromUri(const Uri &selectFile, FileInfo &fileInfo); virtual int GetFileInfoFromRelativePath(const std::string &selectFile, FileInfo &fileInfo); virtual int GetRoots(std::vector &rootInfoVec); diff --git a/interfaces/inner_api/file_access/include/file_access_ext_proxy.h b/interfaces/inner_api/file_access/include/file_access_ext_proxy.h index fb4ebdf3..710ac58a 100644 --- a/interfaces/inner_api/file_access/include/file_access_ext_proxy.h +++ b/interfaces/inner_api/file_access/include/file_access_ext_proxy.h @@ -49,6 +49,7 @@ public: virtual int ScanFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, const FileFilter &filter, std::vector &fileInfoVec) override; virtual int GetThumbnail(const Uri &uri, const ThumbnailSize &thumbnailSize, std::shared_ptr &pixelMap) override; + virtual int Query(const Uri &uri, std::vector &columns, std::vector &results) override; virtual int GetFileInfoFromUri(const Uri &selectFile, FileInfo &fileInfo) override; virtual int GetFileInfoFromRelativePath(const std::string &selectFile, FileInfo &fileInfo) override; virtual int GetRoots(std::vector &rootInfoVec) override; diff --git a/interfaces/inner_api/file_access/include/file_access_ext_stub.h b/interfaces/inner_api/file_access/include/file_access_ext_stub.h index 84e1fdf9..a546c21e 100644 --- a/interfaces/inner_api/file_access/include/file_access_ext_stub.h +++ b/interfaces/inner_api/file_access/include/file_access_ext_stub.h @@ -44,6 +44,7 @@ private: ErrCode CmdListFile(MessageParcel &data, MessageParcel &reply); ErrCode CmdScanFile(MessageParcel &data, MessageParcel &reply); ErrCode CmdGetThumbnail(MessageParcel &data, MessageParcel &reply); + ErrCode CmdQuery(MessageParcel &data, MessageParcel &reply); ErrCode CmdGetFileInfoFromUri(MessageParcel &data, MessageParcel &reply); ErrCode CmdGetFileInfoFromRelativePath(MessageParcel &data, MessageParcel &reply); ErrCode CmdGetRoots(MessageParcel &data, MessageParcel &reply); diff --git a/interfaces/inner_api/file_access/include/file_access_ext_stub_impl.h b/interfaces/inner_api/file_access/include/file_access_ext_stub_impl.h index cce44dce..3a4d1d2e 100644 --- a/interfaces/inner_api/file_access/include/file_access_ext_stub_impl.h +++ b/interfaces/inner_api/file_access/include/file_access_ext_stub_impl.h @@ -47,6 +47,7 @@ public: int ScanFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, const FileFilter &filter, std::vector &fileInfoVec) override; int GetThumbnail(const Uri &uri, const ThumbnailSize &thumbnailSize, std::shared_ptr &pixelMap) override; + int Query(const Uri &uri, std::vector &columns, std::vector &results) override; int GetFileInfoFromUri(const Uri &selectFile, FileInfo &fileInfo) override; int GetFileInfoFromRelativePath(const std::string &selectFile, FileInfo &fileInfo) override; int GetRoots(std::vector &rootInfoVec) override; diff --git a/interfaces/inner_api/file_access/include/file_access_extension_info.h b/interfaces/inner_api/file_access/include/file_access_extension_info.h index a1942bec..70c7de99 100644 --- a/interfaces/inner_api/file_access/include/file_access_extension_info.h +++ b/interfaces/inner_api/file_access/include/file_access_extension_info.h @@ -18,12 +18,24 @@ #include #include +#include #include "parcel.h" #include "uri.h" namespace OHOS { namespace FileAccessFwk { +//Properties of the Common file +const std::string DISPLAY_NAME = "display_name"; +const std::string RELATIVE_PATH = "relative_path"; +const std::string FILE_SIZE = "size"; +const std::string DATE_MODIFIED = "date_modified"; +const std::string DATE_ADDED = "date_added"; +//Properties of the picture file +const std::string HEIGHT = "height"; +const std::string WIDTH = "width"; +//Properties of an image or audio file +const std::string DURATION = "duration"; /** * Indicates the type of the device. */ @@ -214,6 +226,23 @@ public: return size; } }; + +enum ResultType { + STRING_TYPE = 1, + INT32_TYPE, + INT64_TYPE, +}; + +static const std::unordered_map FILE_RESULT_TYPE = { + { DISPLAY_NAME, STRING_TYPE }, + { RELATIVE_PATH, STRING_TYPE }, + { FILE_SIZE, INT64_TYPE }, + { DATE_ADDED, INT64_TYPE }, + { DATE_MODIFIED, INT64_TYPE }, + { WIDTH, INT32_TYPE }, + { HEIGHT, INT32_TYPE }, + { DURATION, INT32_TYPE }, +}; } // namespace FileAccessFwk } // namespace OHOS #endif // FILE_ACCESS_EXTENSION_INFO_H \ No newline at end of file diff --git a/interfaces/inner_api/file_access/include/file_access_helper.h b/interfaces/inner_api/file_access/include/file_access_helper.h index 7a9eca7b..be23eda0 100644 --- a/interfaces/inner_api/file_access/include/file_access_helper.h +++ b/interfaces/inner_api/file_access/include/file_access_helper.h @@ -80,6 +80,7 @@ public: int ScanFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, const FileFilter &filter, std::vector &fileInfoVec); int GetThumbnail(Uri &uri, ThumbnailSize &thumbnailSize, std::shared_ptr &pixelMap); + int Query(Uri &uri, std::string &metaJson); int GetFileInfoFromUri(Uri &selectFile, FileInfo &fileInfo); int GetFileInfoFromRelativePath(std::string &selectFile, FileInfo &fileInfo); int GetRoots(std::vector &rootInfoVec); diff --git a/interfaces/inner_api/file_access/include/ifile_access_ext_base.h b/interfaces/inner_api/file_access/include/ifile_access_ext_base.h index ad54e35e..c7e690b1 100644 --- a/interfaces/inner_api/file_access/include/ifile_access_ext_base.h +++ b/interfaces/inner_api/file_access/include/ifile_access_ext_base.h @@ -46,6 +46,7 @@ public: CMD_RENAME, CMD_LIST_FILE, CMD_SCAN_FILE, + CMD_QUERY, CMD_GET_ROOTS, CMD_ACCESS, CMD_GET_THUMBNAIL, @@ -66,6 +67,7 @@ public: virtual int ScanFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, const FileFilter &filter, std::vector &fileInfoVec) = 0; virtual int GetThumbnail(const Uri &uri, const ThumbnailSize &thumbnailSize, std::shared_ptr &pixelMap) = 0; + virtual int Query(const Uri &uri, std::vector &columns, std::vector &results) = 0; virtual int GetFileInfoFromUri(const Uri &selectFile, FileInfo &fileInfo) = 0; virtual int GetFileInfoFromRelativePath(const std::string &selectFile, FileInfo &fileInfo) = 0; virtual int GetRoots(std::vector &rootInfoVec) = 0; diff --git a/interfaces/inner_api/file_access/include/js_file_access_ext_ability.h b/interfaces/inner_api/file_access/include/js_file_access_ext_ability.h index 8c3eb4d9..ac4b0bd2 100644 --- a/interfaces/inner_api/file_access/include/js_file_access_ext_ability.h +++ b/interfaces/inner_api/file_access/include/js_file_access_ext_ability.h @@ -71,6 +71,7 @@ public: int GetFileInfoFromUri(const Uri &selectFile, FileInfo &fileInfo) override; int GetRoots(std::vector &rootInfoVec) override; int Access(const Uri &uri, bool &isExist) override; + int Query(const Uri &uri, std::vector &columns, std::vector &results) override; private: NativeValue* CallObjectMethod(const char *name, NativeValue * const *argv = nullptr, size_t argc = 0); diff --git a/interfaces/inner_api/file_access/src/file_access_ext_ability.cpp b/interfaces/inner_api/file_access/src/file_access_ext_ability.cpp index 0bfec464..ebe0ea1f 100644 --- a/interfaces/inner_api/file_access/src/file_access_ext_ability.cpp +++ b/interfaces/inner_api/file_access/src/file_access_ext_ability.cpp @@ -110,6 +110,12 @@ int FileAccessExtAbility::ScanFile(const FileInfo &fileInfo, const int64_t offse return EPERM; } +int FileAccessExtAbility::Query(const Uri &uri, std::vector &columns, std::vector &results) +{ + HILOG_ERROR("FileAccessExtAbility::Query Undefined operation"); + return EPERM; +} + int FileAccessExtAbility::GetRoots(std::vector &rootInfoVec) { HILOG_ERROR("FileAccessExtAbility::GetRoots Undefined operation"); diff --git a/interfaces/inner_api/file_access/src/file_access_ext_proxy.cpp b/interfaces/inner_api/file_access/src/file_access_ext_proxy.cpp index fbacbe2d..303e95a6 100644 --- a/interfaces/inner_api/file_access/src/file_access_ext_proxy.cpp +++ b/interfaces/inner_api/file_access/src/file_access_ext_proxy.cpp @@ -508,6 +508,81 @@ int FileAccessExtProxy::ScanFile(const FileInfo &fileInfo, const int64_t offset, return ERR_OK; } +static int GetQueryResult(MessageParcel &reply, std::vector &results) +{ + int ret = E_IPCS; + if (!reply.ReadInt32(ret)) { + HILOG_ERROR("fail to ReadInt32 ret"); + return E_IPCS; + } + + if (ret != ERR_OK) { + HILOG_ERROR("Query operation failed ret : %{public}d", ret); + return ret; + } + + int64_t count = 0; + if (!reply.ReadInt64(count)) { + HILOG_ERROR("Query operation failed to Read count"); + return E_IPCS; + } + + results.clear(); + for (int64_t i = 0; i < count; i++) { + results.push_back(reply.ReadString()); + } + return ERR_OK; +} + +int FileAccessExtProxy::Query(const Uri &uri, std::vector &columns, std::vector &results) +{ + StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Query"); + MessageParcel data; + if (!data.WriteInterfaceToken(FileAccessExtProxy::GetDescriptor())) { + HILOG_ERROR("WriteInterfaceToken failed"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + + if (!data.WriteParcelable(&uri)) { + HILOG_ERROR("fail to WriteParcelable sourceFile"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + int64_t count = columns.size(); + if (!data.WriteInt64(count)) { + HILOG_ERROR("Parameter Query fail to WriteInt64 count"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + + for (const auto &column : columns) { + if (!data.WriteString(column)) { + HILOG_ERROR("parameter Query fail to WriteParcelable column"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + } + + MessageParcel reply; + MessageOption option; + int err = Remote()->SendRequest(CMD_QUERY, data, reply, option); + if (err != ERR_OK) { + HILOG_ERROR("fail to SendRequest. err: %{public}d", err); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return err; + } + + err = GetQueryResult(reply, results); + if (err != ERR_OK) { + HILOG_ERROR("fail to GetQueryResult. err: %{public}d", err); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return err; + } + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ERR_OK; +} + int FileAccessExtProxy::GetRoots(std::vector &rootInfoVec) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "GetRoots"); diff --git a/interfaces/inner_api/file_access/src/file_access_ext_stub.cpp b/interfaces/inner_api/file_access/src/file_access_ext_stub.cpp index e48ce855..88c97d9b 100644 --- a/interfaces/inner_api/file_access/src/file_access_ext_stub.cpp +++ b/interfaces/inner_api/file_access/src/file_access_ext_stub.cpp @@ -51,6 +51,7 @@ FileAccessExtStub::FileAccessExtStub() stubFuncMap_[CMD_RENAME] = &FileAccessExtStub::CmdRename; stubFuncMap_[CMD_LIST_FILE] = &FileAccessExtStub::CmdListFile; stubFuncMap_[CMD_SCAN_FILE] = &FileAccessExtStub::CmdScanFile; + stubFuncMap_[CMD_QUERY] = &FileAccessExtStub::CmdQuery; stubFuncMap_[CMD_GET_ROOTS] = &FileAccessExtStub::CmdGetRoots; stubFuncMap_[CMD_ACCESS] = &FileAccessExtStub::CmdAccess; stubFuncMap_[CMD_GET_THUMBNAIL] = &FileAccessExtStub::CmdGetThumbnail; @@ -464,6 +465,53 @@ ErrCode FileAccessExtStub::CmdGetRoots(MessageParcel &data, MessageParcel &reply return ERR_OK; } +ErrCode FileAccessExtStub::CmdQuery(MessageParcel &data, MessageParcel &reply) +{ + StartTrace(HITRACE_TAG_FILEMANAGEMENT, "CmdQuery"); + std::shared_ptr uri(data.ReadParcelable()); + if (uri == nullptr) { + HILOG_ERROR("Parameter Query fail to ReadParcelable uri"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + + int64_t count = 0; + if (!data.ReadInt64(count)) { + HILOG_ERROR("Query operation failed to Read count"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + std::vector columns; + for (int64_t i = 0; i < count; i++) { + columns.push_back(data.ReadString()); + } + std::vector results; + int ret = Query(*uri, columns, results); + if (!reply.WriteInt32(ret)) { + HILOG_ERROR("Parameter Query fail to WriteInt32 ret"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + + int64_t resCount {results.size()}; + if (!reply.WriteInt64(resCount)) { + HILOG_ERROR("Parameter Query fail to WriteInt64 count"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + + for (const auto &result : results) { + if (!reply.WriteString(result)) { + HILOG_ERROR("parameter Query fail to WriteParcelable column"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + } + + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ERR_OK; +} + ErrCode FileAccessExtStub::CmdGetThumbnail(MessageParcel &data, MessageParcel &reply) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "CmdGetThumbnail"); diff --git a/interfaces/inner_api/file_access/src/file_access_ext_stub_impl.cpp b/interfaces/inner_api/file_access/src/file_access_ext_stub_impl.cpp index b7bab8f6..1883c903 100644 --- a/interfaces/inner_api/file_access/src/file_access_ext_stub_impl.cpp +++ b/interfaces/inner_api/file_access/src/file_access_ext_stub_impl.cpp @@ -142,6 +142,20 @@ int FileAccessExtStubImpl::ScanFile(const FileInfo &fileInfo, const int64_t offs return ret; } +int FileAccessExtStubImpl::Query(const Uri &uri, std::vector &columns, std::vector &results) +{ + StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Query"); + if (extension_ == nullptr) { + HILOG_ERROR("Query get extension failed."); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + + int ret = extension_->Query(uri, columns, results); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ret; +} + int FileAccessExtStubImpl::GetRoots(std::vector &rootInfoVec) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "GetRoots"); diff --git a/interfaces/inner_api/file_access/src/file_access_helper.cpp b/interfaces/inner_api/file_access/src/file_access_helper.cpp index a2b4bf2f..76d3e50a 100644 --- a/interfaces/inner_api/file_access/src/file_access_helper.cpp +++ b/interfaces/inner_api/file_access/src/file_access_helper.cpp @@ -15,9 +15,11 @@ #include "file_access_helper.h" +#include #include "bundle_constants.h" #include "bundle_mgr_proxy.h" #include "file_access_framework_errno.h" +#include "file_access_extension_info.h" #include "hilog_wrapper.h" #include "hitrace_meter.h" #include "if_system_ability_manager.h" @@ -31,6 +33,7 @@ namespace OHOS { namespace FileAccessFwk { using namespace Media; +using json = nlohmann::json; std::vector FileAccessHelper::wants_; static int GetUserId() @@ -734,6 +737,109 @@ int FileAccessHelper::ScanFile(const FileInfo &fileInfo, const int64_t offset, c return ERR_OK; } +static int GetQueryColumns(std::string &uri, std::string &metaJson, std::vector &columns) +{ + if (!json::accept(metaJson)) { + HILOG_ERROR("metaJson format check error."); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return EINVAL; + } + + auto jsonObject = json::parse(metaJson); + for (json::iterator it = jsonObject.begin(); it != jsonObject.end(); ++it) { + auto iterator = FILE_RESULT_TYPE.find(it.key()); + if (iterator == FILE_RESULT_TYPE.end()) { + HILOG_ERROR("columns format check error."); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return EINVAL; + } + columns.push_back(it.key()); + } + + if (columns.empty()) { + HILOG_ERROR("columns is empty."); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return EINVAL; + } + return ERR_OK; +} + +static int GetQueryResult(std::string &uri, std::vector &columns, std::vector &results, + std::string &metaJson) +{ + json jsonObject; + for (size_t i = 0; i < columns.size(); i++) { + auto memberType = FILE_RESULT_TYPE.at(columns.at(i)); + switch (memberType) { + case STRING_TYPE: + jsonObject[columns[i]] = results[i]; + break; + case INT32_TYPE: + jsonObject[columns[i]] = std::stoi(results[i]); + break; + case INT64_TYPE: + jsonObject[columns[i]] = std::stol(results[i]); + break; + default: + jsonObject[columns[i]] = ' '; + HILOG_ERROR("not match memberType %{public}d", memberType); + break; + } + } + metaJson = jsonObject.dump(); + return ERR_OK; +} + +int FileAccessHelper::Query(Uri &uri, std::string &metaJson) +{ + StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Query"); + if (!IsSystemApp()) { + HILOG_ERROR("FileAccessHelper::Query check IsSystemAppByFullTokenID failed"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_PERMISSION_SYS; + } + + if (!CheckUri(uri)) { + HILOG_ERROR("Uri format check error."); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_URIS; + } + + std::string uriString(uri.ToString()); + std::vector columns; + std::vector results; + int ret = GetQueryColumns(uriString, metaJson, columns); + if (ret != ERR_OK) { + HILOG_ERROR("Query get columns error, code:%{public}d", ret); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ret; + } + + sptr fileExtProxy = GetProxyByUri(uri); + if (fileExtProxy == nullptr) { + HILOG_ERROR("failed with invalid fileAccessExtProxy"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + + ret = fileExtProxy->Query(uri, columns, results); + if (ret != ERR_OK) { + HILOG_ERROR("Query get result error, code:%{public}d", ret); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ret; + } + + ret = GetQueryResult(uriString, columns, results, metaJson); + if (ret != ERR_OK) { + HILOG_ERROR("Query get result error, code:%{public}d", ret); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ret; + } + + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ERR_OK; +} + int FileAccessHelper::GetRoots(std::vector &rootInfoVec) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "GetRoots"); diff --git a/interfaces/inner_api/file_access/src/js_file_access_ext_ability.cpp b/interfaces/inner_api/file_access/src/js_file_access_ext_ability.cpp index b0e3b877..c9028f58 100644 --- a/interfaces/inner_api/file_access/src/js_file_access_ext_ability.cpp +++ b/interfaces/inner_api/file_access/src/js_file_access_ext_ability.cpp @@ -1072,6 +1072,105 @@ int JsFileAccessExtAbility::Access(const Uri &uri, bool &isExist) return ERR_OK; } +static bool ParserQueryFileJsResult(NativeEngine &engine, NativeValue *nativeValue, + Value> &results) +{ + NativeObject *obj = ConvertNativeValueTo(nativeValue); + if (obj == nullptr) { + HILOG_ERROR("Convert js object fail."); + return false; + } + + bool ret = ConvertFromJsValue(engine, obj->GetProperty("code"), results.code); + if (!ret) { + HILOG_ERROR("Convert the code of js value fail."); + return ret; + } + + NativeArray *nativeArray = ConvertNativeValueTo(obj->GetProperty("results")); + if (nativeArray == nullptr) { + HILOG_ERROR("Convert js array object fail."); + return false; + } + + for (uint32_t i = 0; i < nativeArray->GetLength(); i++) { + NativeValue *queryResult = nativeArray->GetElement(i); + if (queryResult == nullptr) { + HILOG_ERROR("get native queryResult fail."); + return false; + } + std::string tempValue; + ret = ConvertFromJsValue(engine, queryResult, tempValue); + if (!ret) { + HILOG_ERROR("Convert js value fail."); + return ret; + } + results.data.emplace_back(std::move(tempValue)); + } + return true; +} + +int JsFileAccessExtAbility::Query(const Uri &uri, std::vector &columns, std::vector &results) +{ + StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Query"); + auto value = std::make_shared>>(); + if (value == nullptr) { + HILOG_ERROR("Query value is nullptr."); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_GETRESULT; + } + + auto argParser = [uri, &columns](NativeEngine &engine, NativeValue *argv[], size_t &argc) -> bool { + NativeValue *nativeUri = engine.CreateString(uri.ToString().c_str(), uri.ToString().length()); + if (nativeUri == nullptr) { + HILOG_ERROR("create uri native js value fail."); + return false; + } + NativeValue *resultArray = engine.CreateArray(columns.size()); + if (resultArray == nullptr) { + HILOG_ERROR("Create MimeType native array value fail."); + return false; + } + int errorCode = MakeStringNativeArray(engine, columns, resultArray); + if (errorCode != ERR_OK) { + HILOG_ERROR("Create native array value fail, code:%{public}d.", errorCode); + return false; + } + argv[ARGC_ZERO] = nativeUri; + argv[ARGC_ONE] = resultArray; + argc = ARGC_TWO; + return true; + }; + auto retParser = [value](NativeEngine &engine, NativeValue *result) -> bool { + Value> queryResult; + bool ret = ParserQueryFileJsResult(engine, result, queryResult); + if (!ret) { + HILOG_ERROR("Parser js value fail."); + return ret; + } + value->code = queryResult.code; + value->data = queryResult.data; + return ret; + }; + + auto errCode = CallJsMethod("query", jsRuntime_, jsObj_.get(), argParser, retParser); + if (errCode != ERR_OK) { + HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return errCode; + } + + if (value->code != ERR_OK) { + HILOG_ERROR("fileio fail."); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return value->code; + } + + results = std::move(value->data); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ERR_OK; +} + int JsFileAccessExtAbility::GetFileInfoFromUri(const Uri &selectFile, FileInfo &fileInfo) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "GetFileInfoFromUri"); 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 0954189d..d924ed28 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 @@ -36,6 +36,10 @@ const ERR_ERROR = -1; const E_EXIST = 13900015; const E_URIS = 14300002; const E_GETRESULT = 14300004; +const DATA_DB_DATE_ADDED = 'date_added'; +const DATA_DB_DATE_MODIFIED = 'date_modified'; +const FILE_DATA_ATIME = 'atime'; +const FILE_DATA_MTIME = 'mtime'; let callbackFun = null; export default class FileExtAbility extends Extension { @@ -538,4 +542,76 @@ export default class FileExtAbility extends Extension { code: ERR_OK, }; } + + query(uri, columns) { + if (!this.checkUri(uri)) { + return { + results: [], + code: E_URIS, + }; + } + let queryResults = []; + + try { + let dirPath = this.getPath(uri); + let stat = fileio.statSync(dirPath); + let convertColumn = new Map([ + [DATA_DB_DATE_ADDED, FILE_DATA_ATIME], + [DATA_DB_DATE_MODIFIED, FILE_DATA_MTIME] + ]); + for (let index in columns) { + let column = columns[index]; + convertColumn.forEach((value, key) =>{ + if (column === key) { + column = value; + } + }); + + if (column === 'display_name') { + let index = dirPath.lastIndexOf('/'); + let target = dirPath.substring(index + 1, ); + queryResults.push(String(target)); + continue; + } + + if (column === 'relative_path') { + let index = dirPath.lastIndexOf('/'); + let target = dirPath.substring(0, index + 1); + queryResults.push(target); + continue; + } + + if (column in stat) { + if (column === 'size' && stat.isDirectory()) { + let size = 0; + this.recurseDir(dirPath, function (filePath, isDirectory, hasNextFile) { + if (isDirectory && !hasNextFile) { + return; + } + + if (!isDirectory) { + let stat = fileio.statSync(filePath); + size += stat.size; + } + }); + queryResults.push(String(size)); + continue; + } + queryResults.push(String(stat[column])); + } else { + queryResults.push('0'); + } + } + } catch (e) { + hilog.error(DOMAIN_CODE, TAG, 'query error ' + e.message); + return { + results: [], + code: e.code, + }; + } + return { + results: queryResults, + code: ERR_OK, + }; + } }; \ No newline at end of file -- Gitee