diff --git a/BUILD.gn b/BUILD.gn index e77869cad78404bed23e300c7852cb9f43cb991e..774e8a461c6b2d90026bbf79645ffbce911ec719 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -16,6 +16,7 @@ import("//foundation/filemanagement/dfs_service/distributedfile.gni") group("services_target") { deps = [ + "${services_path}:clouddiskservice_sa_profile", "${services_path}:cloudsyncservice.para", "${services_path}:cloudsyncservice.para.dac", "${services_path}:distributed_file.para", @@ -24,6 +25,8 @@ group("services_target") { "${services_path}/clouddisk_database:clouddisk_database", "${services_path}/cloudfiledaemon:cloudfiledaemon", "${services_path}/cloudsyncservice:cloudsync_sa", + "${services_path}/clouddiskservice:clouddiskservice_sa", + "${services_path}/clouddiskservice/src/seccomp_policy:disk_monitor_seccomp_filter", ] if (dfs_service_feature_enable_dist_file_daemon) { @@ -50,6 +53,11 @@ group("cloud_file_kit_inner_target") { deps = [ "interfaces/inner_api/native/cloud_file_kit_inner:cloudfile_kit" ] } +group("clouddiskservice_kit_inner_target") { + deps = + [ "interfaces/inner_api/native/clouddiskservice_kit_inner:clouddiskservice_kit_inner" ] +} + group("cloudsync_asset_kit_inner_target") { deps = [ "interfaces/inner_api/native/cloudsync_kit_inner:cloudsync_asset_kit_inner", diff --git a/bundle.json b/bundle.json index 5460115ae1514e3d6880351b2c22b9faa0982adb..ec17801c91868d740c4e076f26f7dda837e4e781 100644 --- a/bundle.json +++ b/bundle.json @@ -82,6 +82,7 @@ "fwk_group": [], "service_group": [ "//foundation/filemanagement/dfs_service:services_target", + "//foundation/filemanagement/dfs_service:clouddiskservice_kit_inner_target", "//foundation/filemanagement/dfs_service:cloudsync_kit_inner_target", "//foundation/filemanagement/dfs_service:cloud_daemon_kit_inner_target", "//foundation/filemanagement/dfs_service:cloud_file_kit_inner_target", @@ -108,6 +109,20 @@ "header_base": "//foundation/filemanagement/dfs_service/interfaces/inner_api/native/cloudsync_kit_inner" } }, + { + "name": "//foundation/filemanagement/dfs_service/interfaces/inner_api/native/clouddiskservice_kit_inner:clouddiskservice_kit_inner", + "header": { + "header_files": [ + "cloud_disk_common.h", + "cloud_disk_service_callback.h", + "cloud_disk_service_manager.h", + "cloud_disk_service_task_manager.h", + "i_cloud_disk_service_callback.h", + "svc_death_recipient.h" + ], + "header_base": "//foundation/filemanagement/dfs_service/interfaces/inner_api/native/clouddiskservice_kit_inner" + } + }, { "name": "//foundation/filemanagement/dfs_service/interfaces/inner_api/native/cloudsync_kit_inner:cloudsync_asset_kit_inner", "header": { diff --git a/frameworks/native/clouddiskservice_kit_inner/include/cloud_disk_service_callback_client.h b/frameworks/native/clouddiskservice_kit_inner/include/cloud_disk_service_callback_client.h new file mode 100644 index 0000000000000000000000000000000000000000..75b02c641f82c8f649f776c946c463e329646405 --- /dev/null +++ b/frameworks/native/clouddiskservice_kit_inner/include/cloud_disk_service_callback_client.h @@ -0,0 +1,42 @@ +/* + * 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 OHOS_FILEMGMT_CLOUD_DISK_SERVICE_CALLBACK_CLIENT_H +#define OHOS_FILEMGMT_CLOUD_DISK_SERVICE_CALLBACK_CLIENT_H + +#include "cloud_disk_service_callback.h" +#include "cloud_disk_service_callback_stub.h" +#include "utils_log.h" + +namespace OHOS::FileManagement::CloudDiskService { +class CloudDiskServiceCallbackClient final : public CloudDiskServiceCallbackStub { +public: + explicit CloudDiskServiceCallbackClient(const std::shared_ptr &callback) + :callback_(callback) {} + + int32_t OnChangeData(ChangeData & changeData) override { + if (callback_ == nullptr) { + LOGE("callback_ is nullptr"); + return 0; + } + callback_->OnChangeData(changeData); + return 0; + } +private: + std::shared_ptr callback_{ nullptr }; +}; +} // namespace OHOS::FileManagement::CloudDiskService + +#endif // OHOS_FILEMGMT_CLOUD_DISK_SERVICE_CALLBACK_CLIENT_H \ No newline at end of file diff --git a/frameworks/native/clouddiskservice_kit_inner/include/cloud_disk_service_callback_stub.h b/frameworks/native/clouddiskservice_kit_inner/include/cloud_disk_service_callback_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..452e0013d03f62b894ff031f67ba322bd734e8d0 --- /dev/null +++ b/frameworks/native/clouddiskservice_kit_inner/include/cloud_disk_service_callback_stub.h @@ -0,0 +1,39 @@ +/* +* 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 OHOS_FILEMGMT_CLOUD_DISK_SERVICE_CALLBACK_STUB_H +#define OHOS_FILEMGMT_CLOUD_DISK_SERVICE_CALLBACK_STUB_H + +#include + +#include "i_cloud_disk_service_callback.h" +#include "iremote_stub.h" + +namespace OHOS::FileManagement::CloudDiskService { +using ServiceInterface = std::function; +class CloudDiskServiceCallbackStub : public IRemoteStub { +public: + CloudDiskServiceCallbackStub(); + virtual ~CloudDiskServiceCallbackStub() = default; + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + std::map opToInterfaceMap_; + + int32_t HandleOnChangeData(MessageParcel &data, MessageParcel &reply); +}; +} // namespace OHOS::FileManagement::CloudDiskService + +#endif // OHOS_FILEMGMT_CLOUD_DISK_SERVICE_CALLBACK_STUB_H \ No newline at end of file diff --git a/frameworks/native/clouddiskservice_kit_inner/include/cloud_disk_service_manager_impl.h b/frameworks/native/clouddiskservice_kit_inner/include/cloud_disk_service_manager_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..5a439e935c5ee77dfaa4366c5a0e2bf95e73daa0 --- /dev/null +++ b/frameworks/native/clouddiskservice_kit_inner/include/cloud_disk_service_manager_impl.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 OHOS_FILEMGMT_CLOUD_DISK_SERVICE_MANAGER_IMPL_H +#define OHOS_FILEMGMT_CLOUD_DISK_SERVICE_MANAGER_IMPL_H + +#include + +#include "nocopyable.h" + +#include "cloud_disk_service_manager.h" +#include "cloud_disk_service_callback_client.h" +#include "svc_death_recipient.h" + +namespace OHOS::FileManagement::CloudDiskService { +class CloudDiskServiceManagerImpl final : public CloudDiskServiceManager, public NoCopyable { +public: + static CloudDiskServiceManagerImpl &GetInstance(); + + // int32_t RegisterCallback(const std::shared_ptr callback, + // const std::string &bundleName = "") override; + // int32_t UnRegisterCallback(const std::string &bundleName = "") override; +private: + void SetDeathRecipient(const sptr &remoteObject); + std::shared_ptr callback_; + sptr deathRecipient_; + std::mutex callbackMutex_; + std::atomic_flag isFirstCall_{false}; +}; +} // namespace OHOS::FileManagement::CloudDiskService + +#endif // OHOS_FILEMGMT_CLOUD_DISK_SERVICE_MANAGER_IMPL_H diff --git a/frameworks/native/clouddiskservice_kit_inner/include/service_proxy.h b/frameworks/native/clouddiskservice_kit_inner/include/service_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..9133dffc60f6c080638a164902e7006aa58b2213 --- /dev/null +++ b/frameworks/native/clouddiskservice_kit_inner/include/service_proxy.h @@ -0,0 +1,45 @@ +/* + * 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 OHOS_FILEMGMT_SERVICE_PROXY_H +#define OHOS_FILEMGMT_SERVICE_PROXY_H + +#include "icloud_disk_service.h" +#include "iremote_proxy.h" +#include "system_ability_load_callback_stub.h" + +namespace OHOS::FileManagement::CloudDiskService { +class ServiceProxy : public IRemoteProxy { +public: + static sptr GetInstance(); + static void InvaildInstance(); + + class CloudDiskServiceProxyLoadCallback : public SystemAbilityLoadCallbackStub { + public: + void OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr &remoteObject) override; + void OnLoadSystemAbilityFail(int32_t systemAbilityId) override; + + std::condition_variable proxyConVar_; + std::atomic isLoadSuccess_{false}; + }; + +private: + static inline std::mutex proxyMutex_; + static inline std::mutex instanceMutex_; + static inline sptr serviceProxy_; +}; +} // namespace OHOS::FileManagement::CloudDiskService + +#endif // OHOS_FILEMGMT_SERVICE_PROXY_H diff --git a/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_common.cpp b/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_common.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b67f1df117d1ed90d8cde4f6114706503359a832 --- /dev/null +++ b/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_common.cpp @@ -0,0 +1,57 @@ +/* + * 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 "cloud_disk_common.h" + +#include + +#include "utils_log.h" + +namespace OHOS::FileManagement::CloudDiskService { +namespace { +} + +bool ChangeData::Marshalling(Parcel &parcel) const +{ + if (!parcel.WriteUint64(operationType)) { + LOGE("failed to write operationType"); + return false; + } + + return true; +} + +ChangeData *ChangeData::Unmarshalling(Parcel &parcel) +{ + ChangeData *info = new (std::nothrow) ChangeData(); + if ((info != nullptr) && (!info->ReadFromParcel(parcel))) { + LOGW("read from parcel failed"); + delete info; + info = nullptr; + } + return info; +} + +bool ChangeData::ReadFromParcel(Parcel &parcel) +{ + if (!parcel.WriteUint64(operationType)) { + LOGE("failed to read operationType"); + return false; + } + + return true; +} + +} // namespace OHOS::FileManagement::CloudDiskService diff --git a/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_service_callback_client.cpp b/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_service_callback_client.cpp new file mode 100644 index 0000000000000000000000000000000000000000..148c3423c8391a3a76e7e7b399ac12d9713c9c48 --- /dev/null +++ b/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_service_callback_client.cpp @@ -0,0 +1,19 @@ +/* + * 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 "cloud_disk_service_callback_client.h" + +namespace OHOS::FileManagement::CloudDiskService { +} // namespace OHOS::FileManagement::CloudDiskService diff --git a/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_service_callback_stub.cpp b/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_service_callback_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..251750f768c06418ecd9c764deca2b1e041a9023 --- /dev/null +++ b/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_service_callback_stub.cpp @@ -0,0 +1,58 @@ +/* + * 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 "cloud_disk_service_callback_stub.h" +#include "dfs_error.h" +#include "utils_log.h" + +namespace OHOS::FileManagement::CloudDiskService { +using namespace std; + +CloudDiskServiceCallbackStub::CloudDiskServiceCallbackStub() +{ + opToInterfaceMap_[SERVICE_CMD_ON_PROCESS] = [this](MessageParcel &data, MessageParcel &reply) { + return this->HandleOnChangeData(data, reply); + }; +} + +int32_t CloudDiskServiceCallbackStub::OnRemoteRequest(uint32_t code, + MessageParcel &data, + MessageParcel &reply, + MessageOption &option) +{ + if (data.ReadInterfaceToken() != GetDescriptor()) { + return E_SERVICE_DESCRIPTOR_IS_EMPTY; + } + auto interfaceIndex = opToInterfaceMap_.find(code); + if (interfaceIndex == opToInterfaceMap_.end() || !interfaceIndex->second) { + LOGE("Cannot response request %d: unknown tranction", code); + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + auto memberFunc = interfaceIndex->second; + return memberFunc(data, reply); +} + +int32_t CloudDiskServiceCallbackStub::HandleOnChangeData(MessageParcel &data, MessageParcel &reply) +{ + sptr progress = data.ReadParcelable(); + if (!progress) { + LOGE("object of ChangeData is nullptr"); + return E_INVAL_ARG; + } + OnChangeData(*progress); + LOGI("OnChangeData"); + return E_OK; +} +} // namespace OHOS::FileManagement::CloudDiskService \ No newline at end of file diff --git a/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_service_manager.cpp b/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_service_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..808ff75d89c515e6e61d9ef1859af1b4838ae9f7 --- /dev/null +++ b/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_service_manager.cpp @@ -0,0 +1,24 @@ +/* + * 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 "cloud_disk_service_manager_impl.h" + +namespace OHOS::FileManagement::CloudDiskService { +using namespace std; +CloudDiskServiceManager &CloudDiskServiceManager::GetInstance() +{ + return CloudDiskServiceManagerImpl::GetInstance(); +} +} // namespace OHOS::FileManagement::CloudDiskService \ No newline at end of file diff --git a/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_service_manager_impl.cpp b/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_service_manager_impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4e0e5c66334cf702f051d4c7177197d1d87c8d39 --- /dev/null +++ b/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_service_manager_impl.cpp @@ -0,0 +1,99 @@ +/* + * 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 "cloud_disk_service_manager_impl.h" + +#include "cloud_disk_service_callback_client.h" +#include "dfs_error.h" +#include "iservice_registry.h" +#include "service_proxy.h" +#include "system_ability_definition.h" +#include "utils_directory.h" +#include "utils_log.h" + +namespace OHOS::FileManagement::CloudDiskService { +using namespace std; +CloudDiskServiceManagerImpl &CloudDiskServiceManagerImpl::GetInstance() +{ + static CloudDiskServiceManagerImpl instance; + return instance; +} + +// int32_t CloudDiskServiceImpl::RegisterCallback(const std::shared_ptr callback, +// const std::string &bundleName) +// { +// if (!callback) { +// LOGE("callback is null"); +// return E_INVAL_ARG; +// } +// auto CloudDiskServiceProxy = CloudDiskServiceProxy::GetInstance(); +// if (!CloudDiskServiceProxy) { +// LOGE("proxy is null"); +// return E_SA_LOAD_FAILED; +// } +// auto ret = CloudDiskServiceProxy->RegisterCallbackInner(sptr(new (std::nothrow) CloudSyncCallbackClient(callback)), +// bundleName); +// { +// unique_lock lock(callbackMutex_); +// callback_ = callback; +// } +// SubscribeListener(bundleName); +// SetDeathRecipient(CloudDiskServiceProxy->AsObject()); +// LOGI("RegisterCallback ret %{public}d", ret); +// return ret; +// } + + +// int32_t CloudDiskServiceImpl::UnRegisterCallback(const std::string &bundleName) +// { +// auto CloudDiskServiceProxy = CloudDiskServiceProxy::GetInstance(); +// if (!CloudDiskServiceProxy) { +// LOGE("proxy is null"); +// return E_SA_LOAD_FAILED; +// } + +// auto ret = CloudDiskServiceProxy->UnRegisterCallbackInner(bundleName); +// if (!ret) { +// { +// unique_lock lock(callbackMutex_); +// callback_ = nullptr; +// } +// SubscribeListener(); +// } +// SetDeathRecipient(CloudDiskServiceProxy->AsObject()); +// LOGI("UnRegisterCallback ret %{public}d", ret); +// return ret; +// } + +void CloudDiskServiceManagerImpl::SetDeathRecipient(const sptr &remoteObject) +{ + if (!isFirstCall_.test_and_set()) { + auto deathCallback = [this](const wptr &obj) { + LOGE("service died."); + ServiceProxy::InvaildInstance(); + if (callback_) { + callback_->OnDeathRecipient(); + } + isFirstCall_.clear(); + }; + deathRecipient_ = sptr(new SvcDeathRecipient(deathCallback)); + if (!remoteObject->AddDeathRecipient(deathRecipient_)) { + LOGE("add death recipient failed"); + isFirstCall_.clear(); + } + } +} + +} // namespace OHOS::FileManagement::CloudDiskService diff --git a/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_service_task_manager.cpp b/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_service_task_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c701d1599de58d3c2e1d055d79f4debb9713d95e --- /dev/null +++ b/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_service_task_manager.cpp @@ -0,0 +1,152 @@ +/* + * 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 "cloud_disk_service_task_manager.h" + +#include "iservice_registry.h" +#include "mem_mgr_client.h" +#include "parameters.h" +#include "system_ability_definition.h" +#include "utils_log.h" + +namespace OHOS { +namespace FileManagement { +namespace CloudDiskService { +using namespace std; + +const int32_t DELAY_TIME = 90000; // ms +const int32_t SYSTEM_LOAD_DELAY_TIME = 600000; // ms + +CloudDiskServiceTaskManager &CloudDiskServiceTaskManager::GetInstance() +{ + static CloudDiskServiceTaskManager instance; + return instance; +} + +CloudDiskServiceTaskManager::CloudDiskServiceTaskManager() : queue_("unloadTask") +{ +} + +void CloudDiskServiceTaskManager::StartTask(TaskKey key, TaskType task) +{ + CancelUnloadTask(); + std::lock_guard lock(taskMapsMutex_); + if (criticalStatus_ == false) { + int32_t ret = Memory::MemMgrClient::GetInstance().SetCritical(getpid(), + true, FILEMANAGEMENT_CLOUD_DISK_SERVICE_SA_ID); + if (ret == ERR_OK) { + criticalStatus_ = true; + } + } + auto iterator = taskMaps_.find(key); + if (iterator == taskMaps_.end()) { + taskMaps_[key] = static_cast(task); + return; + } + auto taskState = iterator->second | static_cast(task); + taskMaps_[key] = taskState; +} + +void CloudDiskServiceTaskManager::CompleteTask(TaskKey key, TaskType task) +{ + std::lock_guard lock(taskMapsMutex_); + auto iterator = taskMaps_.find(key); + if (iterator == taskMaps_.end()) { + LOGE("task is not started"); + } else { + taskMaps_[key] = iterator->second & ~static_cast(task); + if (taskMaps_[key] == 0) { + LOGI("start erase"); + taskMaps_.erase(key); + } + } + if (taskMaps_.empty()) { + DelayUnloadTask(true); + } +} + +void CloudDiskServiceTaskManager::StartTask() +{ + std::lock_guard lock(taskMapsMutex_); + if (taskMaps_.empty()) { + DelayUnloadTask(false); + } +} + +bool CloudDiskServiceTaskManager::HasTask(TaskKey key, TaskType task) +{ + std::lock_guard lock(taskMapsMutex_); + auto iterator = taskMaps_.find(key); + if (iterator != taskMaps_.end()) { + if (taskMaps_[key] & static_cast(task)) { + return true; + } + } + return false; +} + + +void CloudDiskServiceTaskManager::CancelUnloadTask() +{ + std::lock_guard lock(unloadTaskMutex_); + if (unloadTaskHandle_ == nullptr) { + return; + } + LOGD("cancel unload task"); + queue_.cancel(unloadTaskHandle_); + unloadTaskHandle_ = nullptr; +} + +void CloudDiskServiceTaskManager::DelayUnloadTask(bool needSetCritical) +{ + LOGI("delay unload task begin"); + auto delayTime = DELAY_TIME; + + if (needSetCritical == true && criticalStatus_ == true) { + int32_t ret = Memory::MemMgrClient::GetInstance().SetCritical(getpid(), + false, FILEMANAGEMENT_CLOUD_DISK_SERVICE_SA_ID); + if (ret == ERR_OK) { + criticalStatus_ = false; + } + } + auto task = [this]() { + LOGI("do unload task"); + { + std::lock_guard lock(unloadTaskMutex_); + unloadTaskHandle_ = nullptr; + } + + auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgrProxy == nullptr) { + LOGE("get samgr failed"); + return; + } + // system::SetParameter(CLOUD_FILE_SERVICE_SA_STATUS_FLAG, CLOUD_FILE_SERVICE_SA_END); + int32_t ret = samgrProxy->UnloadSystemAbility(FILEMANAGEMENT_CLOUD_DISK_SERVICE_SA_ID); + if (ret != ERR_OK) { + LOGE("remove system ability failed"); + return; + } + }; + + CancelUnloadTask(); + std::lock_guard lock(unloadTaskMutex_); + std::chrono::milliseconds ms(delayTime); + auto us = std::chrono::duration_cast(ms); + unloadTaskHandle_ = queue_.submit_h(task, ffrt::task_attr().delay(us.count())); +} +} // namespace CloudDiskService +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/clouddiskservice_kit_inner/src/service_proxy.cpp b/frameworks/native/clouddiskservice_kit_inner/src/service_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ec8cdf45405beaa4a7a933755029968619f26f8f --- /dev/null +++ b/frameworks/native/clouddiskservice_kit_inner/src/service_proxy.cpp @@ -0,0 +1,101 @@ +/* + * 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 "service_proxy.h" + +#include + +#include "cloud_disk_service_proxy.h" +#include "dfs_error.h" +#include "iservice_registry.h" +#include "system_ability_definition.h" +#include "utils_log.h" + +namespace OHOS::FileManagement::CloudDiskService { +using namespace std; + +constexpr int LOAD_SA_TIMEOUT_MS = 2000; + +sptr ServiceProxy::GetInstance() +{ + LOGD("getinstance"); + unique_lock lock(instanceMutex_); + if (serviceProxy_ != nullptr) { + if (serviceProxy_->AsObject() != nullptr && !serviceProxy_->AsObject()->IsObjectDead()) { + return serviceProxy_; + } + } + + auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgr == nullptr) { + LOGE("Samgr is nullptr"); + return nullptr; + } + + sptr cloudDiskServiceLoadCallback = new CloudDiskServiceProxyLoadCallback(); + if (cloudDiskServiceLoadCallback == nullptr) { + LOGE("cloudDiskServiceLoadCallback is nullptr"); + return nullptr; + } + + int32_t ret = samgr->LoadSystemAbility(FILEMANAGEMENT_CLOUD_DISK_SERVICE_SA_ID, cloudDiskServiceLoadCallback); + if (ret != E_OK) { + LOGE("Failed to Load systemAbility, systemAbilityId:%{public}d, ret code:%{public}d", + FILEMANAGEMENT_CLOUD_DISK_SERVICE_SA_ID, ret); + return nullptr; + } + + unique_lock proxyLock(proxyMutex_); + auto waitStatus = cloudDiskServiceLoadCallback->proxyConVar_.wait_for( + proxyLock, std::chrono::milliseconds(LOAD_SA_TIMEOUT_MS), + [cloudDiskServiceLoadCallback]() { return cloudDiskServiceLoadCallback->isLoadSuccess_.load(); }); + if (!waitStatus) { + LOGE("Load CloudDiskService SA timeout"); + return nullptr; + } + return serviceProxy_; +} + +void ServiceProxy::InvaildInstance() +{ + LOGI("invalid instance"); + unique_lock lock(instanceMutex_); + serviceProxy_ = nullptr; +} + +void ServiceProxy::CloudDiskServiceProxyLoadCallback::OnLoadSystemAbilitySuccess( + int32_t systemAbilityId, + const sptr &remoteObject) +{ + LOGI("Load CloudSync SA success,systemAbilityId:%{public}d, remoteObj result:%{private}s", systemAbilityId, + (remoteObject == nullptr ? "false" : "true")); + unique_lock lock(proxyMutex_); + if (serviceProxy_ != nullptr) { + LOGE("CloudDiskService SA proxy has been loaded"); + } else { + serviceProxy_ = iface_cast(remoteObject); + } + isLoadSuccess_.store(true); + proxyConVar_.notify_one(); +} + +void ServiceProxy::CloudDiskServiceProxyLoadCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId) +{ + LOGI("Load CloudDiskService SA failed,systemAbilityId:%{public}d", systemAbilityId); + unique_lock lock(proxyMutex_); + serviceProxy_ = nullptr; + isLoadSuccess_.store(false); + proxyConVar_.notify_one(); +} +} // namespace OHOS::FileManagement::CloudDiskService diff --git a/interfaces/inner_api/native/clouddiskservice_kit_inner/BUILD.gn b/interfaces/inner_api/native/clouddiskservice_kit_inner/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..083c2101dadaeeb3e5f463ca02eb33800121618c --- /dev/null +++ b/interfaces/inner_api/native/clouddiskservice_kit_inner/BUILD.gn @@ -0,0 +1,99 @@ +# 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/ohos.gni") +import("//foundation/filemanagement/dfs_service/distributedfile.gni") + +config("public_config") { + include_dirs = [ + ".", + "${distributedfile_path}/interfaces/inner_api/native/clouddiskservice_kit_inner", + ] +} + +config("private_config") { + include_dirs = [ + "${distributedfile_path}/frameworks/native/clouddiskservice_kit_inner/include", + "${distributedfile_path}/interfaces/inner_api/native/clouddiskservice_kit_inner", + "${distributedfile_path}/utils/log/include", + ] +} + +config("optimize-size") { + cflags = [ + "-fdata-sections", + "-ffunction-sections", + "-Oz", + ] + cflags_cc = [ + "-fvisibility-inlines-hidden", + "-Oz", + ] +} + +ohos_shared_library("clouddiskservice_kit_inner") { + branch_protector_ret = "pac_ret" + configs = [ ":optimize-size" ] + sanitize = { + integer_overflow = true + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } + sources = [ + "${distributedfile_path}/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_common.cpp", + "${distributedfile_path}/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_service_callback_stub.cpp", + "${distributedfile_path}/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_service_manager.cpp", + "${distributedfile_path}/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_service_manager_impl.cpp", + "${distributedfile_path}/frameworks/native/clouddiskservice_kit_inner/src/cloud_disk_service_task_manager.cpp", + "${distributedfile_path}/frameworks/native/clouddiskservice_kit_inner/src/service_proxy.cpp", + "${distributedfile_path}/utils/log/src/utils_log.cpp", + ] + + defines = [ + "LOG_DOMAIN=0xD004309", + "LOG_TAG=\"CLOUDDISKSERVICE_API\"", + ] + + configs += [ ":private_config" ] + public_configs = [ + ":public_config", + "${services_path}/clouddiskservice:cloud_disk_service_public_config", + ] + + external_deps = [ + "ability_base:zuri", + "ability_runtime:ability_manager", + "ability_runtime:dataobs_manager", + "c_utils:utils", + "ffrt:libffrt", + "hilog:libhilog", + "ipc:ipc_single", + "memmgr:memmgrclient", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] + + deps = [ + "${services_path}/clouddiskservice:libcloud_disk_service_proxy", + "${utils_path}:libdistributedfiledentry", + "${utils_path}:libdistributedfileutils", + ] + + use_exceptions = true + part_name = "dfs_service" + subsystem_name = "filemanagement" +} + diff --git a/interfaces/inner_api/native/clouddiskservice_kit_inner/cloud_disk_common.h b/interfaces/inner_api/native/clouddiskservice_kit_inner/cloud_disk_common.h new file mode 100644 index 0000000000000000000000000000000000000000..8931f98b6d53b6f345cbe3b401e44cc4a2850718 --- /dev/null +++ b/interfaces/inner_api/native/clouddiskservice_kit_inner/cloud_disk_common.h @@ -0,0 +1,39 @@ +/* + * 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 OHOS_FILEMGMT_CLOUD_DISK_COMMON_H +#define OHOS_FILEMGMT_CLOUD_DISK_COMMON_H + +#include +#include + +#include "parcel.h" + +namespace OHOS::FileManagement::CloudDiskService { + +struct ChangeData : public Parcelable { + // uint8_t ecordid[33]{0}; + uint32_t operationType{0}; + // std::string relative_path; + // std::string syncRootIndex; + // struct fileAttributes; + // uint64_t timestamp; + bool ReadFromParcel(Parcel &parcel); + bool Marshalling(Parcel &parcel) const override; + static ChangeData *Unmarshalling(Parcel &parcel); +}; + +} // namespace OHOS::FileManagement::CloudDiskService +#endif // OHOS_FILEMGMT_CLOUD_DISK_COMMON_H diff --git a/interfaces/inner_api/native/clouddiskservice_kit_inner/cloud_disk_service_callback.h b/interfaces/inner_api/native/clouddiskservice_kit_inner/cloud_disk_service_callback.h new file mode 100644 index 0000000000000000000000000000000000000000..84c107d35caf33d36dab5ac58ab2da3e7ea0de90 --- /dev/null +++ b/interfaces/inner_api/native/clouddiskservice_kit_inner/cloud_disk_service_callback.h @@ -0,0 +1,30 @@ +/* + * 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 OHOS_FILEMGMT_CLOUD_DISK_SERVICE_CALLBACK_H +#define OHOS_FILEMGMT_CLOUD_DISK_SERVICE_CALLBACK_H + +#include "cloud_disk_common.h" + +namespace OHOS::FileManagement::CloudDiskService { +class CloudDiskServiceCallback { +public: + virtual ~CloudDiskServiceCallback() = default; + virtual int32_t OnChangeData(ChangeData &changeData) = 0; + virtual void OnDeathRecipient() {}; +}; +} // namespace OHOS::FileManagement::CloudDiskService + +#endif // OHOS_FILEMGMT_CLOUD_DISK_SERVICE_CALLBACK_H \ No newline at end of file diff --git a/interfaces/inner_api/native/clouddiskservice_kit_inner/cloud_disk_service_manager.h b/interfaces/inner_api/native/clouddiskservice_kit_inner/cloud_disk_service_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..1ef8766a8e68a0dbcf4cd78339238dd170488c44 --- /dev/null +++ b/interfaces/inner_api/native/clouddiskservice_kit_inner/cloud_disk_service_manager.h @@ -0,0 +1,45 @@ +/* + * 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 OHOS_FILEMGMT_CLOUD_DISK_SERVICE_MANAGER_H +#define OHOS_FILEMGMT_CLOUD_DISK_SERVICE_MANAGER_H + +#include + +#include "cloud_disk_service_callback.h" + +namespace OHOS::FileManagement::CloudDiskService { +class CloudDiskServiceManager { +public: + static CloudDiskServiceManager &GetInstance(); + // /** + // * @brief 注册 + // * + // * @param callback 注册同步回调 + // * @return int32_t 同步返回执行结果 + // */ + // virtual int32_t RegisterCallback(const std::shared_ptr callback, + // const std::string &bundleName = "") = 0; + // /** + // * @brief 注册 + // * + // * @param callback 卸载同步回调 + // * @return int32_t 返回执行结果 + // */ + // virtual int32_t UnRegisterCallback(const std::string &bundleName = "") = 0; +}; +} // namespace OHOS::FileManagement::CloudDiskService + +#endif // OHOS_FILEMGMT_CLOUD_DISK_SERVICE_MANAGER_H diff --git a/interfaces/inner_api/native/clouddiskservice_kit_inner/cloud_disk_service_task_manager.h b/interfaces/inner_api/native/clouddiskservice_kit_inner/cloud_disk_service_task_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..b65c3e84127538f20fc0b7c8a5e054a4e56b1c56 --- /dev/null +++ b/interfaces/inner_api/native/clouddiskservice_kit_inner/cloud_disk_service_task_manager.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 OHOS_FILEMGMT_CLOUD_DISK_SERVICE_TASK_MANAGER_H +#define OHOS_FILEMGMT_CLOUD_DISK_SERVICE_TASK_MANAGER_H + +#include +#include +#include "ffrt_inner.h" + +namespace OHOS::FileManagement::CloudDiskService { +// static const std::string CLOUD_FILE_SERVICE_SA_STATUS_FLAG = "persist.kernel.medialibrarydata.stopflag"; +// static const std::string CLOUD_FILE_SERVICE_SA_START = "0"; +// static const std::string CLOUD_FILE_SERVICE_SA_END = "1"; +enum class TaskType : uint64_t { + REGISTER_TASK = 1, + UNREGISTER_TASK = 1 << 1, + GET_TASK = 1 << 2, +}; + +struct TaskKey { + std::string bundleName; + std::string syncChronousRootPath; + + bool operator ==(const TaskKey& other) const { + return bundleName == other.bundleName && + syncChronousRootPath == other.syncChronousRootPath; + } + + struct Hash { + size_t operator()(const TaskKey& key) const { + auto hasher = std::hash(); + return hasher(key.bundleName) ^ (hasher(key.syncChronousRootPath) << 1); + } + }; +}; + +class CloudDiskServiceTaskManager : public NoCopyable { +public: + static CloudDiskServiceTaskManager &GetInstance(); + ~CloudDiskServiceTaskManager() = default; + void StartTask(TaskKey key, TaskType task); + void CompleteTask(TaskKey key, TaskType task); + bool HasTask(TaskKey key, TaskType task); + void StartTask(); +private: + CloudDiskServiceTaskManager(); + void DelayUnloadTask(bool needSetCritical); + void CancelUnloadTask(); + + bool criticalStatus_ = true; + std::mutex taskMapsMutex_; + std::unordered_map taskMaps_; + ffrt::queue queue_; + ffrt::task_handle unloadTaskHandle_; + ffrt::mutex unloadTaskMutex_; +}; +} // namespace OHOS::FileManagement::CloudDiskService +#endif // OHOS_FILEMGMT_CLOUD_DISK_SERVICE_TASK_MANAGER_H \ No newline at end of file diff --git a/interfaces/inner_api/native/clouddiskservice_kit_inner/i_cloud_disk_service_callback.h b/interfaces/inner_api/native/clouddiskservice_kit_inner/i_cloud_disk_service_callback.h new file mode 100644 index 0000000000000000000000000000000000000000..ef88b6e6024a055cca3cddfb905b5f6bd21a0a39 --- /dev/null +++ b/interfaces/inner_api/native/clouddiskservice_kit_inner/i_cloud_disk_service_callback.h @@ -0,0 +1,33 @@ +/* + * 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 OHOS_FILEMGMT_I_CLOUD_DISK_SERVICE_CALLBACK_H +#define OHOS_FILEMGMT_I_CLOUD_DISK_SERVICE_CALLBACK_H + +#include "iremote_broker.h" +#include "cloud_disk_service_callback.h" + +namespace OHOS::FileManagement::CloudDiskService { +class ICloudDiskServiceCallback : public CloudDiskServiceCallback, public IRemoteBroker { +public: + enum { + SERVICE_CMD_ON_PROCESS = 0, + }; + + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.Filemanagement.Dfs.ICloudDiskServiceCallback") +}; +} // namespace OHOS::FileManagement::CloudDiskService + +#endif // OHOS_FILEMGMT_I_CLOUD_DISK_SERVICE_CALLBACK_H \ No newline at end of file diff --git a/interfaces/inner_api/native/clouddiskservice_kit_inner/svc_death_recipient.h b/interfaces/inner_api/native/clouddiskservice_kit_inner/svc_death_recipient.h new file mode 100644 index 0000000000000000000000000000000000000000..bd5b79a3fb85de81c0f4ebb10a6d4b77d32d9f29 --- /dev/null +++ b/interfaces/inner_api/native/clouddiskservice_kit_inner/svc_death_recipient.h @@ -0,0 +1,41 @@ +/* + * 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 OHOS_FILEMGMT_SVC_DEATH_RECIPIENT_H +#define OHOS_FILEMGMT_SVC_DEATH_RECIPIENT_H + +#include + +#include "iremote_object.h" + +namespace OHOS::FileManagement::CloudDiskService { +class SvcDeathRecipient : public IRemoteObject::DeathRecipient { +public: + explicit SvcDeathRecipient(std::function &)> functor) : functor_(functor){}; + void OnRemoteDied(const wptr &object) override + { + if (object == nullptr) { + return; + } + object->RemoveDeathRecipient(this); + functor_(object); + } + +private: + std::function &)> functor_; +}; +} // namespace OHOS::FileManagement::CloudDiskService + +#endif // OHOS_FILEMGMT_SVC_DEATH_RECIPIENT_H \ No newline at end of file diff --git a/services/5207.json b/services/5207.json new file mode 100644 index 0000000000000000000000000000000000000000..ecd254f9bf8f4f36981da1f7dc910bdebd257f95 --- /dev/null +++ b/services/5207.json @@ -0,0 +1,19 @@ +{ + "process": "clouddiskservice", + "systemability": [ + { + "name": 5207, + "libpath": "libclouddiskservice_sa.z.so", + "run-on-create": false, + "distributed": false, + "dump-level": 1, + "start-on-demand": { + "commonevent": [ + { + "name": "usual.event.SCREEN_OFF" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/services/BUILD.gn b/services/BUILD.gn index 0eec280de075da48f950ae818cfb7345b8d178d0..f3b113a9cbc4258f582d942b225f9a6a9157b430 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -25,6 +25,11 @@ ohos_sa_profile("distributedfile_sa_profile") { part_name = "dfs_service" } +ohos_sa_profile("clouddiskservice_sa_profile") { + sources = [ "5207.json" ] + part_name = "dfs_service" +} + ohos_prebuilt_etc("distributedfile_etc") { source = "distributedfile.cfg" relative_install_dir = "init" diff --git a/services/clouddiskservice/BUILD.gn b/services/clouddiskservice/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..02ebd89216e5365e1e22d304b425c89cda961844 --- /dev/null +++ b/services/clouddiskservice/BUILD.gn @@ -0,0 +1,130 @@ +# 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/idl_tool/idl.gni") +import("//build/ohos.gni") +import("//foundation/filemanagement/dfs_service/distributedfile.gni") + +config("optimize-size") { + cflags = [ + "-fdata-sections", + "-ffunction-sections", + "-Oz", + ] + cflags_cc = [ + "-fvisibility-inlines-hidden", + "-Oz", + ] +} + +config("cloud_disk_service_public_config") { + include_dirs = [ "${target_gen_dir}" ] +} + +idl_gen_interface("cloud_disk_service") { + sources = [ "ICloudDiskService.idl" ] + sources_cpp = [] + sub_include = [ + "${innerkits_native_path}/clouddiskservice_kit_inner", + ] + configs = [] + innerapi_tags = [ "platformsdk" ] + sanitize = { + integer_overflow = true + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } + + log_domainid = "0xD003900" + log_tag = "CloudDiskService" + subsystem_name = "filemanagement" + part_name = "dfs_service" +} + +ohos_shared_library("clouddiskservice_sa") { + branch_protector_ret = "pac_ret" + configs = [ ":optimize-size" ] + public_configs = [ ":cloud_disk_service_public_config" ] + sanitize = { + integer_overflow = true + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } + include_dirs = [ + "include", + "include/ipc", + "include/monitor", + "${innerkits_native_path}/clouddiskservice_kit_inner", + ] + + sources = [ + "src/ipc/cloud_disk_service.cpp", + "src/ipc/cloud_disk_service_callback_manager.cpp", + "src/ipc/cloud_disk_service_callback_proxy.cpp", + "src/monitor/disk_monitor.cpp", + "src/monitor/disk_notifier.cpp", + "${distributedfile_path}/utils/log/src/utils_log.cpp", + ] + + output_values = get_target_outputs(":cloud_disk_service") + sources += filter_include(output_values, [ "*_stub.cpp" ]) + + defines = [ + "LOG_DOMAIN=0xD004308", + "LOG_TAG=\"CLOUDDISKSERVICE_SA\"", + ] + + deps = [ + ":cloud_disk_service", + ":libcloud_disk_service_proxy", + "${innerkits_native_path}/clouddiskservice_kit_inner:clouddiskservice_kit_inner", + "${utils_path}:libdistributedfiledentry", + "${utils_path}:libdistributedfileutils", + ] + + if (build_seccomp) { + deps += [ "${services_path}/clouddiskservice/src/seccomp_policy:disk_monitor_seccomp_filter" ] + } + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_manager", + "app_file_service:sandbox_helper_native", + "c_utils:utils", + "common_event_service:cesfwk_innerkits", + "dsoftbus:softbus_client", + "ffrt:libffrt", + "hilog:libhilog", + "hitrace:hitrace_meter", + "init:libbegetutil", + "ipc:ipc_single", + "libfuse:libfuse", + "memmgr:memmgrclient", + "netmanager_base:net_conn_manager_if", + "os_account:os_account_innerkits", + "preferences:native_preferences", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] + + use_exceptions = true + part_name = "dfs_service" + subsystem_name = "filemanagement" +} diff --git a/services/clouddiskservice/ICloudDiskService.idl b/services/clouddiskservice/ICloudDiskService.idl new file mode 100644 index 0000000000000000000000000000000000000000..5f3d97c91f7da39314e01ba0b2f1de000887663c --- /dev/null +++ b/services/clouddiskservice/ICloudDiskService.idl @@ -0,0 +1,19 @@ +/* + * 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. + */ +sequenceable OHOS.IRemoteObject; + +interface OHOS.FileManagement.CloudDiskService.ICloudDiskService +{ +} \ No newline at end of file diff --git a/services/clouddiskservice/include/ipc/cloud_disk_service.h b/services/clouddiskservice/include/ipc/cloud_disk_service.h new file mode 100644 index 0000000000000000000000000000000000000000..d13a2d1537da7a573a633f3649756352535c7f7b --- /dev/null +++ b/services/clouddiskservice/include/ipc/cloud_disk_service.h @@ -0,0 +1,61 @@ +/* + * 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 CLOUD_DISK_SERVICE_H +#define CLOUD_DISK_SERVICE_H + +#include +#include +#include + +#include "iremote_stub.h" +#include "nocopyable.h" +#include "refbase.h" +#include "system_ability.h" + +#include "cloud_disk_service_stub.h" +#include "icloud_disk_service.h" + +namespace OHOS { +namespace FileManagement { +namespace CloudDiskService { +enum class ServiceRunningState { STATE_NOT_START, STATE_RUNNING }; + +class CloudDiskService final : public SystemAbility, public CloudDiskServiceStub, protected NoCopyable { + DECLARE_SYSTEM_ABILITY(CloudDiskService); + +public: + explicit CloudDiskService(int32_t saID, bool runOnCreate = true); + virtual ~CloudDiskService() = default; + + void OnStart() override; + void OnStop() override; + ServiceRunningState QueryServiceState() const + { + return state_; + } + +private: + CloudDiskService(); + ServiceRunningState state_ { ServiceRunningState::STATE_NOT_START }; + static sptr instance_; + static std::mutex instanceLock_; + bool registerToService_ { false }; + void PublishSA(); +}; +} // namespace CloudDiskService +} // namespace FileManagement +} // namespace OHOS +#endif // CLOUD_DISK_SERVICE_H diff --git a/services/clouddiskservice/include/ipc/cloud_disk_service_callback_manager.h b/services/clouddiskservice/include/ipc/cloud_disk_service_callback_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..3e2d47f91679717262f2222de4b2f3a912ec8bb3 --- /dev/null +++ b/services/clouddiskservice/include/ipc/cloud_disk_service_callback_manager.h @@ -0,0 +1,37 @@ +/* + * 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 OHOS_FILEMGMT_CLOUD_DISK_SERVICE_CALLBACK_MANAGER_H +#define OHOS_FILEMGMT_CLOUD_DISK_SERVICE_CALLBACK_MANAGER_H + +#include "nocopyable.h" + +#include "i_cloud_disk_service_callback.h" +#include "svc_death_recipient.h" + +namespace OHOS::FileManagement::CloudDiskService { +class CloudDiskServiceCallbackManager final : public NoCopyable { +public: + using TaskId = uint64_t; + static CloudDiskServiceCallbackManager &GetInstance(); + void AddCallback(const sptr &callback); + +private: + sptr callbackProxy_; + sptr deathRecipient_; +}; +} // namespace OHOS::FileManagement::CloudDiskService + +#endif // OHOS_FILEMGMT_CLOUD_DISK_SERVICE_CALLBACK_MANAGER_H \ No newline at end of file diff --git a/services/clouddiskservice/include/ipc/cloud_disk_service_callback_proxy.h b/services/clouddiskservice/include/ipc/cloud_disk_service_callback_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..a9b2c0226bad5bc3014c5b0333572d4f58202657 --- /dev/null +++ b/services/clouddiskservice/include/ipc/cloud_disk_service_callback_proxy.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 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 OHOS_FILEMGMT_CLOUD_DISK_SERVICE_CALLBACK_PROXY_H +#define OHOS_FILEMGMT_CLOUD_DISK_SERVICE_CALLBACK_PROXY_H + +#include "iremote_proxy.h" + +#include "i_cloud_disk_service_callback.h" + +namespace OHOS::FileManagement::CloudDiskService { +class CloudDiskServiceCallbackProxy : public IRemoteProxy { +public: + explicit CloudDiskServiceCallbackProxy(const sptr &impl) : IRemoteProxy(impl) {} + ~CloudDiskServiceCallbackProxy() override {} + + int32_t OnChangeData(ChangeData &changeData) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace OHOS::FileManagement::CloudDiskService + +#endif // OHOS_FILEMGMT_CLOUD_DISK_SERVICE_CALLBACK_PROXY_H \ No newline at end of file diff --git a/services/clouddiskservice/include/monitor/disk_monitor.h b/services/clouddiskservice/include/monitor/disk_monitor.h new file mode 100644 index 0000000000000000000000000000000000000000..a5a5ecffcd782b2806714d87f086e97da3a5d82d --- /dev/null +++ b/services/clouddiskservice/include/monitor/disk_monitor.h @@ -0,0 +1,66 @@ +/* + * 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 OHOS_FILEMANAGEMENT_DISK_MONITOR_H +#define OHOS_FILEMANAGEMENT_DISK_MONITOR_H + +#include +#include +#include +#include + +#include "disk_types.h" + +namespace OHOS::FileManagement::CloudDiskService { +class DiskMonitor { +public: + static DiskMonitor &GetInstance(); + bool Init(); + +private: + bool InitFanotify(); + void CollectEvents(); + void HandleEvents(int32_t mountFd, char eventsBuf[], size_t dataLen); + void EventProcess(struct fanotify_event_metadata *metaData, const std::string &filePath); + void HandleCreate(const std::string &filePath); + void HandleDelete(const std::string &filePath); + void HandleMoveFrom(const std::string &filePath); + void HandleMoveTo(const std::string &filePath); + void HandleCloseWrite(const std::string &filePath); + // 1. events handle + bool ExtractFileName(int type, std::string &fileName, struct file_handle *fileHandle); + std::string GetFilePath(int32_t eventFd, const std::string &fileName); + int32_t GetSyncRootIndex(const std::string &filePath); + // 2. utils + // closeFd + // closeDir + std::string FolderAddSlash(bool isDir, const std::string &path); + bool IsInSyncRoots(const std::string &path); + bool IsInBlackList(const std::string &path); + // debug + void PrintEventInfo(EventInfo info); + +private: + // watcher status + int32_t userId_{-1}; + int32_t fanotifyFd_{-1}; + int32_t mountFd_{-1}; + DIR *mountFp_{nullptr}; + bool isRunning_{true}; + // event handle + EventInfo oldEventInfo_; +}; +} // namespace OHOS::FileManagement::CloudDiskService +#endif diff --git a/services/clouddiskservice/include/monitor/disk_notifier.h b/services/clouddiskservice/include/monitor/disk_notifier.h new file mode 100644 index 0000000000000000000000000000000000000000..f27ac784b510a16d74217edb6ee31674ba44c85d --- /dev/null +++ b/services/clouddiskservice/include/monitor/disk_notifier.h @@ -0,0 +1,39 @@ +/* + * 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 OHOS_FILEMANAGEMENT_DISK_NOTIFIER_H +#define OHOS_FILEMANAGEMENT_DISK_NOTIFIER_H + +#include +#include + +#include "disk_types.h" +#include "ffrt_inner.h" + +namespace OHOS::FileManagement::CloudDiskService { +class DiskNotifier { +public: + static DiskNotifier &GetInstance(); + void PostEvent(EventInfo eventInfo); + +private: + void NotifyAllEvent(); + static void CallBack(void *data); +private: + std::vector eventList_; + ffrt_timer_t handle_{-1}; + ffrt::mutex mutex_; +}; +} // namespace OHOS::FileManagement::CloudDiskService +#endif \ No newline at end of file diff --git a/services/clouddiskservice/include/monitor/disk_types.h b/services/clouddiskservice/include/monitor/disk_types.h new file mode 100644 index 0000000000000000000000000000000000000000..ec3a1e90ffef18fceaba3f6d79d651919b61a6bc --- /dev/null +++ b/services/clouddiskservice/include/monitor/disk_types.h @@ -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. + */ + +#ifndef OHOS_FILEMANAGEMENT_DISK_TYPES_H +#define OHOS_FILEMANAGEMENT_DISK_TYPES_H +#include +#include +#include + +namespace OHOS::FileManagement::CloudDiskService { +constexpr int64_t SECOND_TO_MILLISECOND = 1e3; +constexpr int64_t MILLISECOND_TO_NANOSECOND = 1e6; +enum class OperationType : uint8_t { + NONE = 0, + CREATE, + DELETE, + MOVE_FROM, + MOVE_TO, + ATTR_CHANGE, + CLOSE_WRITE, +}; + +static uint64_t UTCTimeMilliSeconds() +{ + struct timespec t; + clock_gettime(CLOCK_REALTIME, &t); + return t.tv_sec * SECOND_TO_MILLISECOND + t.tv_nsec / MILLISECOND_TO_NANOSECOND; +} + +struct EventInfo { + int32_t userId{-1}; + int32_t syncRootIndex{-1}; + std::string path{""}; + std::string name{""}; + uint8_t operateType{static_cast(OperationType::NONE)}; + uint64_t timestamp{0}; + EventInfo() {} + EventInfo(int32_t uid, int32_t syncRoot, OperationType type, const std::string &filePath) + : userId(uid), syncRootIndex(syncRoot), operateType(static_cast(type)) + { + path = std::filesystem::path(filePath).parent_path().string(); + name = std::filesystem::path(filePath).filename().string(); + timestamp = UTCTimeMilliSeconds(); + } + + void Reset() + { + userId = -1; + syncRootIndex = -1; + path = ""; + name = ""; + operateType = static_cast(OperationType::NONE); + timestamp = 0; + } +}; +} // namespace OHOS::FileManagement::CloudDiskService +#endif \ No newline at end of file diff --git a/services/clouddiskservice/src/ipc/cloud_disk_service.cpp b/services/clouddiskservice/src/ipc/cloud_disk_service.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2ab678288f4f096af4440d67ee3eecfb8341ff69 --- /dev/null +++ b/services/clouddiskservice/src/ipc/cloud_disk_service.cpp @@ -0,0 +1,97 @@ +/* + * 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 "cloud_disk_service.h" + +#include +#include +#include +#include +#include +#include + +#include "cloud_disk_service_callback_manager.h" +#include "cloud_disk_service_task_manager.h" +#include "cloud_disk_service_callback_proxy.h" +#include "dfs_error.h" +#include "disk_monitor.h" +#include "ffrt_inner.h" +#include "iremote_object.h" +#include "parameters.h" +#include "system_ability_definition.h" +#include "utils_directory.h" +#include "utils_log.h" +#ifdef HICOLLIE_ENABLE +#include "xcollie_helper.h" +#endif + +namespace OHOS { +namespace FileManagement { +namespace CloudDiskService { +using namespace std; + +namespace { +} +REGISTER_SYSTEM_ABILITY_BY_ID(CloudDiskService, FILEMANAGEMENT_CLOUD_DISK_SERVICE_SA_ID, true); + +CloudDiskService::CloudDiskService(int32_t saID, bool runOnCreate) : SystemAbility(saID, runOnCreate) +{ +} + +void CloudDiskService::PublishSA() +{ + LOGI("Begin to init"); + if (!registerToService_) { + bool ret = SystemAbility::Publish(this); + if (!ret) { + throw runtime_error("Failed to publish the daemon"); + } + registerToService_ = true; + } + LOGI("Init finished successfully"); +} + +void CloudDiskService::OnStart() +{ + LOGI("Begin to start service"); + if (state_ == ServiceRunningState::STATE_RUNNING) { + LOGI("CloudDiskService has already started"); + return; + } + + try { + PublishSA(); + } catch (const exception &e) { + LOGE("%{public}s", e.what()); + } + + // system::SetParameter(CLOUD_FILE_SERVICE_SA_STATUS_FLAG, CLOUD_FILE_SERVICE_SA_START); + CloudDiskServiceTaskManager::GetInstance().StartTask(); + DiskMonitor::GetInstance().Init(); + state_ = ServiceRunningState::STATE_RUNNING; + + LOGI("Start service successfully"); +} + +void CloudDiskService::OnStop() +{ + LOGI("Begin to stop"); + state_ = ServiceRunningState::STATE_NOT_START; + registerToService_ = false; + LOGI("Stop finished successfully"); +} +} // namespace CloudDiskService +} // namespace FileManagement +} // namespace OHOS diff --git a/services/clouddiskservice/src/ipc/cloud_disk_service_callback_manager.cpp b/services/clouddiskservice/src/ipc/cloud_disk_service_callback_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..87405f0dc8884cf065d36252c63d77cc3536f413 --- /dev/null +++ b/services/clouddiskservice/src/ipc/cloud_disk_service_callback_manager.cpp @@ -0,0 +1,45 @@ +/* + * 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 "ipc/cloud_disk_service_callback_manager.h" + +#include + +#include "utils_log.h" + +namespace OHOS::FileManagement::CloudDiskService { +using namespace std; + +CloudDiskServiceCallbackManager &CloudDiskServiceCallbackManager::GetInstance() +{ + static CloudDiskServiceCallbackManager instance; + return instance; +} + +void CloudDiskServiceCallbackManager::AddCallback(const sptr &callback) +{ + if (callback == nullptr) { + return; + } + callbackProxy_ = callback; + auto remoteObject = callback->AsObject(); + auto deathCb = [this](const wptr &obj) { + callbackProxy_ = nullptr; + LOGE("client died"); + }; + deathRecipient_ = sptr(new SvcDeathRecipient(deathCb)); + remoteObject->AddDeathRecipient(deathRecipient_); +} + +} // namespace OHOS::FileManagement::CloudDiskService \ No newline at end of file diff --git a/services/clouddiskservice/src/ipc/cloud_disk_service_callback_proxy.cpp b/services/clouddiskservice/src/ipc/cloud_disk_service_callback_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..85bdf81b727416238e61b07533a27a8f76469dc4 --- /dev/null +++ b/services/clouddiskservice/src/ipc/cloud_disk_service_callback_proxy.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023 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 "cloud_disk_service_callback_proxy.h" + +#include "cloud_file_error.h" +#include "utils_log.h" + +namespace OHOS::FileManagement::CloudDiskService { +using namespace std; + +int32_t CloudDiskServiceCallbackProxy::OnChangeData(ChangeData &changeData) +{ + LOGI("Start"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + LOGE("Failed to write interface token"); + return -1; + } + + if (!data.WriteUint64(changeData.operationType)) { + LOGE("Failed to send the uri"); + return -1; + } + + auto remote = Remote(); + if (!remote) { + LOGE("remote is nullptr"); + return -1; + } + int32_t ret = remote->SendRequest(ICloudDiskServiceCallback::SERVICE_CMD_ON_PROCESS, data, reply, option); + if (ret != E_OK) { + LOGE("Failed to send out the requeset, ret:%{public}d", ret); + return ret; + } + LOGI("End"); + return E_OK; +} +} // namespace OHOS::FileManagement::CloudDiskService \ No newline at end of file diff --git a/services/clouddiskservice/src/monitor/disk_monitor.cpp b/services/clouddiskservice/src/monitor/disk_monitor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..887f84304d68d412d982d35b30175ae8a3870d30 --- /dev/null +++ b/services/clouddiskservice/src/monitor/disk_monitor.cpp @@ -0,0 +1,327 @@ +/* + * 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 "disk_monitor.h" + +#include +#include +#include +#include + +#include "disk_notifier.h" +#include "ffrt_inner.h" +#include "utils_log.h" + +namespace OHOS::FileManagement::CloudDiskService { +using namespace std; +namespace{ +constexpr uint32_t INIT_FLAGS = FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME | FAN_UNLIMITED_QUEUE; +constexpr uint32_t INIT_EVENT_FLAGS = O_RDONLY | O_LARGEFILE; +constexpr uint32_t MARK_FLAGS = FAN_MARK_ADD | FAN_MARK_FILESYSTEM; +constexpr uint64_t MARK_MASK = FAN_CREATE | FAN_DELETE | FAN_MOVED_FROM | FAN_MOVED_TO | FAN_ONDIR | FAN_CLOSE_WRITE; +const string MOUNT_PATH = "/data/service"; +const string PROC_SELF_FD = "/proc/self/fd/"; +const map SYNC_ROOTS = {{66666666, "/data/service/el2/100/hmdfs/account/files/Docs/Documents"}, + {11111111, "/data/service/el2/100/hmdfs/account/files/Docs/Download"}}; +const vector BLACK_PATHS = {"/data/service/el2/100/hmdfs/account/files/Docs/.Trash", + "/data/service/el2/100/hmdfs/account/files/Docs/.Recent", + "/data/service/el2/100/hmdfs/account/files/Docs/.thumbs"}; +} + +DiskMonitor &DiskMonitor::GetInstance() +{ + static DiskMonitor instance_; + return instance_; +} + +bool DiskMonitor::Init() +{ + if(!InitFanotify()){ + return false; + } + ffrt::submit([this] { this->CollectEvents(); }); + return true; +} + +bool DiskMonitor::InitFanotify() +{ + LOGI("init start"); + fanotifyFd_ = fanotify_init(INIT_FLAGS, INIT_EVENT_FLAGS); + if (fanotifyFd_ == -1) { + LOGE("disk monitor init failed, errno: %{public}d", errno); + return false; + } + if (fanotify_mark(fanotifyFd_, MARK_FLAGS, MARK_MASK, AT_FDCWD, MOUNT_PATH.c_str()) == -1) { + LOGE("fanotify_mark failed, errno: %{public}d", errno); + close(fanotifyFd_); + fanotifyFd_ = -1; + return false; + } + mountFp_ = opendir(MOUNT_PATH.c_str()); + if (mountFp_ == nullptr) { + LOGE("open dir failed, errno: %{public}d", errno); + close(fanotifyFd_); + fanotifyFd_ = -1; + return false; + } + mountFd_ = dirfd(mountFp_); + if (mountFd_ == -1) { + LOGE("get dirfd failed, errno: %{public}d", errno); + close(fanotifyFd_); + fanotifyFd_ = -1; + closedir(mountFp_); + mountFp_ = nullptr; + return false; + } + LOGI("Init end"); + return true; +} + +void DiskMonitor::CollectEvents() +{ + while (isRunning_) { + char eventsBuf[4096]{}; + ssize_t dataLen = read(fanotifyFd_, eventsBuf, sizeof(eventsBuf)); + if (dataLen == -1 && errno != EAGAIN) { + LOGE("read failed, errno: %{public}d", errno); + continue; + } + if (dataLen == 0) { + LOGI("no data to read"); + continue; + } + // TODO: check current user is active(unlock) + HandleEvents(mountFd_, eventsBuf, dataLen); + } +} + +void DiskMonitor::HandleEvents(int32_t mountFd, char eventsBuf[], size_t dataLen) +{ + for (struct fanotify_event_metadata *metaData = reinterpret_cast(eventsBuf); + FAN_EVENT_OK(metaData, dataLen); metaData = FAN_EVENT_NEXT(metaData, dataLen)) { + struct fanotify_event_info_fid *fID = reinterpret_cast(metaData + 1); + struct file_handle *fileHandle = reinterpret_cast(fID->handle); + if (fileHandle == nullptr) { + LOGE("fileHandle is null"); + continue; + } + + // get file name + string fileName; + if (!ExtractFileName(fID->hdr.info_type, fileName, fileHandle)) { + continue; + } + bool isDir = metaData->mask & FAN_ONDIR; + // other info + int eventFd = open_by_handle_at(mountFd, fileHandle, O_RDONLY); + if (eventFd == -1) { + LOGE("open_by_handle_at, errno: %{public}d", errno); + continue; + } + + string filePath = GetFilePath(eventFd, fileName); + if (filePath.empty()) { + close(eventFd); + continue; + } + // filePath = FolderAddSlash(isDir, filePath); + + EventProcess(metaData, filePath); + + close(eventFd); + } +} + +void DiskMonitor::EventProcess(struct fanotify_event_metadata *metaData, const string &filePath) +{ + if (metaData->mask & FAN_CREATE) { + HandleCreate(filePath); + } else if (metaData->mask & FAN_DELETE) { + HandleDelete(filePath); + } else if (metaData->mask & FAN_MOVED_FROM) { + HandleMoveFrom(filePath); + } else if (metaData->mask & FAN_MOVED_TO) { + HandleMoveTo(filePath); + } else if (metaData->mask & FAN_CLOSE_WRITE) { + HandleCloseWrite(filePath); + } + if (IsInSyncRoots(filePath) && !IsInBlackList(filePath)) { + LOGD("mask: %{public}llu, path: %{public}s", metaData->mask, filePath.c_str()); + } +} + +void DiskMonitor::HandleCreate(const std::string &filePath) +{ + int32_t syncRootIndex = GetSyncRootIndex(filePath); + if (syncRootIndex == -1) { + return; + } + auto eventInfo = EventInfo(userId_, syncRootIndex, OperationType::CREATE, filePath); + // POST EVENT + DiskNotifier::GetInstance().PostEvent(eventInfo); + PrintEventInfo(eventInfo); +} + +void DiskMonitor::HandleDelete(const std::string &filePath) +{ + int32_t syncRootIndex = GetSyncRootIndex(filePath); + if (syncRootIndex == -1) { + return; + } + auto eventInfo = EventInfo(userId_, syncRootIndex, OperationType::DELETE, filePath); + DiskNotifier::GetInstance().PostEvent(eventInfo); + PrintEventInfo(eventInfo); +} + +void DiskMonitor::HandleMoveFrom(const std::string &filePath) +{ + oldEventInfo_ = EventInfo(userId_, GetSyncRootIndex(filePath), OperationType::MOVE_FROM, filePath); +} + +// 1. old 不在同步根中,new 在同步根 => 通知 create->new +// 2. old 在同步根中,new 不在同步根中 => 通知 delete -> delete +// 3. old 不在同步根中,new 不在同步跟中 => 忽略 +// 4. old 在同步根中,new 在同步根中;同步根相同 -> 通知 move_from->old + move_to->new +// 4. old 在同步根中,new 在同步根中;同步根不相同 -> 通知 delete->old + create->new +void DiskMonitor::HandleMoveTo(const std::string &filePath) +{ + auto eventInfo = EventInfo(userId_, GetSyncRootIndex(filePath), OperationType::MOVE_TO, filePath); + do { + if (oldEventInfo_.syncRootIndex == -1) { + if (eventInfo.syncRootIndex == -1) { + break; + } + eventInfo.operateType = static_cast(OperationType::CREATE); + // POST EVENT + DiskNotifier::GetInstance().PostEvent(eventInfo); + PrintEventInfo(eventInfo); + break; + } + // oldEventInfo_->syncRootIndex != -1) + if (eventInfo.syncRootIndex == -1) { + oldEventInfo_.operateType = static_cast(OperationType::DELETE); + // POST DELETE oldEventInfo + DiskNotifier::GetInstance().PostEvent(oldEventInfo_); + PrintEventInfo(oldEventInfo_); + break; + } + if (oldEventInfo_.syncRootIndex == eventInfo.syncRootIndex) { + oldEventInfo_.operateType = static_cast(OperationType::MOVE_FROM); + eventInfo.operateType = static_cast(OperationType::MOVE_TO); + // POST MOVE_FROM oldEventInfo + // POST MOVE_TO eventInfo + DiskNotifier::GetInstance().PostEvent(oldEventInfo_); + DiskNotifier::GetInstance().PostEvent(eventInfo); + PrintEventInfo(oldEventInfo_); + PrintEventInfo(eventInfo); + break; + } + oldEventInfo_.operateType = static_cast(OperationType::DELETE); + eventInfo.operateType = static_cast(OperationType::CREATE); + // POST DELETE oldEventInfo + // POST CREATE eventInfo + DiskNotifier::GetInstance().PostEvent(oldEventInfo_); + DiskNotifier::GetInstance().PostEvent(eventInfo); + PrintEventInfo(oldEventInfo_); + PrintEventInfo(eventInfo); + } while (0); + oldEventInfo_.Reset(); +} + +void DiskMonitor::HandleCloseWrite(const std::string &filePath) +{ + int32_t syncRootIndex = GetSyncRootIndex(filePath); + if (syncRootIndex == -1) { + return; + } + auto eventInfo = EventInfo(userId_, syncRootIndex, OperationType::CLOSE_WRITE, filePath); + DiskNotifier::GetInstance().PostEvent(eventInfo); + PrintEventInfo(eventInfo); +} + +bool DiskMonitor::ExtractFileName(int type, string &fileName, struct file_handle *fileHandle) +{ + if (type == FAN_EVENT_INFO_TYPE_FID || type == FAN_EVENT_INFO_TYPE_DFID) { + fileName.clear(); + } else if (type == FAN_EVENT_INFO_TYPE_DFID_NAME) { + fileName = reinterpret_cast(fileHandle->f_handle + fileHandle->handle_bytes); + } else { + return false; + } + return true; +} + +string DiskMonitor::GetFilePath(int32_t eventFd, const string &fileName) +{ + char eventFilePath[PATH_MAX + 1]; + string procFdPath = PROC_SELF_FD + std::to_string(eventFd); + ssize_t pathLen = readlink(procFdPath.c_str(), eventFilePath, sizeof(eventFilePath) - 1); + if (pathLen == -1 || pathLen > PATH_MAX) { + LOGI("readlink failed , errno: %{public}d", errno); + return ""; + } + eventFilePath[pathLen] = '\0'; + + string filePath(eventFilePath); + if (!fileName.empty() && fileName.compare(".") != 0) { + filePath += "/" + fileName; + } + return filePath; +} + +int32_t DiskMonitor::GetSyncRootIndex(const std::string &filePath) +{ + for (auto &it : SYNC_ROOTS) { + if (filePath.find(it.second) == 0) { + return it.first; + } + } + return -1; +} + +string DiskMonitor::FolderAddSlash(bool isDir, const string &path) +{ + if (path.empty() || path.back() == '/') { + return path; + } + return isDir ? path + "/" : path; +} + +bool DiskMonitor::IsInSyncRoots(const string &path) +{ + for (auto &it : SYNC_ROOTS) { + if (path.find(it.second) == 0) { + return true; + } + } + return false; +} + +bool DiskMonitor::IsInBlackList(const string &path) +{ + + for (auto &it : BLACK_PATHS) { + if (path.find(it) == 0) { + return true; + } + } + return false; +} + +// debug +void DiskMonitor::PrintEventInfo(EventInfo info) +{ + LOGD("opt: %{public}d path: %{public}s name: %{public}s", info.operateType, info.path.c_str(), info.name.c_str()); +} +} // namespace OHOS::FileManagement::CloudDiskService \ No newline at end of file diff --git a/services/clouddiskservice/src/monitor/disk_notifier.cpp b/services/clouddiskservice/src/monitor/disk_notifier.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0878fe2067c62b7086782228ab3d3caeeb7ffe4f --- /dev/null +++ b/services/clouddiskservice/src/monitor/disk_notifier.cpp @@ -0,0 +1,75 @@ +/* + * 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 "disk_notifier.h" + +#include "utils_log.h" + +namespace OHOS::FileManagement::CloudDiskService { +using namespace std; +namespace{ +constexpr uint32_t MAX_EVENT_NUM = 10 * 1000; +constexpr uint64_t NOTIFY_TIMEOUT_MS = 200; +} +DiskNotifier &DiskNotifier::GetInstance() +{ + static DiskNotifier instance_; + return instance_; +} + +void DiskNotifier::PostEvent(EventInfo eventInfo) +{ + // 1. list 为空,首次收到事件 -> 启动定时器 + // 2. list 到达最大容量 -> 通知事件 -> 重置定时器 + if (eventList_.size() > MAX_EVENT_NUM || eventList_.empty()) { + ffrt_timer_stop(ffrt_qos_default, handle_); + NotifyAllEvent(); + handle_ = ffrt_timer_start(ffrt_qos_default, NOTIFY_TIMEOUT_MS, this, CallBack, false); + } + { + lock_guard lock(mutex_); + // 最后一条 type path name 都相同,则仅仅更新时间 + if (!eventList_.empty() && eventList_.back().operateType == eventInfo.operateType && + eventList_.back().path == eventInfo.path && eventList_.back().name == eventInfo.name) { + eventList_.back().timestamp = eventInfo.timestamp; + return; + } + eventList_.push_back(eventInfo); + } +} + +void DiskNotifier::NotifyAllEvent() +{ + vector tempEventList; + { + lock_guard lock(mutex_); + if (eventList_.empty()) { + return; + } + eventList_.swap(tempEventList); + eventList_.clear(); + } + // call LOG_MOUDLE -> tempEventList; + LOGI("NOTIFY_ALL: size: %{public}zu", tempEventList.size()); +} + +void DiskNotifier::CallBack(void *data) +{ + if (data == nullptr) { + return; + } + auto notifier = reinterpret_cast(data); + notifier->NotifyAllEvent(); +} +} // namespace OHOS::FileManagement::CloudDiskService \ No newline at end of file diff --git a/services/clouddiskservice/src/seccomp_policy/BUILD.gn b/services/clouddiskservice/src/seccomp_policy/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..3a2587f26c88e295371960113f3a4ba841e4076e --- /dev/null +++ b/services/clouddiskservice/src/seccomp_policy/BUILD.gn @@ -0,0 +1,15 @@ +import("//build/config/components/init/seccomp/scripts/seccomp_policy_fixer.gni") + +ohos_prebuilt_seccomp("disk_monitor_seccomp_filter") { + sources = [ "clouddiskservice.seccomp.policy" ] + + filtername = "clouddiskservice" + + process_type = "system" + + part_name = "dfs_service" + subsystem_name = "filemanagement" + + install_enable = true + install_images = [ "system" ] +} diff --git a/services/clouddiskservice/src/seccomp_policy/clouddiskservice.seccomp.policy b/services/clouddiskservice/src/seccomp_policy/clouddiskservice.seccomp.policy new file mode 100644 index 0000000000000000000000000000000000000000..ccb4fe499c2b6dae15469489dd18fb1ca350ed26 --- /dev/null +++ b/services/clouddiskservice/src/seccomp_policy/clouddiskservice.seccomp.policy @@ -0,0 +1,341 @@ +# 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. + +# For now, it supports architechture of ['arm', 'arm64', 'riscv64']. + +@returnValue +TRAP + +@allowList +io_setup;all +io_destroy;all +io_submit;all +io_cancel;all +io_getevents;all +setxattr;all +lsetxattr;all +fsetxattr;all +getxattr;all +lgetxattr;all +fgetxattr;all +listxattr;all +llistxattr;all +flistxattr;all +removexattr;all +lremovexattr;all +fremovexattr;all +getcwd;all +eventfd2;all +epoll_create1;all +epoll_ctl;all +epoll_pwait;all +dup;all +dup3;all +fcntl;arm64 +inotify_init1;all +inotify_add_watch;all +inotify_rm_watch;all +ioctl;all +ioprio_set;arm64 +ioprio_get;arm64 +flock;all +mknodat;all +mkdirat;all +unlinkat;all +symlinkat;all +linkat;all +renameat;arm +renameat;arm64 +umount2;all +mount;all +pivot_root;all +statfs;arm64 +fstatfs;arm64 +truncate;all +ftruncate;arm64 +fallocate;all +faccessat;all +faccessat2;all +chdir;all +fchdir;all +chroot;all +fchmod;all +fchmodat;all +fchownat;all +fchown;arm64 +openat;all +close;all +pipe2;all +quotactl;all +getdents64;all +lseek;all +read;all +write;all +readv;all +writev;all +pread64;all +pwrite64;all +preadv;all +pwritev;all +sendfile;all +pselect6;all +ppoll;all +signalfd4;all +vmsplice;all +splice;all +tee;all +readlinkat;all +newfstatat;arm64 +fstat;arm64 +sync;all +fsync;all +fdatasync;all +sync_file_range;arm64 +timerfd_create;all +timerfd_settime;all +timerfd_gettime;all +utimensat;all +acct;all +capget;all +capset;all +personality;all +exit;all +exit_group;all +waitid;all +set_tid_address;all +unshare;all +futex;all +set_robust_list;all +get_robust_list;all +nanosleep;all +getitimer;all +setitimer;all +init_module;all +delete_module;all +timer_create;all +timer_gettime;all +timer_getoverrun;all +timer_settime;all +timer_delete;all +clock_settime;all +clock_gettime;all +clock_getres;all +clock_nanosleep;all +syslog;all +ptrace;all +sched_setparam;all +sched_setscheduler;all +sched_getscheduler;all +sched_getparam;all +sched_setaffinity;all +sched_getaffinity;all +sched_yield;all +sched_get_priority_max;all +sched_get_priority_min;all +sched_rr_get_interval;all +restart_syscall;all +kill;all +tkill;all +tgkill;all +sigaltstack;all +rt_sigsuspend;all +rt_sigaction;all +rt_sigprocmask;all +rt_sigpending;all +rt_sigtimedwait;all +rt_sigqueueinfo;all +rt_sigreturn;all +setpriority;all +getpriority;all +reboot;all +setregid;arm64 +setgid;arm64 +setreuid;arm64 +setuid;arm64 +setresuid;arm64 +getresuid;arm64 +setresgid;arm64 +getresgid;arm64 +setfsuid;all +setfsgid;all +times;all +setpgid;all +getpgid;all +getsid;all +setsid;all +getgroups;arm64 +setgroups;arm64 +uname;all +sethostname;all +setdomainname;all +getrlimit;arm64 +setrlimit;all +getrusage;all +umask;all +prctl;all +getcpu;all +gettimeofday;all +settimeofday;all +adjtimex;all +getpid;all +getppid;all +getuid;arm64 +geteuid;arm64 +getgid;arm64 +getegid;arm64 +gettid;all +sysinfo;all +semget;all +shmget;all +shmctl;all +shmat;all +shmdt;all +socket;all +socketpair;all +bind;all +listen;all +accept;all +connect;all +getsockname;all +getpeername;all +sendto;all +recvfrom;all +setsockopt;all +getsockopt;all +shutdown;all +sendmsg;all +recvmsg;all +readahead;all +brk;all +munmap;all +mremap;all +add_key;all +keyctl;all +clone;all +execve;all +mmap;arm64 +fadvise64;arm64 +mprotect;all +msync;all +mlock;all +munlock;all +mlockall;all +munlockall;all +mincore;all +madvise;all +rt_tgsigqueueinfo;all +perf_event_open;all +accept4;all +recvmmsg;all +wait4;all +prlimit64;all +clock_adjtime;all +syncfs;all +setns;all +sendmmsg;all +process_vm_readv;all +process_vm_writev;all +finit_module;all +sched_setattr;all +sched_getattr;all +renameat2;all +seccomp;all +getrandom;all +memfd_create;all +bpf;all +execveat;all +userfaultfd;all +membarrier;all +mlock2;all +copy_file_range;all +preadv2;all +pwritev2;all +statx;all +pidfd_send_signal;all +pidfd_open;all +close_range;all +pidfd_getfd;all +process_madvise;all +fork;arm +open;arm +unlink;arm +mknod;arm +chmod;arm +access;arm +rename;arm +mkdir;arm +rmdir;arm +pipe;arm +dup2;arm +sigaction;arm +symlink;arm +readlink;arm +stat;arm +sigreturn;arm +_llseek;arm +_newselect;arm +poll;arm +vfork;arm +ugetrlimit;arm +mmap2;arm +truncate64;arm +ftruncate64;arm +stat64;arm +fstat64;arm +lchown32;arm +getuid32;arm +getgid32;arm +geteuid32;arm +getegid32;arm +setreuid32;arm +setregid32;arm +chown32;arm +getgroups32;arm +setgroups32;arm +fchown32;arm +setresuid32;arm +getresuid32;arm +setresgid32;arm +getresgid32;arm +setuid32;arm +setgid32;arm +fcntl64;arm +sendfile64;arm +statfs64;arm +fstatfs64;arm +fadvise64_64;arm +fstatat64;arm +sync_file_range2;arm +clock_gettime64;arm +clock_settime64;arm +clock_adjtime64;arm +clock_getres_time64;arm +clock_nanosleep_time64;arm +timer_gettime64;arm +timer_settime64;arm +timerfd_gettime64;arm +timerfd_settime64;arm +utimensat_time64;arm +pselect6_time64;arm +ppoll_time64;arm +recvmmsg_time64;arm +semtimedop_time64;arm +rt_sigtimedwait_time64;arm +futex_time64;arm +sched_rr_get_interval_time64;arm +cacheflush;arm +set_tls;arm +mbind;all +fanotify_init;arm64 +fanotify_mark;arm64 +open_by_handle_at;arm64 diff --git a/services/distributedfile.cfg b/services/distributedfile.cfg index 4464a8acb1a197424aa6d6d736848777468a5435..0e55efdd3da8bbf31e20ca29848512c0319086a0 100644 --- a/services/distributedfile.cfg +++ b/services/distributedfile.cfg @@ -64,5 +64,14 @@ "ohos.permission.WRITE_ALL_PHOTO", "ohos.permission.MEMOSPACE_SYNC" ] + }, { + "name": "clouddiskservice", + "path": ["/system/bin/sa_main", "/system/profile/clouddiskservice.json"], + "uid": "6161", + "gid": ["6161", "dfs"], + "sandbox": 0, + "secon": "u:r:clouddiskservice:s0", + "apl": "system_basic", + "ondemand": true }] } \ No newline at end of file