diff --git a/bundle.json b/bundle.json index 5460115ae1514e3d6880351b2c22b9faa0982adb..dc8f96493db1e1c15ae741e1029fb115b98699f1 100644 --- a/bundle.json +++ b/bundle.json @@ -124,7 +124,7 @@ "cloud_daemon_manager.h", "i_cloud_daemon.h", "svc_death_recipient.h" - ], + ], "header_base": "//foundation/filemanagement/dfs_service/interfaces/inner_api/native/cloud_daemon_kit_inner" } }, diff --git a/interfaces/kits/ndk/clouddiskmanager/BUILD.gn b/interfaces/kits/ndk/clouddiskmanager/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..1ece37fc5440fb43d62db03e8facc12ec7406e79 --- /dev/null +++ b/interfaces/kits/ndk/clouddiskmanager/BUILD.gn @@ -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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") +import("//foundation/filemanagement/dfs_service/distributedfile.gni") + +ohos_ndk_library("libohclouddiskmanager") { + output_name = "ohclouddiskmanager" + output_extension = "so" + min_compact_version = "21" + ndk_description_file = "./liboh_cloud_disk_manager.ndk.json" + system_capability = "SystemCapability.FileManagement.CloudDiskManager" + system_capability_headers = [ + "filemanagement/clouddiskmanager/oh_cloud_disk_error_code.h", + "filemanagement/clouddiskmanager/oh_cloud_disk_manager.h", + ] +} + +ohos_ndk_headers("oh_cloud_disk_manager") { + dest_dir = "${ndk_headers_out_dir}/filemanagement/clouddiskmanager" + sources = [ + "./include/oh_cloud_disk_error_code.h", + "./include/oh_cloud_disk_manager.h", + ] +} diff --git a/interfaces/kits/ndk/clouddiskmanager/include/oh_cloud_disk_error_code.h b/interfaces/kits/ndk/clouddiskmanager/include/oh_cloud_disk_error_code.h new file mode 100644 index 0000000000000000000000000000000000000000..72aaf4fbf655246e7cb81bf3fb87c4800ad248a8 --- /dev/null +++ b/interfaces/kits/ndk/clouddiskmanager/include/oh_cloud_disk_error_code.h @@ -0,0 +1,121 @@ +/* + * 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_KIT_OH_CLOUD_DISK_MANAGER_ERROR_CODE_H +#define FILEMANAGEMENT_KIT_OH_CLOUD_DISK_MANAGER_ERROR_CODE_H + +/** + * @addtogroup CloudDiskManager + * @{ + * + * @brief Provides APIs and error code for managing cloud disks. + * @since 21 + */ + +/** + * @file oh_cloud_disk_error_code.h + * + * @brief Provides the definitions of cloud disk manager error codes. + * @syscap SystemCapability.FileManagement.CloudDiskManager + * @since 21 + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Defines error codes for the cloud disk synchronization manager feature. + * @since 21 + */ +typedef enum CloudDisk_ErrorCode { + /** + * @error Operation completed successfully. + */ + CLOUD_DISK_ERR_OK = 0, + /** + * @error Permission verification failed. + */ + CLOUD_DISK_PERMISSION_DENIED = 201, + /** + * @error Invalid input parameter. + */ + CLOUD_DISK_INVALID_ARG = 34400001, + /** + * @error Sync folder path unauthorized. + */ + CLOUD_DISK_SYNC_FOLDER_PATH_UNAUTHORIZED = 34400002, + /** + * @error Inter-process communication (IPC) failure. + */ + CLOUD_DISK_IPC_FAILED = 34400003, + /** + * @error Sync folder exceeds the allowed limit. + */ + CLOUD_DISK_SYNC_FOLDER_LIMIT_EXCEEDED = 34400004, + /** + * @error Sync folder conflicts with an existing sync folder of this application. + */ + CLOUD_DISK_CONFLICT_THIS_APP = 34400005, + /** + * @error Sync folder conflicts with an existing sync folder of another application. + */ + CLOUD_DISK_CONFLICT_OTHER_APP = 34400006, + /** + * @error Failed to register sync folder. + */ + CLOUD_DISK_REGISTER_SYNC_FOLDER_FAILED = 34400007, + /** + * @error Sync folder is not registered. + */ + CLOUD_DISK_SYNC_FOLDER_NOT_REGISTERED = 34400008, + /** + * @error Failed to unregister sync folder. + */ + CLOUD_DISK_UNREGISTER_SYNC_FOLDER_FAILED = 34400009, + /** + * @error Sync folder path does not exist. + */ + CLOUD_DISK_SYNC_FOLDER_PATH_NOT_EXIST = 34400010, + /** + * @error Change listener is not registered. + */ + CLOUD_DISK_LISTENER_NOT_REGISTERED = 34400011, + /** + * @error Change listener is already registered. + */ + CLOUD_DISK_LISTENER_ALREADY_REGISTERED = 34400012, + /** + * @error Invalid change sequence. Full query is recommended. + */ + CLOUD_DISK_INVALID_CHANGE_SEQUENCE = 34400013, + /** + * @error Temporary failure. Retry is recommended (e.g., network issues). + */ + CLOUD_DISK_TRY_AGAIN = 34400014, + /** + * @error Internal error occurred. + */ + CLOUD_DISK_INTERNAL_ERROR = 34400015, + /** + * @error Cloud disk not support. + */ + CLOUD_DISK_NOT_SUPPORTED = 34400016, +} CloudDisk_ErrorCode; + +#ifdef __cplusplus +} +#endif +#endif // FILEMANAGEMENT_KIT_OH_CLOUD_DISK_MANAGER_ERROR_CODE_H \ No newline at end of file diff --git a/interfaces/kits/ndk/clouddiskmanager/include/oh_cloud_disk_manager.h b/interfaces/kits/ndk/clouddiskmanager/include/oh_cloud_disk_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..01701575620dbfda378a969bf8ac13b7961b0f2f --- /dev/null +++ b/interfaces/kits/ndk/clouddiskmanager/include/oh_cloud_disk_manager.h @@ -0,0 +1,377 @@ +/* + * 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_KIT_OH_CLOUD_DISK_MANAGER_NDK_H +#define FILEMANAGEMENT_KIT_OH_CLOUD_DISK_MANAGER_NDK_H + +#include +#include + +#include "oh_cloud_disk_error_code.h" + +/** + * @addtogroup CloudDiskManager + * @{ + * + * @brief Provides APIs and error code for managing cloud disks. + * + * @since 21 + * @version 1.0 + */ + +/** + * @file oh_cloud_disk_manager.h + * + * @brief Provides APIs for managing cloud disks. + * @library libohclouddiskmanager.so + * @syscap SystemCapability.FileManagement.CloudDiskManager + * @since 21 + * @version 1.0 + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enumerates the synchronization states of a cloud disk. + * @since 21 + * + * This enumeration defines the possible states during cloud disk synchronization. + */ +typedef enum CloudDisk_SyncState { + /** + * The cloud disk is idle and not performing any synchronization. + */ + IDLE = 0, + /** + * The cloud disk is currently synchronizing. + */ + SYNCING = 1, + /** + * The cloud disk synchronization completed successfully. + */ + SYNC_SUCCESSED = 2, + /** + * The cloud disk synchronization failed. + */ + SYNC_FAILED = 3, + /** + * The cloud disk synchronization was canceled. + */ + SYNC_CANCELED = 4, + /** + * The cloud disk synchronization encountered a conflict. + */ + SYNC_CONFLICTED = 5, +} CloudDisk_SyncState; + +/** + * @brief Enumerates the operation types for file changes in the cloud disk. + * @since 21 + */ +typedef enum CloudDisk_OperationType { + /** + * Create a file or folder. + */ + CREATE = 0, + /** + * Delete a file or folder. + */ + DELETE = 1, + /** + * Move a file or folder from a source location. + */ + MOVE_FROM = 2, + /** + * Move a file or folder to a target location. + */ + MOVE_TO = 3, + /** + * Close a file after writing to operations. + */ + CLOSE_WRITE = 4, + /** + * The sync folder path is invalid. + */ + SYNC_FOLDER_INVALID = 5, +} CloudDisk_OperationType; + +/** + * @brief Enumerates the error reasons for file synchronization failures. + * @since 21 + */ +typedef enum CloudDisk_ErrorReason { + /** + * The input parameter is invalid. + */ + INVALID_ARGUMENT = 0, + /** + * The specified file does not exist. + */ + NO_SUCH_FILE = 1, + /** + * There is no space left on the device. + */ + NO_SPACE_LEFT = 2, + /** + * The operation is out of the valid range. + */ + OUT_OF_RANGE = 3, + /** + * The sync state is not set for the cloud disk. + */ + NO_SYNC_STATE = 4, +} CloudDisk_ErrorReason; + +/** + * @brief Represents file path information. + * @since 21 + */ +typedef struct CloudDisk_PathInfo { + /** + * The file path as a null-terminated string. + */ + char *value; + /** + * The length of the file path, excluding the null terminator. + */ + size_t length; +} CloudDisk_PathInfo; + +/** + * @brief Defines the file ID information. + * @since 21 + */ +typedef CloudDisk_PathInfo CloudDisk_FileIdInfo; + +/** + * @brief Defines the sync folder path information. + * @since 21 + */ +typedef CloudDisk_PathInfo CloudDisk_SyncFolderPath; + +/** + * @brief Defines file sync states. + * @since 21 + */ +typedef struct CloudDisk_FileSyncState { + /** + * Indicates the file path information. + */ + CloudDisk_PathInfo filePathInfo; + /** + * Indicates the synchronization state of the file. + */ + CloudDisk_SyncState syncState; +} CloudDisk_FileSyncState; + +/** + * @brief Defines the data structure for a single file change event in the sync folder. + * @since 21 + * + * This structure contains detailed information about a file change, including its unique ID, + * parent ID, relative path, change type, file size, and timestamps. + */ +typedef struct CloudDisk_ChangeData { + /** + * The update sequence number for the change event. + * Increases by 1 each time the file is changed, and is monotonically increasing. + * Used for incremental change queries. + */ + uint64_t updateSequenceNumber{0}; + /** + * The globally unique file ID. Remains unchanged during the lifecycle of the file. + */ + CloudDisk_FileIdInfo fileId; + /** + * The parent file ID information. + */ + CloudDisk_FileIdInfo parentFileId; + /** + * The relative path information of the file. + */ + CloudDisk_PathInfo relativePathInfo; + /** + * The type of operation for this file change (such as create, delete, move, etc.). + */ + CloudDisk_OperationType operationType; + /** + * The size of the file in bytes. + */ + uint64_t size{0}; + /** + * The last modified time of the file, in milliseconds. + */ + uint64_t mtime{0}; + /** + * The timestamp of the change event, in milliseconds. + */ + uint64_t timeStamp{0}; +} CloudDisk_ChangeData; + +/** + * @brief Represents the result of querying file changes in a sync folder. + * @since 21 + * + * This structure contains the incremental change data for files in a sync folder, + * including the next update sequence number, end-of-log flag, and an array of change data items. + */ +typedef struct CloudDisk_ChangesResult { + /** + * The next update sequence number for incremental queries. + */ + uint64_t nextUsn{0}; + /** + * Indicates whether the end of the change log is reached. + * If true, all file changes have been returned. + */ + bool isEof{false}; + /** + * The number of change data items in the array. + */ + size_t length{0}; + /** + * The array of file change data items. + */ + CloudDisk_ChangeData dataDatas[]; +} CloudDisk_ChangesResult; + +/** + * @brief Represents a failed file in a synchronization operation. + * @since 21 + * + * This structure contains the file path information and the specific error reason for the failure. + */ +typedef struct CloudDisk_FailedList { + /** + * The file path information of the failed file. + */ + CloudDisk_PathInfo pathInfo; + /** + * The error reason for the file synchronization failure. + */ + CloudDisk_ErrorReason errorReason; +} CloudDisk_FailedList; + +/** + * @brief Represents the result of a file synchronization operation. + * @since 21 + * + * This structure contains the absolute path of the file, the synchronization result, + * and either the sync state or the error reason depending on the operation outcome. + */ +typedef struct CloudDisk_ResultList { + /** + * The absolute path information of the file. + */ + CloudDisk_PathInfo pathInfo; + /** + * Indicates whether the synchronization operation was successful. + * If true, syncState is valid; if false, errorReason is valid. + */ + bool isSuccess; + /** + * The synchronization state of the file. Valid only if isSuccess is true. + */ + CloudDisk_SyncState syncState; + /** + * The error reason for the file synchronization failure. Valid only if isSuccess is false. + */ + CloudDisk_ErrorReason errorReason; +} CloudDisk_ResultList; + +/** + * @brief Registers a callback function to notify the application of sync folder changes. + * + * @param syncFolderPath Indicates the sync folder path information. + * @param callback Indicates the callback function to be registered. + * @return Returns {@link CLOUD_DISK_ERR_OK} if the callback function is registered successfully; + *
returns an error code defined in {@link oh_cloud_disk_error_code.h} otherwise. + * @since 21 + */ +CloudDisk_ErrorCode + OH_CloudDisk_RegisterSyncFolderChanges(const CloudDisk_SyncFolderPath syncFolderPath, + void (*callback)(const CloudDisk_SyncFolderPath syncFolderPath, + const CloudDisk_ChangeData changeDatas[], size_t length)); + +/** + * @brief Unregisters a callback function for sync folder changes. + * + * @param syncFolderPath Indicates the sync folder path information. + * @return Returns {@link CLOUD_DISK_ERR_OK} if the callback function is unregistered successfully; + *
returns an error code defined in {@link oh_cloud_disk_error_code.h} otherwise. + * @since 21 + */ +CloudDisk_ErrorCode OH_CloudDisk_UnregisterSyncFolderChanges(const CloudDisk_SyncFolderPath syncFolderPath); + +/** + * @brief Gets the change datas of specified folder. + * + * @param syncFolderPath Indicates the sync folder path information. + * @param startUsn Indicates the start update sequence number. + * @param count Indicates the number of files. + * @param changesResult Indicates the result of querying file changes. For details, see {@link CloudDisk_ChangesResult}. + * @return Returns {@link CLOUD_DISK_ERR_OK} if the callback function is unregistered successfully; + *
returns an error code defined in {@link oh_cloud_disk_error_code.h} otherwise. + * @since 21 + */ +CloudDisk_ErrorCode OH_CloudDisk_GetSyncFolderChanges(const CloudDisk_SyncFolderPath syncFolderPath, + uint64_t startUsn, + size_t count, + CloudDisk_ChangesResult **changesResult); + +/** + * @brief Sets the synchronization state for specified files in a sync folder. + * + * @param syncFolderPath Indicates the sync folder path information. + * @param fileSyncStates The array of {@link CloudDisk_FileSyncState} specifying the file paths and their target sync + *
states. + * @param length The number of files to set. + * @param failedLists Output parameter. Returns a pointer to an array of {@link CloudDisk_FailedList} for files that + *
failed to set. + * @param failedCount Output parameter. Returns the number of failed files in {@link failedLists}. + * @return Returns {@link CLOUD_DISK_ERR_OK} if the operation is successful; + *
otherwise, returns an error code defined in {@link oh_cloud_disk_error_code.h}. + * @since 21 + */ +CloudDisk_ErrorCode OH_CloudDisk_SetFileSyncStates(const CloudDisk_SyncFolderPath syncFolderPath, + const CloudDisk_FileSyncState fileSyncStates[], + size_t length, + CloudDisk_FailedList **failedLists, + size_t *failedCount); + +/** + * @brief Queries the synchronization state of specified files in a sync folder. + * + * @param syncFolderPath Indicates the sync folder path information. + * @param paths The array of file paths to query. + * @param length The number of file paths in the array. + * @param resultLists Output parameter. Returns a pointer to an array of {@link CloudDisk_ResultList} containing the + *
query results. + * @param resultCount Output parameter. Returns the number of results in {@link resultLists}. + * @return Returns {@link CLOUD_DISK_ERR_OK} if the query is successful; + *
otherwise, returns an error code defined in {@link oh_cloud_disk_error_code.h}. + * @since 21 + */ +CloudDisk_ErrorCode OH_CloudDisk_GetFileSyncStates(const CloudDisk_SyncFolderPath syncFolderPath, + const CloudDisk_PathInfo paths[], + size_t length, + CloudDisk_ResultList **resultLists, + size_t *resultCount); +#ifdef __cplusplus +} +#endif +#endif // FILEMANAGEMENT_KIT_OH_CLOUD_DISK_MANAGER_NDK_H \ No newline at end of file diff --git a/interfaces/kits/ndk/clouddiskmanager/include/oh_cloud_disk_utils.h b/interfaces/kits/ndk/clouddiskmanager/include/oh_cloud_disk_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..e1c13246d12c2add50e06729f77ea54fc5d6d318 --- /dev/null +++ b/interfaces/kits/ndk/clouddiskmanager/include/oh_cloud_disk_utils.h @@ -0,0 +1,65 @@ +/* + * 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_KIT_OH_CLOUD_DISK_MANAGER_UTILS_H +#define FILEMANAGEMENT_KIT_OH_CLOUD_DISK_MANAGER_UTILS_H + +#include + +#include "cloud_disk_service_error.h" +#include "oh_cloud_disk_error_code.h" + +CloudDisk_ErrorCode CovertToErrorCode(int32_t innerErrorCode); + +const std::unordered_map innerToNErrTable = { + {OHOS::FileManagement::CloudDiskService::CloudDiskServiceErrCode::E_OK, CLOUD_DISK_ERR_OK}, + {OHOS::FileManagement::CloudDiskService::CloudDiskServiceErrCode::E_INVALID_ARG, CLOUD_DISK_INVALID_ARG}, + {OHOS::FileManagement::CloudDiskService::CloudDiskServiceErrCode::E_SYNC_FOLDER_PATH_UNAUTHORIZED, + CLOUD_DISK_SYNC_FOLDER_PATH_UNAUTHORIZED}, + {OHOS::FileManagement::CloudDiskService::CloudDiskServiceErrCode::E_IPC_FAILED, CLOUD_DISK_IPC_FAILED}, + {OHOS::FileManagement::CloudDiskService::CloudDiskServiceErrCode::E_SYNC_FOLDER_LIMIT_EXCEEDED, + CLOUD_DISK_SYNC_FOLDER_LIMIT_EXCEEDED}, + {OHOS::FileManagement::CloudDiskService::CloudDiskServiceErrCode::E_CONFLICT_THIS_APP, + CLOUD_DISK_CONFLICT_THIS_APP}, + {OHOS::FileManagement::CloudDiskService::CloudDiskServiceErrCode::E_CONFLICT_OTHER_APP, + CLOUD_DISK_CONFLICT_OTHER_APP}, + {OHOS::FileManagement::CloudDiskService::CloudDiskServiceErrCode::E_REGISTER_SYNC_FOLDER_FAILED, + CLOUD_DISK_REGISTER_SYNC_FOLDER_FAILED}, + {OHOS::FileManagement::CloudDiskService::CloudDiskServiceErrCode::E_SYNC_FOLDER_NOT_REGISTERED, + CLOUD_DISK_SYNC_FOLDER_NOT_REGISTERED}, + {OHOS::FileManagement::CloudDiskService::CloudDiskServiceErrCode::E_UNREGISTER_SYNC_FOLDER_FAILED, + CLOUD_DISK_UNREGISTER_SYNC_FOLDER_FAILED}, + {OHOS::FileManagement::CloudDiskService::CloudDiskServiceErrCode::E_SYNC_FOLDER_PATH_NOT_EXIST, + CLOUD_DISK_SYNC_FOLDER_PATH_NOT_EXIST}, + {OHOS::FileManagement::CloudDiskService::CloudDiskServiceErrCode::E_LISTENER_NOT_REGISTERED, + CLOUD_DISK_LISTENER_NOT_REGISTERED}, + {OHOS::FileManagement::CloudDiskService::CloudDiskServiceErrCode::E_LISTENER_ALREADY_REGISTERED, + CLOUD_DISK_LISTENER_ALREADY_REGISTERED}, + {OHOS::FileManagement::CloudDiskService::CloudDiskServiceErrCode::E_INVALID_CHANGE_SEQUENCE, + CLOUD_DISK_INVALID_CHANGE_SEQUENCE}, + {OHOS::FileManagement::CloudDiskService::CloudDiskServiceErrCode::E_TRY_AGAIN, CLOUD_DISK_TRY_AGAIN}, + {OHOS::FileManagement::CloudDiskService::CloudDiskServiceErrCode::E_INTERNAL_ERROR, CLOUD_DISK_INTERNAL_ERROR}, + {OHOS::FileManagement::CloudDiskService::CloudDiskServiceErrCode::E_NOT_SUPPORTED, CLOUD_DISK_NOT_SUPPORTED}, + {OHOS::FileManagement::CloudDiskService::CloudDiskServiceErrCode::E_PERMISSION_DENIED, + CLOUD_DISK_PERMISSION_DENIED}, +}; + +#define CHECK_NULLPTR_AND_CONTINUE(ptr, ...) \ + if ((ptr) == nullptr) { \ + LOGE("Pointer " #ptr " is nullptr, skip this item."); \ + __VA_ARGS__; \ + continue; \ + } +#endif // FILEMANAGEMENT_KIT_OH_CLOUD_DISK_MANAGER_UTILS_H \ No newline at end of file diff --git a/interfaces/kits/ndk/clouddiskmanager/liboh_cloud_disk_manager.ndk.json b/interfaces/kits/ndk/clouddiskmanager/liboh_cloud_disk_manager.ndk.json new file mode 100644 index 0000000000000000000000000000000000000000..a1c510f753944788a5c7aa7da042126d094d2ed8 --- /dev/null +++ b/interfaces/kits/ndk/clouddiskmanager/liboh_cloud_disk_manager.ndk.json @@ -0,0 +1,22 @@ +[ + { + "first_introduced": "21", + "name": "OH_CloudDisk_RegisterSyncFolderChange" + }, + { + "first_introduced": "21", + "name": "OH_CloudDisk_UnregisterSyncFolderChange" + }, + { + "first_introduced": "21", + "name": "OH_CloudDisk_GetSyncFolderChanges" + }, + { + "first_introduced": "21", + "name": "OH_CloudDisk_SetFileSyncStates" + }, + { + "first_introduced": "21", + "name": "OH_CloudDisk_GetFileSyncStates" + } +] \ No newline at end of file diff --git a/interfaces/kits/ndk/clouddiskmanager/src/BUILD.gn b/interfaces/kits/ndk/clouddiskmanager/src/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..1bc0c99b3d276adbb8d131e5743658076b28dce2 --- /dev/null +++ b/interfaces/kits/ndk/clouddiskmanager/src/BUILD.gn @@ -0,0 +1,52 @@ +# 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") + +ohos_shared_library("ohclouddiskmanager") { + branch_protector_ret = "pac_ret" + sanitize = { + integer_overflow = true + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } + + include_dirs = [ + "${distributedfile_path}/interfaces/kits/ndk/clouddiskmanager/include", + ] + + sources = [ + "./oh_cloud_disk_manager.cpp", + "./oh_cloud_disk_utils.cpp", + ] + + deps = [ + "${innerkits_native_path}/clouddiskservice_kit_inner:clouddiskservice_kit_inner", + "${utils_path}:libdistributedfileutils_lite", + ] + + external_deps = [ + "ability_base:zuri", + "c_utils:utils", + "hilog:libhilog", + "user_file_service:cloud_disk_manager_kit", + ] + output_extension = "so" + relative_install_dir = "ndk" + part_name = "dfs_service" + subsystem_name = "filemanagement" +} diff --git a/interfaces/kits/ndk/clouddiskmanager/src/oh_cloud_disk_manager.cpp b/interfaces/kits/ndk/clouddiskmanager/src/oh_cloud_disk_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b0b09e26656db07c17ba81060bd0f9cd23b6d987 --- /dev/null +++ b/interfaces/kits/ndk/clouddiskmanager/src/oh_cloud_disk_manager.cpp @@ -0,0 +1,322 @@ +/* + * 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 "oh_cloud_disk_manager.h" + +#include +#include +#include +#include + +#include + +#include "cloud_disk_common.h" +#include "cloud_disk_service_callback.h" +#include "cloud_disk_service_manager.h" +#include "oh_cloud_disk_utils.h" +#include "utils_log.h" + +using namespace std; +using namespace OHOS; +using namespace OHOS::FileManagement; +using namespace OHOS::FileManagement::CloudDiskService; + +static char *AllocField(const char *value, size_t length) +{ + char *field = new(std::nothrow) char[length + 1]; + if (field == nullptr) { + LOGE("new failed"); + return nullptr; + } + + if (strncpy_s(field, length + 1, value, length) != 0) { + LOGE("strncpy_s failed"); + delete[] field; + return nullptr; + } + field[length] = '\0'; + return field; +} + +static bool IsValidPathInfo(const char *path, size_t length) +{ + if (path == nullptr) { + LOGE("path is nullptr"); + return false; + } + if (length == 0) { + LOGE("length is invalid: %{public}zu", length); + return false; + } + size_t actualLen = strnlen(path, length + 1); + if (actualLen != length) { + LOGE("length not equal to actual string length: %{public}zu", actualLen); + return false; + } + return true; +} + +class CloudDiskServiceCallbackImpl : public CloudDiskServiceCallback { +public: + using OnChangeDataCallback = + function; + explicit CloudDiskServiceCallbackImpl(OnChangeDataCallback callback) + : callback_(callback) {}; + void OnChangeData(const std::string &syncFolder, const std::vector &changeData) override; + ~CloudDiskServiceCallbackImpl() override = default; + +private: + OnChangeDataCallback callback_; +}; + +void CloudDiskServiceCallbackImpl::OnChangeData(const std::string &syncFolder, + const std::vector &changeData) +{ + if (callback_ == nullptr) { + LOGE("Can not find callback, just return"); + return; + } + char *path = new (std::nothrow) char[syncFolder.length() + 1]; + if (path == nullptr) { + LOGE("Failed to allocate memory for path"); + return; + } + if (strncpy_s(path, syncFolder.length() + 1, syncFolder.c_str(), syncFolder.length()) != 0) { + LOGE("strncpy_s failed"); + delete[] path; + return; + } + CloudDisk_SyncFolderPath syncFolderPath = {.value = path, .length = syncFolder.length()}; + CloudDisk_ChangeData *dataDatas = new (std::nothrow) CloudDisk_ChangeData[changeData.size()]; + if (dataDatas == nullptr) { + LOGE("Failed to allocate memory for changeDatas"); + delete[] syncFolderPath.value = nullptr; + syncFolderPath.value = nullptr; + return; + } + LOGD("OnChangeData callback, syncFolder: %{public}s, change datas size: %{public}zu", syncFolder.c_str(), + changeData.size()); + size_t length = 0; + for (auto &item : changeData) { + CloudDisk_ChangeData data; + data.fileId.value = AllocField(item.fileId.c_str(), item.fileId.length()); + CHECK_NULLPTR_AND_CONTINUE(data.fileId.value); + data.fileId.length = item.fileId.length(); + data.parentFileId.value = AllocField(item.parentFileId.c_str(), item.parentFileId.length()); + CHECK_NULLPTR_AND_CONTINUE(data.parentFileId.value, delete[] data.fileId.value; data.fileId.value = nullptr;); + data.parentFileId.length = item.parentFileId.length(); + data.relativePathInfo.value = AllocField(item.relativePath.c_str(), item.relativePath.length()); + CHECK_NULLPTR_AND_CONTINUE(data.relativePathInfo.value, delete[] data.fileId.value; data.fileId.value = nullptr; + delete[] data.parentFileId.value; data.parentFileId.value = nullptr;); + data.relativePathInfo.length = item.relativePath.length(); + data.updateSequenceNumber = item.updateSequenceNumber; + data.operationType = static_cast(item.operationType); + data.size = item.size; + data.mtime = item.mtime; + data.timeStamp = item.timeStamp; + dataDatas[length++] = data; + } + callback_(syncFolderPath, dataDatas, length); +} + +CloudDisk_ErrorCode + OH_CloudDisk_RegisterSyncFolderChanges(const CloudDisk_SyncFolderPath syncFolderPath, + void (*callback)(const CloudDisk_SyncFolderPath syncFolderPath, + const CloudDisk_ChangeData changeDatas[], size_t length)) +{ + if (!IsValidPathInfo(syncFolderPath.value, syncFolderPath.length)) { + LOGE("Invalid argument, syncFolder path is invalid"); + return CloudDisk_ErrorCode::CLOUD_DISK_INVALID_ARG; + } + if (callback == nullptr) { + LOGE("Invalid argument, callback is nullptr"); + return CloudDisk_ErrorCode::CLOUD_DISK_INVALID_ARG; + } + auto callbackInner = [callback](const CloudDisk_SyncFolderPath syncFolderPath, + const CloudDisk_ChangeData changeDatas[], size_t length) { + callback(syncFolderPath, changeDatas, length); + }; + shared_ptr callbackImpl = make_shared(callbackInner); + int32_t ret = CloudDiskServiceManager::GetInstance().RegisterSyncFolderChanges( + string(syncFolderPath.value, syncFolderPath.length), callbackImpl); + if (ret != CloudDiskServiceErrCode::E_OK) { + LOGE("Register sync folder change failed, ret: %{public}d", ret); + return CovertToErrorCode(ret); + } + return CloudDisk_ErrorCode::CLOUD_DISK_ERR_OK; +} + +CloudDisk_ErrorCode OH_CloudDisk_UnregisterSyncFolderChanges(const CloudDisk_SyncFolderPath syncFolderPath) +{ + if (!IsValidPathInfo(syncFolderPath.value, syncFolderPath.length)) { + LOGE("Invalid argument, syncFolder path is invalid"); + return CloudDisk_ErrorCode::CLOUD_DISK_INVALID_ARG; + } + int32_t ret = CloudDiskServiceManager::GetInstance().UnregisterSyncFolderChanges( + string(syncFolderPath.value, syncFolderPath.length)); + if (ret != CloudDiskServiceErrCode::E_OK) { + LOGE("Unegister sync folder change failed, ret: %{public}d", ret); + return CovertToErrorCode(ret); + } + return CloudDisk_ErrorCode::CLOUD_DISK_ERR_OK; +} + +CloudDisk_ErrorCode OH_CloudDisk_GetSyncFolderChanges(const CloudDisk_SyncFolderPath syncFolderPath, + uint64_t startUsn, + size_t count, + CloudDisk_ChangesResult **changesResult) +{ + if (!IsValidPathInfo(syncFolderPath.value, syncFolderPath.length)) { + LOGE("Invalid argument, syncFolder path is invalid"); + return CloudDisk_ErrorCode::CLOUD_DISK_INVALID_ARG; + } + ChangesResult changesRes; + auto ret = CloudDiskServiceManager::GetInstance().GetSyncFolderChanges( + string(syncFolderPath.value, syncFolderPath.length), count, startUsn, changesRes); + if (ret != CloudDiskServiceErrCode::E_OK) { + LOGE("Get sync folder change failed, ret: %{public}d", ret); + return CovertToErrorCode(ret); + } + *changesResult = (CloudDisk_ChangesResult *)malloc(sizeof(CloudDisk_ChangesResult) + + sizeof(CloudDisk_ChangeData) * changesRes.changesData.size()); + if (*changesResult == nullptr) { + LOGE("Failed to allocate memory for changesResult"); + return CloudDisk_ErrorCode::CLOUD_DISK_INTERNAL_ERROR; + } + (*changesResult)->length = 0; + (*changesResult)->nextUsn = changesRes.nextUsn; + (*changesResult)->isEof = changesRes.isEof; + for (auto &item : changesRes.changesData) { + LOGD("change data: fileId=%{public}s, parentFileId=%{public}s, relativePath=%{public}s, " + "updateSequenceNumber=%{public}lu, operationType=%{public}hhu", + item.fileId.c_str(), item.parentFileId.c_str(), item.relativePath.c_str(), item.updateSequenceNumber, + item.operationType); + CloudDisk_ChangeData data; + data.fileId.value = AllocField(item.fileId.c_str(), item.fileId.length()); + CHECK_NULLPTR_AND_CONTINUE(data.fileId.value); + data.fileId.length = item.fileId.length(); + data.parentFileId.value = AllocField(item.parentFileId.c_str(), item.parentFileId.length()); + CHECK_NULLPTR_AND_CONTINUE(data.parentFileId.value, delete[] data.fileId.value; data.fileId.value = nullptr;); + data.parentFileId.length = item.parentFileId.length(); + data.relativePathInfo.value = AllocField(item.relativePath.c_str(), item.relativePath.length()); + CHECK_NULLPTR_AND_CONTINUE(data.relativePathInfo.value, delete[] data.fileId.value; data.fileId.value = nullptr; + delete[] data.parentFileId.value; data.parentFileId.value = nullptr;); + data.relativePathInfo.length = item.relativePath.length(); + data.updateSequenceNumber = item.updateSequenceNumber; + data.operationType = static_cast(item.operationType); + data.size = item.size; + data.mtime = item.mtime; + data.timeStamp = item.timeStamp; + (*changesResult)->dataDatas[(*changesResult)->length++] = data; + } + return CloudDisk_ErrorCode::CLOUD_DISK_ERR_OK; +} + +CloudDisk_ErrorCode OH_CloudDisk_SetFileSyncStates(const CloudDisk_SyncFolderPath syncFolderPath, + const CloudDisk_FileSyncState fileSyncStates[], + size_t length, + CloudDisk_FailedList **failedLists, + size_t *failedCount) +{ + if (!IsValidPathInfo(syncFolderPath.value, syncFolderPath.length)) { + LOGE("Invalid argument, syncFolder path is invalid"); + return CloudDisk_ErrorCode::CLOUD_DISK_INVALID_ARG; + } + vector syncStatesVec; + for (size_t i = 0; i < length; ++i) { + FileSyncState state; + state.path = string(fileSyncStates[i].filePathInfo.value, fileSyncStates[i].filePathInfo.length); + state.state = static_cast(fileSyncStates[i].syncState); + syncStatesVec.emplace_back(state); + } + vector failedVec; + int32_t ret = CloudDiskServiceManager::GetInstance().SetFileSyncStates( + string(syncFolderPath.value, syncFolderPath.length), syncStatesVec, failedVec); + if (ret != CloudDiskServiceErrCode::E_OK) { + LOGE("Get sync folder change failed, ret: %{public}d", ret); + return CovertToErrorCode(ret); + } + *failedCount = failedVec.size(); + if (*failedCount == 0) { + *failedLists = nullptr; + return CloudDisk_ErrorCode::CLOUD_DISK_ERR_OK; + } + *failedLists = new (std::nothrow) CloudDisk_FailedList[*failedCount]; + if (*failedLists == nullptr) { + LOGE("Failed to allocate memory for failedLists"); + return CloudDisk_ErrorCode::CLOUD_DISK_INTERNAL_ERROR; + } + for (size_t index = 0; index < *failedCount; ++index) { + LOGD("failed list: path=%{public}s, errorReason=%{public}d", + failedVec[index].path.c_str(), failedVec[index].error); + (*failedLists)[index].pathInfo.value = + AllocField(failedVec[index].path.c_str(), failedVec[index].path.length()); + CHECK_NULLPTR_AND_CONTINUE((*failedLists)[index].pathInfo.value); + (*failedLists)[index].pathInfo.length = failedVec[index].path.length(); + (*failedLists)[index].errorReason = static_cast(failedVec[index].error); + } + return CloudDisk_ErrorCode::CLOUD_DISK_ERR_OK; +} + +CloudDisk_ErrorCode OH_CloudDisk_GetFileSyncStates(const CloudDisk_SyncFolderPath syncFolderPath, + const CloudDisk_PathInfo paths[], + size_t length, + CloudDisk_ResultList **resultLists, + size_t *resultCount) +{ + if (!IsValidPathInfo(syncFolderPath.value, syncFolderPath.length)) { + LOGE("Invalid argument, syncFolder path is invalid"); + return CloudDisk_ErrorCode::CLOUD_DISK_INVALID_ARG; + } + vector pathVec; + for (size_t i = 0; i < length; ++i) { + if (!IsValidPathInfo(paths[i].value, paths[i].length)) { + LOGE("Invalid argument, paths[%{public}zu] is nullptr", i); + return CloudDisk_ErrorCode::CLOUD_DISK_INVALID_ARG; + } + pathVec.emplace_back(string(paths[i].value, paths[i].length)); + } + vector resultVec; + int32_t ret = CloudDiskServiceManager::GetInstance().GetFileSyncStates( + string(syncFolderPath.value, syncFolderPath.length), pathVec, resultVec); + if (ret != CloudDiskServiceErrCode::E_OK) { + LOGE("Get file sync state failed, ret: %{public}d", ret); + return CovertToErrorCode(ret); + } + *resultCount = resultVec.size(); + if (*resultCount == 0) { + *resultLists = nullptr; + return CloudDisk_ErrorCode::CLOUD_DISK_ERR_OK; + } + *resultLists = new (std::nothrow) CloudDisk_ResultList[*resultCount]; + if (*resultLists == nullptr) { + LOGE("Failed to allocate memory for resultLists"); + return CloudDisk_ErrorCode::CLOUD_DISK_INTERNAL_ERROR; + } + for (size_t index = 0; index < *resultCount; ++index) { + LOGD("result list: path=%{public}s, isSuccess=%{public}d, syncState=%{public}d, errorReason=%{public}d", + resultVec[index].path.c_str(), resultVec[index].isSuccess, resultVec[index].state, + resultVec[index].error); + (*resultLists)[index].pathInfo.value = + AllocField(resultVec[index].path.c_str(), resultVec[index].path.length()); + (*resultLists)[index].pathInfo.length = resultVec[index].path.length(); + CHECK_NULLPTR_AND_CONTINUE((*resultLists)[index].pathInfo.value); + (*resultLists)[index].isSuccess = resultVec[index].isSuccess; + (*resultLists)[index].syncState = static_cast(resultVec[index].state); + (*resultLists)[index].errorReason = static_cast(resultVec[index].error); + } + return CloudDisk_ErrorCode::CLOUD_DISK_ERR_OK; +} diff --git a/interfaces/kits/ndk/clouddiskmanager/src/oh_cloud_disk_utils.cpp b/interfaces/kits/ndk/clouddiskmanager/src/oh_cloud_disk_utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3e54411b9d0c653609eb9fb81188d5211deda270 --- /dev/null +++ b/interfaces/kits/ndk/clouddiskmanager/src/oh_cloud_disk_utils.cpp @@ -0,0 +1,25 @@ +/* + * 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 "oh_cloud_disk_utils.h" + +CloudDisk_ErrorCode CovertToErrorCode(int32_t innerErrorCode) +{ + if (innerToNErrTable.find(innerErrorCode) != innerToNErrTable.end()) { + return innerToNErrTable.at(innerErrorCode); + } else { + return CloudDisk_ErrorCode::CLOUD_DISK_INTERNAL_ERROR; + } +} \ No newline at end of file