From 44181edbf1e2d19a7165ec9dcda9abc7e842b1de Mon Sep 17 00:00:00 2001 From: BrainL Date: Tue, 8 Jul 2025 15:29:04 +0800 Subject: [PATCH 1/2] =?UTF-8?q?afs=200328=E5=90=88=E5=B9=B6=E5=88=B00702?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: BrainL --- interfaces/kits/taihe/fileshare/BUILD.gn | 113 +++++ .../idl/ohos.fileshare.fileShare.taihe | 69 ++++ .../taihe/fileshare/idl/ohos.fileshare.taihe | 20 + .../taihe/fileshare/include/fileshare_taihe.h | 71 ++++ .../taihe/fileshare/src/ani_constructor.cpp | 36 ++ .../taihe/fileshare/src/fileshare_taihe.cpp | 388 ++++++++++++++++++ interfaces/kits/taihe/fileuri/BUILD.gn | 98 +++++ .../taihe/fileuri/idl/ohos.file.fileuri.taihe | 31 ++ .../taihe/fileuri/include/fileuri_taihe.h | 44 ++ .../taihe/fileuri/src/ani_constructor.cpp | 29 ++ .../kits/taihe/fileuri/src/fileuri_taihe.cpp | 59 +++ 11 files changed, 958 insertions(+) create mode 100644 interfaces/kits/taihe/fileshare/BUILD.gn create mode 100644 interfaces/kits/taihe/fileshare/idl/ohos.fileshare.fileShare.taihe create mode 100644 interfaces/kits/taihe/fileshare/idl/ohos.fileshare.taihe create mode 100644 interfaces/kits/taihe/fileshare/include/fileshare_taihe.h create mode 100644 interfaces/kits/taihe/fileshare/src/ani_constructor.cpp create mode 100644 interfaces/kits/taihe/fileshare/src/fileshare_taihe.cpp create mode 100644 interfaces/kits/taihe/fileuri/BUILD.gn create mode 100644 interfaces/kits/taihe/fileuri/idl/ohos.file.fileuri.taihe create mode 100644 interfaces/kits/taihe/fileuri/include/fileuri_taihe.h create mode 100644 interfaces/kits/taihe/fileuri/src/ani_constructor.cpp create mode 100644 interfaces/kits/taihe/fileuri/src/fileuri_taihe.cpp diff --git a/interfaces/kits/taihe/fileshare/BUILD.gn b/interfaces/kits/taihe/fileshare/BUILD.gn new file mode 100644 index 000000000..f718dc78b --- /dev/null +++ b/interfaces/kits/taihe/fileshare/BUILD.gn @@ -0,0 +1,113 @@ +# Copyright (c) 2025 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. + +import("//build/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") +import("//build/ohos/taihe_idl/taihe.gni") +import("//foundation/filemanagement/app_file_service/app_file_service.gni") + +part_name = "app_file_service" +subsystem_name = "filemanagement" +taihe_generated_file_path = "$taihe_file_path/out/$subsystem_name/$part_name/fileshare" + +copy_taihe_idl("copy_taihe") { + sources = [ + "${app_file_service_path}/interfaces/kits/taihe/fileshare/idl/ohos.fileshare.fileShare.taihe", + "${app_file_service_path}/interfaces/kits/taihe/fileshare/idl/ohos.fileshare.taihe", + ] +} + +ohos_taihe("run_taihe") { + taihe_generated_file_path = "$taihe_generated_file_path" + deps = [ ":copy_taihe" ] + outputs = [ + "$taihe_generated_file_path/src/ohos.fileshare.fileShare.ani.cpp", + "$taihe_generated_file_path/src/ohos.fileshare.fileShare.abi.c", + ] +} + +taihe_shared_library("file_share_taihe") { + taihe_generated_file_path = "$taihe_generated_file_path" + subsystem_name = "filemanagement" + part_name = "app_file_service" + + sanitize = { + integer_overflow = true + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } + + include_dirs = [ + "include", + "${app_file_service_path}/interfaces/common/include/log.h", + "${app_file_service_path}/interfaces/innerkits/native/file_share/include", + "${app_file_service_path}/interfaces/kits/ndk/fileshare/include" + ] + + sources = get_target_outputs(":run_taihe") + sources += [ + "src/ani_constructor.cpp", + "src/fileshare_taihe.cpp" + ] + + deps = [ + ":run_taihe", + "${app_file_service_path}/interfaces/innerkits/native:fileshare_native", + ] + + external_deps = [ + "hilog:libhilog", + "hitrace:hitrace_meter", + "ability_base:want", + "ability_base:zuri", + "ipc:ipc_core", + "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", + "bundle_framework:appexecfwk_base", + "c_utils:utils", + "ability_runtime:abilitykit_native", + "ability_runtime:extensionkit_native", + "ability_runtime:uri_permission_mgr", + "data_share:datashare_common", + "data_share:datashare_consumer", + "file_api:remote_uri_native", + ] +} + +generate_static_abc("file_share_taihe_abc") { + base_url = "$taihe_generated_file_path" + files = [ "$taihe_generated_file_path/@ohos.fileshare.ets" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/file_share_taihe_abc.abc" + dependencies = [ ":run_taihe" ] +} + +ohos_prebuilt_etc("file_share_etc") { + source = "$target_out_dir/file_share_taihe_abc.abc" + module_install_dir = "framework" + part_name = "app_file_service" + subsystem_name = "filemanagement" + deps = [ + ":file_share_taihe_abc", + ] +} + +group("afs_fileshare_taihe") { + deps = [ + ":file_share_taihe", + ":file_share_etc", + ] +} diff --git a/interfaces/kits/taihe/fileshare/idl/ohos.fileshare.fileShare.taihe b/interfaces/kits/taihe/fileshare/idl/ohos.fileshare.fileShare.taihe new file mode 100644 index 000000000..0ad3bdf30 --- /dev/null +++ b/interfaces/kits/taihe/fileshare/idl/ohos.fileshare.fileShare.taihe @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2025 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. +*/ + +@!namespace("@ohos.fileshare","fileShare") + +@!sts_inject(""" +static { loadLibrary("file_share_taihe.z"); } +""") + +enum OperationMode: i32 { + READ_MODE = 1, + WRITE_MODE = 2, +} + +struct PolicyInfo { + uri: String; + operationMode: i32; +} + +struct PathPolicyInfo { + path: String; + operationMode: OperationMode; +} + +enum PolicyType: i32 { + TEMPORARY_TYPE = 0, + PERSISTENT_TYPE = 1, +} + +function MakePolicyInfo(uri: String, operationMode: i32): PolicyInfo; + +function MakePathPolicyInfo(path: String, operationMode: OperationMode): PathPolicyInfo; + +@gen_promise("activatePermission") +function ActivatePermissionSync( + policies: Array +): void; + +@gen_promise("deactivatePermission") +function DeactivatePermissionSync( + policies: Array +): void; + +@gen_async("grantUriPermission") +@gen_promise("grantUriPermission") +function GrantUriPermissionSync( + uri:String, + bundleName:String, + flag: @sts_type("wantConstant.Flags") Opaque, +): void; + +@gen_promise("checkPathPermission") +function CheckPathPermissionSync( + tokenID: i32, + policies: Array, + policyType: PolicyType, +): Array; diff --git a/interfaces/kits/taihe/fileshare/idl/ohos.fileshare.taihe b/interfaces/kits/taihe/fileshare/idl/ohos.fileshare.taihe new file mode 100644 index 000000000..203801bc8 --- /dev/null +++ b/interfaces/kits/taihe/fileshare/idl/ohos.fileshare.taihe @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2025 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. +*/ + +@!namespace("@ohos.fileshare") + +@!sts_inject(""" +import type wantConstant from '@ohos.app.ability.wantConstant'; +""") diff --git a/interfaces/kits/taihe/fileshare/include/fileshare_taihe.h b/interfaces/kits/taihe/fileshare/include/fileshare_taihe.h new file mode 100644 index 000000000..f586db5e1 --- /dev/null +++ b/interfaces/kits/taihe/fileshare/include/fileshare_taihe.h @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2025 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 FILEMANAGEMENT_APP_FILE_SERVICE_INTERFACES_FILE_SHARE_TAIHE_GRANT_PERMISSONS_H +#define FILEMANAGEMENT_APP_FILE_SERVICE_INTERFACES_FILE_SHARE_TAIHE_GRANT_PERMISSONS_H + +#include "ohos.fileshare.fileShare.proj.hpp" +#include "ohos.fileshare.fileShare.impl.hpp" +#include "taihe/runtime.hpp" +#include "file_permission.h" +#include "iremote_broker.h" + +namespace ANI::FileShare { + + ohos::fileshare::fileShare::PolicyInfo MakePolicyInfo(taihe::string_view uri, int32_t operationMode); + ohos::fileshare::fileShare::PathPolicyInfo MakePathPolicyInfo(taihe::string_view path, + ohos::fileshare::fileShare::OperationMode operationMode); + void ActivatePermissionSync(taihe::array_view policies); + void DeactivatePermissionSync(taihe::array_view policies); + void GrantUriPermissionSync(taihe::string_view uri, taihe::string_view bundleName, uintptr_t flag); + taihe::array CheckPathPermissionSync(int32_t tokenID, + taihe::array_view policies, + ohos::fileshare::fileShare::PolicyType policyType); + + struct PolicyErrorArgs { + std::deque errorResults; + int32_t errNo = 0; + ~PolicyErrorArgs() = default; + }; + + struct PolicyInfoResultArgs { + std::vector resultData; + int32_t errNo = 0; + ~PolicyInfoResultArgs() = default; + }; + + struct UriPermissionInfo { + unsigned int flag; + std::string mode; + std::string bundleName; + std::string uri; + }; + + enum MediaFileTable { + FILE_TABLE = 0, + PHOTO_TABLE = 1, + AUDIO_TABLE = 2, + }; + +class FileShareGrantToken : public OHOS::IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.fileshare.grantUriPermission"); + + FileShareGrantToken() = default; + virtual ~FileShareGrantToken() noexcept = default; +}; +} //namespace ANI::FileShare + +#endif // FILEMANAGEMENT_APP_FILE_SERVICE_INTERFACES_FILE_SHARE_TAIHE_GRANT_PERMISSONS_H diff --git a/interfaces/kits/taihe/fileshare/src/ani_constructor.cpp b/interfaces/kits/taihe/fileshare/src/ani_constructor.cpp new file mode 100644 index 000000000..773148598 --- /dev/null +++ b/interfaces/kits/taihe/fileshare/src/ani_constructor.cpp @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2025 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 FILEMANAGEMENT_APP_FILE_SERVICE_INTERFACES_FILE_SHARE_TAIHE_ANI_CONSTRUCTOR_H +#define FILEMANAGEMENT_APP_FILE_SERVICE_INTERFACES_FILE_SHARE_TAIHE_ANI_CONSTRUCTOR_H + +#include "taihe/runtime.hpp" +#include "ohos.fileshare.fileShare.ani.hpp" +#include "ohos.fileshare.ani.hpp" + +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + ani_env *env; + if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) { + return ANI_ERROR; + } + if (ANI_OK != ohos::fileshare::fileShare::ANIRegister(env)) { + std::cerr << "Error from ohos::fileshare::fileShare::ANIRegister" << std::endl; + return ANI_ERROR; + } + *result = ANI_VERSION_1; + return ANI_OK; +} + +#endif // FILEMANAGEMENT_APP_FILE_SERVICE_INTERFACES_FILE_SHARE_TAIHE_ANI_CONSTRUCTOR_H diff --git a/interfaces/kits/taihe/fileshare/src/fileshare_taihe.cpp b/interfaces/kits/taihe/fileshare/src/fileshare_taihe.cpp new file mode 100644 index 000000000..0c9303929 --- /dev/null +++ b/interfaces/kits/taihe/fileshare/src/fileshare_taihe.cpp @@ -0,0 +1,388 @@ +/* +* Copyright (c) 2025 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 "fileshare_taihe.h" +#include +#include "ability.h" +#include "accesstoken_kit.h" +#include "ani.h" +#include "datashare_helper.h" +#include "datashare_values_bucket.h" +#include "ipc_skeleton.h" +#include "log.h" +#include "oh_file_share.h" +#include "remote_uri.h" +#include "tokenid_kit.h" +#include "uri_permission_manager_client.h" +#include "want.h" + +namespace ANI::FileShare { +constexpr int32_t E_PERMISSION_SYS = 202; +constexpr int32_t E_PERMISSION_DENIED = -1; +const std::string MEDIA_FILE_URI_PHOTO_PREFEX = "file://media/Photo/"; +const std::string MEDIA_FILE_URI_AUDIO_PREFEX = "file://media/Audio/"; +const std::string MEDIA_FILE_URI_VIDEO_PREFEX = "file://media/video/"; +const std::string MEDIA_FILE_URI_IMAGE_PREFEX = "file://media/image/"; +const std::string MEDIA_FILE_URI_FILE_PREFEX = "file://media/file/"; +const std::string MEDIA_FILE_URI_AUDIO_LOW_PREFEX = "file://media/audio/"; +const std::string PERMISSION_BUNDLE_NAME = "bundle_name"; +const std::string PERMISSION_FILE_ID = "file_id"; +const std::string PERMISSION_MODE = "mode"; +const std::string PERMISSION_TABLE_TYPE = "table_type"; +const std::string MEDIALIBRARY_DATA_URI = "datashare:///media"; +const std::string MEDIA_GRANT_URI_PERMISSION = + "datashare:///media/bundle_permission_insert_operation/bundle_permission_insert_operation"; +const std::string MEDIA_API_VERSION_10 = "?api_version=10"; +const std::string MEDIA_AUTHORITY = "media"; +const std::string FILE_SCHEME = "file"; +const std::string FILE_MANAGER_AUTHORITY = "docs"; +const std::string FILE_NOPS = ""; +const std::string FILE_READ = "r"; +const std::string FILE_WRITE = "w"; + +ohos::fileshare::fileShare::PolicyInfo MakePolicyInfo(taihe::string_view uri, int32_t operationMode) +{ + return {uri, operationMode}; +} + +ohos::fileshare::fileShare::PathPolicyInfo MakePathPolicyInfo(taihe::string_view path, + ohos::fileshare::fileShare::OperationMode operationMode) +{ + return {path, operationMode}; +} + +static int32_t GetUriPoliciesArg(taihe::array_view policies, + std::vector &uriPolicies) +{ + uint32_t count = policies.size(); + if (count > OHOS::AppFileService::MAX_ARRAY_SIZE) { + LOGE("The length of the array is extra-long"); + return E_PARAMS; + } + for (uint32_t i = 0; i < count; i++) { + OHOS::AppFileService::UriPolicyInfo uriPolicy; + uriPolicy.uri = policies[i].uri; + uriPolicy.mode = policies[i].operationMode; + if (uriPolicy.uri == FILE_NOPS) { + LOGE("URI is empty"); + return E_PARAMS; + } + if (uriPolicy.mode != READ_MODE && + uriPolicy.mode != (READ_MODE | WRITE_MODE)) { + LOGE("Invalid operation mode"); + return E_PARAMS; + } + uriPolicies.emplace_back(uriPolicy); + } + return E_NO_ERROR; +} + +static int32_t GetPathPoliciesArg(taihe::array_view policies, + std::vector &pathPolicies) +{ + uint32_t count = policies.size(); + if (count > OHOS::AppFileService::MAX_ARRAY_SIZE) { + LOGE("The length of the array is extra-long"); + return E_PARAMS; + } + for (uint32_t i = 0; i < count; i++) { + OHOS::AppFileService::PathPolicyInfo pathPolicie; + pathPolicie.path = policies[i].path; + pathPolicie.mode = policies[i].operationMode; + if (pathPolicie.path == FILE_NOPS) { + LOGE("path is empty"); + return E_PARAMS; + } + if (pathPolicie.mode != READ_MODE && pathPolicie.mode != WRITE_MODE && + pathPolicie.mode != (READ_MODE | WRITE_MODE)) { + LOGE("Invalid operation mode"); + return E_PARAMS; + } + pathPolicies.emplace_back(pathPolicie); + } + return E_NO_ERROR; +} + +void ActivatePermissionSync(taihe::array_view policies) +{ + std::vector uriPolicies; + if (GetUriPoliciesArg(policies, uriPolicies)) { + LOGE("Failed to get URI policies"); + taihe::set_business_error(E_PARAMS, "Failed to get URI policies"); + return; + } + + std::shared_ptr arg = std::make_shared(); + if (arg == nullptr) { + LOGE("PolicyErrorArgs make make_shared failed"); + taihe::set_business_error(E_UNKNOWN_ERROR, "PolicyErrorArgs make make_shared failed"); + return; + } + + arg->errNo = OHOS::AppFileService::FilePermission::ActivatePermission(uriPolicies, arg->errorResults); + if (arg->errNo) { + LOGE("Activation failed"); + taihe::set_business_error(arg->errNo, "Activation failed"); + } +} + +void DeactivatePermissionSync(taihe::array_view policies) +{ + std::vector uriPolicies; + if (GetUriPoliciesArg(policies, uriPolicies)) { + LOGE("Failed to get URI policies"); + taihe::set_business_error(E_PARAMS, "Failed to get URI policies"); + return; + } + + std::shared_ptr arg = std::make_shared(); + if (arg == nullptr) { + LOGE("PolicyErrorArgs make make_shared failed"); + taihe::set_business_error(E_UNKNOWN_ERROR, "PolicyErrorArgs make make_shared failed"); + return; + } + + arg->errNo = OHOS::AppFileService::FilePermission::DeactivatePermission(uriPolicies, arg->errorResults); + if (arg->errNo) { + LOGE("Deactivation failed"); + taihe::set_business_error(arg->errNo, "Deactivation failed"); + return; + } +} + +static bool IsSystemApp() +{ + uint64_t fullTokenId = OHOS::IPCSkeleton::GetCallingFullTokenID(); + return OHOS::Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId); +} + +static bool CheckTokenIdPermission(uint32_t tokenCaller, const std::string &permission) +{ + return OHOS::Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenCaller, permission) == + OHOS::Security::AccessToken::PermissionState::PERMISSION_GRANTED; +} + +static int32_t GetIdFromUri(std::string uri) +{ + std::replace(uri.begin(), uri.end(), '/', ' '); + std::stringstream ss(uri); + std::string tmp; + int32_t fileId = E_PERMISSION_DENIED; + ss >> tmp >> tmp >> tmp >> fileId; + return fileId; +} + +static std::string GetModeFromFlag(uint32_t flag) +{ + std::string mode = FILE_NOPS; + if (flag & OHOS::AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION) { + mode += FILE_READ; + } + if (flag & OHOS::AAFwk::Want::FLAG_AUTH_WRITE_URI_PERMISSION) { + mode += FILE_WRITE; + } + return mode; +} + +static int32_t GetMediaTypeAndApiFromUri(const std::string &uri, bool &isApi10) +{ + if (uri.find(MEDIA_FILE_URI_PHOTO_PREFEX) == 0) { + isApi10 = true; + return MediaFileTable::PHOTO_TABLE; + } else if (uri.find(MEDIA_FILE_URI_VIDEO_PREFEX) == 0 || + uri.find(MEDIA_FILE_URI_IMAGE_PREFEX) == 0) { + return MediaFileTable::PHOTO_TABLE; + } else if (uri.find(MEDIA_FILE_URI_AUDIO_PREFEX) == 0) { + isApi10 = true; + return MediaFileTable::AUDIO_TABLE; + } else if (uri.find(MEDIA_FILE_URI_AUDIO_LOW_PREFEX) == 0) { + return MediaFileTable::AUDIO_TABLE; + } else if (uri.find(MEDIA_FILE_URI_FILE_PREFEX) == 0) { + return MediaFileTable::FILE_TABLE; + } + + return MediaFileTable::FILE_TABLE; +} + +static int32_t InitValuesBucket(const UriPermissionInfo &uriPermInfo, Uri &uri, bool &isApi10, + OHOS::DataShare::DataShareValuesBucket &valuesBucket) +{ + int32_t fileId = GetIdFromUri(uriPermInfo.uri); + if (fileId == E_PERMISSION_DENIED) { + LOGE("FileShare::InitValuesBucket get fileId parameter failed!"); + return -EINVAL; + } + + int32_t filesType = GetMediaTypeAndApiFromUri(uri.ToString(), isApi10); + valuesBucket.Put(PERMISSION_FILE_ID, fileId); + valuesBucket.Put(PERMISSION_BUNDLE_NAME, uriPermInfo.bundleName); + valuesBucket.Put(PERMISSION_MODE, uriPermInfo.mode); + valuesBucket.Put(PERMISSION_TABLE_TYPE, filesType); + return E_NO_ERROR; +} + +static int32_t InsertByDatashare(const OHOS::DataShare::DataShareValuesBucket &valuesBucket, bool isApi10) +{ + int32_t ret = E_PERMISSION_DENIED; + std::shared_ptr dataShareHelper = nullptr; + OHOS::sptr remote = new OHOS::IRemoteStub(); + if (remote == nullptr) { + LOGE("FileShare::InsertByDatashare get remoteObject failed!"); + return -ENOMEM; + } + + dataShareHelper = OHOS::DataShare::DataShareHelper::Creator(remote->AsObject(), MEDIALIBRARY_DATA_URI); + if (!dataShareHelper) { + LOGE("FileShare::InsertByDatashare connect to datashare failed!"); + return -E_PERMISSION; + } + std::string uriStr = MEDIA_GRANT_URI_PERMISSION; + if (isApi10) { + uriStr += MEDIA_API_VERSION_10; + } + + OHOS::Uri uri(uriStr); + ret = dataShareHelper->Insert(uri, valuesBucket); + if (ret < 0) { + LOGE("FileShare::InsertByDatashare insert failed with error code %{public}d!", ret); + return ret; + } + return ret; +} + +static int32_t GrantInMediaLibrary(const UriPermissionInfo &uriPermInfo, Uri &uri) +{ + bool isApi10 = false; + OHOS::DataShare::DataShareValuesBucket valuesBucket; + int32_t ret = InitValuesBucket(uriPermInfo, uri, isApi10, valuesBucket); + if (ret < 0) { + return ret; + } + + ret = InsertByDatashare(valuesBucket, isApi10); + if (ret < 0) { + return ret; + } + return E_NO_ERROR; +} + +static int32_t DoGrantUriPermission(const UriPermissionInfo &uriPermInfo) +{ + Uri uri(uriPermInfo.uri); + std::string authority = uri.GetAuthority(); + std::string path = uri.GetPath(); + if (authority == MEDIA_AUTHORITY && path.find(".") == std::string::npos) { + return GrantInMediaLibrary(uriPermInfo, uri); + } else { + auto& uriPermissionClient = OHOS::AAFwk::UriPermissionManagerClient::GetInstance(); + int32_t ret = uriPermissionClient.GrantUriPermission(uri, uriPermInfo.flag, + uriPermInfo.bundleName); + if (ret != E_NO_ERROR) { + LOGD("uriPermissionClient.GrantUriPermission by uri permission client failed!"); + return GrantInMediaLibrary(uriPermInfo, uri); + } + } + return E_NO_ERROR; +} + +void GrantUriPermissionSync(taihe::string_view uri, taihe::string_view bundleName, uintptr_t flag) +{ + LOGD("fileShare::GrantUriPermission begin!"); + if (!IsSystemApp()) { + LOGE("fileShare::GrantUriPermission is not System App!"); + taihe::set_business_error(E_PERMISSION_SYS, "fileShare::GrantUriPermission is not System App!"); + } + + std::string uri_ = std::string(uri); + OHOS::Uri inputUri(uri_); + std::string scheme = inputUri.GetScheme(); + if (scheme != FILE_SCHEME) { + return; + } + std::string authority = inputUri.GetAuthority(); + if (authority != MEDIA_AUTHORITY && authority != FILE_MANAGER_AUTHORITY) { + return; + } + + ani_env *env = taihe::get_env(); + ani_enum_item enumItem = reinterpret_cast(flag); + ani_int result; + env->EnumItem_GetValue_Int(enumItem, &result); + + UriPermissionInfo uriPermInfo; + uriPermInfo.uri = uri; + uriPermInfo.bundleName = bundleName; + uriPermInfo.flag = result; + uriPermInfo.mode = GetModeFromFlag((int32_t)result); + + int ret = DoGrantUriPermission(uriPermInfo); + if (ret < 0) { + LOGE("fileShare::GrantUriPermission DoGrantUriPermission failed with %{public}d", ret); + taihe::set_business_error(-ret, "fileShare::GrantUriPermission failed"); + } +} + +taihe::array CheckPathPermissionSync(int32_t tokenID, + taihe::array_view policies, + ohos::fileshare::fileShare::PolicyType policyType) +{ + if (!IsSystemApp()) { + LOGE("fileShare::CheckPathPermissionSync is not System App!"); + taihe::set_business_error(E_PERMISSION_SYS, "fileShare::CheckPathPermissionSync is not System App!"); + return taihe::array::make(0); + } + + int32_t callerTokenId = static_cast(OHOS::IPCSkeleton::GetCallingTokenID()); + if (tokenID != callerTokenId) { + if (!CheckTokenIdPermission(callerTokenId, "ohos.permission.CHECK_SANDBOX_POLICY")) { + taihe::set_business_error(E_PERMISSION, "fileShare::CheckPathPermissionSync checkPermission failed!"); + return taihe::array::make(0); + } + } + + std::vector pathPolicies; + if (GetPathPoliciesArg(policies, pathPolicies)) { + LOGE("Failed to get pathPolicies."); + taihe::set_business_error(E_PARAMS, "Failed to get pathPolicies."); + return taihe::array::make(0); + } + + std::shared_ptr arg = std::make_shared(); + if (arg == nullptr) { + LOGE("PolicyInfoResultArgs make make_shared failed."); + taihe::set_business_error(E_UNKNOWN_ERROR, "PolicyInfoResultArgs make make_shared failed."); + return taihe::array::make(0); + } + + arg->errNo = OHOS::AppFileService::FilePermission::CheckPathPermission(tokenID, + pathPolicies, policyType, arg->resultData); + if (arg->errNo) { + LOGE("Activation failed."); + taihe::set_business_error(arg->errNo, "Activation failed."); + return taihe::array::make(0); + } + taihe::array result(taihe::copy_data_t{}, arg->resultData.begin(), arg->resultData.size()); + return result; +} +} // namespace + +// NOLINTBEGIN +TH_EXPORT_CPP_API_MakePolicyInfo(ANI::FileShare::MakePolicyInfo); +TH_EXPORT_CPP_API_MakePathPolicyInfo(ANI::FileShare::MakePathPolicyInfo); +TH_EXPORT_CPP_API_ActivatePermissionSync(ANI::FileShare::ActivatePermissionSync); +TH_EXPORT_CPP_API_DeactivatePermissionSync(ANI::FileShare::DeactivatePermissionSync); +TH_EXPORT_CPP_API_GrantUriPermissionSync(ANI::FileShare::GrantUriPermissionSync); +TH_EXPORT_CPP_API_CheckPathPermissionSync(ANI::FileShare::CheckPathPermissionSync); + // NOLINTEND diff --git a/interfaces/kits/taihe/fileuri/BUILD.gn b/interfaces/kits/taihe/fileuri/BUILD.gn new file mode 100644 index 000000000..f2f815cf4 --- /dev/null +++ b/interfaces/kits/taihe/fileuri/BUILD.gn @@ -0,0 +1,98 @@ +# Copyright (c) 2025 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. + +import("//build/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") +import("//build/ohos/taihe_idl/taihe.gni") +import("//foundation/filemanagement/app_file_service/app_file_service.gni") + +part_name = "app_file_service" +subsystem_name = "filemanagement" +taihe_generated_file_path = "$taihe_file_path/out/$subsystem_name/$part_name/fileuri" + +copy_taihe_idl("copy_taihe") { + sources = [ "${app_file_service_path}/interfaces/kits/taihe/fileuri/idl/ohos.file.fileuri.taihe" ] +} + +ohos_taihe("run_taihe") { + taihe_generated_file_path = "$taihe_generated_file_path" + deps = [ ":copy_taihe" ] + outputs = [ + "$taihe_generated_file_path/src/ohos.file.fileuri.ani.cpp", + "$taihe_generated_file_path/src/ohos.file.fileuri.abi.c", + ] +} + +taihe_shared_library("file_fileuri_taihe") { + taihe_generated_file_path = "$taihe_generated_file_path" + subsystem_name = "$subsystem_name" + part_name = "$part_name" + + sanitize = { + integer_overflow = true + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } + + include_dirs = [ + "include", + "${app_file_service_path}/interfaces/common/include", + "${app_file_service_path}/interfaces/common/include/log.h", + "${app_file_service_path}/interfaces/innerkits/native/file_uri/include", + "${app_file_service_path}/interfaces/kits/ndk/fileshare/include" + ] + + sources = get_target_outputs(":run_taihe") + sources += [ + "src/ani_constructor.cpp", + "src/fileuri_taihe.cpp" + ] + + deps = [ + ":run_taihe", + "${app_file_service_path}/interfaces/innerkits/native:fileuri_native", + ] + + external_deps = [ + "hilog:libhilog", + "ability_base:zuri", + ] +} + +generate_static_abc("file_fileuri_taihe_abc") { + base_url = "$taihe_generated_file_path" + files = [ "$taihe_generated_file_path/@ohos.file.fileuri.ets" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/file_fileuri_taihe_abc.abc" + dependencies = [ ":run_taihe" ] +} + +ohos_prebuilt_etc("file_fileuri_etc") { + source = "$target_out_dir/file_fileuri_taihe_abc.abc" + module_install_dir = "framework" + part_name = "app_file_service" + subsystem_name = "filemanagement" + deps = [ + ":file_fileuri_taihe_abc", + ] +} + +group("afs_fileuri_taihe") { + deps = [ + ":file_fileuri_taihe", + ":file_fileuri_etc", + ] +} diff --git a/interfaces/kits/taihe/fileuri/idl/ohos.file.fileuri.taihe b/interfaces/kits/taihe/fileuri/idl/ohos.file.fileuri.taihe new file mode 100644 index 000000000..b2c25a848 --- /dev/null +++ b/interfaces/kits/taihe/fileuri/idl/ohos.file.fileuri.taihe @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2025 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. +*/ + +@!namespace("@ohos.file.fileuri", "fileUri") + +@!sts_inject(""" +static { loadLibrary("file_fileuri_taihe.z"); } +""") + +@class +interface FileUri { + @get("name") + getName(): String; +} + +@ctor("FileUri") +function makeFileUri(name: String): FileUri; + +function getUriFromPath(path: String): String; diff --git a/interfaces/kits/taihe/fileuri/include/fileuri_taihe.h b/interfaces/kits/taihe/fileuri/include/fileuri_taihe.h new file mode 100644 index 000000000..a6bc30905 --- /dev/null +++ b/interfaces/kits/taihe/fileuri/include/fileuri_taihe.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 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 INTERFACES_KITS_TAIHE_INCLUDE_FILEURI_TAIHE_H +#define INTERFACES_KITS_TAIHE_INCLUDE_FILEURI_TAIHE_H + +#include +#include "ohos.file.fileuri.proj.hpp" +#include "ohos.file.fileuri.impl.hpp" +#include "taihe/runtime.hpp" +#include "file_uri.h" + +namespace ANI::FileUri { + +class FileUriImpl { +public: + FileUriImpl() = delete; + + FileUriImpl(taihe::string_view name); + + std::string getName(); + +private: + OHOS::Uri uri_; +}; + +ohos::file::fileuri::FileUri makeFileUri(taihe::string_view name); + +std::string getUriFromPath(taihe::string_view path); +} // ANI::FileUri + +#endif // INTERFACES_KITS_TAIHE_INCLUDE_FILEURI_TAIHE_H diff --git a/interfaces/kits/taihe/fileuri/src/ani_constructor.cpp b/interfaces/kits/taihe/fileuri/src/ani_constructor.cpp new file mode 100644 index 000000000..c68f4de4a --- /dev/null +++ b/interfaces/kits/taihe/fileuri/src/ani_constructor.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2025 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 "ohos.file.fileuri.ani.hpp" +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + ani_env *env; + if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) { + return ANI_ERROR; + } + if (ANI_OK != ohos::file::fileuri::ANIRegister(env)) { + std::cerr << "Error from ohos::file::fileuri::ANIRegister" << std::endl; + return ANI_ERROR; + } + *result = ANI_VERSION_1; + return ANI_OK; +} diff --git a/interfaces/kits/taihe/fileuri/src/fileuri_taihe.cpp b/interfaces/kits/taihe/fileuri/src/fileuri_taihe.cpp new file mode 100644 index 000000000..783f8b682 --- /dev/null +++ b/interfaces/kits/taihe/fileuri/src/fileuri_taihe.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2025 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 "fileuri_taihe.h" + +#include "common_func.h" +#include "sandbox_helper.h" + +namespace ANI::FileUri { + +const std::string FILE_SCHEME_PREFIX_TAIHE = "file://"; +const std::string FILE_FILEURI_FAILED = ""; + +FileUriImpl::FileUriImpl(taihe::string_view name) + : uri_((std::string(name.c_str()).find(FILE_SCHEME_PREFIX_TAIHE) == 0) ? std::string(name.c_str()) + : OHOS::AppFileService::CommonFunc::GetUriFromPath(std::string(name.c_str()))) +{ +} + +std::string FileUriImpl::getName() +{ + std::string sandboxPath = OHOS::AppFileService::SandboxHelper::Decode(uri_.GetPath()); + size_t posLast = sandboxPath.find_last_of("/"); + if (posLast == std::string::npos) { + return FILE_FILEURI_FAILED; + } + if (posLast == (sandboxPath.size() - 1)) { + return FILE_FILEURI_FAILED; + } + return sandboxPath.substr(posLast + 1); +} + +ohos::file::fileuri::FileUri makeFileUri(taihe::string_view name) +{ + return taihe::make_holder(name); +} + +std::string getUriFromPath(taihe::string_view path) +{ + const std::string strPath = path.c_str(); + std::string uri = OHOS::AppFileService::CommonFunc::GetUriFromPath(strPath); + return uri; +} +} // namespace ANI::FileUri + +TH_EXPORT_CPP_API_makeFileUri(ANI::FileUri::makeFileUri); +TH_EXPORT_CPP_API_getUriFromPath(ANI::FileUri::getUriFromPath); -- Gitee From 5fb55f241c91fc8e1d6b5b22e748e071c3d806b5 Mon Sep 17 00:00:00 2001 From: BrainL Date: Tue, 8 Jul 2025 21:57:36 +0800 Subject: [PATCH 2/2] modify bundle.son Signed-off-by: BrainL --- bundle.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bundle.json b/bundle.json index a6d9c33f1..48ba56c11 100644 --- a/bundle.json +++ b/bundle.json @@ -75,7 +75,9 @@ "//foundation/filemanagement/app_file_service/interfaces/kits/ani/file_uri:fileuri_ani_package", "//foundation/filemanagement/app_file_service/interfaces/kits/ndk/fileuri/src:ohfileuri", "//foundation/filemanagement/app_file_service/interfaces/kits/ndk/fileshare/src:ohfileshare", - "//foundation/filemanagement/app_file_service/frameworks/native/backup_ext/ani:backup_ext_ani_package" + "//foundation/filemanagement/app_file_service/frameworks/native/backup_ext/ani:backup_ext_ani_package", + "//foundation/filemanagement/app_file_service/interfaces/kits/taihe/fileuri:afs_fileuri_taihe", + "//foundation/filemanagement/app_file_service/interfaces/kits/taihe/fileshare:afs_fileshare_taihe" ], "service_group": [ "//foundation/filemanagement/app_file_service:tgt_backup_extension", -- Gitee