diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000000000000000000000000000000000000..5820ac6362a3dec47378aac6fe1f266f97221ae3 --- /dev/null +++ b/.clang-format @@ -0,0 +1,162 @@ +Language: Cpp +# BasedOnStyle: LLVM +# 访问说明符(public、private等)的偏移 +AccessModifierOffset: -4 +# 开括号(开圆括号、开尖括号、开方括号)后的对齐 +AlignAfterOpenBracket: Align +# 连续赋值时,等号对齐 +AlignConsecutiveAssignments: false +# 连续赋值时,变量名对齐 +AlignConsecutiveDeclarations: false +# 左对齐逃脱换行(使用反斜杠换行)的反斜杠 +AlignEscapedNewlinesLeft: true +# 水平对齐二元和三元表达式的操作数 +AlignOperands: true +# 对齐连续的尾随的注释 +AlignTrailingComments: true +# 允许函数声明的所有参数在放在下一行 +AllowAllParametersOfDeclarationOnNextLine: false +# 允许短的块放在同一行 +AllowShortBlocksOnASingleLine: false +# 允许短的case标签放在同一行 +AllowShortCaseLabelsOnASingleLine: false +# 允许短的函数放在同一行: None, InlineOnly(定义在类中), Empty(空函数), Inline(定义在类中,空函数), All +AllowShortFunctionsOnASingleLine: Empty +# 允许短的if语句保持在同一行 +AllowShortIfStatementsOnASingleLine: false +# 允许短的循环保持在同一行 +AllowShortLoopsOnASingleLine: false +# 总是在定义返回类型后换行(deprecated) +AlwaysBreakAfterDefinitionReturnType: None +# 总是在返回类型后换行: None, All, TopLevel(顶级函数,不包括在类中的函数), +# AllDefinitions(所有的定义,不包括声明), TopLevelDefinitions(所有的顶级函数的定义) +AlwaysBreakAfterReturnType: None +# 总是在多行string字面量前换行 +AlwaysBreakBeforeMultilineStrings: true +# 总是在template声明后换行 +AlwaysBreakTemplateDeclarations: true +# +SpaceAfterTemplateKeyword: false +# false表示函数实参要么都在同一行,要么都各自一行 +BinPackArguments: true +# false表示所有形参要么都在同一行,要么都各自一行 +BinPackParameters: false +# 大括号换行,只有当BreakBeforeBraces设置为Custom时才有效 +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false +# 在二元运算符前换行: None(在操作符后换行), NonAssignment(在非赋值的操作符前换行), All(在操作符前换行) +BreakBeforeBinaryOperators: None +# 在大括号前换行: Attach(始终将大括号附加到周围的上下文), Linux(除函数、命名空间和类定义,与Attach类似), +# Mozilla(除枚举、函数、记录定义,与Attach类似), Stroustrup(除函数定义、catch、else,与Attach类似), +# Allman(总是在大括号前换行), GNU(总是在大括号前换行,并对于控制语句的大括号增加额外的缩进), WebKit(在函数前换行), Custom +# 注:这里认为语句块也属于函数 +BreakBeforeBraces: Custom +# 在三元运算符前换行 +BreakBeforeTernaryOperators: true +# 在构造函数的初始化列表的逗号前换行 +BreakConstructorInitializersBeforeComma: false +# 每行字符的限制,0表示没有限制 +ColumnLimit: 120 +# 描述具有特殊意义的注释的正则表达式,它不应该被分割为多行或以其它方式改变 +CommentPragmas: "^ IWYU pragma:" +# 构造函数的初始化列表要么都在同一行,要么都各自一行 +ConstructorInitializerAllOnOneLineOrOnePerLine: true +# 构造函数的初始化列表的缩进宽度 +ConstructorInitializerIndentWidth: 4 +# 延续的行的缩进宽度 +ContinuationIndentWidth: 4 +# 去除C++11的列表初始化的大括号{后和}前的空格 +Cpp11BracedListStyle: true +# 继承最常用的指针和引用的对齐方式 +DerivePointerAlignment: false +# 关闭格式化 +DisableFormat: false +# 自动检测函数的调用和定义是否被格式为每行一个参数(Experimental) +ExperimentalAutoDetectBinPacking: false +# 需要被解读为foreach循环而不是函数调用的宏 +ForEachMacros: [foreach, Q_FOREACH, BOOST_FOREACH] +# 对#include进行排序,匹配了某正则表达式的#include拥有对应的优先级,匹配不到的则默认优先级为INT_MAX(优先级越小排序越靠前), +# 可以定义负数优先级从而保证某些#include永远在最前面 +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + - Regex: '^(<|"(gtest|isl|json)/)' + Priority: 3 + - Regex: ".*" + Priority: 1 +# 缩进case标签 +IndentCaseLabels: true +# 缩进宽度 +IndentWidth: 4 +# 函数返回类型换行时,缩进函数声明或函数定义的函数名 +IndentWrappedFunctionNames: true +# 保留在块开始处的空行 +KeepEmptyLinesAtTheStartOfBlocks: true +# 开始一个块的宏的正则表达式 +MacroBlockBegin: "" +# 结束一个块的宏的正则表达式 +MacroBlockEnd: "" +# 连续空行的最大数量 +MaxEmptyLinesToKeep: 1 +# 命名空间的缩进: None, Inner(缩进嵌套的命名空间中的内容), All +NamespaceIndentation: None +# 使用ObjC块时缩进宽度 +ObjCBlockIndentWidth: 4 +# 在ObjC的@property后添加一个空格 +ObjCSpaceAfterProperty: false +# 在ObjC的protocol列表前添加一个空格 +ObjCSpaceBeforeProtocolList: true +# 在call(后对函数调用换行的penalty +PenaltyBreakBeforeFirstCallParameter: 19 +# 在一个注释中引入换行的penalty +PenaltyBreakComment: 300 +# 第一次在<<前换行的penalty +PenaltyBreakFirstLessLess: 120 +# 在一个字符串字面量中引入换行的penalty +PenaltyBreakString: 1000 +# 对于每个在行字符数限制之外的字符的penalty +PenaltyExcessCharacter: 1000000 +# 将函数的返回类型放到它自己的行的penalty +PenaltyReturnTypeOnItsOwnLine: 60 +# 指针和引用的对齐: Left, Right, Middle +PointerAlignment: Right +# 允许重新排版注释 +ReflowComments: true +# 允许排序#include +SortIncludes: true +# 在C风格类型转换后添加空格 +SpaceAfterCStyleCast: false +# 在赋值运算符之前添加空格 +SpaceBeforeAssignmentOperators: true +# 开圆括号之前添加一个空格: Never, ControlStatements, Always +SpaceBeforeParens: ControlStatements +# 在空的圆括号中添加空格 +SpaceInEmptyParentheses: false +# 在尾随的评论前添加的空格数(只适用于//) +SpacesBeforeTrailingComments: 1 +# 在尖括号的<后和>前添加空格 +SpacesInAngles: false +# 在容器(ObjC和JavaScript的数组和字典等)字面量中添加空格 +SpacesInContainerLiterals: true +# 在C风格类型转换的括号中添加空格 +SpacesInCStyleCastParentheses: false +# 在圆括号的(后和)前添加空格 +SpacesInParentheses: false +# 在方括号的[后和]前添加空格,lamda表达式和未指明大小的数组的声明不受影响 +SpacesInSquareBrackets: false +# 标准: Cpp03, Cpp11, Auto +Standard: Cpp11 +# tab宽度 +TabWidth: 4 +# 使用tab字符: Never, ForIndentation, ForContinuationAndIndentation, Always +UseTab: Never \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..4947287f7b5ccb5d1e8b7b2d3aa5d89f322c160d --- /dev/null +++ b/LICENSE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/distributedfile.gni b/distributedfile.gni new file mode 100755 index 0000000000000000000000000000000000000000..60ee10292c5c4ed30a454437ea08018866253772 --- /dev/null +++ b/distributedfile.gni @@ -0,0 +1,18 @@ +# Copyright (c) 2021 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. + +distributedfile_path = "//foundation/storage/distributed_file_manager" + +utils_path = "${distributedfile_path}/utils" +services_path = "${distributedfile_path}/services" +innerkits_native_path = "${distributedfile_path}/interfaces/innerkits/native" \ No newline at end of file diff --git a/frameworks/native/BUILD.gn b/frameworks/native/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..942bde711ee4e8e355ca60e38367ba4dbd8e1c42 --- /dev/null +++ b/frameworks/native/BUILD.gn @@ -0,0 +1,24 @@ +# Copyright (C) 2021 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/storage/distributed_file_manager/distributedfile.gni") + +ohos_shared_library("libdistributedfile_innerkits") { + include_dirs = [ "${innerkits_native_path}" ] + + sources = [ + ] + + part_name = "storage_distributed_file_manager" + subsystem_name = "storage" +} \ No newline at end of file diff --git a/interfaces/innerkits/native/daemon_proxy.h b/interfaces/innerkits/native/daemon_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..013803ef38a758e8f9c68248a3d4bbb6db06f251 --- /dev/null +++ b/interfaces/innerkits/native/daemon_proxy.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 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 DAEMON_PROXY_H +#define DAEMON_PROXY_H + +#include + +#include "i_daemon.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class DaemonProxy : public IRemoteProxy { +public: + explicit DaemonProxy(const sptr &impl) : IRemoteProxy(impl) {} + ~DaemonProxy() {} + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // DAEMON_PROXY_H \ No newline at end of file diff --git a/ohos.build b/ohos.build new file mode 100755 index 0000000000000000000000000000000000000000..575dc9bbad43f2c715848719870e084f72014348 --- /dev/null +++ b/ohos.build @@ -0,0 +1,18 @@ +{ + "subsystem": "storage", + "parts": { + "storage_distributed_file_manager": { + "variants": [ + "wearable", + "phone" + ], + "module_list": [ + "//foundation/storage/distributed_file_manager/services/:services_target" + ], + "test_list": [ + "//foundation/storage/distributed_file_manager/services/distributedfiledaemon/test/unittest:unittest", + "//foundation/storage/distributed_file_manager/test/moduletest:moduletest" + ] + } + } +} diff --git a/services/4901.xml b/services/4901.xml new file mode 100755 index 0000000000000000000000000000000000000000..7d140a704e3f867490b801fa6fb9d2789502f28b --- /dev/null +++ b/services/4901.xml @@ -0,0 +1,30 @@ + + + + distributedfiledaemon + + libdistributedfiledaemon.z.so + + + 4901 + libdistributedfiledaemon.z.so + + + true + false + 1 + + diff --git a/services/BUILD.gn b/services/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..91e21af8e8e29264b6c9969328b6e40d2a018867 --- /dev/null +++ b/services/BUILD.gn @@ -0,0 +1,35 @@ +# Copyright (C) 2021 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/sa_profile/sa_profile.gni") +import("//foundation/storage/distributed_file_manager/distributedfile.gni") + +ohos_sa_profile("distributedfile_sa_profile") { + sources = [ "4901.xml" ] + part_name = "storage_distributed_file_manager" +} + +ohos_prebuilt_etc("distributedfile_etc") { + source = "distributedfile.cfg" + relative_install_dir = "init" + part_name = "storage_distributed_file_manager" + subsystem_name = "storage" +} + +group("services_target") { + deps = [ + ":distributedfile_etc", + ":distributedfile_sa_profile", + "distributedfiledaemon:distributedfiledaemon_target", + ] +} diff --git a/services/distributedfile.cfg b/services/distributedfile.cfg new file mode 100644 index 0000000000000000000000000000000000000000..bc21a7068bfc146ffe0bcf56f39ffc6571df87d0 --- /dev/null +++ b/services/distributedfile.cfg @@ -0,0 +1,20 @@ +{ + "jobs": [{ + "name": "boot", + "cmds": [ + "start distributedfiledaemon" + ] + },{ + "name" : "init", + "cmds" : [ + "mount tmpfs tmpfs /mnt" + ] + }], + "services": [{ + "name": "distributedfiledaemon", + "path": ["/system/bin/sa_main", "/system/profile/distributedfiledaemon.xml"], + "uid": "root", + "gid": ["root", "system", "shell", "readproc", "media_rw", "inet"], + "caps": ["SYS_PTRACE", "KILL"] + }] +} \ No newline at end of file diff --git a/services/distributedfiledaemon/BUILD.gn b/services/distributedfiledaemon/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..c18dc7558ba715de63637c0fb711cda2b2f4c43f --- /dev/null +++ b/services/distributedfiledaemon/BUILD.gn @@ -0,0 +1,54 @@ +# Copyright (C) 2021 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/storage/distributed_file_manager/distributedfile.gni") + +ohos_shared_library("libdistributedfiledaemon") { + include_dirs = [ + "include", + "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp/include", + ] + + sources = [ + "src/ipc/daemon.cpp", + "src/ipc/daemon_stub.cpp", + "src/mountpoint/mount_manager.cpp", + "src/mountpoint/mount_point.cpp", + "src/device/device_info.cpp", + "src/device/device_manager_agent.cpp", + "src/network/network_agent_template.cpp", + "src/network/softbus/softbus_agent.cpp", + "src/network/softbus/softbus_session_dispatcher.cpp", + "src/network/softbus/softbus_session.cpp", + "src/network/kernel_talker.cpp", + "src/network/session_pool.cpp" + ] + + deps = [ + "${utils_path}:libdistributedfileutils", + "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp:devicemanagersdk", + ] + external_deps = [ + "dsoftbus_standard:softbus_client", + "ipc:ipc_core", + "safwk:system_ability_fwk", + ] + configs = [ "${utils_path}:compiler_configs" ] + + part_name = "storage_distributed_file_manager" + subsystem_name = "storage" +} + +group("distributedfiledaemon_target") { + deps = [ ":libdistributedfiledaemon" ] +} diff --git a/services/distributedfiledaemon/include/device/device_info.h b/services/distributedfiledaemon/include/device/device_info.h new file mode 100644 index 0000000000000000000000000000000000000000..2a340d56c2625cceae56c61f5bf0acaa384245fa --- /dev/null +++ b/services/distributedfiledaemon/include/device/device_info.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 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 DEVICE_INFO_H +#define DEVICE_INFO_H + +#include +#include + +#include "dm_device_info.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class DeviceInfo final { +public: + DeviceInfo() = default; + ~DeviceInfo() = default; + explicit DeviceInfo(const DistributedHardware::DmDeviceInfo &nodeInfo); + explicit DeviceInfo(const DeviceInfo &nodeInfo); + DeviceInfo &operator=(const DistributedHardware::DmDeviceInfo &nodeInfo); + + /** + * @note Remove the concept iid later + */ + void SetIid(const uint64_t iid); + void SetCid(const std::string &cid); + + uint64_t GetIid() const; + const std::string &GetCid() const; + +private: + std::atomic initIidFlag_{false}; + std::atomic initCidFlag_{false}; + + uint64_t iid_{0}; + std::string cid_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // DEVICE_INFO_H \ No newline at end of file diff --git a/services/distributedfiledaemon/include/device/device_manager_agent.h b/services/distributedfiledaemon/include/device/device_manager_agent.h new file mode 100644 index 0000000000000000000000000000000000000000..aa3948fb256c07591eccb650f20c362706868a1e --- /dev/null +++ b/services/distributedfiledaemon/include/device/device_manager_agent.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2021 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 DEVICE_MANAGER_AGENT_H +#define DEVICE_MANAGER_AGENT_H + +#include +#include +#include +#include + +#include "device_info.h" +#include "device_manager.h" +#include "mountpoint/mount_point.h" +#include "network/network_agent_template.h" +#include "utils_singleton.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class DeviceManagerAgent final : public DistributedHardware::DmInitCallback, + public DistributedHardware::DeviceStateCallback, + public std::enable_shared_from_this, + public Utils::Singleton { + DECLARE_SINGLETON(DeviceManagerAgent); + +public: + void JoinGroup(std::weak_ptr mp); + void QuitGroup(std::weak_ptr mp); + + void OnDeviceOnline(const DistributedHardware::DmDeviceInfo &deviceInfo) override; + void OnDeviceOffline(const DistributedHardware::DmDeviceInfo &deviceInfo) override; + void OnDeviceChanged(const DistributedHardware::DmDeviceInfo &deviceInfo) override; + void OnDeviceReady(const DistributedHardware::DmDeviceInfo &deviceInfo) override {} + + void OnRemoteDied() override; + + DeviceInfo &GetLocalDeviceInfo(); + std::vector GetRemoteDevicesInfo(); + +private: + void InitLocalIid(); + void InitLocalNodeInfo(); + void RegisterToExternalDm(); + void UnregisterFromExternalDm(); + void Start() override; + void Stop() override; + + // We use a mutex instead of a shared_mutex to serialize online/offline procedures + std::mutex mpToNetworksMutex_; + std::map> mpToNetworks_; + DeviceInfo localDeviceInfo_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // DEVICE_MANAGER_AGENT_H \ No newline at end of file diff --git a/services/distributedfiledaemon/include/ipc/daemon.h b/services/distributedfiledaemon/include/ipc/daemon.h new file mode 100644 index 0000000000000000000000000000000000000000..986cc7a3f35209ff6c188040df8eaac78b4e3cfe --- /dev/null +++ b/services/distributedfiledaemon/include/ipc/daemon.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2021 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 DAEMON_H +#define DAEMON_H + +#include + +#include "daemon_stub.h" +#include "i_daemon.h" +#include "iremote_stub.h" +#include "system_ability.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +enum class ServiceRunningState { STATE_NOT_START, STATE_RUNNING }; + +class Daemon final: public SystemAbility, public DaemonStub, protected NoCopyable { + DECLARE_SYSTEM_ABILITY(Daemon); + +public: + explicit Daemon(int32_t saID, bool runOnCreate = true) : SystemAbility(saID, runOnCreate){}; + virtual ~Daemon() = default; + + void OnStart() override; + void OnStop() override; + ServiceRunningState QueryServiceState() const + { + return state_; + } + + int32_t EchoServerDemo(const std::string &echoStr) override; + +private: + Daemon(); + ServiceRunningState state_{ServiceRunningState::STATE_NOT_START}; + static sptr instance_; + static std::mutex instanceLock_; + bool registerToService_{false}; + + void PublishSA(); + void StartManagers(); +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // DAEMON_H \ No newline at end of file diff --git a/services/distributedfiledaemon/include/ipc/daemon_stub.h b/services/distributedfiledaemon/include/ipc/daemon_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..7ebf25ecde9826c51cf8c649553b7c3fc714a57a --- /dev/null +++ b/services/distributedfiledaemon/include/ipc/daemon_stub.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 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 DAEMON_STUB_H +#define DAEMON_STUB_H + +#include + +#include "i_daemon.h" +#include "iremote_stub.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class DaemonStub : public IRemoteStub { +public: + DaemonStub(); + virtual ~DaemonStub() = default; + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + using DaemonInterface = int32_t (DaemonStub::*)(MessageParcel &data, MessageParcel &reply); + std::map opToInterfaceMap_; + + int32_t EchoServerDemoInner(MessageParcel &data, MessageParcel &reply); +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // DAEMON_STUB_H \ No newline at end of file diff --git a/services/distributedfiledaemon/include/ipc/i_daemon.h b/services/distributedfiledaemon/include/ipc/i_daemon.h new file mode 100644 index 0000000000000000000000000000000000000000..fce520673c0ca6f62a03c02a65925712fd3b58e7 --- /dev/null +++ b/services/distributedfiledaemon/include/ipc/i_daemon.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 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 I_DAEMON_H +#define I_DAEMON_H + +#include "iremote_broker.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class IDaemon : public IRemoteBroker { +public: + enum { + DFS_DAEMON_CMD_ECHO = 0, + }; + virtual int32_t EchoServerDemo(const std::string &echoStr) = 0; + + static inline const std::string SERVICE_NAME{"ohos.storage.distributedfile.daemon"}; + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.storage.distributedfile.daemon") +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // I_DAEMON_H \ No newline at end of file diff --git a/services/distributedfiledaemon/include/mountpoint/mount_manager.h b/services/distributedfiledaemon/include/mountpoint/mount_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..41b0156506961829fbcf7d8c8d38e7dda14d23ed --- /dev/null +++ b/services/distributedfiledaemon/include/mountpoint/mount_manager.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 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 MOUNT_MANAGER_H +#define MOUNT_MANAGER_H + +#include +#include +#include + +#include "mount_point.h" +#include "utils_singleton.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class MountManager final : public Utils::Singleton { +public: + void Mount(std::unique_ptr mp); + void Umount(std::weak_ptr wmp); + + DECLARE_SINGLETON(MountManager); + +private: + void Start() override {} + void Stop() override {} + + std::mutex serializer_; + std::vector> mountPoints_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // MOUNT_MANAGER_H \ No newline at end of file diff --git a/services/distributedfiledaemon/include/mountpoint/mount_point.h b/services/distributedfiledaemon/include/mountpoint/mount_point.h new file mode 100644 index 0000000000000000000000000000000000000000..59019a953f847abb4bda491f5cdd3dac9b46b2b0 --- /dev/null +++ b/services/distributedfiledaemon/include/mountpoint/mount_point.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 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 MOUNT_POINT_H +#define MOUNT_POINT_H + +#include +#include + +#include "nocopyable.h" +#include "utils_mount_argument.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class MountPoint final : public NoCopyable { +public: + MountPoint(const Utils::MountArgument &mountArg); + ~MountPoint() = default; + + uint32_t GetID() const + { + return id_; + }; + + std::string ToString() const; + Utils::MountArgument GetMountArgument() const; + bool operator==(const MountPoint &rop) const; + +private: + friend class MountManager; + Utils::MountArgument mountArg_; + void Mount() const; + void Umount() const; + static std::atomic idGen_; + uint32_t id_{0}; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // MOUNT_POINT_H \ No newline at end of file diff --git a/services/distributedfiledaemon/include/network/base_session.h b/services/distributedfiledaemon/include/network/base_session.h new file mode 100644 index 0000000000000000000000000000000000000000..db1f3aea37bb712243a39f3586862f4b53120363 --- /dev/null +++ b/services/distributedfiledaemon/include/network/base_session.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 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 BASE_SESSION_H +#define BASE_SESSION_H + +#include + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +constexpr int KEY_SIZE_MAX = 32; + +class BaseSession { +public: + virtual ~BaseSession() = default; + virtual bool IsFromServer() const = 0; + virtual std::string GetCid() const = 0; + virtual int32_t GetHandle() const = 0; + virtual std::array GetKey() const = 0; + virtual void Release() const = 0; + virtual void DisableSessionListener() const = 0; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // BASE_SESSION_H \ No newline at end of file diff --git a/services/distributedfiledaemon/include/network/kernel_talker.h b/services/distributedfiledaemon/include/network/kernel_talker.h new file mode 100644 index 0000000000000000000000000000000000000000..c33a95ffa29c1a9eb7116e0534cd3c8c44542fa6 --- /dev/null +++ b/services/distributedfiledaemon/include/network/kernel_talker.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2021 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 KERNEL_TALKER_H +#define KERNEL_TALKER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mountpoint/mount_point.h" +#include "network/base_session.h" +#include "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +constexpr int CID_MAX_LEN = 64; +struct NotifyParam { + int32_t notify; + int32_t fd; + uint64_t remoteIid; + uint16_t udpPort; + uint8_t deviceType; + int32_t flag; + int32_t reserved; + char remoteCid[CID_MAX_LEN]; +} __attribute__((packed)); + +class KernelTalker final : protected NoCopyable { +public: + explicit KernelTalker(std::weak_ptr mountPoint, std::function callback) + : mountPoint_(mountPoint), GetSessionCallback_(callback) + { + } + KernelTalker() = default; + ~KernelTalker() = default; + + void SinkSessionTokernel(std::shared_ptr session); + void SinkInitCmdToKernel(uint64_t iid); + void SinkOfflineCmdToKernel(std::string cid); + std::unordered_set GetKernelSesions(); + + void CreatePollThread(); + void WaitForPollThreadExited(); + +private: + template + void SetCmd(T &cmd) + { + auto spt = mountPoint_.lock(); + if (spt == nullptr) { + LOGE("mountPoint is not exist! bad weak_ptr"); + return; // ! 抛异常 + } + std::string ctrlPath = spt->GetMountArgument().GetCtrlPath(); + LOGI("cmd path:%{public}s", ctrlPath.c_str()); + std::lock_guard lock(cmdMutex_); + int file = open(ctrlPath.c_str(), O_RDWR); + if (file < 0) { + LOGE("Open node file error. %{public}d", file); + return; + } + int err = write(file, &cmd, sizeof(T)); + if (err < 0) { + LOGE("write return err. %{public}d", err); + } + close(file); + return; + } + + void PollRun(); + void HandleAllNotify(int fd); + void NotifyHandler(NotifyParam ¶m); + + std::weak_ptr mountPoint_; + std::mutex cmdMutex_; + std::atomic isRunning_{true}; + std::unique_ptr pollThread_{nullptr}; + std::function GetSessionCallback_{nullptr}; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // KERNEL_TALKER_H \ No newline at end of file diff --git a/services/distributedfiledaemon/include/network/network_agent_template.h b/services/distributedfiledaemon/include/network/network_agent_template.h new file mode 100644 index 0000000000000000000000000000000000000000..0f9485fae2007c28945b7f4df1854d5c985a1af7 --- /dev/null +++ b/services/distributedfiledaemon/include/network/network_agent_template.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2021 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 NETWORK_AGENT_TEMPLATE_H +#define NETWORK_AGENT_TEMPLATE_H + +#include +#include +#include +#include + +#include "device/device_info.h" +#include "mountpoint/mount_point.h" +#include "network/kernel_talker.h" +#include "network/session_pool.h" +#include "utils_dfs_thread.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class NetworkAgentTemplate { +public: + explicit NetworkAgentTemplate(std::weak_ptr mountPoint) + : mountPoint_(mountPoint), + kernerlTalker_(mountPoint, [&](NotifyParam ¶m) { GetSessionProcess(param); }), + sessionPool_(kernerlTalker_) + { + } + virtual ~NetworkAgentTemplate() {} + void Start(); + void Stop(); + void ConnectOnlineDevices(); + void ConnectDeviceAsync(const DeviceInfo &info); + void DisconnectDevice(const DeviceInfo &info); + void AcceptSession(std::shared_ptr session); + +protected: + virtual void JoinDomain() = 0; + virtual void QuitDomain() = 0; + virtual void StopTopHalf() = 0; + virtual void StopBottomHalf() = 0; + virtual std::shared_ptr OpenSession(const DeviceInfo &info) = 0; + virtual void CloseSession(std::shared_ptr session) = 0; + + std::weak_ptr mountPoint_; + +private: + void HandleAllNotify(int fd); + void NotifyHandler(NotifyParam ¶m); + void GetSessionProcess(NotifyParam ¶m); + void GetSesion(const std::string &cid); + + std::mutex taskMut_; + std::list tasks_; + KernelTalker kernerlTalker_; + SessionPool sessionPool_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // NETWORK_AGENT_TEMPLATE_H \ No newline at end of file diff --git a/services/distributedfiledaemon/include/network/session_pool.h b/services/distributedfiledaemon/include/network/session_pool.h new file mode 100644 index 0000000000000000000000000000000000000000..52226b18624000c66512d5cb0971a572dac29859 --- /dev/null +++ b/services/distributedfiledaemon/include/network/session_pool.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 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 SESSION_POOL_H +#define SESSION_POOL_H + +#include +#include +#include +#include + +#include "network/base_session.h" +#include "network/kernel_talker.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class SessionPool final : protected NoCopyable { +public: + explicit SessionPool(KernelTalker &talker) : talker_(talker) {} + ~SessionPool() = default; + void HoldSession(std::shared_ptr session); + void RefreshSessionPoolBasedOnKernel(); + +private: + std::recursive_mutex sessionPoolLock_; + std::list> usrSpaceSessionPool_; + KernelTalker &talker_; + + void AddSessionToPool(std::shared_ptr session); +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // SESSION_POOL_H \ No newline at end of file diff --git a/services/distributedfiledaemon/include/network/softbus/softbus_agent.h b/services/distributedfiledaemon/include/network/softbus/softbus_agent.h new file mode 100644 index 0000000000000000000000000000000000000000..c3065aff3e5ab76ea8af9e1b8a3b1eb50145313a --- /dev/null +++ b/services/distributedfiledaemon/include/network/softbus/softbus_agent.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 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 SOFTBUS_AGENT_H +#define SOFTBUS_AGENT_H + +#include "network/network_agent_template.h" +#include + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class SoftbusAgent final : public NetworkAgentTemplate, public std::enable_shared_from_this { +public: + explicit SoftbusAgent(std::weak_ptr mountPoint); + ~SoftbusAgent() = default; + int OnSessionOpened(const int sessionId, const int result); + void OnSessionClosed(int sessionId); + +protected: + void JoinDomain() override; + void QuitDomain() override; + void StopTopHalf() override; + void StopBottomHalf() override; + std::shared_ptr OpenSession(const DeviceInfo &info) override; + void CloseSession(std::shared_ptr session) override; + +private: + std::string sessionName_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // SOFTBUS_AGENT_H \ No newline at end of file diff --git a/services/distributedfiledaemon/include/network/softbus/softbus_session.h b/services/distributedfiledaemon/include/network/softbus/softbus_session.h new file mode 100644 index 0000000000000000000000000000000000000000..0d6d30eef8d376b718267012fd2cf3593e343783 --- /dev/null +++ b/services/distributedfiledaemon/include/network/softbus/softbus_session.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 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 SOFTBUS_SESSION_H +#define SOFTBUS_SESSION_H + +#include "network/base_session.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class SoftbusSession final : public BaseSession { +public: + SoftbusSession(int sessionId) : sessionId_(sessionId) {} + ~SoftbusSession() = default; + bool IsFromServer() const override; + std::string GetCid() const override; + int32_t GetHandle() const override; + std::array GetKey() const override; + void Release() const override; + void DisableSessionListener() const override; + +private: + int sessionId_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // SOFTBUS_SESSION_H \ No newline at end of file diff --git a/services/distributedfiledaemon/include/network/softbus/softbus_session_dispatcher.h b/services/distributedfiledaemon/include/network/softbus/softbus_session_dispatcher.h new file mode 100644 index 0000000000000000000000000000000000000000..fc7e1d9cd0617601a9e51cfcaa990ac989fe3d0a --- /dev/null +++ b/services/distributedfiledaemon/include/network/softbus/softbus_session_dispatcher.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 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 SOFTBUS_SESSION_DISPATCHER_H +#define SOFTBUS_SESSION_DISPATCHER_H + +#include +#include +#include +#include + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class SoftbusAgent; +class SoftbusSessionDispatcher final { +public: + SoftbusSessionDispatcher() = delete; + ~SoftbusSessionDispatcher() = delete; + static void RegisterSessionListener(const std::string busName, std::weak_ptr); + static void UnregisterSessionListener(const std::string busName); + static std::weak_ptr GetAgent(int sessionId); + static int OnSessionOpened(int sessionId, int result); + static void OnSessionClosed(int sessionId); + +private: + static std::mutex softbusAgentMutex_; + static std::map> busNameToAgent_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // SOFTBUS_SESSION_DISPATCHER_H \ No newline at end of file diff --git a/services/distributedfiledaemon/include/network/softbus/softbus_session_name.h b/services/distributedfiledaemon/include/network/softbus/softbus_session_name.h new file mode 100644 index 0000000000000000000000000000000000000000..87d3b4de38bb0318063d66e6321d7391637def21 --- /dev/null +++ b/services/distributedfiledaemon/include/network/softbus/softbus_session_name.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 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 SOFTBUS_SESSION_NAME_H +#define SOFTBUS_SESSION_NAME_H + +#include + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class SoftbusSessionName final { +public: + explicit SoftbusSessionName(std::string path) : path_(path) {} + ~SoftbusSessionName() = default; + std::string ToString() + { + return prefix + path_; + } + +private: + const std::string prefix = "DistributedFileService"; + std::string path_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // SOFTBUS_SESSION_NAME_H \ No newline at end of file diff --git a/services/distributedfiledaemon/src/device/device_info.cpp b/services/distributedfiledaemon/src/device/device_info.cpp new file mode 100644 index 0000000000000000000000000000000000000000..293ece7b72427cd142415b3b3c169a22743b2697 --- /dev/null +++ b/services/distributedfiledaemon/src/device/device_info.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2021 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 "device/device_info.h" +#include "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +using namespace std; + +DeviceInfo::DeviceInfo(const DistributedHardware::DmDeviceInfo &nodeInfo) +{ + cid_ = string(nodeInfo.deviceId); +} + +DeviceInfo &DeviceInfo::operator=(const DistributedHardware::DmDeviceInfo &nodeInfo) +{ + cid_ = string(nodeInfo.deviceId); + return *this; +} + +DeviceInfo::DeviceInfo(const DeviceInfo &nodeInfo) : iid_(nodeInfo.iid_), cid_(nodeInfo.cid_) +{ + initIidFlag_.store(nodeInfo.initIidFlag_.load()); + initCidFlag_.store(nodeInfo.initCidFlag_.load()); +} + +void DeviceInfo::SetIid(const uint64_t iid) +{ + if (initIidFlag_ == false) { + iid_ = iid; + initIidFlag_ = true; + } else { + LOGI("Iid is already initializing"); + } +} + +void DeviceInfo::SetCid(const string &cid) +{ + if (initCidFlag_ == false) { + cid_ = cid; + initCidFlag_ = true; + } else { + LOGI("Cid is already initializing"); + } +} + +uint64_t DeviceInfo::GetIid() const +{ + if (initIidFlag_ == false) { + // TODO 抛异常 + } + return iid_; +} +const string &DeviceInfo::GetCid() const +{ + if (initCidFlag_ == false) { + // TODO 抛异常 + } + return cid_; +} +} // namespace DistributedFile +} // namespace Storages +} // namespace OHOS \ No newline at end of file diff --git a/services/distributedfiledaemon/src/device/device_manager_agent.cpp b/services/distributedfiledaemon/src/device/device_manager_agent.cpp new file mode 100644 index 0000000000000000000000000000000000000000..84e57a38e21e936bd0f698482c5b9ab6b87dd511 --- /dev/null +++ b/services/distributedfiledaemon/src/device/device_manager_agent.cpp @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2021 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 "device/device_manager_agent.h" +#include "network/softbus/softbus_agent.h" + +#include +#include + +#include "ipc/i_daemon.h" +#include "softbus_bus_center.h" +#include "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +using namespace std; + +DeviceManagerAgent::DeviceManagerAgent() {} + +DeviceManagerAgent::~DeviceManagerAgent() +{ + StopInstance(); +} + +void DeviceManagerAgent::Start() +{ + RegisterToExternalDm(); // TODO Catch? + InitLocalNodeInfo(); +} + +void DeviceManagerAgent::Stop() +{ + UnregisterFromExternalDm(); +} + +void DeviceManagerAgent::JoinGroup(weak_ptr mp) +{ + auto smp = mp.lock(); + if (!smp) { + stringstream ss("Failed to join group: Received empty mountpoint"); + LOGE("%s", ss.str().c_str()); + throw runtime_error(ss.str()); + } + + unique_lock lock(mpToNetworksMutex_); + auto agent = make_shared(mp); + auto [ignored, inserted] = mpToNetworks_.insert({smp->GetID(), agent}); + if (!inserted) { + stringstream ss; + ss << "Failed to join group: Mountpoint existed" << smp->ToString(); + throw runtime_error(ss.str()); + } + + agent->Start(); +} + +void DeviceManagerAgent::QuitGroup(weak_ptr mp) +{ + auto smp = mp.lock(); + if (!smp) { + stringstream ss("Failed to quit group: Received empty mountpoint"); + LOGE("%s", ss.str().c_str()); + throw runtime_error(ss.str()); + } + + unique_lock lock(mpToNetworksMutex_); + auto it = mpToNetworks_.find(smp->GetID()); + if (it == mpToNetworks_.end()) { + stringstream ss; + ss << "Failed to quit group: Mountpoint didn't exist " << smp->ToString(); + throw runtime_error(ss.str()); + } + + it->second->Stop(); + mpToNetworks_.erase(smp->GetID()); +} + +void DeviceManagerAgent::OnDeviceOnline(const DistributedHardware::DmDeviceInfo &deviceInfo) +{ + LOGI("OnDeviceOnline begin"); + auto dm = DeviceManagerAgent::GetInstance(); + unique_lock lock(dm->mpToNetworksMutex_); + for (auto &&networkAgent : dm->mpToNetworks_) { + DeviceInfo info(deviceInfo); + networkAgent.second->ConnectDeviceAsync(info); + } + LOGI("OnDeviceOnline end"); +} + +void DeviceManagerAgent::OnDeviceOffline(const DistributedHardware::DmDeviceInfo &deviceInfo) +{ + LOGI("OnDeviceOffline begin"); + auto dm = DeviceManagerAgent::GetInstance(); + + unique_lock lock(dm->mpToNetworksMutex_); + for (auto &&networkAgent : dm->mpToNetworks_) { + DeviceInfo info(deviceInfo); + networkAgent.second->DisconnectDevice(info); + } + LOGI("OnDeviceOffline end"); +} + +void DeviceManagerAgent::OnDeviceChanged(const DistributedHardware::DmDeviceInfo &deviceInfo) +{ + LOGI("OnDeviceInfoChanged"); +} + +void DeviceManagerAgent::InitLocalNodeInfo() +{ + NodeBasicInfo tmpNodeInfo; + int errCode = GetLocalNodeDeviceInfo(IDaemon::SERVICE_NAME.c_str(), &tmpNodeInfo); + if (errCode != 0) { + stringstream ss; + ss << "Failed to get local cid: error code reads " << errCode; + LOGW("%s", ss.str().c_str()); + throw runtime_error(ss.str()); + } + localDeviceInfo_.SetCid(string(tmpNodeInfo.networkId)); + InitLocalIid(); +} + +void DeviceManagerAgent::OnRemoteDied() +{ + LOGI("device manager service died"); + RegisterToExternalDm(); // ! TODO +} + +void DeviceManagerAgent::InitLocalIid() +{ + localDeviceInfo_.SetIid(0x12345678); // TODO 随机产生 +} + +DeviceInfo &DeviceManagerAgent::GetLocalDeviceInfo() +{ + return localDeviceInfo_; +} + +vector DeviceManagerAgent::GetRemoteDevicesInfo() +{ + string extra = ""; + string pkgName = IDaemon::SERVICE_NAME; + vector deviceList; + + auto &deviceManager = DistributedHardware::DeviceManager::GetInstance(); + int errCode = deviceManager.GetTrustedDeviceList(pkgName, extra, deviceList); + if (errCode) { + stringstream ss; + ss << "Failed to get info of remote devices: the error code reads " << errCode; + LOGE("%s", ss.str().c_str()); + throw runtime_error(ss.str()); + } + + vector res; + for (const auto &item : deviceList) { + res.push_back(DeviceInfo(item)); + } + return res; +} + +void DeviceManagerAgent::RegisterToExternalDm() +{ + auto &deviceManager = DistributedHardware::DeviceManager::GetInstance(); + string pkgName = IDaemon::SERVICE_NAME; + int errCode = deviceManager.InitDeviceManager(pkgName, shared_from_this()); + if (errCode != 0) { + stringstream ss; + ss << "Failed to InitDeviceManager: the error code reads " << errCode; + LOGE("%s", ss.str().c_str()); + throw runtime_error(ss.str()); + } + string extra = ""; + errCode = deviceManager.RegisterDevStateCallback(pkgName, extra, shared_from_this()); + if (errCode != 0) { + stringstream ss; + ss << "Failed to RegisterDevStateCallback: the error code reads " << errCode; + LOGE("%s", ss.str().c_str()); + throw runtime_error(ss.str()); + } +} + +void DeviceManagerAgent::UnregisterFromExternalDm() +{ + auto &deviceManager = DistributedHardware::DeviceManager::GetInstance(); + string pkgName = IDaemon::SERVICE_NAME; + int errCode = deviceManager.UnRegisterDevStateCallback(pkgName); + if (errCode != 0) { + stringstream ss; + ss << "Failed to UnRegisterDevStateCallback: the error code reads " << errCode; + LOGE("%s", ss.str().c_str()); + throw runtime_error(ss.str()); + } + errCode = deviceManager.UnInitDeviceManager(pkgName); + if (errCode != 0) { + stringstream ss; + ss << "Failed to UnInitDeviceManager: the error code reads " << errCode; + LOGE("%s", ss.str().c_str()); + throw runtime_error(ss.str()); + } +} +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/services/distributedfiledaemon/src/ipc/daemon.cpp b/services/distributedfiledaemon/src/ipc/daemon.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2db0236d397002d07706d51bb677096f5249398f --- /dev/null +++ b/services/distributedfiledaemon/src/ipc/daemon.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021 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/daemon.h" + +#include "mountpoint/mount_manager.h" +#include "system_ability_definition.h" +#include "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +using namespace std; + +REGISTER_SYSTEM_ABILITY_BY_ID(Daemon, STORAGE_DISTRIBUTED_FILE_DAEMON_SA_ID, true); + +void Daemon::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 Daemon::StartManagers() +{ + MountManager::GetInstance(); +} + +void Daemon::OnStart() +{ + LOGI("Begin to start service"); + if (state_ == ServiceRunningState::STATE_RUNNING) { + LOGD("Daemon has already started"); + return; + } + + try { + PublishSA(); + StartManagers(); + } catch (const exception &e) { + LOGE("%{public}s", e.what()); + } + + state_ = ServiceRunningState::STATE_RUNNING; + LOGI("Start service successfully"); +} + +void Daemon::OnStop() +{ + LOGI("Begin to stop"); + state_ = ServiceRunningState::STATE_NOT_START; + registerToService_ = false; + LOGI("Stop finished successfully"); +} + +int32_t Daemon::EchoServerDemo(const string &echoStr) +{ + return 0; +} +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/services/distributedfiledaemon/src/ipc/daemon_stub.cpp b/services/distributedfiledaemon/src/ipc/daemon_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b05455f021253bf24f90c3e9bdbcf63672037b01 --- /dev/null +++ b/services/distributedfiledaemon/src/ipc/daemon_stub.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 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/daemon_stub.h" +#include "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +DaemonStub::DaemonStub() +{ + opToInterfaceMap_[DFS_DAEMON_CMD_ECHO] = &DaemonStub::EchoServerDemoInner; +} + +int32_t DaemonStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + 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); + } + return (this->*(interfaceIndex->second))(data, reply); +} + +int32_t DaemonStub::EchoServerDemoInner(MessageParcel &data, MessageParcel &reply) +{ + LOGI("hello, world"); + return ERR_NONE; +} +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/services/distributedfiledaemon/src/mountpoint/mount_manager.cpp b/services/distributedfiledaemon/src/mountpoint/mount_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b0197e0688489e82933074fc268ba00c17174419 --- /dev/null +++ b/services/distributedfiledaemon/src/mountpoint/mount_manager.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021 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 "mountpoint/mount_manager.h" + +#include +#include + +#include "device/device_manager_agent.h" +#include "utils_log.h" +#include "utils_mount_argument.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +using namespace std; + +MountManager::MountManager() +{ + Mount(make_unique(Utils::MountArgumentDescriptors::Alpha())); +} + +MountManager::~MountManager() +{ + try { + // Umount mountpoints in reverse order to eliminate dependencies + for_each(mountPoints_.rbegin(), mountPoints_.rend(), [this](auto &cur_mp) { Umount(cur_mp); }); + } catch (const exception &e) { + LOGE("%{public}s", e.what()); + } +} + +void MountManager::Mount(unique_ptr mp) +{ + lock_guard lock(serializer_); + + shared_ptr smp = move(mp); + + auto isExisted = [smp](const auto &cur_mp) { return *smp == *cur_mp; }; + if (!smp || any_of(mountPoints_.begin(), mountPoints_.end(), isExisted)) { + stringstream ss; + ss << "Mount an empty/existent mountpoint" << (smp ? smp->GetMountArgument().GetFullDst() : ""); + LOGE("%{public}s", ss.str().c_str()); + throw runtime_error(ss.str()); + } + + smp->Mount(); + DeviceManagerAgent::GetInstance()->JoinGroup(smp); + mountPoints_.push_back(smp); +} + +void MountManager::Umount(weak_ptr wmp) +{ + auto smp = wmp.lock(); + lock_guard lock(serializer_); + + decltype(mountPoints_.begin()) it; + auto isExisted = [smp](const auto &cur_mp) { return *smp == *cur_mp; }; + if (!smp || ((it = find_if(mountPoints_.begin(), mountPoints_.end(), isExisted)) == mountPoints_.end())) { + stringstream ss; + ss << "Umount an empty/non-existent mountpoint" << (smp ? smp->GetMountArgument().GetFullDst() : ""); + LOGE("%{public}s", ss.str().c_str()); + throw runtime_error(ss.str()); + } + + smp->Umount(); + DeviceManagerAgent::GetInstance()->QuitGroup(smp); + mountPoints_.erase(it); +} +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/services/distributedfiledaemon/src/mountpoint/mount_point.cpp b/services/distributedfiledaemon/src/mountpoint/mount_point.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b77e02ad56b2df77f8027b697e53818b6f0df53a --- /dev/null +++ b/services/distributedfiledaemon/src/mountpoint/mount_point.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2021 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 "mountpoint/mount_point.h" + +#include +#include + +#include "utils_directory.h" +#include "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +using namespace std; + +atomic MountPoint::idGen_; + +MountPoint::MountPoint(const Utils::MountArgument &mountArg) : mountArg_(mountArg) +{ + id_ = idGen_++; +} + +void MountPoint::Mount() const +{ + auto mntArg = GetMountArgument(); + + string src = mntArg.GetFullSrc(); + Utils::ForceCreateDirectory(src, S_IRWXU | S_IRWXG | S_IXOTH, Utils::UID_SYSTEM, Utils::UID_MEDIA_RW); + + string dst = mntArg.GetFullDst(); + Utils::ForceCreateDirectory(dst, S_IRWXU | S_IRWXG | S_IXOTH); + + string cache = mntArg.GetCachePath(); + Utils::ForceCreateDirectory(cache, S_IRWXU | S_IRWXG | S_IXOTH); + + unsigned long flags = mntArg.GetFlags(); + string options = mntArg.OptionsToString(); + int ret = mount(src.c_str(), dst.c_str(), "hmdfs", flags, options.c_str()); + if (ret == -1 && errno != EEXIST && errno != EBUSY) { + auto cond = system_category().default_error_condition(errno); + LOGE("Failed to mount: %{public}d %{public}s", cond.value(), cond.message().c_str()); + throw system_error(errno, system_category()); + } +} + +void MountPoint::Umount() const +{ + string dst = GetMountArgument().GetFullDst(); + if (umount2(dst.c_str(), MNT_DETACH) == -1) { + auto cond = system_category().default_error_condition(errno); + LOGE("Failed to umount: %{public}d %{public}s", cond.value(), cond.message().c_str()); + throw system_error(errno, system_category()); + } + + Utils::ForceRemoveDirectory(dst); +} + +bool MountPoint::operator==(const MountPoint &rop) const +{ + return mountArg_.GetFullDst() == rop.mountArg_.GetFullDst(); +} + +Utils::MountArgument MountPoint::GetMountArgument() const +{ + return mountArg_; +} + +string MountPoint::ToString() const +{ + return ""; +} +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/services/distributedfiledaemon/src/network/kernel_talker.cpp b/services/distributedfiledaemon/src/network/kernel_talker.cpp new file mode 100644 index 0000000000000000000000000000000000000000..acb5e42f1a0436b2032564297d8473c9b7237b63 --- /dev/null +++ b/services/distributedfiledaemon/src/network/kernel_talker.cpp @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2021 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 "network/kernel_talker.h" +#include "device/device_manager_agent.h" +#include "securec.h" +#include "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +using namespace std; + +constexpr int KEY_MAX_LEN = 32; +constexpr int HMDFS_ACCOUNT_HASH_MAX_LEN = 21; +constexpr int POLL_TIMEOUT_MS = 200; +constexpr int NONE_EVENT = -1; +constexpr int READ_EVENT = 1; +constexpr int TIME_OUT_EVENT = 0; + +struct InitParam { + int32_t cmd; + uint64_t localIid; + uint8_t currentAccout[HMDFS_ACCOUNT_HASH_MAX_LEN]; +} __attribute__((packed)); + +struct UpdateSocketParam { + int32_t cmd; + int32_t newfd; + uint64_t localIid; + uint8_t status; + uint8_t protocol; + uint16_t udpPort; + uint8_t deviceType; + uint8_t masterKey[KEY_MAX_LEN]; + char cid[CID_MAX_LEN]; + int32_t linkType; + int32_t binderFd; +} __attribute__((packed)); + +struct OfflineParam { + int32_t cmd; + char remoteCid[CID_MAX_LEN]; +} __attribute__((packed)); + +enum { + CMD_INIT = 0, + CMD_UPDATE_SOCKET, + CMD_OFF_LINE, + CMD_SET_ACCOUNT, + CMD_OFF_LINE_ALL, + CMD_UPDATE_CAPABILITY, + CMD_GET_P2P_SESSION_FAIL, + CMD_DELETE_CONNECTION, + CMD_CNT +}; + +enum { + SOCKET_STAT_ACCEPT = 0, + SOCKET_STAT_OPEN, +}; + +enum { + TCP_TRANSPORT_PROTO = 0, + UDP_TRANSPORT_PROTO, +}; + +enum Notify { + NOTIFY_HS_DONE = 0, + NOTIFY_OFFLINE, + NOTIFY_OFFLINE_IID, + NOTIFY_GET_SESSION, + NOTIFY_GOT_UDP_PORT, + NOTIFY_NONE, + NOTIFY_DISCONNECT, + NOTIFY_D2DP_FAILED, + NOTIFY_CNT, +}; + +void KernelTalker::SinkSessionTokernel(shared_ptr session) +{ + int socketFd = session->GetHandle(); + auto masterkey = session->GetKey(); + auto cid = session->GetCid(); + LOGD("sink session to kernel success, cid:%{public}s, socketFd:%{public}d, key[0]:%{public}x", cid.c_str(), + socketFd, *(uint32_t *)masterkey.data()); + + uint8_t status = (session->IsFromServer() ? SOCKET_STAT_ACCEPT : SOCKET_STAT_OPEN); + + UpdateSocketParam cmd = { + .cmd = CMD_UPDATE_SOCKET, + .newfd = socketFd, + .localIid = DeviceManagerAgent::GetInstance()->GetLocalDeviceInfo().GetIid(), + .status = status, + .protocol = TCP_TRANSPORT_PROTO, + .linkType = 0, + .binderFd = -1, + }; + if (memcpy_s(cmd.masterKey, KEY_MAX_LEN, masterkey.data(), KEY_MAX_LEN) != EOK) { + return; // !抛异常 + } + + if (memcpy_s(cmd.cid, CID_MAX_LEN, cid.c_str(), CID_MAX_LEN)) { + return; // !抛异常 + } + SetCmd(cmd); +} + +void KernelTalker::SinkInitCmdToKernel(uint64_t iid) +{ + InitParam cmd = { + .cmd = CMD_INIT, + .localIid = iid, + }; + + SetCmd(cmd); +} + +void KernelTalker::SinkOfflineCmdToKernel(string cid) +{ + OfflineParam cmd = { + .cmd = CMD_OFF_LINE, + }; + + if (cid.length() < CID_MAX_LEN) { + return; // ! 抛异常 + } + + if (memcpy_s(cmd.remoteCid, CID_MAX_LEN, cid.c_str(), CID_MAX_LEN) != EOK) { + return; // ! 抛异常 + } + SetCmd(cmd); +} + +unordered_set KernelTalker::GetKernelSesions() +{ + return {}; +} + +void KernelTalker::CreatePollThread() +{ + isRunning_ = true; + if (pollThread_ != nullptr) { + LOGE("pollTread is not null"); + return; + } + pollThread_ = make_unique(&KernelTalker::PollRun, this); + LOGI("Create pollThread OK"); +} + +void KernelTalker::WaitForPollThreadExited() +{ + isRunning_ = false; + if (pollThread_ == nullptr) { + LOGE("pollTread is null"); + return; + } + + if (pollThread_->joinable()) { + LOGI("pollThread->joinable is true"); + pollThread_->join(); + } + pollThread_ = nullptr; + LOGI("pollTread exit ok"); +} + +void KernelTalker::PollRun() +{ + struct pollfd fileFd; + int cmdFd = -1; + + LOGI("entry"); + auto spt = mountPoint_.lock(); + if (spt == nullptr) { + LOGE("mountPoint is not exist! bad weak_ptr"); + return; // ! 抛异常 + } + string ctrlPath = spt->GetMountArgument().GetCtrlPath(); + cmdFd = open(ctrlPath.c_str(), O_RDWR); + if (cmdFd < 0) { + LOGE("Open node file error %{public}d", errno); + return; // ! 待审视,此处不能抛异常,用户态还没有通知到内核时,这个文件可能就不存在 + } + + LOGI("Open node file success"); + + while (isRunning_) { + fileFd.fd = cmdFd; + fileFd.events = POLLPRI; + fileFd.revents = 0; + int ret = poll(&fileFd, 1, POLL_TIMEOUT_MS); + switch (ret) { + case NONE_EVENT: + LOGI("none event, poll exit"); + break; + case TIME_OUT_EVENT: + break; + case READ_EVENT: + HandleAllNotify(cmdFd); + break; + default: + LOGI("poll exit"); + } + } + close(cmdFd); + LOGI("exit"); + return; +} + +void KernelTalker::HandleAllNotify(int fd) +{ + NotifyParam param; + + while (isRunning_) { + lseek(fd, 0, SEEK_SET); + param.notify = NOTIFY_NONE; + int readSize = read(fd, ¶m, sizeof(NotifyParam)); + if ((readSize < (int)sizeof(NotifyParam)) || (param.notify == NOTIFY_NONE)) { + return; + } + NotifyHandler(param); + } +} + +void KernelTalker::NotifyHandler(NotifyParam ¶m) +{ + int cmd = param.notify; + string cidStr(param.remoteCid, CID_MAX_LEN); + switch (cmd) { + case NOTIFY_HS_DONE: + LOGI("NOTIFY_HS_DONE, remote cid %{public}s", cidStr.c_str()); + break; + case NOTIFY_OFFLINE: + case NOTIFY_OFFLINE_IID: + LOGI("%{public}s, remote cid %{public}s", (cmd == NOTIFY_OFFLINE) ? "NOTIFY_OFFLINE" : "NOTIFY_OFFLINE_IID", + cidStr.c_str()); + break; + case NOTIFY_GET_SESSION: + GetSessionCallback_(param); + break; + default: + LOGI("cmd %{public}d not support now", cmd); + break; + } +} +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/services/distributedfiledaemon/src/network/network_agent_template.cpp b/services/distributedfiledaemon/src/network/network_agent_template.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3a2ed16b40806d150d7344aac90f3262f291f185 --- /dev/null +++ b/services/distributedfiledaemon/src/network/network_agent_template.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2021 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 "network/network_agent_template.h" +#include "device/device_manager_agent.h" +#include "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +using namespace std; +namespace { +constexpr int MAX_RETRY_COUNT = 7; +constexpr int SLEEP_TIME = 1500; +} + +void NetworkAgentTemplate::Start() +{ + JoinDomain(); // TODO 考虑下软总线是否有可能还没有起来 + ConnectOnlineDevices(); + kernerlTalker_.CreatePollThread(); +} + +void NetworkAgentTemplate::Stop() +{ + StopTopHalf(); + StopBottomHalf(); + kernerlTalker_.WaitForPollThreadExited(); +} + +void NetworkAgentTemplate::ConnectDeviceAsync(const DeviceInfo &info) +{ + kernerlTalker_.SinkInitCmdToKernel(info.GetIid()); + + unique_lock taskLock(taskMut_); + tasks_.emplace_back(); + tasks_.back().RunLoopFlexible( + [info{DeviceInfo(info)}, this](uint64_t &sleepTime) { // ! 不能使用this,待解决 + auto session = OpenSession(info); + if (session == nullptr) { + LOGE("open session fail, retry, cid:%{public}s", info.GetCid().c_str()); + return false; + } + LOGI("open session success, cid:%{public}s", info.GetCid().c_str()); + return true; + }, + SLEEP_TIME, MAX_RETRY_COUNT); +} + +void NetworkAgentTemplate::ConnectOnlineDevices() +{ + auto infos = DeviceManagerAgent::GetInstance()->GetRemoteDevicesInfo(); + LOGI("Have %{public}d devices Online", infos.size()); + for (const auto &info : infos) { + ConnectDeviceAsync(info); + } +} + +void NetworkAgentTemplate::DisconnectDevice(const DeviceInfo &info) +{ + LOGI("DeviceOffline, cid:%{public}s", info.GetCid().c_str()); + kernerlTalker_.SinkOfflineCmdToKernel(info.GetCid()); + sessionPool_.RefreshSessionPoolBasedOnKernel(); +} + +void NetworkAgentTemplate::AcceptSession(shared_ptr session) +{ + unique_lock taskLock(taskMut_); + tasks_.emplace_back(); + tasks_.back().Run([=] { + auto cid = session->GetCid(); + LOGI("AcceptSession thread run, cid:%{public}s", cid.c_str()); + sessionPool_.HoldSession(session); + return true; + }); +} + +void NetworkAgentTemplate::GetSessionProcess(NotifyParam ¶m) +{ + string cidStr(param.remoteCid, CID_MAX_LEN); + LOGI("NOTIFY_GET_SESSION, old fd %{public}d, remote cid %{public}s", param.fd, cidStr.c_str()); + sessionPool_.RefreshSessionPoolBasedOnKernel(); + GetSesion(cidStr); +} + +void NetworkAgentTemplate::GetSesion(const string &cid) +{ + DeviceInfo deviceInfo; + deviceInfo.SetCid(cid); + auto session = OpenSession(deviceInfo); + if (session == nullptr) { + LOGE("open session fail, retry, cid:%{public}s", cid.c_str()); + return; + } + LOGI("open session success, cid:%{public}s", cid.c_str()); +} +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/services/distributedfiledaemon/src/network/session_pool.cpp b/services/distributedfiledaemon/src/network/session_pool.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6824636dd1541002c033516b1940f323647398ed --- /dev/null +++ b/services/distributedfiledaemon/src/network/session_pool.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 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 "network/session_pool.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +using namespace std; + +void SessionPool::HoldSession(shared_ptr session) +{ + lock_guard lock(sessionPoolLock_); + talker_.SinkSessionTokernel(session); + AddSessionToPool(session); + RefreshSessionPoolBasedOnKernel(); +} + +void SessionPool::RefreshSessionPoolBasedOnKernel() +{ + lock_guard lock(sessionPoolLock_); + auto kernelSessions = talker_.GetKernelSesions(); + for (auto iter = usrSpaceSessionPool_.begin(); iter != usrSpaceSessionPool_.end();) { + if (kernelSessions.count((*iter)->GetHandle() == 0)) { + // (*iter)->Release(); + // iter = usrSpaceSessionPool_.erase(iter); // ! 待GetKernelSessions实现后放开 + } else { + ++iter; + } + } +} + +void SessionPool::AddSessionToPool(shared_ptr session) +{ + usrSpaceSessionPool_.push_back(session); +} +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/services/distributedfiledaemon/src/network/softbus/softbus_agent.cpp b/services/distributedfiledaemon/src/network/softbus/softbus_agent.cpp new file mode 100644 index 0000000000000000000000000000000000000000..59d988ac44be1f036b71c09045492b3c6b778354 --- /dev/null +++ b/services/distributedfiledaemon/src/network/softbus/softbus_agent.cpp @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2021 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 "network/softbus/softbus_agent.h" + +#include + +#include "ipc/i_daemon.h" +#include "network/softbus/softbus_session.h" +#include "network/softbus/softbus_session_dispatcher.h" +#include "network/softbus/softbus_session_name.h" +#include "session.h" +#include "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +using namespace std; + +SoftbusAgent::SoftbusAgent(weak_ptr mountPoint) : NetworkAgentTemplate(mountPoint) +{ + auto spt = mountPoint.lock(); + if (spt == nullptr) { + LOGE("mountPoint is not exist! bad weak_ptr"); + sessionName_ = ""; + return; + } + + string path = spt->GetMountArgument().GetFullDst(); + SoftbusSessionName sessionName(path); + sessionName_ = sessionName.ToString(); +} + +void SoftbusAgent::JoinDomain() +{ + ISessionListener sessionListener = { + .OnSessionOpened = SoftbusSessionDispatcher::OnSessionOpened, + .OnSessionClosed = SoftbusSessionDispatcher::OnSessionClosed, + .OnBytesReceived = nullptr, + .OnMessageReceived = nullptr, + .OnStreamReceived = nullptr, + }; + + SoftbusSessionDispatcher::RegisterSessionListener(sessionName_, shared_from_this()); + int ret = ::CreateSessionServer(IDaemon::SERVICE_NAME.c_str(), sessionName_.c_str(), &sessionListener); + if (ret != 0) { // ! 错误码 + stringstream ss; + ss << "Failed to CreateSessionServer, errno:" << ret; + LOGE("%{public}s, sessionName:%{public}s", ss.str().c_str(), sessionName_.c_str()); + throw runtime_error(ss.str()); + } + LOGD("Succeed to JoinDomain, busName:%{public}s", sessionName_.c_str()); +} + +void SoftbusAgent::QuitDomain() +{ + int ret = ::RemoveSessionServer(IDaemon::SERVICE_NAME.c_str(), sessionName_.c_str()); + if (ret != 0) { // ! 错误码 + stringstream ss; + ss << "Failed to RemoveSessionServer, errno:" << ret; + LOGE("%{public}s", ss.str().c_str()); + throw runtime_error(ss.str()); + } + + SoftbusSessionDispatcher::UnregisterSessionListener(sessionName_.c_str()); + LOGD("Succeed to QuitDomain, busName:%{public}s", sessionName_.c_str()); +} +void SoftbusAgent::StopTopHalf() +{ + QuitDomain(); +} +void SoftbusAgent::StopBottomHalf() {} +shared_ptr SoftbusAgent::OpenSession(const DeviceInfo &info) +{ + SessionAttribute attr; + attr.dataType = TYPE_BYTES; + attr.unique = true; + + LOGD("Start to Open Session, cid:%{public}s", info.GetCid().c_str()); + + int sessionId = + ::OpenSession(sessionName_.c_str(), sessionName_.c_str(), info.GetCid().c_str(), "hmdfs_wifiGroup", &attr); + if (sessionId < 0) { + LOGE("Failed to open session, cid:%{public}s, sessionId:%{public}d", info.GetCid().c_str(), sessionId); + return nullptr; + } + return make_shared(sessionId); +} + +void SoftbusAgent::CloseSession(shared_ptr session) +{ + if (session == nullptr) { + LOGE("Failed to close session, error:invalid session"); + return; + } + session->Release(); +} + +int SoftbusAgent::OnSessionOpened(const int sessionId, const int result) +{ + auto session = make_shared(sessionId); + auto cid = session->GetCid(); + if (!session->IsFromServer()) { + if (result != 0) { + // !是否加OpenSession重试? + LOGE("open session failed, result:%{public}d", result); + return 0; + } + } + int socket_fd = session->GetHandle(); + LOGI( + "accept sesion, sessionid:%{public}d, Is %{public}s Side, fd %{public}d, from cid %{public}s, result " + "%{public}d", + sessionId, (session->IsFromServer() == true) ? "Server" : "Client", socket_fd, cid.c_str(), result); + session->DisableSessionListener(); + AcceptSession(session); + return 0; +} + +void SoftbusAgent::OnSessionClosed(int sessionId) +{ + auto session = make_shared(sessionId); + auto cid = session->GetCid(); + LOGI("Session to %{public}s closed by unknown reason, Is %{public}s Side", cid.c_str(), + (session->IsFromServer() == true) ? "Server" : "Client"); +} +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/services/distributedfiledaemon/src/network/softbus/softbus_session.cpp b/services/distributedfiledaemon/src/network/softbus/softbus_session.cpp new file mode 100644 index 0000000000000000000000000000000000000000..92264a0a7a7f283a5650a9a5ce9958d68c0f7601 --- /dev/null +++ b/services/distributedfiledaemon/src/network/softbus/softbus_session.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021 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 "network/softbus/softbus_session.h" + +#include "dfs_session.h" +#include "session.h" +#include "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +using namespace std; + +constexpr int32_t SOFTBUS_OK = 0; +constexpr int32_t INVALID_SOCKET_FD = -1; +constexpr int32_t DEVICE_ID_SIZE_MAX = 65; + +bool SoftbusSession::IsFromServer() const +{ + return (::GetSessionSide(sessionId_) == IS_SERVER) ? true : false; +} + +string SoftbusSession::GetCid() const +{ + char perDevId[DEVICE_ID_SIZE_MAX] = ""; + int ret = ::GetPeerDeviceId(sessionId_, perDevId, sizeof(perDevId)); + if (ret != SOFTBUS_OK) { + LOGE("get my peer device id failed, errno:%{public}d, sessionId:%{public}d", ret, sessionId_); + return {}; // ! 抛异常 + } + return string(perDevId); +} + +int32_t SoftbusSession::GetHandle() const +{ + int32_t socket_fd; + int32_t ret = ::GetSessionHandle(sessionId_, &socket_fd); + if (ret != SOFTBUS_OK) { + LOGE("get session socket fd failed, errno:%{public}d, sessionId:%{public}d", ret, sessionId_); + return INVALID_SOCKET_FD; + } + return socket_fd; +} + +array SoftbusSession::GetKey() const +{ + array key; + int32_t ret = ::GetSessionKey(sessionId_, key.data(), key.size()); + if (ret != SOFTBUS_OK) { + LOGE("get session key failed, errno:%{public}d, sessionId:%{public}d", ret, sessionId_); + return {}; // ! 抛异常 + } + return key; +} + +void SoftbusSession::Release() const +{ + ::CloseSession(sessionId_); +} + +void SoftbusSession::DisableSessionListener() const +{ + int32_t ret = ::DisableSessionListener(sessionId_); + if (ret != SOFTBUS_OK) { + LOGE("disableSessionlistener failed, errno:%{public}d, sessionId:%{public}d", ret, sessionId_); + return; // !抛异常 + } +} +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/services/distributedfiledaemon/src/network/softbus/softbus_session_dispatcher.cpp b/services/distributedfiledaemon/src/network/softbus/softbus_session_dispatcher.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d1c1faf42ab8135b1bb76ce309994b4f580cc5e4 --- /dev/null +++ b/services/distributedfiledaemon/src/network/softbus/softbus_session_dispatcher.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2021 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 "network/softbus/softbus_session_dispatcher.h" + +#include + +#include "network/softbus/softbus_agent.h" +#include "session.h" +#include "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +using namespace std; + +constexpr int32_t SESSION_NAME_SIZE_MAX = 256; + +mutex SoftbusSessionDispatcher::softbusAgentMutex_; +map> SoftbusSessionDispatcher::busNameToAgent_; + +void SoftbusSessionDispatcher::RegisterSessionListener(const string busName, + weak_ptr softbusAgent) +{ + if (busName == "") { + stringstream ss; + ss << "Failed to register session to softbus"; + LOGE("%{public}s", ss.str().c_str()); + throw runtime_error(ss.str()); + } + lock_guard lock(softbusAgentMutex_); + auto agent = busNameToAgent_.find(busName); + if (agent != busNameToAgent_.end()) { + stringstream ss; + ss << "this softbusAgent is not exist, busName: " << busName.c_str(); + LOGE("%{public}s", ss.str().c_str()); + throw runtime_error(ss.str()); + } else { + busNameToAgent_.insert(make_pair(busName, softbusAgent)); + } + LOGD("RegisterSessionListener SUCCESS, busName:%{public}s", busName.c_str()); +} +void SoftbusSessionDispatcher::UnregisterSessionListener(const string busName) +{ + lock_guard lock(softbusAgentMutex_); + auto agent = busNameToAgent_.find(busName); + if (agent != busNameToAgent_.end()) { + busNameToAgent_.erase(busName); + } else { + stringstream ss; + ss << "this softbusAgent is not exist, busName: " << busName.c_str(); + LOGE("%{public}s", ss.str().c_str()); + throw runtime_error(ss.str()); + } + LOGD("UnregisterSessionListener SUCCESS, busName:%{public}s", busName.c_str()); +} +weak_ptr SoftbusSessionDispatcher::GetAgent(int sessionId) +{ + char peeSessionName[SESSION_NAME_SIZE_MAX]; + int ret = GetPeerSessionName(sessionId, peeSessionName, sizeof(peeSessionName)); + if (ret != 0) { // ! TODO 魔术字 + LOGE("Get my peer session name failed, session id is %{public}d.", sessionId); + return {}; // ! TODO + } + auto agent = busNameToAgent_.find(string(peeSessionName)); + if (agent != busNameToAgent_.end()) { + LOGD("Get softbus Agent Success, busName:%{public}s", peeSessionName); + return agent->second; + } + LOGE("Get Session Agent fail, not exist! sessionId:%{public}d, busName:%{public}s", sessionId, peeSessionName); + return {}; // ! TODO +} +int SoftbusSessionDispatcher::OnSessionOpened(int sessionId, int result) +{ + auto agent = GetAgent(sessionId); + if (auto spt = agent.lock()) { + return spt->OnSessionOpened(sessionId, result); + } else { + LOGE("session not exist!, session id is %{public}d", sessionId); + return -1; + } +} +void SoftbusSessionDispatcher::OnSessionClosed(int sessionId) +{ + auto agent = GetAgent(sessionId); + if (auto spt = agent.lock()) { + spt->OnSessionClosed(sessionId); + } else { + LOGE("session not exist!, session id is %{public}d", sessionId); + } +} +} // namespace DistributedFile +} // namespace Storages +} // namespace OHOS \ No newline at end of file diff --git a/services/distributedfiledaemon/test/unittest/BUILD.gn b/services/distributedfiledaemon/test/unittest/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..e6df95ed913af946079648553cc028bb96c24f9d --- /dev/null +++ b/services/distributedfiledaemon/test/unittest/BUILD.gn @@ -0,0 +1,54 @@ +# Copyright (C) 2021 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/test.gni") +import("//foundation/storage/distributed_file_manager/distributedfile.gni") + +module_output_path = "storage_distributed_file_manager/distributedfiledaemon" + +config("module_private_config") { + visibility = [ ":*" ] + + include_dirs = [ + "${services_path}/distributedfiledaemon/include", + "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp/include", + ] +} + +ohos_unittest("DeviceManagerAgentTest") { + module_out_path = module_output_path + + sources = [ + ] + + sources += [ "device/device_manager_agent_test.cpp" ] + + configs = [ + ":module_private_config", + "${utils_path}:compiler_configs" + ] + + deps = [ + "//third_party/googletest:gtest_main", + "${utils_path}:libdistributedfileutils", + "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp:devicemanagersdk", + ] + + defines = [ + "private=public" + ] +} + +group("unittest") { + testonly = true + deps = [":DeviceManagerAgentTest"] +} \ No newline at end of file diff --git a/services/distributedfiledaemon/test/unittest/device/device_manager_agent_test.cpp b/services/distributedfiledaemon/test/unittest/device/device_manager_agent_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..20613477f87d553a17242b8a61354d580ca57520 --- /dev/null +++ b/services/distributedfiledaemon/test/unittest/device/device_manager_agent_test.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2021 XXXX 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 "device/device_manager_agent.h" +#include + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +namespace Test { +using namespace testing::ext; + +class DeviceManagerAgentTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void DeviceManagerAgentTest::SetUpTestCase(void) +{ + // input testsuit setup step,setup invoked before all testcases +} + +void DeviceManagerAgentTest::TearDownTestCase(void) +{ + // input testsuit teardown step,teardown invoked after all testcases +} + +void DeviceManagerAgentTest::SetUp(void) +{ + // input testcase setup step,setup invoked before each testcases +} + +void DeviceManagerAgentTest::TearDown(void) +{ + // input testcase teardown step,teardown invoked after each testcases +} + +/** + * @tc.name: integer_sub_001 + * @tc.desc: Verify the sub function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(DeviceManagerAgentTest, test_001, TestSize.Level1) +{ + // step 1:调用函数获取结果 + int actual = 4; + // Step 2:使用断言比较预期与实际结果 + EXPECT_EQ(4, actual); +} +} // namespace Test +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/test/moduletest/BUILD.gn b/test/moduletest/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..26350e2a5bf6db2a28c18858149842b4e44ff6a6 --- /dev/null +++ b/test/moduletest/BUILD.gn @@ -0,0 +1,56 @@ +# Copyright (C) 2021 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/test.gni") +import("//foundation/storage/distributed_file_manager/distributedfile.gni") + +module_output_path = "storage_distributed_file_manager/distributedfiledaemon" + +config("module_private_config") { + visibility = [ ":*" ] + + include_dirs = [ + "${services_path}/distributedfiledaemon/include", + "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp/include", + ] +} + +ohos_moduletest("DistributedFileDaemonServiceTest") { + module_out_path = module_output_path + + sources = [ + "${services_path}/distributedfiledaemon/src/mountpoint/mount_point.cpp" + ] + + sources += [ "src/distributedfiledaemon_service_test.cpp" ] + + configs = [ + ":module_private_config", + "${utils_path}:compiler_configs" + ] + + defines = [ + "private=public" + ] + + deps = [ + "//third_party/googletest:gtest_main", + "//third_party/googletest:gmock", + "${utils_path}:libdistributedfileutils", + "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp:devicemanagersdk", + ] +} + +group("moduletest") { + testonly = true + deps = [":DistributedFileDaemonServiceTest"] +} \ No newline at end of file diff --git a/test/moduletest/src/distributedfiledeamon_service_test.cpp b/test/moduletest/src/distributedfiledeamon_service_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7329e67d835d1415c250bab87b5c547a85509a42 --- /dev/null +++ b/test/moduletest/src/distributedfiledeamon_service_test.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021 XXXX 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 +#include +#include +#include + +#include "device/device_manager_agent.h" +#include "mountpoint/mount_point.h" +#include "utils_directory.h" +#include "utils_log.h" +namespace OHOS { +namespace Storage { +namespace DistributedFile { +namespace Test { +using namespace testing::ext; +using namespace std; + +class DistributedFileDaemonServiceTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void DistributedFileDaemonServiceTest::SetUpTestCase(void) +{ + // input testsuit setup step,setup invoked before all testcases +} + +void DistributedFileDaemonServiceTest::TearDownTestCase(void) +{ + // input testsuit teardown step,teardown invoked after all testcases +} + +void DistributedFileDaemonServiceTest::SetUp(void) +{ + // input testcase setup step,setup invoked before each testcases +} + +void DistributedFileDaemonServiceTest::TearDown(void) +{ + // input testcase teardown step,teardown invoked after each testcases +} + +/** + * @tc.name: mount_test_001 + * @tc.desc: Verify the mount/umount function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(DistributedFileDaemonServiceTest, mount_umount_test_001, TestSize.Level1) +{ + auto mp = make_unique(OHOS::DistributedFile::Utils::MountArgumentDescriptors::Alpha(9527)); + + shared_ptr smp = move(mp); + + try { + smp->Mount(); + smp->Umount(); + LOGE("testcase run OK"); + } catch (const exception &e) { + LOGE("%{public}s", e.what()); + EXPECT_EQ(0, 1); + } + EXPECT_EQ(0, 0); +} +} // namespace Test +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/utils/BUILD.gn b/utils/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..c25662f4bf7dd848d92e9ffcda07cbf153ada0ee --- /dev/null +++ b/utils/BUILD.gn @@ -0,0 +1,70 @@ +# Copyright (c) 2021 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/storage/distributed_file_manager/distributedfile.gni") + +config("compiler_configs") { + visibility = [ ":*" ] + + cflags = [ + "-Wall", + "-Werror", + "-Wdate-time", + "-Wfloat-equal", + "-Wshadow", + "-Wformat=2", + "-fvisibility=hidden", + "-ffunction-sections", + "-Os", + ] + configs = [ "//build/config/compiler:exceptions" ] + + cflags_cc = [ + "-fvisibility-inlines-hidden", + "-Os", + ] + + defines = [ + "LOG_TAG=\"distributedfile\"", + "LOG_DOMAIN=0xD001600", + "LOG_LEVEL=INFO", + ] +} + +config("utils_public_config") { + include_dirs = [ + "log/include", + "system/include", + "//utils/native/base/include", + ] +} + +ohos_shared_library("libdistributedfileutils") { + sources = [ + "log/src/utils_log.cpp", + "system/src/utils_directory.cpp", + "system/src/utils_mount_argument.cpp", + ] + + configs = [ "//build/config/compiler:exceptions" ] + public_configs = [ ":utils_public_config" ] + + public_deps = [ + "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", + "//utils/native/base:utils", + ] + + part_name = "storage_distributed_file_manager" + subsystem_name = "storage" +} diff --git a/utils/log/include/utils_log.h b/utils/log/include/utils_log.h new file mode 100755 index 0000000000000000000000000000000000000000..8da302ecc9da4aaae510d71d166dc16461e50056 --- /dev/null +++ b/utils/log/include/utils_log.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 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 UTILS_LOG_H +#define UTILS_LOG_H + +#include + +#include "hilog/log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +#ifndef LOG_DOMAIN +#define LOG_DOMAIN 0xD001600 +#endif + +#ifndef LOG_TAG +#define LOG_TAG "distributedfile" +#endif + +static constexpr HiviewDFX::HiLogLabel APP_LABEL = {LOG_CORE, LOG_DOMAIN, LOG_TAG}; + +std::string GetFileNameFromFullPath(const char *str); +#define PRINT_LOG(Level, fmt, ...) \ + HiviewDFX::HiLog::Level(APP_LABEL, "[%{public}s:%{public}d->%{public}s] " fmt, \ + GetFileNameFromFullPath(__FILE__).c_str(), __LINE__, __FUNCTION__, ##__VA_ARGS__) + +#define LOGD(fmt, ...) PRINT_LOG(Debug, fmt, ##__VA_ARGS__) +#define LOGI(fmt, ...) PRINT_LOG(Info, fmt, ##__VA_ARGS__) +#define LOGW(fmt, ...) PRINT_LOG(Warn, fmt, ##__VA_ARGS__) +#define LOGE(fmt, ...) PRINT_LOG(Error, fmt, ##__VA_ARGS__) +#define LOGF(fmt, ...) PRINT_LOG(Fatal, fmt, ##__VA_ARGS__) +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // UTILS_LOG_H \ No newline at end of file diff --git a/utils/log/src/utils_log.cpp b/utils/log/src/utils_log.cpp new file mode 100644 index 0000000000000000000000000000000000000000..37deb39c6cc9344301b30e0b5165902c5e1ed1e5 --- /dev/null +++ b/utils/log/src/utils_log.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021 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 "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +std::string GetFileNameFromFullPath(const char *str) +{ + std::string fullPath(str); + size_t pos = fullPath.find_last_of("/"); + return (pos == std::string::npos) ? std::string() : fullPath.substr(pos + 1); +} +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/utils/system/include/utils_dfs_thread.h b/utils/system/include/utils_dfs_thread.h new file mode 100644 index 0000000000000000000000000000000000000000..593ec79fd7a80936e9f77087251185c763524558 --- /dev/null +++ b/utils/system/include/utils_dfs_thread.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2021 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 UTILS_DFS_THREAD_H +#define UTILS_DFS_THREAD_H + +#include "utils_log.h" +#include +#include +#include +#include +#include + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +namespace Utils { +class DfsThread { +public: + DfsThread() = default; + DfsThread(const DfsThread &) = delete; + DfsThread &operator=(const DfsThread &) = delete; + + ~DfsThread() + { + Stop(); + } + + template + bool Run(_Fn &&_Fx, _Args &&..._Ax) + { + std::unique_lock lock(threadMutex_); + if (thread_ != nullptr) { + return false; + } + running_ = true; + thread_ = std::make_unique(std::forward<_Fn>(_Fx), std::forward<_Args>(_Ax)...); + return true; + } + + bool RunLoop(std::function task, uint64_t interval, uint32_t retryTimes = UINT32_MAX) + { + std::unique_lock lock(threadMutex_); + if (thread_ != nullptr) { + return false; + } + running_ = true; + thread_ = std::make_unique([this, task, interval, retryTimes] { + uint32_t times = retryTimes; + LOGD("DfsThread: entering loop"); + while ((!task()) && (times > 0)) { + times--; + std::unique_lock lock(sleepMutex_); + bool stop = + sleepCv_.wait_for(lock, std::chrono::milliseconds(interval), [this]() { return !this->running_; }); + if (stop) { // is stopped + break; + } + } + LOGD("DfsThread: leaving loop"); + }); + return true; + } + + bool RunLoopFlexible(std::function task, uint64_t interval, uint32_t retryTimes = UINT32_MAX) + { + std::unique_lock lock(threadMutex_); + if (thread_ != nullptr) { + return false; + } + running_ = true; + thread_ = std::make_unique([this, task, interval, retryTimes] { + uint32_t times = retryTimes; + uint64_t duration = interval; + LOGD("DfsThread: entering flexible loop"); + while ((!task(duration)) && (times > 0)) { + times--; + std::unique_lock lock(sleepMutex_); + bool stop = + sleepCv_.wait_for(lock, std::chrono::milliseconds(duration), [this]() { return !this->running_; }); + if (stop) { // is stopped + break; + } + } + LOGD("DfsThread: leaving flexible loop"); + }); + return true; + } + + bool Stop() + { + std::unique_lock lockThread(threadMutex_); + if (thread_ == nullptr) { + return true; + } + { + std::unique_lock lockSleep(sleepMutex_); + running_ = false; + sleepCv_.notify_one(); + } + LOGD("wait thread to stop"); + if (thread_->joinable()) { + thread_->join(); + } + thread_ = nullptr; + return true; + } + + bool operator==(std::thread::id id) + { + if (thread_ == nullptr) { + return false; + } + return thread_->get_id() == id; + } + +private: + std::atomic_bool running_{false}; + std::mutex threadMutex_{}; + std::unique_ptr thread_{nullptr}; + std::mutex sleepMutex_{}; + std::condition_variable sleepCv_{}; +}; +} // namespace Utils +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // UTILS_DFS_THREAD_H \ No newline at end of file diff --git a/utils/system/include/utils_directory.h b/utils/system/include/utils_directory.h new file mode 100644 index 0000000000000000000000000000000000000000..48d89abcf0771a5197331b3e00d4c7a24ab05bad --- /dev/null +++ b/utils/system/include/utils_directory.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 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 UTILS_DIRECTORY_H +#define UTILS_DIRECTORY_H + +#include +#include +#include +#include + +#include "nocopyable.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +namespace Utils { +enum Uid { + UID_ROOT = 0, + UID_SYSTEM = 1000, + UID_MEDIA_RW = 1023, +}; + +void ForceCreateDirectory(const std::string &path); +void ForceCreateDirectory(const std::string &path, mode_t mode); +void ForceCreateDirectory(const std::string &path, mode_t mode, uid_t uid, gid_t gid); + +void ForceRemoveDirectory(const std::string &path); +} // namespace Utils +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // UTILS_DIRECTORY_H \ No newline at end of file diff --git a/utils/system/include/utils_mount_argument.h b/utils/system/include/utils_mount_argument.h new file mode 100644 index 0000000000000000000000000000000000000000..a57a077388e8640722eda95b237eff5bdbc53616 --- /dev/null +++ b/utils/system/include/utils_mount_argument.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 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 UTILS_MOUNT_ARGUMENT_H +#define UTILS_MOUNT_ARGUMENT_H + +#include + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +namespace Utils { +struct MountArgument final { + int userId_{0}; + + std::string account_; + bool needInitDir_{false}; + bool useCache_{false}; + bool caseSensitive_{true}; + bool enableMergeView_{false}; + bool enableFixupOwnerShip_{false}; + bool enableOfflineStash_{true}; + bool externalFS_{false}; + + std::string GetFullSrc() const; + std::string GetFullDst() const; + std::string GetCtrlPath() const; + std::string GetCachePath() const; + std::string OptionsToString() const; + unsigned long GetFlags() const; +}; + +class MountArgumentDescriptors final { +public: + static MountArgument Alpha(int userId = 0); +}; +} // namespace Utils +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // UTILS_MOUNT_ARGUMENT_H \ No newline at end of file diff --git a/utils/system/include/utils_singleton.h b/utils/system/include/utils_singleton.h new file mode 100644 index 0000000000000000000000000000000000000000..5704975564fd1b6653c6206997a00ae6e34ffee0 --- /dev/null +++ b/utils/system/include/utils_singleton.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021 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 UTILS_SINGLETON_H +#define UTILS_SINGLETON_H + +#include "nocopyable.h" +#include +#include +#include + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +namespace Utils { +#define DECLARE_SINGLETON(MyClass) \ +public: \ + ~MyClass(); \ + \ +private: \ + friend Singleton; \ + MyClass(); + +template +class Singleton : public NoCopyable { +public: + static std::shared_ptr GetInstance(); + static void StopInstance(); + +protected: + /** + * @note We depend on the IPC manager to serialize the start and the stop procedure + */ + virtual void Start() = 0; + + /** + * @note Be very careful when freeing memory! Threads may call stop and other member functions simultaneously + */ + virtual void Stop() = 0; +}; + +/** + * @brief + * + * @tparam T + * @return T& + * + * @note We use call_once to ensure the atomicity of new() and start() + * @note Memory leaking of T is exactly what we want. Now T will be available along the program's life-time + */ +template +std::shared_ptr Singleton::GetInstance() +{ + static std::shared_ptr *dummy = nullptr; + static std::once_flag once; + std::call_once(once, []() mutable { + dummy = new std::shared_ptr(new T()); + (*dummy)->Start(); + }); + return *dummy; +} + +template +void Singleton::StopInstance() +{ + static std::once_flag once; + std::call_once(once, []() { + auto instance = GetInstance(); + instance->Stop(); + }); +} +} // namespace Utils +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // UTILS_SINGLETON_H \ No newline at end of file diff --git a/utils/system/include/utils_uid.h b/utils/system/include/utils_uid.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/utils/system/src/utils_directory.cpp b/utils/system/src/utils_directory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7c62a2a40001d0fe930f594e2fd3dcb11cdbe49a --- /dev/null +++ b/utils/system/src/utils_directory.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021 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 "utils_directory.h" + +#include +#include +#include +#include + +#include "directory_ex.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +namespace Utils { +using namespace std; + +void ForceCreateDirectory(const string &path, function onSubDirCreated) +{ + string::size_type index = 0; + do { + string subPath; + index = path.find('/', index + 1); + if (index == string::npos) { + subPath = path; + } else { + subPath = path.substr(0, index); + } + + if (access(subPath.c_str(), F_OK) != 0) { + if (mkdir(subPath.c_str(), (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) != 0 && errno != EEXIST) { + throw system_error(errno, system_category()); + } + onSubDirCreated(subPath); + } + } while (index != string::npos); +} + +void ForceCreateDirectory(const string &path) +{ + ForceCreateDirectory(path, nullptr); +} + +void ForceCreateDirectory(const string &path, mode_t mode) +{ + ForceCreateDirectory(path, [mode](const string &subPath) { + if (chmod(subPath.c_str(), mode) == -1) { + throw system_error(errno, system_category()); + } + }); +} + +void ForceCreateDirectory(const string &path, mode_t mode, uid_t uid, gid_t gid) +{ + ForceCreateDirectory(path, [mode, uid, gid](const string &subPath) { + if (chmod(subPath.c_str(), mode) == -1 || chown(subPath.c_str(), uid, gid) == -1) { + throw system_error(errno, system_category()); + } + }); +} + +void ForceRemoveDirectory(const string &path) +{ + if (!OHOS::ForceRemoveDirectory(path)) { + throw system_error(errno, system_category()); + } +} +} // namespace Utils +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/utils/system/src/utils_mount_argument.cpp b/utils/system/src/utils_mount_argument.cpp new file mode 100644 index 0000000000000000000000000000000000000000..abde578d53f7793678d43bdb0143148ed2a70715 --- /dev/null +++ b/utils/system/src/utils_mount_argument.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2021 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 "utils_mount_argument.h" + +#include +#include + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +namespace Utils { +using namespace std; + +string MountArgument::GetFullSrc() const +{ + stringstream ss; + ss << "/data/misc_ce/" << userId_ << "/hmdfs/storage"; + return ss.str(); +} + +string MountArgument::GetFullDst() const +{ + stringstream ss; + ss << "/mnt/hmdfs/" << userId_ << "/"; + return ss.str(); +} + +string MountArgument::GetCachePath() const +{ + stringstream ss; + ss << "/data/misc_ce/" << userId_ << "/hmdfs/cache/"; + return ss.str(); +} + +static uint64_t MocklispHash(const string &str) +{ + uint64_t res = 0; + constexpr int mocklispHashPos = 5; + /* Mocklisp hash function. */ + for (auto ch : str) { + res = (res << mocklispHashPos) - res + (uint64_t)ch; + } + return res; +} + +string MountArgument::GetCtrlPath() const +{ + auto dst = GetFullDst(); + auto res = MocklispHash(dst); + stringstream ss; + ss << "/sys/fs/hmdfs/" << res << "/cmd"; + return ss.str(); +} + +string MountArgument::OptionsToString() const +{ + stringstream ss; + ss << "local_dst=" << GetFullDst(); + if (useCache_) { + ss << ",cache_dir=" << GetCachePath(); + } + if (caseSensitive_) { + ss << ",sensitive"; + } + if (enableMergeView_) { + ss << ",merge"; + } + if (enableFixupOwnerShip_) { + ss << ",fixupownership"; + } + if (!enableOfflineStash_) { + ss << ",no_offline_stash"; + } + if (externalFS_) { + ss << ",external_fs"; + } + return ss.str(); +} + +unsigned long MountArgument::GetFlags() const +{ + return 0; +} + +MountArgument MountArgumentDescriptors::Alpha(int userId) +{ + MountArgument mountArgument = { + .account_ = "default", + .needInitDir_ = true, + .useCache_ = true, + .enableMergeView_ = true, + .enableFixupOwnerShip_ = true, + .enableOfflineStash_ = true, + .externalFS_ = false, + }; + mountArgument.userId_ = userId; + return mountArgument; +} +} // namespace Utils +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/utils/system/src/utils_uid.cpp b/utils/system/src/utils_uid.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391