From 844e3b9ab8f51151653c8c60dd5b62baabd2ad07 Mon Sep 17 00:00:00 2001 From: pengguanqi Date: Thu, 15 Jul 2021 18:05:36 +0800 Subject: [PATCH] add devicemanager Signed-off-by: pengguanqi Change-Id: I9517b404d6323ed5c379e2547e5c69854e8ca6ea --- LICENSE | 178 ++++ README.en.md | 36 - README.md | 39 - README_zh.md | 95 ++ common/log/include/device_manager_log.h | 54 ++ common/utils/include/device_manager_errno.h | 35 + common/utils/include/single_instance.h | 46 + devicemanager.gni | 22 + figures/devicemanager_zh.png | Bin 0 -> 7965 bytes interfaces/inner_kits/native_cpp/BUILD.gn | 80 ++ .../native_cpp/include/device_manager.h | 67 ++ .../include/device_manager_callback.h | 52 + .../include/device_manager_listener_stub.h | 64 ++ .../native_cpp/include/device_manager_proxy.h | 49 + .../native_cpp/include/dm_device_info.h | 51 + .../native_cpp/include/dm_subscribe_info.h | 82 ++ .../native_cpp/include/idevice_manager.h | 55 ++ .../include/idevice_manager_listener.h | 50 + .../native_cpp/src/device_manager.cpp | 314 +++++++ .../src/device_manager_listener_stub.cpp | 303 ++++++ .../native_cpp/src/device_manager_proxy.cpp | 316 +++++++ .../native_cpp/src/dm_device_info.cpp | 50 + .../native_cpp/src/dm_subscribe_info.cpp | 58 ++ ...hos.distributedHardware.deviceManager.d.ts | 367 ++++++++ interfaces/kits/js/BUILD.gn | 82 ++ interfaces/kits/js/include/dm_native_event.h | 44 + .../kits/js/include/native_devicemanager_js.h | 145 +++ interfaces/kits/js/src/dm_native_event.cpp | 106 +++ .../kits/js/src/native_devicemanager_js.cpp | 886 ++++++++++++++++++ ohos.build | 23 +- sa_profile/4802.xml | 27 + sa_profile/BUILD.gn | 20 + services/devicemanagerservice/BUILD.gn | 93 ++ .../include/authdemo/device_client_channel.h | 53 ++ .../include/authdemo/device_server_channel.h | 53 ++ .../include/authdemo/hichain_adapter.h | 115 +++ .../include/device_manager_listener_proxy.h | 44 + .../include/device_manager_service.h | 98 ++ .../include/device_manager_stub.h | 48 + .../include/softbus/softbus_adapter.h | 85 ++ .../include/util/anonymous_string.h | 26 + .../src/authdemo/device_client_channel.cpp | 166 ++++ .../src/authdemo/device_server_channel.cpp | 205 ++++ .../src/authdemo/hichain_adapter.cpp | 379 ++++++++ .../src/device_manager_listener_proxy.cpp | 294 ++++++ .../src/device_manager_service.cpp | 280 ++++++ .../src/device_manager_stub.cpp | 205 ++++ .../src/softbus/softbus_adapter.cpp | 524 +++++++++++ .../src/util/anonymous_string.cpp | 71 ++ 49 files changed, 6456 insertions(+), 79 deletions(-) create mode 100644 LICENSE delete mode 100644 README.en.md delete mode 100644 README.md create mode 100644 README_zh.md create mode 100644 common/log/include/device_manager_log.h create mode 100644 common/utils/include/device_manager_errno.h create mode 100644 common/utils/include/single_instance.h create mode 100644 devicemanager.gni create mode 100644 figures/devicemanager_zh.png create mode 100644 interfaces/inner_kits/native_cpp/BUILD.gn create mode 100644 interfaces/inner_kits/native_cpp/include/device_manager.h create mode 100644 interfaces/inner_kits/native_cpp/include/device_manager_callback.h create mode 100644 interfaces/inner_kits/native_cpp/include/device_manager_listener_stub.h create mode 100644 interfaces/inner_kits/native_cpp/include/device_manager_proxy.h create mode 100644 interfaces/inner_kits/native_cpp/include/dm_device_info.h create mode 100644 interfaces/inner_kits/native_cpp/include/dm_subscribe_info.h create mode 100644 interfaces/inner_kits/native_cpp/include/idevice_manager.h create mode 100644 interfaces/inner_kits/native_cpp/include/idevice_manager_listener.h create mode 100644 interfaces/inner_kits/native_cpp/src/device_manager.cpp create mode 100644 interfaces/inner_kits/native_cpp/src/device_manager_listener_stub.cpp create mode 100644 interfaces/inner_kits/native_cpp/src/device_manager_proxy.cpp create mode 100644 interfaces/inner_kits/native_cpp/src/dm_device_info.cpp create mode 100644 interfaces/inner_kits/native_cpp/src/dm_subscribe_info.cpp create mode 100644 interfaces/kits/js/@ohos.distributedHardware.deviceManager.d.ts create mode 100644 interfaces/kits/js/BUILD.gn create mode 100644 interfaces/kits/js/include/dm_native_event.h create mode 100644 interfaces/kits/js/include/native_devicemanager_js.h create mode 100644 interfaces/kits/js/src/dm_native_event.cpp create mode 100644 interfaces/kits/js/src/native_devicemanager_js.cpp create mode 100644 sa_profile/4802.xml create mode 100644 sa_profile/BUILD.gn create mode 100644 services/devicemanagerservice/BUILD.gn create mode 100644 services/devicemanagerservice/include/authdemo/device_client_channel.h create mode 100644 services/devicemanagerservice/include/authdemo/device_server_channel.h create mode 100644 services/devicemanagerservice/include/authdemo/hichain_adapter.h create mode 100644 services/devicemanagerservice/include/device_manager_listener_proxy.h create mode 100644 services/devicemanagerservice/include/device_manager_service.h create mode 100644 services/devicemanagerservice/include/device_manager_stub.h create mode 100644 services/devicemanagerservice/include/softbus/softbus_adapter.h create mode 100644 services/devicemanagerservice/include/util/anonymous_string.h create mode 100644 services/devicemanagerservice/src/authdemo/device_client_channel.cpp create mode 100644 services/devicemanagerservice/src/authdemo/device_server_channel.cpp create mode 100644 services/devicemanagerservice/src/authdemo/hichain_adapter.cpp create mode 100644 services/devicemanagerservice/src/device_manager_listener_proxy.cpp create mode 100644 services/devicemanagerservice/src/device_manager_service.cpp create mode 100644 services/devicemanagerservice/src/device_manager_stub.cpp create mode 100644 services/devicemanagerservice/src/softbus/softbus_adapter.cpp create mode 100644 services/devicemanagerservice/src/util/anonymous_string.cpp diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..f91efc558 --- /dev/null +++ b/LICENSE @@ -0,0 +1,178 @@ + + 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 + diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 90f9a4fa1..000000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# device_manager - -#### Description -{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md deleted file mode 100644 index 41863f6dc..000000000 --- a/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# device_manager - -#### 介绍 -{**以下是 Gitee 平台说明,您可以替换此简介** -Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 -无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} - -#### 软件架构 -软件架构说明 - - -#### 安装教程 - -1. xxxx -2. xxxx -3. xxxx - -#### 使用说明 - -1. xxxx -2. xxxx -3. xxxx - -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request - - -#### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README_zh.md b/README_zh.md new file mode 100644 index 000000000..92a18a6b9 --- /dev/null +++ b/README_zh.md @@ -0,0 +1,95 @@ +# **DeviceManager组件** + +## 简介 + +DeviceManager组件是OpenHarmony为开发者提供的一套分布式设备账号无关的认证组网接口。 + +其组成及依赖如下所示: + +![](figures/devicemanager_zh.png) + +## 目录 + +``` +foundation/distributedhardware/devicemanager +├── common +│   ├── log #log相关头文件存放目录 +│   └── utils #公共能力头文件存放目录 +├── interfaces +│   ├── inner_kits #内部接口头文件存放目录 +│   │   └── native_cpp #内部native接口及实现存放目录 +│   kits #外接口头文件存放目录 +│   └── js #外部JS接口及实现存放目录 +└── services + └── devicemanagerservice #devicemanagerservice服务实现核心代码 + ├── include + │   ├── authdemo #与设备认证相关头文件(非正式) + │   └── softbus #与软总线相关头文件 + └── src + ├── authdemo #设备认证功能示例代码(非正式) + └── softbus #通道建立及组网功能核心代码 +``` + +## 约束 + +- 开发语言:JS +- 适用于Hi3516DV300单板等OpenHarmony设备 + + +## 接口说明 + +当前版本设备管理服务不具备权限管理的能力。 + +以下模块的JS接口为非正式API,仅供分布式Demo应用使用,展示分布式能力,不排除对这些接口进行变更的可能性,后续版本将提供正式API。 + +参见 *ohos.distributedHardware.deviceManager.d.ts* + +| 原型 | 描述 | +| ------- | ---------- | +| createDeviceManager(bundleName: string, callback: AsyncCallback): void | 以异步方法获取DeviceManager实例 | +| release(): void | 释放DeviceManager实例 | +| getTrustedDeviceListSync(): Array | 获取信任设备列表 | +| authenticateDevice(deviceInfo: DeviceInfo): void | 设备认证 | +| on(type: 'authResult', callback: Callback<{ deviceId: string, status: number, reason: number }>): void | 订阅设备认证回调 | +| off(type: 'authResult', callback?: Callback<{ deviceId: string, status: number, reason: number }>): void | 取消订阅设备认证回调 | + + +### 示例如下: +``` +deviceManager.createDeviceManager(app.getInfo. appID, (err, data) => { + if (err) { + console.info(TAG + "createDeviceManager err:" + JSON.stringify(err)); + return; + } + console.info(TAG + "createDeviceManager success"); + dmClass = data; +} + +var deviceInfo ={ + "deviceId": "XXXXXXXX", + "deviceName": "", + deviceType: 0 +}; +dmClass.authenticateDevice(deviceInfo); +``` + +## 使用说明 + +当前版本是一个临时Demo认证方案,默认无法成功建立连接和PIN码认证,仅用于验证分布式能力,后续会提供正式的设备认证方案。 + +如果开发者感兴趣,可以通过修改代码来验证分布式能力。 + +**注:该方法存在一定安全风险,仅用于验证分布式能力。** +``` +devicemanager\services\devicemanagerservice\src\authdemo\hichain_adapter.cpp + +// PIN_CODE一般为随机6位数字字符串, 例如; +const std::string PIN_CODE = "123456"; + +// PORT为server端的监听端口号,随机端口范围一般为1024~65534, 例如 +const int32_t PORT = 10001; +``` + +## 相关仓 + +**device_manager** diff --git a/common/log/include/device_manager_log.h b/common/log/include/device_manager_log.h new file mode 100644 index 000000000..2350623f2 --- /dev/null +++ b/common/log/include/device_manager_log.h @@ -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. + */ + +#ifndef OHOS_DEVICE_MANAGER_LOG_H +#define OHOS_DEVICE_MANAGER_LOG_H +#include "hilog/log.h" + +namespace OHOS { +namespace DistributedHardware { +static constexpr OHOS::HiviewDFX::HiLogLabel DM_LABEL = {LOG_CORE, LOG_DOMAIN, DH_LOG_TAG}; + +#define PRINT_LOG(Level, fmt, ...) \ + OHOS::HiviewDFX::HiLog::Level(DM_LABEL, "[%{public}s] " fmt, __FUNCTION__, ##__VA_ARGS__) + +#ifdef HILOGD +#undef HILOGD +#endif + +#ifdef HILOGI +#undef HILOGI +#endif + +#ifdef HILOGW +#undef HILOGW +#endif + +#ifdef HILOGE +#undef HILOGE +#endif + +#ifdef HILOGF +#undef HILOGF +#endif + +#define HILOGD(fmt, ...) PRINT_LOG(Debug, fmt, ##__VA_ARGS__) +#define HILOGI(fmt, ...) PRINT_LOG(Info, fmt, ##__VA_ARGS__) +#define HILOGW(fmt, ...) PRINT_LOG(Warn, fmt, ##__VA_ARGS__) +#define HILOGE(fmt, ...) PRINT_LOG(Error, fmt, ##__VA_ARGS__) +#define HILOGF(fmt, ...) PRINT_LOG(Fatal, fmt, ##__VA_ARGS__) +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DEVICE_MANAGER_LOG_H diff --git a/common/utils/include/device_manager_errno.h b/common/utils/include/device_manager_errno.h new file mode 100644 index 000000000..11fcbfa73 --- /dev/null +++ b/common/utils/include/device_manager_errno.h @@ -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. + */ + +#ifndef OHOS_DEVICE_MANAGER_ERRNO_H +#define OHOS_DEVICE_MANAGER_ERRNO_H +#include "errors.h" + +namespace OHOS { +namespace DistributedHardware { +enum { + DISTRIBUTEDHARDWARE_MODULE_DEVICEMANAGER = 0x00 +}; + +// Error code for Common +constexpr ErrCode DEVICE_MANAGER_ERR_OFFSET = ErrCodeOffset(SUBSYS_DISTRIBUTEDHARDWARE, + DISTRIBUTEDHARDWARE_MODULE_DEVICEMANAGER); +enum { + ERR_DEVICEMANAGER_OPERATION_FAILED = DEVICE_MANAGER_ERR_OFFSET + 1, + ERR_DEVICEMANAGER_SERVICE_NOT_READY = DEVICE_MANAGER_ERR_OFFSET + 2, +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DEVICE_MANAGER_LOG_H diff --git a/common/utils/include/single_instance.h b/common/utils/include/single_instance.h new file mode 100644 index 000000000..f149f90e7 --- /dev/null +++ b/common/utils/include/single_instance.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 OHOS_DEVICE_MANAGER_SINGLE_INSTANCE_H +#define OHOS_DEVICE_MANAGER_SINGLE_INSTANCE_H + +namespace OHOS { +namespace DistributedHardware { +#define DECLARE_SINGLE_INSTANCE_BASE(className) \ +public: \ + static className & GetInstance(); \ +private: \ + className(const className&) = delete; \ + className& operator= (const className&) = delete; \ + className(className&&) = delete; \ + className& operator= (className&&) = delete; \ + + +#define DECLARE_SINGLE_INSTANCE(className) \ + DECLARE_SINGLE_INSTANCE_BASE(className) \ +private: \ + className() = default; \ + ~className() = default; \ + +#define IMPLEMENT_SINGLE_INSTANCE(className) \ +className & className::GetInstance() \ +{ \ + static auto instance = new className(); \ + return *instance; \ +} +}; // namespace DistributedHardware +}; // namespace OHOS + +#endif // OHOS_DEVICE_MANAGER_SINGLE_INSTANCE_H \ No newline at end of file diff --git a/devicemanager.gni b/devicemanager.gni new file mode 100644 index 000000000..179cd6027 --- /dev/null +++ b/devicemanager.gni @@ -0,0 +1,22 @@ +# 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. + + +devicemanager_path = "//foundation/distributedhardware/devicemanager" + +common_path = "${devicemanager_path}/common" + +services_path = "${devicemanager_path}/services" + +innerkits_path = "${devicemanager_path}/interfaces/inner_kits" + diff --git a/figures/devicemanager_zh.png b/figures/devicemanager_zh.png new file mode 100644 index 0000000000000000000000000000000000000000..0891790acd1fd75f448e04c0d98ea9fd02e1639a GIT binary patch literal 7965 zcmd5>S6EY9w~Zi5f)qm&5Me_ULKhH}2tp`^B4}tzFCrbJ_ofL_1VRW+1Ox&SiZrE2 zJ5r>hbP)uliWKP}^+xoZ|D6BjzMT7g_aS8`d#yFsT(gWZcKA)r>$DJd2nYnCRYfVG zK_Ch-^7lb%3i7-BY0+r%$1ykbbtLFT_t`n}#c^we8wwy$Nes=NITiUDd>?hk4FsZV z{P{Z8;+%UI1Ugr$s-&RfZL*m9F7oX4gqE%G+(U)uubeYWiebb^f9JbR+(Z>*`OgoJh9vu#oLVEyDkS5Kll7XJI58^CaZpR^@*eI>rOD_-=VolZITU3_f}i3>wK zeq;u`5lkAj#zZv>8D@tUBVPyD91aJ@&WOkbt~NVmLZz|ph~4fEI*Nq7n?GU4aj{25{fkrq5I zZ8F}Dm4&)##wXx+XV&H%MTjeY>t$Q<#@rChaR6Ya1gzX?NGo!+xc4{b=!G>tJ|FSZ=VVk(7*+>>QTeFs&XdDlc;eqvDys;Y{_(p z0WMqpQI-!+jT&EU-Sl%uHf-`+BZ1nhGQM+MbpgHuT{Y?sUOqlLmuNA*bRI-?qkx@q z?}-;r3}VaJso`W7mIsF_%Hr=kFE94_erRB%JU`OsCOpCy#dY%Ti3#ND2pt!KJ?_S0 zTAoV>x1zSesnY#(0PzXj3)ObIN?46_*;cZ5y|ox;^VGFpfj(JqbB?|TN}f2^cZXA+ zDY$UqAq0$hGQyv;d9%tT{Go*Ji)IW{yY%4%h!MS>;AaQ7YD|}6ub`W_tL@a$@SKqG zZqpBgv&&(^!w;^%rJ0JIdIVz@&B}T{Gv0H$+(VvE5xFX}dRR*TLM}j!Lp0G}($D4( z-LPJH6q_(m)vMYzUpmf0xJ2+xVD4j{Z`7K%Go*$)i9`6J0!SgIku>l#1boV~^Te8m z0lEbD=c!0`&L%Ch&7H>m967`9Js!b0*BoX%Sd~~D#!QE`edBKbij|E4e|Z1>o*$XD)kDlZHkq^_wJoeO@?}hhaJ?#GZ^B z?YpX9x1A^X-V^XR)tfZX=)B!(xO5tsmtktCe_xADG&G0F|3R{m#k-p1YTmx6$VCQ& zvdCL~HFDw`i(K`4CkE*YnJ|PNCiI=JZb{1Q)4lXb&e}rpI19^D2pQkPP~3vef~EWg z;)e+fgoM_8M@fzfT8q{IOH+CKsn{cDLh)cy^X&|#m>YQHCOdECwS9s_#wk0$E}5n*#1hV^Qx1MkN=w6{@ul1YToc)dA0EZ z4bmlU!k2GcDviU9@?-rR93mN0cb_BVlz**o`a^|sXgwdrPBI#GL4#SUTkAzsbOlqR zu@rPy*ZEqg^er*1%gJedjj931f$(GGx+?q27?jLyFB z(6{O_!}{qPpQ3aeL=QhXu}E`sN(6+4CNJlEGT@nhE+zg5S77Z*sf*0>y;)-zL3DOD zoUS~KLk~wr8Mocf`@MAgRis5)?xNz#p+tRB0?w%5vA1374@!7k9{9JJGf;GF4$fNz zJEa*zU$gX-v~ULta=b7msPN19_I@M;5#K-ui#DRGi*besWCU5KuF7>IguYOWA-=r! zS+!4-`O~IXIEM+%x6Kgj2;gKU4qS;L*41g96_KN!y@|)Is-ue)WwJW?iL=)Zcb?Zj zglE95;;u^HZfZ-uf7%P$`{qqZkR&JjV_uV58N1-Nc5Q7Qitp3%XXws=0azBU zz&9E0W2_tISo#7+a+;~0V!%@*u;S+jhlj%&o6bBq=PN4q<%3*~`E`J^s>E^#1{+Cx zL_efCTX^fF-u53d8SzKq1UEAWn&o6u;VN{4+$u7|b9|9wcO0P*$tna`htqXjxzO&@1x9rWx% zd)FGf?zyde;TQ{K5A=2I37E8W+m=Nzl?>Ic)z~G1$fW~zf?D<18aP~5c>?pEQg1uK z%opGsFA*sX!Fe8k<>1NvjnK_rR#9VHYSG7o>=BouYd`<^%LW6W%GAWrHTF%XT~;|WGC&mD#EIin8%g}5 zBQ)r0lV!g`CfQONtsv!c~+MPeg?P24}U$A^5qHu#U=mMb}ZvO6W z+`RSYbu}pjm;_brDN{u8ih8U388S(VD8hdZgHUSsAc|51R%!X(>oi-N)qjXI z(d3|Zju&_k(1FoIWCtat@4Xtm?n$4YsPkCQbY)rL;=wje8qJ^CJ;MUc9+vCB<1X`^ zU~v0OO3371jG@LIYp&GzUJDaoBB%ZQ$T$;c9%G*e4REVsFM>94O7w$6!1nft$@1Bs z$$Oic0gN}i-tP9SE&6UHq(9V!llxNlY`*G{#~ZtsDPsJ#o?gX z^mtbBP05w7CV>e)203!`WxI*eDSp!JZ!gTmrw8rb>Djh$E*thER4j9h`rX}m+3V4> z0kQ2SUC@~I_m>!O7lALX^1ZXLr1jvK=MFfX(kvay$@yJKGIa~JSg;)8ffRf-!-@A{ z?8;NjYQO5||H9a-bB=_ISB|qgTZF&&^vhIyzCdM4*R-3vaKe4H91VTd4iz`!FUTj( zdBTdw*Ckqd`9VmENk+k-(~rJ6YmAxOTZhlpD9AMZDh$0CC6B4SNsgKQjr(Y2^-b~b zZY_DR4R_M$Jwg3Vaff&NEy~~=6}MY%xi4a@~Xp{kjFO{VI{mKox(oe zk}|L9%i{8u%jf`_p><*OMHLdG33!^WsStxM+j5E2n7d%kIn+ugeNa{F7BdOyH>SzY*m)M;|N z$H9mkyE--z364{#a{|+TcG?*c5OIggDFt%S0wtBw(g6nz^5$PH;_fBcsY#98`?mQ# zRj_*aV#mB*5hhtRx^XJPx$SHo zIeA|+GfvJFzV>Mx%eC74dfyIsHD)BOYSm%#I(cWKzrYmLr|I#u!oR$$YRRQ!kj1TP zy^P@dHtRLZ?>R3~+hVjK@TFRd*j3@KhFF2`R9}w+OxSs2L|8z6=F_G&NL6-0k*Zmthx%T&%tgy;Cwi}D->pTuc1jE=B{}A> zT^~J@trApqwQw%JE{p+fO@^NZXq4r`dTgrHpa|^!G0aPU@^4{`y~!t#Xwa`Kc@&-u zC_sQP*H18c)D`4W9Y=8Us6jIHt{#C%Rf_-PAypppQeDiY2Y+H55CF82rHG#pB^bwW z7xoL3$fKymp}(*eH|#hY_!o3wfIcAi^q&m_L=9F@p*X7hAPk0^H{>T`hl7wv99g~i z37w9nogssg^q}lo>rqg0|Ii#a6uqr4Q$!lfPV&8HvGo#a8>KS{Pc@?{42qN$F6VA4diQ$@9-)5_`Do;h&I`= zhKt60sFE}o7TzpYlB-~?j6?{j7XO!H<>Zf+swJ+zE(@!tfLXsphOMM*)8^H%AEH~G^1R2Yw*fNiSWCQqT@)ZnkmLL(TBX2FA?=o< zzeov4rmUaziE~sDqUP{dg)eQ4a(bBk zo!_vq;OG1Lv~7HyaM8c8%5U(l4uN}q_^9pVyA(@Tas*<2{}Bm>Uy~WrcK3CP`*`Q5 zxBfEa-Rj90?ufti)65O< z%}UQM)#rVjCZD{S9xxy*qPPg@b?aD9Vy?6G4y+t@5Rvn59MNiup)b<7{PD4d@6ag& z_${QbyK~uLrnf;3%RB2WQD>cx}6kD@BQL`+`9kt*46|yBy^vp17{DteR%ej?%5xb=&M&K5OY2MyTJD*`F*Z zuk(lntsE2d?*johXbTAiocQ4-7+-uKkM4cin~M@wR@^?*?ah{Urg=)`-pcwurS{2* zP2Y?s<26E9fZClV4S4>BFd*ya(fBo8ORgvFOXy3H^!#xV3^pg8_8~FHy1=%dq_}W{GD8Kmat!_G!lMSr zxa3#X-jtJxUs(Vmokps_4Q&>9b)xHcEY1E0&lkD5FC4+~BGoJyNh*Zip>L>LV~=GS z!@W<9$cne3*#5^Lpel%mT$ME;7|F+^%ThIiN)voivs{NE^@ZI6nj4t~s3wi^c*r<-Dpd{-^YBuC!j zblN{vd8Jv)hNq_)5%t(3&W$koJTi^`p0wsKQ^d^QZN)jtb*H3bI;y$r<97b@YR}iM zq@qBmP4d(}8??yEa9Lp0`bX)d+cvqq%t7Tk<}!E5Xq^i4lDANKiYrqEkCDN=9N-E( zULLloPP>Y6|I$FE?--jlTH_NLUvJzR=^SeW^*BB5@Z#!r+c}TbO24xRMl7=cP?crX zU^6)+F2+#>b9`!mY8k+2e1=saBb?KHjxd_A75c07{o7KSdJL25?81rK&u*i}7^1rD zpXf?8dfqbX?G@{rBIzsbT=(SiUq1G2IDAhV6+$!j$92G_2m0L zd47tJpzk>Q_8&WU$5%qxqCwM2>YfdQ-C4(coY027rf5NBf}>ehDyRoRtkJpC zS-p_?ph@e;N0JwEGwzSt{f;QtJD%MHMiab`A}z3Slcw#}`v-#*XPD4#pcbJpAS%+O6#{6UAb+bY>THGX?@D?U{= z>e462nY_?qdnmO#G?er0lMymc?fT;8VEuI=vBnCLlhq23>7-{jzh`gtyH9La@OfU3$1SC> z(d=*y6Fy)ozmLhTgGqiLf7s5Tb@xccP2C_XWk=f@@C>vAZb(vnRMRX!CQ7 zPxB)8ArD7}5f0ycPTYJ1gM_a((qHrcF`amznk=!M zPM1k~26l-daR~ZXPmIPTZdX#7pHH(5))evrG?^cH*<~>yBPLlj*>};3F2a8CMljF& zYObNqs*}5Z4%DP|9!!(V_a{HB5hs2_V=Eu=PkY6M+6@^A%d3fBq;y3J3kT+I@(_cQ zYZIWAai_k}w%lyEywatF=;~;0cFfs_Xm$G|GyQiLD@=p-Uj^Z_mq-`746{_9k(RY` z7|^@#EJaFgg!X~7;Kb0jtJ%0Pn=qjs+Q}hTo;J7XH;OZlU%&f8x%)BHm#d~FnyUsk2wzcDRv3N)DCRpJ8o)GnO6+%jpBET|K3x{k^%Ja>bMp0`TA6a)Or^k zd6mBlcf7EO-M3|aSIKR6qA<#TEA^klBf;UW`#T%tZ0UPgC_DZ3)5q;`x*WM*YQS&J z1dq%#s`gy`RP7}ziw$*hoDaGd{?A!xXu@5;G+?{apo$gc8}(x90l%p8@Af{8Rbty2 z$s+e+`@g`Ow)f$t36i literal 0 HcmV?d00001 diff --git a/interfaces/inner_kits/native_cpp/BUILD.gn b/interfaces/inner_kits/native_cpp/BUILD.gn new file mode 100644 index 000000000..dde1bdd95 --- /dev/null +++ b/interfaces/inner_kits/native_cpp/BUILD.gn @@ -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. + +import("//build/ohos.gni") +import("//foundation/distributedhardware/devicemanager/devicemanager.gni") + +config("dmnativeinnerkit_config") { + visibility = [ ":*" ] + include_dirs = [ + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "include", + "${common_path}/log/include", + "${common_path}/utils/include", + ] + + cflags = [ + "-Wall", + "-Werror", + "-Wdate-time", + "-Wfloat-equal", + "-Wshadow", + "-Wformat=2", + "-fdata-sections", + "-ffunction-sections", + "-Os", + ] + + cflags_cc = [ + "-Os", + ] +} + +config("dmnativeinnerkit_public_config") { + include_dirs = [ "include" ] +} + +ohos_shared_library("devicemanagersdk") { + sources = [ + "src/device_manager_proxy.cpp", + "src/device_manager_listener_stub.cpp", + "src/device_manager.cpp", + "src/dm_device_info.cpp", + "src/dm_subscribe_info.cpp", + ] + + configs = [ ":dmnativeinnerkit_config" ] + + public_configs = [ ":dmnativeinnerkit_public_config" ] + + deps = [ "//utils/native/base:utils" ] + + defines = [ + "DH_LOG_TAG=\"devicemanagerkit\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "appexecfwk_standard:appexecfwk_base", + "appexecfwk_standard:appexecfwk_core", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_L2:samgr_proxy", + ] + + subsystem_name = "distributedhardware" + + part_name = "device_manager_base" +} diff --git a/interfaces/inner_kits/native_cpp/include/device_manager.h b/interfaces/inner_kits/native_cpp/include/device_manager.h new file mode 100644 index 000000000..a21f8a14c --- /dev/null +++ b/interfaces/inner_kits/native_cpp/include/device_manager.h @@ -0,0 +1,67 @@ +/* + * 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 OHOS_DEVICE_MANAGER_H +#define OHOS_DEVICE_MANAGER_H +#include "iremote_object.h" + +#include + +#include "device_manager_callback.h" +#include "device_manager_listener_stub.h" +#include "idevice_manager.h" +#include "single_instance.h" +#include "dm_subscribe_info.h" + +namespace OHOS { +namespace DistributedHardware { +class DmDeathRecipient : public IRemoteObject::DeathRecipient { +public: + void OnRemoteDied(const wptr& remote) override; + DmDeathRecipient() = default; + ~DmDeathRecipient() = default; +}; + +class DeviceManager { +friend class DmDeathRecipient; +DECLARE_SINGLE_INSTANCE(DeviceManager); +public: + int32_t InitDeviceManager(std::string &packageName, std::shared_ptr dmInitCallback); + int32_t UnInitDeviceManager(std::string &packageName); + int32_t GetTrustedDeviceList(std::string &packageName, std::string &extra, + std::vector &deviceList); + int32_t RegisterDevStateCallback(std::string &packageName, std::string &extra, + std::shared_ptr callback); + int32_t UnRegisterDevStateCallback(std::string &packageName); + int32_t StartDeviceDiscovery(std::string &packageName, DmSubscribeInfo &subscribeInfo, + std::shared_ptr callback); + int32_t StopDeviceDiscovery(std::string &packageName, uint16_t subscribeId); + int32_t AuthenticateDevice(std::string &packageName, const DmDeviceInfo &deviceInfo, std::string &extra, + std::shared_ptr callback); + +private: + int32_t InitDeviceManagerService(); + bool IsInit(std::string &packageName); + +private: + std::mutex lock_; + sptr dmInterface_; + sptr dmRecipient_; + std::map> dmListener_; + std::map> dmInitCallback_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DEVICE_MANAGER_H diff --git a/interfaces/inner_kits/native_cpp/include/device_manager_callback.h b/interfaces/inner_kits/native_cpp/include/device_manager_callback.h new file mode 100644 index 000000000..58aff430f --- /dev/null +++ b/interfaces/inner_kits/native_cpp/include/device_manager_callback.h @@ -0,0 +1,52 @@ +/* + * 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 OHOS_DEVICE_MANAGER_CALLBACK_H +#define OHOS_DEVICE_MANAGER_CALLBACK_H +#include "dm_device_info.h" + +namespace OHOS { +namespace DistributedHardware { +class DmInitCallback { +public: + virtual ~DmInitCallback() {} + virtual void OnRemoteDied() = 0; +}; + +class DeviceStateCallback { +public: + virtual ~DeviceStateCallback() {} + virtual void OnDeviceOnline(const DmDeviceInfo &deviceInfo) = 0; + virtual void OnDeviceReady(const DmDeviceInfo &deviceInfo) = 0; + virtual void OnDeviceOffline(const DmDeviceInfo &deviceInfo) = 0; + virtual void OnDeviceChanged(const DmDeviceInfo &deviceInfo) = 0; +}; + +class DiscoverCallback { +public: + virtual ~DiscoverCallback() {} + virtual void OnDiscoverySuccess(uint16_t subscribeId) = 0; + virtual void OnDiscoverFailed(uint16_t subscribeId, int32_t failedReason) = 0; + virtual void OnDeviceFound(uint16_t subscribeId, DmDeviceInfo &deviceInfo) = 0; +}; + +class AuthenticateCallback { +public: + virtual ~AuthenticateCallback() {} + virtual void OnAuthResult(std::string &deviceId, int32_t status, int32_t reason) = 0; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DEVICE_MANAGER_CALLBACK_H diff --git a/interfaces/inner_kits/native_cpp/include/device_manager_listener_stub.h b/interfaces/inner_kits/native_cpp/include/device_manager_listener_stub.h new file mode 100644 index 000000000..600b96457 --- /dev/null +++ b/interfaces/inner_kits/native_cpp/include/device_manager_listener_stub.h @@ -0,0 +1,64 @@ +/* + * 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 OHOS_DEVICE_MANAGER_LISTENER_STUB_H +#define OHOS_DEVICE_MANAGER_LISTENER_STUB_H + +#include +#include "iremote_stub.h" +#include "idevice_manager_listener.h" + +#include "device_manager_callback.h" + +namespace OHOS { +namespace DistributedHardware { +class DeviceManagerListenerStub : public IRemoteStub { +public: + DeviceManagerListenerStub(); + ~DeviceManagerListenerStub(); + int32_t OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel &reply, MessageOption &option) override; + int32_t OnDeviceOnline(std::string &packageName, const DmDeviceInfo &deviceInfo) override; + int32_t OnDeviceOffline(std::string &packageName, const DmDeviceInfo &deviceInfo) override; + int32_t OnDeviceChanged(std::string &packageName, const DmDeviceInfo &deviceInfo) override; + int32_t OnDeviceFound(std::string &packageName, uint16_t subscribeId, const DmDeviceInfo &deviceInfo) override; + int32_t OnDiscoverFailed(std::string &packageName, uint16_t subscribeId, int32_t failedReason) override; + int32_t OnDiscoverySuccess(std::string &packageName, uint16_t subscribeId) override; + int32_t OnAuthResult(std::string &packageName, std::string &deviceId, int32_t status, int32_t reason) override; + void AddDeviceStateCallback(std::shared_ptr callback); + void RemoveDeviceStateCallback(); + void AddDiscoverCallback(uint16_t subscribeId, std::shared_ptr callback); + void RemoveDiscoverCallback(uint16_t subscribeId); + void AddAuthenticateCallback(std::string deviceId, std::shared_ptr callback); + +private: + template + int32_t GetParcelableInfo(MessageParcel &reply, T &parcelableInfo); + int32_t OnDeviceOnlineInner(MessageParcel &data, MessageParcel &reply); + int32_t OnDeviceOfflineInner(MessageParcel &data, MessageParcel &reply); + int32_t OnDeviceChangedInner(MessageParcel &data, MessageParcel &reply); + int32_t OnDeviceFoundInner(MessageParcel &data, MessageParcel &reply); + int32_t OnDiscoverFailedInner(MessageParcel &data, MessageParcel &reply); + int32_t OnDiscoverySuccessInner(MessageParcel &data, MessageParcel &reply); + int32_t OnAuthResultInner(MessageParcel &data, MessageParcel &reply); + + using ListenerFunc = int32_t (DeviceManagerListenerStub::*)(MessageParcel& data, MessageParcel& reply); + std::map memberFuncMap_; + std::shared_ptr deviceStateCallback_; + std::map> deviceDiscoverCallbacks_; + std::map> authenticateCallback_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DEVICE_MANAGER_LISTENER_STUB_H diff --git a/interfaces/inner_kits/native_cpp/include/device_manager_proxy.h b/interfaces/inner_kits/native_cpp/include/device_manager_proxy.h new file mode 100644 index 000000000..8d8a9755f --- /dev/null +++ b/interfaces/inner_kits/native_cpp/include/device_manager_proxy.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 OHOS_DEVICE_MANAGER_PROXY_H +#define OHOS_DEVICE_MANAGER_PROXY_H + +#include "idevice_manager.h" +#include "iremote_proxy.h" + +namespace OHOS { +namespace DistributedHardware { +class DeviceManagerProxy : public IRemoteProxy { +public: + explicit DeviceManagerProxy(const sptr& impl) : IRemoteProxy(impl) {}; + ~DeviceManagerProxy() {}; + + int32_t GetTrustedDeviceList(std::string &packageName, std::string &extra, + std::vector &deviceList) override; + int32_t RegisterDeviceManagerListener(std::string &packageName, sptr listener) override; + int32_t UnRegisterDeviceManagerListener(std::string &packageName) override; + int32_t RegisterDeviceStateCallback(std::string &packageName, std::string &extra) override; + int32_t UnRegisterDeviceStateCallback(std::string &packageName) override; + int32_t StartDeviceDiscovery(std::string &packageName, DmSubscribeInfo &subscribeInfo) override; + int32_t StopDeviceDiscovery(std::string &packageName, uint16_t subscribeId) override; + int32_t AuthenticateDevice(std::string &packageName, const DmDeviceInfo &deviceInfo, std::string &extra) override; + +private: + template + int32_t GetParcelableInfos(MessageParcel &reply, std::vector &parcelableInfos); + bool WriteInterfaceToken(MessageParcel &data); + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DEVICE_MANAGER_PROXY_H diff --git a/interfaces/inner_kits/native_cpp/include/dm_device_info.h b/interfaces/inner_kits/native_cpp/include/dm_device_info.h new file mode 100644 index 000000000..58952222e --- /dev/null +++ b/interfaces/inner_kits/native_cpp/include/dm_device_info.h @@ -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. + */ + +#ifndef OHOS_DEVICE_MANAGER_DEVICE_INFO_H +#define OHOS_DEVICE_MANAGER_DEVICE_INFO_H + +#include "parcel.h" + +namespace OHOS { +namespace DistributedHardware { +enum DMDeviceType : uint8_t { + DEVICE_TYPE_UNKNOWN = 0x00, + DEVICE_TYPE_WIFI_CAMERA = 0x08, + DEVICE_TYPE_AUDIO = 0x0A, + DEVICE_TYPE_PC = 0x0C, + DEVICE_TYPE_PHONE = 0x0E, + DEVICE_TYPE_PAD = 0x11, + DEVICE_TYPE_WATCH = 0x6D, + DEVICE_TYPE_CAR = 0x83, + DEVICE_TYPE_TV = 0x9C, +}; + +enum DmDeviceState : uint8_t { + DEVICE_STATE_UNKNOWN = 0, + DEVICE_STATE_ONLINE = 1, + DEVICE_STATE_OFFLINE = 2, +}; + +struct DmDeviceInfo : public Parcelable { + std::string deviceId; + std::string deviceName; + DMDeviceType deviceTypeId; + bool ReadFromParcel(Parcel &parcel); + virtual bool Marshalling(Parcel &parcel) const override; + static DmDeviceInfo *Unmarshalling(Parcel &parcel); +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DEVICE_MANAGER_DEVICE_INFO_H diff --git a/interfaces/inner_kits/native_cpp/include/dm_subscribe_info.h b/interfaces/inner_kits/native_cpp/include/dm_subscribe_info.h new file mode 100644 index 000000000..2a6f982ee --- /dev/null +++ b/interfaces/inner_kits/native_cpp/include/dm_subscribe_info.h @@ -0,0 +1,82 @@ +/* + * 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 OHOS_DEVICE_MANAGER_SUBSCRIBE_INFO_H +#define OHOS_DEVICE_MANAGER_SUBSCRIBE_INFO_H + +#include "parcel.h" + +namespace OHOS { +namespace DistributedHardware { +enum DmDiscoverMode : int32_t { + /* Passive */ + DISCOVER_MODE_PASSIVE = 0x55, + /* Proactive */ + DISCOVER_MODE_ACTIVE = 0xAA +}; + +enum DmExchangeMedium : int32_t { + /** Automatic medium selection */ + AUTO = 0, + /** Bluetooth */ + BLE = 1, + /** Wi-Fi */ + COAP = 2, + /** USB */ + USB = 3, + MEDIUM_BUTT +}; + +/** + * @brief Enumerates frequencies for publishing services. + * + * This enumeration applies only to Bluetooth and is not supported currently. + */ +enum DmExchangeFreq : int32_t { + /** Low */ + LOW = 0, + /** Medium */ + MID = 1, + /** High */ + HIGH = 2, + /** Super-high */ + SUPER_HIGH = 3, + FREQ_BUTT +}; + +const std::string DM_CAPABILITY_DDMP = "ddmpCapability"; + +struct DmSubscribeInfo : public Parcelable { + /** Service ID */ + uint16_t subscribeId; + /** Discovery mode for service subscription. For details, see {@link DmDiscoverMode}. */ + DmDiscoverMode mode; + /** Service subscription medium. For details, see {@link DmExchangeMedium}. */ + DmExchangeMedium medium; + /** Service subscription frequency. For details, see {@link DmExchangeFreq}. */ + DmExchangeFreq freq; + /** only find the device with the same account */ + bool isSameAccount; + /** find the sleeping devices */ + bool isWakeRemote; + /** Service subscription capability. */ + std::string capability; + bool ReadFromParcel(Parcel &parcel); + virtual bool Marshalling(Parcel &parcel) const override; + static DmSubscribeInfo *Unmarshalling(Parcel &parcel); +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DEVICE_MANAGER_SUBSCRIBE_INFO_H diff --git a/interfaces/inner_kits/native_cpp/include/idevice_manager.h b/interfaces/inner_kits/native_cpp/include/idevice_manager.h new file mode 100644 index 000000000..b71235000 --- /dev/null +++ b/interfaces/inner_kits/native_cpp/include/idevice_manager.h @@ -0,0 +1,55 @@ +/* + * 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 OHOS_DEVICE_MANAGER_INTERFACE_H +#define OHOS_DEVICE_MANAGER_INTERFACE_H + +#include "iremote_broker.h" +#include "dm_device_info.h" +#include "dm_subscribe_info.h" + +namespace OHOS { +namespace DistributedHardware { +enum { + REGISTER_DEVICE_MANAGER_LISTENER = 0, + UNREGISTER_DEVICE_MANAGER_LISTENER = 1, + REGISTER_DEVICE_STATE_CALLBACK = 2, + UNREGISTER_DEVICE_STATE_CALLBACK = 3, + GET_TRUST_DEVICE_LIST = 4, + START_DEVICE_DISCOVER = 5, + STOP_DEVICE_DISCOVER = 6, + AUTHENTICATE_DEVICE = 7, +}; + +class IDeviceManager : public OHOS::IRemoteBroker { +public: + virtual ~IDeviceManager() {} + virtual int32_t GetTrustedDeviceList(std::string &packageName, std::string &extra, + std::vector &deviceList) = 0; + virtual int32_t RegisterDeviceManagerListener(std::string &packageName, sptr listener) = 0; + virtual int32_t UnRegisterDeviceManagerListener(std::string &packageName) = 0; + virtual int32_t RegisterDeviceStateCallback(std::string &packageName, std::string &extra) = 0; + virtual int32_t UnRegisterDeviceStateCallback(std::string &packageName) = 0; + virtual int32_t StartDeviceDiscovery(std::string &packageName, DmSubscribeInfo &subscribeInfo) = 0; + virtual int32_t StopDeviceDiscovery(std::string &packageName, uint16_t subscribeId) = 0; + virtual int32_t AuthenticateDevice(std::string &packageName, const DmDeviceInfo &deviceInfo, + std::string &extra) = 0; + +public: + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.distributedhardware.devicemanager"); +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DEVICE_MANAGER_INTERFACE_H diff --git a/interfaces/inner_kits/native_cpp/include/idevice_manager_listener.h b/interfaces/inner_kits/native_cpp/include/idevice_manager_listener.h new file mode 100644 index 000000000..bf55490d3 --- /dev/null +++ b/interfaces/inner_kits/native_cpp/include/idevice_manager_listener.h @@ -0,0 +1,50 @@ +/* + * 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 OHOS_DEVICE_MANAGER_LISTENER_INTERFACE_H +#define OHOS_DEVICE_MANAGER_LISTENER_INTERFACE_H + +#include "iremote_broker.h" +#include "dm_device_info.h" + +namespace OHOS { +namespace DistributedHardware { +enum { + ON_DEVICE_ONLINE = 0, + ON_DEVICE_OFFLINE = 1, + ON_DEVICE_CHANGE = 2, + ON_DEVICE_FOUND = 3, + ON_DISCOVER_SUCCESS = 4, + ON_DISCOVER_FAILED = 5, + ON_AUTH_RESULT = 6, +}; + +class IDeviceManagerListener : public OHOS::IRemoteBroker { +public: + virtual ~IDeviceManagerListener() {} + virtual int32_t OnDeviceOnline(std::string &packageName, const DmDeviceInfo &deviceInfo) = 0; + virtual int32_t OnDeviceOffline(std::string &packageName, const DmDeviceInfo &deviceInfo) = 0; + virtual int32_t OnDeviceChanged(std::string &packageName, const DmDeviceInfo &deviceInfo) = 0; + virtual int32_t OnDeviceFound(std::string &packageName, uint16_t subscribeId, const DmDeviceInfo &deviceInfo) = 0; + virtual int32_t OnDiscoverFailed(std::string &packageName, uint16_t subscribeId, int32_t failedReason) = 0; + virtual int32_t OnDiscoverySuccess(std::string &packageName, uint16_t subscribeId) = 0; + virtual int32_t OnAuthResult(std::string &packageName, std::string &deviceId, int32_t status, int32_t reason) = 0; + +public: + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.distributedhardware.devicemanagerlistener"); +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DEVICE_MANAGER_LISTENER_INTERFACE_H diff --git a/interfaces/inner_kits/native_cpp/src/device_manager.cpp b/interfaces/inner_kits/native_cpp/src/device_manager.cpp new file mode 100644 index 000000000..65da53e98 --- /dev/null +++ b/interfaces/inner_kits/native_cpp/src/device_manager.cpp @@ -0,0 +1,314 @@ +/* + * 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_manager.h" + +#include "iservice_registry.h" +#include "system_ability_definition.h" + +#include "device_manager_errno.h" +#include "device_manager_log.h" + +namespace OHOS { +namespace DistributedHardware { +IMPLEMENT_SINGLE_INSTANCE(DeviceManager); + +int32_t DeviceManager::InitDeviceManagerService() +{ + HILOGI("DeviceManager::InitDeviceManagerService start"); + if (dmInterface_ != nullptr) { + HILOGI("DeviceManagerService Already Init"); + return ERR_OK; + } + + auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgr == nullptr) { + HILOGE("Get SystemAbilityManager Failed"); + return ERR_NO_INIT; + } + + auto object = samgr->CheckSystemAbility(DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID); + if (object == nullptr) { + HILOGE("Get DeviceManager SystemAbility Failed"); + return ERR_DEVICEMANAGER_SERVICE_NOT_READY; + } + + if (dmRecipient_ == nullptr) { + dmRecipient_ = sptr(new DmDeathRecipient()); + } + + if (!object->AddDeathRecipient(dmRecipient_)) { + HILOGE("InitDeviceManagerService: AddDeathRecipient Failed"); + } + + dmInterface_ = iface_cast(object); + HILOGI("DeviceManager::InitDeviceManagerService completed"); + return ERR_OK; +} + +bool DeviceManager::IsInit(std::string &packageName) +{ + if (dmInterface_ == nullptr) { + HILOGE("DeviceManager not Init"); + return false; + } + + if (dmListener_.find(packageName) == dmListener_.end()) { + HILOGE("dmListener_ not Init for %{public}s", packageName.c_str()); + return false; + } + return true; +} + +int32_t DeviceManager::InitDeviceManager(std::string &packageName, std::shared_ptr dmInitCallback) +{ + HILOGI("DeviceManager::InitDeviceManager start, packageName: %{public}s", packageName.c_str()); + if (packageName.empty() || dmInitCallback == nullptr) { + HILOGE("InitDeviceManager error: Invalid parameter"); + return ERR_INVALID_VALUE; + } + + HILOGI("InitDeviceManager in, packageName %{public}s", packageName.c_str()); + std::lock_guard autoLock(lock_); + int32_t ret = InitDeviceManagerService(); + if (ret != ERR_OK) { + HILOGE("InitDeviceManager Failed with ret %{public}d", ret); + return ret; + } + + auto iter = dmListener_.find(packageName); + if (iter != dmListener_.end()) { + HILOGI("dmListener_ Already Init"); + dmInitCallback_[packageName] = dmInitCallback; + return ERR_OK; + } + + sptr listener = sptr(new DeviceManagerListenerStub()); + ret = dmInterface_->RegisterDeviceManagerListener(packageName, listener); + if (ret != ERR_OK) { + HILOGE("InitDeviceManager: RegisterDeviceManagerListener Failed with ret %{public}d", ret); + return ret; + } + + dmListener_[packageName] = listener; + dmInitCallback_[packageName] = dmInitCallback; + + HILOGI("DeviceManager::InitDeviceManager completed, packageName: %{public}s", packageName.c_str()); + return ERR_OK; +} + +int32_t DeviceManager::UnInitDeviceManager(std::string &packageName) +{ + HILOGI("DeviceManager::UnInitDeviceManager start, packageName: %{public}s", packageName.c_str()); + if (packageName.empty()) { + HILOGE("InitDeviceManager error: Invalid parameter"); + return ERR_INVALID_VALUE; + } + + HILOGI("UnInitDeviceManager in, packageName %{public}s", packageName.c_str()); + std::lock_guard autoLock(lock_); + if (dmInterface_ == nullptr) { + HILOGE("DeviceManager not Init"); + return ERR_NO_INIT; + } + + auto iter = dmListener_.find(packageName); + if (iter != dmListener_.end()) { + int32_t ret = dmInterface_->UnRegisterDeviceManagerListener(packageName); + if (ret != ERR_OK) { + HILOGE("UnInitDeviceManager: UnRegisterDeviceManagerListener Failed with ret %{public}d", ret); + return ret; + } + dmListener_.erase(packageName); + dmInitCallback_.erase(packageName); + } + + if (dmListener_.empty()) { + dmRecipient_ = nullptr; + dmInterface_ = nullptr; + } + HILOGI("DeviceManager::UnInitDeviceManager completed, packageName: %{public}s", packageName.c_str()); + return ERR_OK; +} + +int32_t DeviceManager::GetTrustedDeviceList(std::string &packageName, std::string &extra, + std::vector &deviceList) +{ + HILOGI("DeviceManager::GetTrustedDeviceList start, packageName: %{public}s", packageName.c_str()); + if (packageName.empty()) { + HILOGE("Invalid para"); + return ERR_INVALID_VALUE; + } + + if (!IsInit(packageName)) { + HILOGE("DeviceManager not Init for %{public}s", packageName.c_str()); + return ERR_NO_INIT; + } + + HILOGI("GetTrustedDeviceList in, packageName %{public}s", packageName.c_str()); + int32_t ret = dmInterface_->GetTrustedDeviceList(packageName, extra, deviceList); + if (ret != ERR_OK) { + HILOGE("RegisterDevStateCallback Failed with ret %{public}d", ret); + return ret; + } + HILOGI("DeviceManager::GetTrustedDeviceList completed, packageName: %{public}s", packageName.c_str()); + return ERR_OK; +} + +int32_t DeviceManager::RegisterDevStateCallback(std::string &packageName, std::string &extra, + std::shared_ptr callback) +{ + HILOGI("DeviceManager::RegisterDevStateCallback start, packageName: %{public}s", packageName.c_str()); + if (packageName.empty() || callback == nullptr) { + HILOGE("Invalid para"); + return ERR_INVALID_VALUE; + } + + if (!IsInit(packageName)) { + HILOGE("DeviceManager not Init for %{public}s", packageName.c_str()); + return ERR_NO_INIT; + } + + HILOGI("RegisterDevStateCallback in, packageName %{public}s", packageName.c_str()); + int32_t ret = dmInterface_->RegisterDeviceStateCallback(packageName, extra); + if (ret != ERR_OK) { + HILOGE("RegisterDevStateCallback Failed with ret %{public}d", ret); + return ret; + } + + std::lock_guard autoLock(lock_); + dmListener_[packageName]->AddDeviceStateCallback(callback); + HILOGI("DeviceManager::RegisterDevStateCallback completed, packageName: %{public}s", packageName.c_str()); + return ERR_OK; +} + +int32_t DeviceManager::UnRegisterDevStateCallback(std::string &packageName) +{ + HILOGI("DeviceManager::UnRegisterDevStateCallback start, packageName: %{public}s", packageName.c_str()); + if (packageName.empty()) { + HILOGE("Invalid para"); + return ERR_INVALID_VALUE; + } + + if (!IsInit(packageName)) { + HILOGE("DeviceManager not Init for %{public}s", packageName.c_str()); + return ERR_NO_INIT; + } + + HILOGI("UnRegisterDevStateCallback in, packageName %{public}s", packageName.c_str()); + int32_t ret = dmInterface_->UnRegisterDeviceStateCallback(packageName); + if (ret != ERR_OK) { + HILOGE("UnRegisterDeviceStateCallback Failed with ret %{public}d", ret); + return ret; + } + + std::lock_guard autoLock(lock_); + dmListener_[packageName]->RemoveDeviceStateCallback(); + HILOGI("DeviceManager::UnRegisterDevStateCallback completed, packageName: %{public}s", packageName.c_str()); + return ERR_OK; +} + +int32_t DeviceManager::StartDeviceDiscovery(std::string &packageName, DmSubscribeInfo &subscribeInfo, + std::shared_ptr callback) +{ + HILOGI("DeviceManager::StartDeviceDiscovery start, packageName: %{public}s", packageName.c_str()); + if (packageName.empty() || callback == nullptr) { + HILOGE("Invalid para"); + return ERR_INVALID_VALUE; + } + + if (!IsInit(packageName)) { + HILOGE("DeviceManager not Init for %{public}s", packageName.c_str()); + return ERR_NO_INIT; + } + + HILOGI("StartDeviceDiscovery in, packageName %{public}s", packageName.c_str()); + { + std::lock_guard autoLock(lock_); + dmListener_[packageName]->AddDiscoverCallback(subscribeInfo.subscribeId, callback); + } + int32_t ret = dmInterface_->StartDeviceDiscovery(packageName, subscribeInfo); + if (ret != ERR_OK) { + HILOGE("StartDeviceDiscovery Failed with ret %{public}d", ret); + return ret; + } + + HILOGI("DeviceManager::StartDeviceDiscovery completed, packageName: %{public}s", packageName.c_str()); + return ERR_OK; +} + +int32_t DeviceManager::StopDeviceDiscovery(std::string &packageName, uint16_t subscribeId) +{ + HILOGI("DeviceManager::StopDeviceDiscovery start , packageName: %{public}s", packageName.c_str()); + if (packageName.empty()) { + HILOGE("Invalid para"); + return ERR_INVALID_VALUE; + } + + if (!IsInit(packageName)) { + HILOGE("DeviceManager not Init for %{public}s", packageName.c_str()); + return ERR_NO_INIT; + } + + HILOGI("StopDeviceDiscovery in, packageName %{public}s", packageName.c_str()); + int32_t ret = dmInterface_->StopDeviceDiscovery(packageName, subscribeId); + if (ret != ERR_OK) { + HILOGE("StopDeviceDiscovery Failed with ret %{public}d", ret); + return ret; + } + + std::lock_guard autoLock(lock_); + dmListener_[packageName]->RemoveDiscoverCallback(subscribeId); + HILOGI("DeviceManager::StopDeviceDiscovery completed, packageName: %{public}s", packageName.c_str()); + return ERR_OK; +} + +int32_t DeviceManager::AuthenticateDevice(std::string &packageName, const DmDeviceInfo &deviceInfo, std::string &extra, + std::shared_ptr callback) +{ + HILOGI("DeviceManager::AuthenticateDevice start , packageName: %{public}s", packageName.c_str()); + if (packageName.empty()) { + HILOGE("Invalid para"); + return ERR_INVALID_VALUE; + } + + if (!IsInit(packageName)) { + HILOGE("DeviceManager not Init for %{public}s", packageName.c_str()); + return ERR_NO_INIT; + } + + HILOGI("AuthenticateDevice in, packageName %{public}s", packageName.c_str()); + int32_t ret = dmInterface_->AuthenticateDevice(packageName, deviceInfo, extra); + if (ret != ERR_OK) { + HILOGE("AuthenticateDevice Failed with ret %{public}d", ret); + return ret; + } + + std::lock_guard autoLock(lock_); + dmListener_[packageName]->AddAuthenticateCallback(deviceInfo.deviceId, callback); + HILOGI("DeviceManager::AuthenticateDevice completed, packageName: %{public}s", packageName.c_str()); + return ERR_OK; +} + +void DmDeathRecipient::OnRemoteDied(const wptr& remote) +{ + (void)remote; + HILOGW("DmDeathRecipient : OnRemoteDied"); + for (auto iter : DeviceManager::GetInstance().dmInitCallback_) { + iter.second->OnRemoteDied(); + } +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/interfaces/inner_kits/native_cpp/src/device_manager_listener_stub.cpp b/interfaces/inner_kits/native_cpp/src/device_manager_listener_stub.cpp new file mode 100644 index 000000000..e3fc817a7 --- /dev/null +++ b/interfaces/inner_kits/native_cpp/src/device_manager_listener_stub.cpp @@ -0,0 +1,303 @@ +/* + * 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_manager_listener_stub.h" + +#include "ipc_skeleton.h" +#include "ipc_types.h" + +#include "device_manager_log.h" + +using namespace std; + +namespace OHOS { +namespace DistributedHardware { +DeviceManagerListenerStub::DeviceManagerListenerStub() +{ + memberFuncMap_[ON_DEVICE_ONLINE] = &DeviceManagerListenerStub::OnDeviceOnlineInner; + memberFuncMap_[ON_DEVICE_OFFLINE] = &DeviceManagerListenerStub::OnDeviceOfflineInner; + memberFuncMap_[ON_DEVICE_CHANGE] = &DeviceManagerListenerStub::OnDeviceChangedInner; + memberFuncMap_[ON_DEVICE_FOUND] = &DeviceManagerListenerStub::OnDeviceFoundInner; + memberFuncMap_[ON_DISCOVER_SUCCESS] = &DeviceManagerListenerStub::OnDiscoverySuccessInner; + memberFuncMap_[ON_DISCOVER_FAILED] = &DeviceManagerListenerStub::OnDiscoverFailedInner; + memberFuncMap_[ON_AUTH_RESULT] = &DeviceManagerListenerStub::OnAuthResultInner; +} + +DeviceManagerListenerStub::~DeviceManagerListenerStub() +{ + memberFuncMap_.clear(); +} + +int32_t DeviceManagerListenerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + HILOGI("code = %{public}d, flags= %{public}d.", code, option.GetFlags()); + auto itFunc = memberFuncMap_.find(code); + if (itFunc != memberFuncMap_.end()) { + auto memberFunc = itFunc->second; + if (data.ReadInterfaceToken() != DeviceManagerListenerStub::GetDescriptor()) { + HILOGE("interface token check failed!"); + return ERR_INVALID_STATE; + } + return (this->*memberFunc)(data, reply); + } + HILOGW("unsupport code: %{public}d", code); + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); +} + +template +int32_t DeviceManagerListenerStub::GetParcelableInfo(MessageParcel &reply, T &parcelableInfo) +{ + std::unique_ptr info(reply.ReadParcelable()); + if (!info) { + HILOGE("readParcelableInfo failed"); + return ERR_INVALID_VALUE; + } + parcelableInfo = *info; + return ERR_NONE; +} + +int32_t DeviceManagerListenerStub::OnDeviceOnlineInner(MessageParcel &data, MessageParcel &reply) +{ + string packageName = data.ReadString(); + DmDeviceInfo deviceInfo; + int32_t result = GetParcelableInfo(data, deviceInfo); + if (result != ERR_NONE) { + HILOGE("GetParcelableInfo fail, result: %{public}d", result); + reply.WriteInt32(result); + return result; + } + + int32_t ret = OnDeviceOnline(packageName, deviceInfo); + reply.WriteInt32(ret); + return ret; +} + +int32_t DeviceManagerListenerStub::OnDeviceOfflineInner(MessageParcel &data, MessageParcel &reply) +{ + string packageName = data.ReadString(); + DmDeviceInfo deviceInfo; + int32_t result = GetParcelableInfo(data, deviceInfo); + if (result != ERR_NONE) { + HILOGE("GetParcelableInfo fail, result: %{public}d", result); + reply.WriteInt32(result); + return result; + } + + int32_t ret = OnDeviceOffline(packageName, deviceInfo); + reply.WriteInt32(ret); + return ret; +} + +int32_t DeviceManagerListenerStub::OnDeviceChangedInner(MessageParcel &data, MessageParcel &reply) +{ + string packageName = data.ReadString(); + DmDeviceInfo deviceInfo; + int32_t result = GetParcelableInfo(data, deviceInfo); + if (result != ERR_NONE) { + HILOGE("GetParcelableInfo deviceInfo fail, result: %{public}d", result); + reply.WriteInt32(result); + return result; + } + + int32_t ret = OnDeviceChanged(packageName, deviceInfo); + reply.WriteInt32(ret); + return ret; +} + +int32_t DeviceManagerListenerStub::OnDeviceFoundInner(MessageParcel &data, MessageParcel &reply) +{ + string packageName = data.ReadString(); + uint16_t subscribeId = data.ReadInt16(); + DmDeviceInfo deviceInfo; + int32_t result = GetParcelableInfo(data, deviceInfo); + if (result != ERR_NONE) { + HILOGE("GetParcelableInfo fail, result: %{public}d", result); + reply.WriteInt32(result); + return result; + } + + int32_t ret = OnDeviceFound(packageName, subscribeId, deviceInfo); + reply.WriteInt32(ret); + return ret; +} + +int32_t DeviceManagerListenerStub::OnDiscoverFailedInner(MessageParcel &data, MessageParcel &reply) +{ + string packageName = data.ReadString(); + uint16_t subscribeId = data.ReadInt16(); + int32_t failedReason = data.ReadInt32(); + + int32_t ret = OnDiscoverFailed(packageName, subscribeId, failedReason); + reply.WriteInt32(ret); + return ret; +} + +int32_t DeviceManagerListenerStub::OnDiscoverySuccessInner(MessageParcel &data, MessageParcel &reply) +{ + string packageName = data.ReadString(); + uint16_t subscribeId = data.ReadInt16(); + + int32_t ret = OnDiscoverySuccess(packageName, subscribeId); + reply.WriteInt32(ret); + return ret; +} + +int32_t DeviceManagerListenerStub::OnAuthResultInner(MessageParcel &data, MessageParcel &reply) +{ + string packageName = data.ReadString(); + string deviceId = data.ReadString(); + int32_t status = data.ReadInt32(); + int32_t reason = data.ReadInt32(); + + int32_t ret = OnAuthResult(packageName, deviceId, status, reason); + reply.WriteInt32(ret); + return ret; +} + +int32_t DeviceManagerListenerStub::OnDeviceOnline(std::string &packageName, const DmDeviceInfo &deviceInfo) +{ + HILOGI("OnDeviceOnline packageName:%{public}s", packageName.c_str()); + if (deviceStateCallback_ == nullptr) { + HILOGE("OnDeviceOnlinecallback not register"); + return ERR_NULL_OBJECT; + } + deviceStateCallback_->OnDeviceOnline(deviceInfo); + return ERR_OK; +} + +int32_t DeviceManagerListenerStub::OnDeviceOffline(std::string &packageName, const DmDeviceInfo &deviceInfo) +{ + HILOGI("OnDeviceOffline packageName:%{public}s", packageName.c_str()); + if (deviceStateCallback_ == nullptr) { + HILOGE("OnDeviceOnlinecallback not register"); + return ERR_NULL_OBJECT; + } + deviceStateCallback_->OnDeviceOffline(deviceInfo); + return ERR_OK; +} + +int32_t DeviceManagerListenerStub::OnDeviceChanged(std::string &packageName, const DmDeviceInfo &deviceInfo) +{ + HILOGI("OnDeviceChanged packageName:%{public}s", packageName.c_str()); + if (deviceStateCallback_ == nullptr) { + HILOGE("OnDeviceOnlinecallback not register"); + return ERR_NULL_OBJECT; + } + deviceStateCallback_->OnDeviceChanged(deviceInfo); + return ERR_OK; +} + +int32_t DeviceManagerListenerStub::OnDeviceFound(std::string &packageName, uint16_t subscribeId, + const DmDeviceInfo &deviceInfo) +{ + HILOGI("OnDeviceFound packageName:%{public}s, subscribeId:%{public}d.", packageName.c_str(), (int32_t)subscribeId); + auto iter = deviceDiscoverCallbacks_.find(subscribeId); + if (iter == deviceDiscoverCallbacks_.end()) { + HILOGE("OnDeviceFound: no register discoverCallback for subscribeId %{public}d", subscribeId); + return ERR_NULL_OBJECT; + } + auto callback = iter->second; + if (callback == nullptr) { + HILOGE("OnDeviceFound: discoverCallback is nullptr for subscribeId %{public}d", subscribeId); + return ERR_NULL_OBJECT; + } + callback->OnDeviceFound(subscribeId, const_cast(deviceInfo)); + return ERR_OK; +} + +int32_t DeviceManagerListenerStub::OnDiscoverFailed(std::string &packageName, uint16_t subscribeId, + int32_t failedReason) +{ + HILOGI("OnDiscoverFailed packageName:%{public}s, subscribeId %{public}d, reason %{public}d", + packageName.c_str(), subscribeId, failedReason); + auto iter = deviceDiscoverCallbacks_.find(subscribeId); + if (iter == deviceDiscoverCallbacks_.end()) { + HILOGE("OnDiscoverFailed: no register discoverCallback for subscribeId %{public}d", subscribeId); + return ERR_NULL_OBJECT; + } + auto callback = iter->second; + if (callback == nullptr) { + HILOGE("OnDiscoverFailed: discoverCallback is nullptr for subscribeId %{public}d", subscribeId); + return ERR_NULL_OBJECT; + } + callback->OnDiscoverFailed(subscribeId, failedReason); + return ERR_OK; +} + +int32_t DeviceManagerListenerStub::OnDiscoverySuccess(std::string &packageName, uint16_t subscribeId) +{ + HILOGI("OnDiscoverySuccess packageName:%{public}s, subscribeId %{public}d", packageName.c_str(), subscribeId); + auto iter = deviceDiscoverCallbacks_.find(subscribeId); + if (iter == deviceDiscoverCallbacks_.end()) { + HILOGE("OnDiscoverySuccess: no register discoverCallback for subscribeId %{public}d", subscribeId); + return ERR_NULL_OBJECT; + } + auto callback = iter->second; + if (callback == nullptr) { + HILOGE("OnDiscoverySuccess: discoverCallback is nullptr for subscribeId %{public}d", subscribeId); + return ERR_NULL_OBJECT; + } + callback->OnDiscoverySuccess(subscribeId); + return ERR_OK; +} + +int32_t DeviceManagerListenerStub::OnAuthResult(std::string &packageName, std::string &deviceId, int32_t status, + int32_t reason) +{ + HILOGI("OnAuthResult packageName:%{public}s, status %{public}d, reason %{public}d", + packageName.c_str(), status, reason); + auto iter = authenticateCallback_.find(deviceId); + if (iter == authenticateCallback_.end()) { + HILOGE("OnAuthResult: cannot find Auth callback"); + return ERR_NULL_OBJECT; + } + auto callback = iter->second; + if (callback == nullptr) { + HILOGE("OnAuthResult: Auth callback is nullptr"); + return ERR_NULL_OBJECT; + } + callback->OnAuthResult(deviceId, status, reason); + authenticateCallback_.erase(deviceId); + return ERR_OK; +} + +void DeviceManagerListenerStub::AddDeviceStateCallback(std::shared_ptr callback) +{ + deviceStateCallback_ = callback; +} + +void DeviceManagerListenerStub::RemoveDeviceStateCallback() +{ + deviceStateCallback_ = nullptr; +} + +void DeviceManagerListenerStub::AddDiscoverCallback(uint16_t subscribeId, std::shared_ptr callback) +{ + deviceDiscoverCallbacks_[subscribeId] = callback; +} + +void DeviceManagerListenerStub::RemoveDiscoverCallback(uint16_t subscribeId) +{ + deviceDiscoverCallbacks_.erase(subscribeId); +} + +void DeviceManagerListenerStub::AddAuthenticateCallback(std::string deviceId, + std::shared_ptr callback) +{ + authenticateCallback_[deviceId] = callback; +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/interfaces/inner_kits/native_cpp/src/device_manager_proxy.cpp b/interfaces/inner_kits/native_cpp/src/device_manager_proxy.cpp new file mode 100644 index 000000000..d5045590c --- /dev/null +++ b/interfaces/inner_kits/native_cpp/src/device_manager_proxy.cpp @@ -0,0 +1,316 @@ +/* + * 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_manager_proxy.h" + +#include "ipc_types.h" + +#include "device_manager_log.h" + +namespace OHOS { +namespace DistributedHardware { +bool DeviceManagerProxy::WriteInterfaceToken(MessageParcel &data) +{ + if (!data.WriteInterfaceToken(DeviceManagerProxy::GetDescriptor())) { + HILOGE("write interface token failed"); + return false; + } + return true; +} + +int32_t DeviceManagerProxy::RegisterDeviceManagerListener(std::string &packageName, sptr listener) +{ + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("remote service null"); + return ERR_NULL_OBJECT; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!WriteInterfaceToken(data)) { + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteString(packageName)) { + HILOGE("write packageName failed"); + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteRemoteObject(listener)) { + HILOGE("write callback failed"); + return ERR_FLATTEN_OBJECT; + } + + int32_t error = remote->SendRequest(REGISTER_DEVICE_MANAGER_LISTENER, data, reply, option); + if (error != ERR_NONE) { + HILOGE("RegisterDeviceManagerListener SendRequest fail, error: %{public}d", error); + return error; + } + return ERR_NONE; +} + +int32_t DeviceManagerProxy::UnRegisterDeviceManagerListener(std::string &packageName) +{ + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("remote service null"); + return ERR_NULL_OBJECT; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!WriteInterfaceToken(data)) { + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteString(packageName)) { + HILOGE("write packageName failed"); + return ERR_FLATTEN_OBJECT; + } + + int32_t error = remote->SendRequest(UNREGISTER_DEVICE_MANAGER_LISTENER, data, reply, option); + if (error != ERR_NONE) { + HILOGE("UnRegisterDeviceManagerListener SendRequest fail, error: %{public}d", error); + return error; + } + return ERR_NONE; +} + +int32_t DeviceManagerProxy::RegisterDeviceStateCallback(std::string &packageName, std::string &extra) +{ + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("remote service null"); + return ERR_NULL_OBJECT; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!WriteInterfaceToken(data)) { + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteString(packageName)) { + HILOGE("write packageName failed"); + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteString(extra)) { + HILOGE("write extra failed"); + return ERR_FLATTEN_OBJECT; + } + + int32_t error = remote->SendRequest(REGISTER_DEVICE_STATE_CALLBACK, data, reply, option); + if (error != ERR_NONE) { + HILOGE("RegisterDeviceStateCallback SendRequest fail, error: %{public}d", error); + return error; + } + return ERR_NONE; +} + +int32_t DeviceManagerProxy::UnRegisterDeviceStateCallback(std::string &packageName) +{ + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("remote service null"); + return ERR_NULL_OBJECT; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!WriteInterfaceToken(data)) { + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteString(packageName)) { + HILOGE("write packageName failed"); + return ERR_FLATTEN_OBJECT; + } + + int32_t error = remote->SendRequest(UNREGISTER_DEVICE_STATE_CALLBACK, data, reply, option); + if (error != ERR_NONE) { + HILOGE("UnRegisterDeviceStateCallback SendRequest fail, error: %{public}d", error); + return error; + } + return ERR_NONE; +} + +template +int32_t DeviceManagerProxy::GetParcelableInfos(MessageParcel &reply, std::vector &parcelableInfos) +{ + int32_t infoSize = reply.ReadInt32(); + for (int32_t i = 0; i < infoSize; i++) { + std::unique_ptr info(reply.ReadParcelable()); + if (!info) { + HILOGE("Read Parcelable infos failed"); + return ERR_INVALID_VALUE; + } + parcelableInfos.emplace_back(*info); + } + HILOGI("get parcelable infos success"); + return ERR_NONE; +} + +int32_t DeviceManagerProxy::GetTrustedDeviceList(std::string &packageName, std::string &extra, + std::vector &deviceList) +{ + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("remote service null"); + return ERR_NULL_OBJECT; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!WriteInterfaceToken(data)) { + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteString(packageName)) { + HILOGE("write packageName failed"); + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteString(extra)) { + HILOGE("write extra failed"); + return ERR_FLATTEN_OBJECT; + } + + int32_t error = remote->SendRequest(GET_TRUST_DEVICE_LIST, data, reply, option); + if (error != ERR_NONE) { + HILOGE("GetTrustedDeviceList SendRequest fail, error: %{public}d", error); + return error; + } + + error = GetParcelableInfos(reply, deviceList); + if (error != ERR_NONE) { + HILOGE("GetTrustedDeviceList GetParcelableInfos fail, error: %{public}d", error); + return error; + } + return ERR_NONE; +} + +int32_t DeviceManagerProxy::StartDeviceDiscovery(std::string &packageName, DmSubscribeInfo &subscribeInfo) +{ + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("remote service null"); + return ERR_NULL_OBJECT; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!WriteInterfaceToken(data)) { + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteString(packageName)) { + HILOGE("write packageName failed"); + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteParcelable(&subscribeInfo)) { + HILOGE("write subscribeInfo failed"); + return ERR_FLATTEN_OBJECT; + } + + int32_t error = remote->SendRequest(START_DEVICE_DISCOVER, data, reply, option); + if (error != ERR_NONE) { + HILOGE("StartDeviceDiscovery SendRequest fail, error: %{public}d", error); + return error; + } + return ERR_NONE; +} + +int32_t DeviceManagerProxy::StopDeviceDiscovery(std::string &packageName, uint16_t subscribeId) +{ + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("remote service null"); + return ERR_NULL_OBJECT; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!WriteInterfaceToken(data)) { + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteString(packageName)) { + HILOGE("write packageName failed"); + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteInt16(subscribeId)) { + HILOGE("write subscribeInfo failed"); + return ERR_FLATTEN_OBJECT; + } + + int32_t error = remote->SendRequest(STOP_DEVICE_DISCOVER, data, reply, option); + if (error != ERR_NONE) { + HILOGE("StopDeviceDiscovery SendRequest fail, error: %{public}d", error); + return error; + } + return ERR_NONE; +} + +int32_t DeviceManagerProxy::AuthenticateDevice(std::string &packageName, const DmDeviceInfo &deviceInfo, + std::string &extra) +{ + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("remote service null"); + return ERR_NULL_OBJECT; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!WriteInterfaceToken(data)) { + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteString(packageName)) { + HILOGE("write packageName failed"); + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteParcelable(&deviceInfo)) { + HILOGE("write deviceInfo failed"); + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteString(extra)) { + HILOGE("write extra failed"); + return ERR_FLATTEN_OBJECT; + } + + int32_t error = remote->SendRequest(AUTHENTICATE_DEVICE, data, reply, option); + if (error != ERR_NONE) { + HILOGE("AuthenticateDevice SendRequest fail, error: %{public}d", error); + return error; + } + return ERR_NONE; +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/interfaces/inner_kits/native_cpp/src/dm_device_info.cpp b/interfaces/inner_kits/native_cpp/src/dm_device_info.cpp new file mode 100644 index 000000000..b4a3bfa5e --- /dev/null +++ b/interfaces/inner_kits/native_cpp/src/dm_device_info.cpp @@ -0,0 +1,50 @@ +/* + * 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 "dm_device_info.h" + +namespace OHOS { +namespace DistributedHardware { +bool DmDeviceInfo::ReadFromParcel(Parcel &parcel) +{ + deviceId = parcel.ReadString(); + deviceName = parcel.ReadString(); + deviceTypeId = (DMDeviceType)parcel.ReadUint8(); + return true; +} + +DmDeviceInfo *DmDeviceInfo::Unmarshalling(Parcel &parcel) +{ + DmDeviceInfo *info = new (std::nothrow) DmDeviceInfo(); + if (info == nullptr) { + return nullptr; + } + + if (!info->ReadFromParcel(parcel)) { + delete info; + info = nullptr; + } + return info; +} + +bool DmDeviceInfo::Marshalling(Parcel &parcel) const +{ + parcel.WriteString(deviceId); + parcel.WriteString(deviceName); + parcel.WriteUint8((uint8_t)deviceTypeId); + return true; +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/interfaces/inner_kits/native_cpp/src/dm_subscribe_info.cpp b/interfaces/inner_kits/native_cpp/src/dm_subscribe_info.cpp new file mode 100644 index 000000000..0bba105f1 --- /dev/null +++ b/interfaces/inner_kits/native_cpp/src/dm_subscribe_info.cpp @@ -0,0 +1,58 @@ +/* + * 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 "dm_subscribe_info.h" + +namespace OHOS { +namespace DistributedHardware { +bool DmSubscribeInfo::ReadFromParcel(Parcel &parcel) +{ + subscribeId = parcel.ReadInt16(); + mode = (DmDiscoverMode)parcel.ReadInt32(); + medium = (DmExchangeMedium)parcel.ReadInt32(); + freq = (DmExchangeFreq)parcel.ReadInt32(); + isSameAccount = parcel.ReadBool(); + isWakeRemote = parcel.ReadBool(); + capability = parcel.ReadString(); + return true; +} + +DmSubscribeInfo *DmSubscribeInfo::Unmarshalling(Parcel &parcel) +{ + DmSubscribeInfo *info = new (std::nothrow) DmSubscribeInfo(); + if (info == nullptr) { + return nullptr; + } + + if (!info->ReadFromParcel(parcel)) { + delete info; + info = nullptr; + } + return info; +} + +bool DmSubscribeInfo::Marshalling(Parcel &parcel) const +{ + parcel.WriteInt16(subscribeId); + parcel.WriteInt32((int32_t)mode); + parcel.WriteInt32((int32_t)medium); + parcel.WriteInt32((uint8_t)freq); + parcel.WriteBool(isSameAccount); + parcel.WriteBool(isWakeRemote); + parcel.WriteString(capability); + return true; +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/interfaces/kits/js/@ohos.distributedHardware.deviceManager.d.ts b/interfaces/kits/js/@ohos.distributedHardware.deviceManager.d.ts new file mode 100644 index 000000000..f918e3e45 --- /dev/null +++ b/interfaces/kits/js/@ohos.distributedHardware.deviceManager.d.ts @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2020 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 { AsyncCallback, Callback } from './basic'; + +declare namespace deviceManager { + /** + * DeviceInfo + */ + interface DeviceInfo { + /** + * DeviceId ID. + */ + deviceId: string; + + /** + * Device name of the device. + */ + deviceName: string; + + /** + * Device type of the device. + */ + deviceType: DeviceType; + } + + /** + * Device Type definitions + */ + enum DeviceType { + /** + * Indicates an unknown device type. + */ + UNKNOWN_TYPE = 0, + + /** + * Indicates a speaker. + */ + SPEAKER = 0x0A, + + /** + * Indicates a smartphone. + */ + PHONE = 0x0E, + + /** + * Indicates a tablet. + */ + TABLET = 0x11, + + /** + * Indicates a smart watch. + */ + WEARABLE = 0x6D, + + /** + * Indicates a car. + */ + CAR = 0x83, + + /** + * Indicates a smart TV. + */ + TV = 0x9C + } + + /** + * Device state change event definition + */ + enum DeviceStateChangeAction { + /** + * device online action + */ + ONLINE = 0, + + /** + * device ready action, the device information synchronization was completed. + */ + READY = 1, + + /** + * device offline action + */ + OFFLINE = 2, + + /** + * device change action + */ + CHANGE = 3 + } + + /** + * Service subscribe info for device discover + * + * @systemapi this method can be used only by system applications. + */ + interface SubscribeInfo { + /** + * Service subscribe ID, the value is in scope [0, 65535], should be unique for each discover process + */ + subscribeId: number; + + /** + * Discovery mode for service subscription. + */ + mode: DiscoverMode; + + /** + * Service subscription medium. + */ + medium: ExchangeMedium; + + /** + * Service subscription frequency. + */ + freq: ExchangeFreq; + + /** + * only find the device with the same account. + */ + isSameAccount: boolean; + + /** + * find the sleeping devices. + */ + isWakeRemote: boolean; + + /** + * Subscribe capability. + */ + capability: SubscribeCap; + } + + /** + * device discover mode + * + * @systemapi this method can be used only by system applications. + */ + enum DiscoverMode { + /** + * Passive + */ + DISCOVER_MODE_PASSIVE = 0x55, + + /** + * Proactive + */ + DISCOVER_MODE_ACTIVE = 0xAA + } + + /** + * device discover medium + * + * @systemapi this method can be used only by system applications. + */ + enum ExchangeMedium { + /** + * Automatic medium selection + */ + AUTO = 0, + + /** + * Bluetooth + */ + BLE = 1, + + /** + * Wi-Fi + */ + COAP = 2, + + /** + * USB + */ + USB = 3 + } + + /** + * device discover freq + * + * @systemapi this method can be used only by system applications. + */ + enum ExchangeFreq { + /** + * Low + */ + LOW = 0, + + /** + * Medium + */ + MID = 1, + + /** + * High + */ + HIGH = 2, + + /** + * Super-high + */ + SUPER_HIGH = 3 + } + + /** + * device discover capability + * + * @systemapi this method can be used only by system applications. + */ + enum SubscribeCap { + /** + * ddmpCapability + */ + SUBSCRIBE_CAPABILITY_DDMP = 0 + } + + /** + * Creates a {@code DeviceManager} instance. + * + *

To manage devices, you must first call this method to obtain a {@code DeviceManager} instance and then + * use this instance to call other device management methods. + * + * @param bundleName Indicates the bundle name of the application. + * @param callback Indicates the callback to be invoked upon {@code DeviceManager} instance creation. + */ + function createDeviceManager(bundleName: string, callback: AsyncCallback): void; + + /** + * Provides methods for managing devices. + */ + interface DeviceManager { + /** + * Releases the {@code DeviceManager} instance after the methods for device management are no longer used. + */ + release(): void; + + /** + * Obtains a list of trusted devices. + * + * @param options Indicates the extra parameters to be passed to this method for device filtering or sorting. + * This parameter can be null. For details about available values, see {@link #TARGET_PACKAGE_NAME} and + * {@link #SORT_TYPE}. + * @return Returns a list of trusted devices. + */ + getTrustedDeviceListSync(): Array; + + /** + * Start to discover device. + * + * @param bundleName Indicates the bundle name of the application. + * @param subscribeInfo subscribe info to discovery device + * @systemapi this method can be used only by system applications. + */ + startDeviceDiscovery(subscribeInfo: SubscribeInfo): void; + + /** + * Stop to discover device. + * + * @param bundleName Indicates the bundle name of the application. + * @param subscribeId Service subscribe ID + * @systemapi this method can be used only by system applications. + */ + stopDeviceDiscovery(subscribeId: number): void; + + /** + * authenticate the specified device. + * + * @param bundleName Indicates the bundle name of the application. + * @param deviceInfo deviceInfo of device to authenticate + * @systemapi this method can be used only by system applications. + */ + authenticateDevice(deviceInfo: DeviceInfo): void; + + /** + * Register a device state callback so that the application can be notified upon device state changes based on + * the application bundle name. + * + * @param bundleName Indicates the bundle name of the application. + * @param callback Indicates the device state callback to register. + */ + on(type: 'deviceStateChange', callback: Callback<{ action: DeviceStateChangeAction, device: DeviceInfo }>): void; + + /** + * UnRegister device state callback based on the application bundle name. + * + * @param bundleName Indicates the bundle name of the application. + * @param callback Indicates the device state callback to register. + */ + off(type: 'deviceStateChange', callback?: Callback<{ action: DeviceStateChangeAction, device: DeviceInfo }>): void; + + /** + * Register a device found callback so that the application can be notified when the device was found + * + * @param callback Indicates the device found callback to register. + * @systemapi this method can be used only by system applications. + */ + on(type: 'deviceFound', callback: Callback<{ subscribeId: number, device: DeviceInfo }>): void; + + /** + * UnRegister a device found callback so that the application can be notified when the device was found + * + * @param callback Indicates the device found callback to register. + * @systemapi this method can be used only by system applications. + */ + off(type: 'deviceFound', callback?: Callback<{ subscribeId: number, device: DeviceInfo }>): void; + + /** + * Register a device found result callback so that the application can be notified when the device discover was failed + * + * @param callback Indicates the device found result callback to register. + * @systemapi this method can be used only by system applications. + */ + on(type: 'discoverFail', callback: Callback<{ subscribeId: number, reason: number }>): void; + + /** + * UnRegister a device found result callback so that the application can be notified when the device discover was failed + * + * @param callback Indicates the device found result callback to register. + * @systemapi this method can be used only by system applications. + */ + off(type: 'discoverFail', callback?: Callback<{ subscribeId: number, reason: number }>): void; + + /** + * Register a device auth result callback so that the application can be notified when the device was found + * + * @param callback Indicates the device auth result callback to register. + * @systemapi this method can be used only by system applications. + */ + on(type: 'authResult', callback: Callback<{ deviceId: string, status: number, reason: number }>): void; + + /** + * UnRegister a device auth result callback so that the application can be notified when the device was found + * + * @param callback Indicates the device auth result callback to register. + * @systemapi this method can be used only by system applications. + */ + off(type: 'authResult', callback?: Callback<{ deviceId: string, status: number, reason: number }>): void; + + /** + * Register a serviceError callback so that the application can be notified when devicemanager service died + * + * @param callback Indicates the service error callback to register. + */ + on(type: 'serviceDie', callback: () => void): void; + + /** + * UnRegister a serviceError callback so that the application can be notified when devicemanager service died + * + * @param callback Indicates the service error callback to register. + */ + off(type: 'serviceDie', callback?: () => void): void; + } +} + +export default deviceManager; diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn new file mode 100644 index 000000000..f2ea6932d --- /dev/null +++ b/interfaces/kits/js/BUILD.gn @@ -0,0 +1,82 @@ +# 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/distributedhardware/devicemanager/devicemanager.gni") + +config("dmnativejs_config") { + visibility = [ ":*" ] + include_dirs = [ + "//third_party/node/src", + "//foundation/ace/napi/native_engine", + "//foundation/ace/napi/interfaces/kits", + "//utils/native/base/include", + "include", + "${common_path}/log/include", + "${common_path}/utils/include", + "${innerkits_path}/native_cpp/include", + ] + + cflags = [ + "-Wall", + "-Werror", + "-Wdate-time", + "-Wfloat-equal", + "-Wshadow", + "-Wformat=2", + "-fdata-sections", + "-ffunction-sections", + "-Os", + ] + + cflags_cc = [ + "-Os", + ] +} + +ohos_shared_library("devicemanager") { + sources = [ + "src/native_devicemanager_js.cpp", + "src/dm_native_event.cpp", + ] + + configs = [ ":dmnativejs_config" ] + + deps = [ + "//utils/native/base:utils", + "//foundation/ace/napi:ace_napi", + "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp:devicemanagersdk", + ] + + defines = [ + "DH_LOG_TAG=\"devicemanagerkit_js\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "appexecfwk_standard:appexecfwk_base", + "appexecfwk_standard:appexecfwk_core", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_L2:samgr_proxy", + ] + + subsystem_name = "distributedhardware" + relative_install_dir = "module/distributedhardware" + part_name = "device_manager_base" +} + +group("devicemanager_native_js") { + deps = [ ":devicemanager" ] +} diff --git a/interfaces/kits/js/include/dm_native_event.h b/interfaces/kits/js/include/dm_native_event.h new file mode 100644 index 000000000..dcffbd1d3 --- /dev/null +++ b/interfaces/kits/js/include/dm_native_event.h @@ -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. + */ + +#ifndef OHOS_DEVICE_MANAGER_NATIVE_EVENT_H +#define OHOS_DEVICE_MANAGER_NATIVE_EVENT_H + +#include +#include +#include +#include "napi/native_api.h" + +struct DmEventListener { + std::string eventType; + napi_ref handlerRef = nullptr; +}; + +class DmNativeEvent { +public: + DmNativeEvent(napi_env env, napi_value thisVar); + virtual ~DmNativeEvent(); + + virtual void On(std::string &eventType, napi_value handler); + virtual void Off(std::string &eventType); + virtual void OnEvent(const std::string &eventType, size_t argc, const napi_value* argv); + +protected: + napi_env env_; + napi_ref thisVarRef_; + std::map> eventMap_; +}; + +#endif /* OHOS_DEVICE_MANAGER_NATIVE_EVENT_H */ \ No newline at end of file diff --git a/interfaces/kits/js/include/native_devicemanager_js.h b/interfaces/kits/js/include/native_devicemanager_js.h new file mode 100644 index 000000000..872d7b457 --- /dev/null +++ b/interfaces/kits/js/include/native_devicemanager_js.h @@ -0,0 +1,145 @@ +/* + * 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 OHOS_DEVICE_MANAGER_NATIVE_DEVICEMANAGER_JS_H +#define OHOS_DEVICE_MANAGER_NATIVE_DEVICEMANAGER_JS_H + +#include +#include +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "device_manager_callback.h" +#include "dm_native_event.h" +#include "dm_device_info.h" +#include "dm_subscribe_info.h" + +const int DM_NAPI_BUF_LENGTH = 256; + +struct AsyncCallbackInfo { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + + char bundleName[DM_NAPI_BUF_LENGTH] = {0}; + size_t bundleNameLen = 0; + + napi_ref callback = nullptr; + int32_t status = -1; +}; + +enum DmNapiDevStateChangeAction { + ONLINE = 0, + READY = 1, + OFFLINE = 2, + CHANGE = 3 +}; + +class DmNapiInitCallback : public OHOS::DistributedHardware::DmInitCallback { +public: + explicit DmNapiInitCallback(std::string &bundleName) : bundleName_(bundleName) {} + virtual ~DmNapiInitCallback() {} + void OnRemoteDied() override; + +private: + std::string bundleName_; +}; + +class DmNapiDeviceStateCallback : public OHOS::DistributedHardware::DeviceStateCallback { +public: + explicit DmNapiDeviceStateCallback(std::string &bundleName) : bundleName_(bundleName) {} + virtual ~DmNapiDeviceStateCallback() {}; + void OnDeviceOnline(const OHOS::DistributedHardware::DmDeviceInfo &deviceInfo) override; + void OnDeviceReady(const OHOS::DistributedHardware::DmDeviceInfo &deviceInfo) override; + void OnDeviceOffline(const OHOS::DistributedHardware::DmDeviceInfo &deviceInfo) override; + void OnDeviceChanged(const OHOS::DistributedHardware::DmDeviceInfo &deviceInfo) override; + +private: + std::string bundleName_; +}; + +class DmNapiDiscoverCallback : public OHOS::DistributedHardware::DiscoverCallback { +public: + explicit DmNapiDiscoverCallback(std::string &bundleName) : refCount_(0), bundleName_(bundleName) {} + virtual ~DmNapiDiscoverCallback() {}; + void OnDeviceFound(uint16_t subscribeId, OHOS::DistributedHardware::DmDeviceInfo &deviceInfo) override; + void OnDiscoverFailed(uint16_t subscribeId, int32_t failedReason) override; + void OnDiscoverySuccess(uint16_t subscribeId) override; + void IncreaseRefCount(); + void DecreaseRefCount(); + int32_t GetRefCount(); + +private: + std::atomic refCount_; + std::string bundleName_; +}; + +class DmNapiAuthenticateCallback : public OHOS::DistributedHardware::AuthenticateCallback { +public: + explicit DmNapiAuthenticateCallback(std::string &bundleName) : bundleName_(bundleName) {} + virtual ~DmNapiAuthenticateCallback() {}; + void OnAuthResult(std::string &deviceId, int32_t status, int32_t reason) override; + +private: + std::string bundleName_; +}; + +class DeviceManagerNapi : public DmNativeEvent { +public: + explicit DeviceManagerNapi(napi_env env, napi_value thisVar); + virtual ~DeviceManagerNapi(); + static napi_value Init(napi_env env, napi_value exports); + static napi_value Constructor(napi_env env, napi_callback_info info); + static napi_value CreateDeviceManager(napi_env env, napi_callback_info info); + static napi_value ReleaseDeviceManager(napi_env env, napi_callback_info info); + static napi_value GetTrustedDeviceListSync(napi_env env, napi_callback_info info); + static napi_value StartDeviceDiscoverSync(napi_env env, napi_callback_info info); + static napi_value StopDeviceDiscoverSync(napi_env env, napi_callback_info info); + static napi_value AuthenticateDeviceSync(napi_env env, napi_callback_info info); + static napi_value JsOn(napi_env env, napi_callback_info info); + static napi_value JsOff(napi_env env, napi_callback_info info); + static void HandleCreateDmCallBack(const napi_env &env, AsyncCallbackInfo *asCallbackInfo); + static DeviceManagerNapi *GetDeviceManagerNapi(std::string &buldleName); + static void CreateDmCallback(std::string &bundleName, std::string &eventType); + static void ReleaseDmCallback(std::string &bundleName, std::string &eventType); + static void DeviceInfoToJsArray(const napi_env& env, + const std::vector& vecDevInfo, + const int idx, napi_value& arrayResult); + static void SetValueInt32(const napi_env& env, const std::string& fieldStr, const int intValue, + napi_value& result); + static void SetValueUtf8String(const napi_env& env, const std::string& fieldStr, const std::string& str, + napi_value& result); + static void JsObjectToString(const napi_env& env, const napi_value& object, + const std::string& fieldStr, const int bufLen, std::string& fieldRef); + static void JsObjectToBool(const napi_env& env, const napi_value& object, + const std::string& fieldStr, bool& fieldRef); + static void JsObjectToInt(const napi_env& env, const napi_value& object, const std::string& fieldStr, + int& fieldRef); + static int32_t JsToDmSubscribeInfo(const napi_env& env, const napi_value& object, + OHOS::DistributedHardware::DmSubscribeInfo& info); + static void JsToDmDeviceInfo(const napi_env& env, const napi_value& object, + OHOS::DistributedHardware::DmDeviceInfo& info); + void OnDeviceStateChange(DmNapiDevStateChangeAction action, + const OHOS::DistributedHardware::DmDeviceInfo &deviceInfo); + void OnDeviceFound(uint16_t subscribeId, const OHOS::DistributedHardware::DmDeviceInfo &deviceInfo); + void OnDiscoverFailed(uint16_t subscribeId, int32_t failedReason); + void OnAuthResult(const std::string& deviceId, int32_t status, int32_t reason); + +private: + napi_env env_; + napi_ref wrapper_; + static napi_ref sConstructor_; + std::string bundleName_; +}; + +#endif // OHOS_DEVICE_MANAGER_NATIVE_DEVICEMANAGER_JS_H diff --git a/interfaces/kits/js/src/dm_native_event.cpp b/interfaces/kits/js/src/dm_native_event.cpp new file mode 100644 index 000000000..d3aca3d17 --- /dev/null +++ b/interfaces/kits/js/src/dm_native_event.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 "dm_native_event.h" + +#include "device_manager_log.h" + +using namespace OHOS::DistributedHardware; + +DmNativeEvent::DmNativeEvent(napi_env env, napi_value thisVar) +{ + env_ = env; + thisVarRef_ = nullptr; + napi_create_reference(env, thisVar, 1, &thisVarRef_); +} + +DmNativeEvent::~DmNativeEvent() +{ + for (auto iter = eventMap_.begin(); iter != eventMap_.end(); iter++) { + auto listener = iter->second; + napi_delete_reference(env_, listener->handlerRef); + } + eventMap_.clear(); + napi_delete_reference(env_, thisVarRef_); +} + +void DmNativeEvent::On(std::string &eventType, napi_value handler) +{ + HILOGI("DmNativeEvent On in for event: %{public}s", eventType.c_str()); + auto listener = std::make_shared(); + listener->eventType = eventType; + napi_create_reference(env_, handler, 1, &listener->handlerRef); + eventMap_[eventType] = listener; +} + +void DmNativeEvent::Off(std::string &eventType) +{ + HILOGI("DmNativeEvent Off in for event: %{public}s", eventType.c_str()); + napi_handle_scope scope = nullptr; + napi_open_handle_scope(env_, &scope); + if (scope == nullptr) { + HILOGE("scope is nullptr"); + return; + } + + auto iter = eventMap_.find(eventType); + if (iter == eventMap_.end()) { + HILOGE("eventType %{public}s not find", eventType.c_str()); + return; + } + auto listener = iter->second; + napi_delete_reference(env_, listener->handlerRef); + eventMap_.erase(eventType); + napi_close_handle_scope(env_, scope); +} + +void DmNativeEvent::OnEvent(const std::string &eventType, size_t argc, const napi_value* argv) +{ + HILOGI("OnEvent for %{public}s", eventType.c_str()); + napi_handle_scope scope = nullptr; + napi_open_handle_scope(env_, &scope); + if (scope == nullptr) { + HILOGE("scope is nullptr"); + return; + } + + auto iter = eventMap_.find(eventType); + if (iter == eventMap_.end()) { + HILOGE("eventType %{public}s not find", eventType.c_str()); + return; + } + auto listener = iter->second; + napi_value thisVar = nullptr; + napi_status status = napi_get_reference_value(env_, thisVarRef_, &thisVar); + if (status != napi_ok) { + HILOGE("napi_get_reference_value thisVar for %{public}s failed, status=%{public}d", eventType.c_str(), status); + return; + } + + napi_value handler = nullptr; + status = napi_get_reference_value(env_, listener->handlerRef, &handler); + if (status != napi_ok) { + HILOGE("napi_get_reference_value handler for %{public}s failed, status=%{public}d", eventType.c_str(), status); + return; + } + + napi_value callResult = nullptr; + status = napi_call_function(env_, thisVar, handler, argc, argv, &callResult); + if (status != napi_ok) { + HILOGE("napi_call_function for %{public}s failed, status=%{public}d", eventType.c_str(), status); + return; + } + napi_close_handle_scope(env_, scope); +} \ No newline at end of file diff --git a/interfaces/kits/js/src/native_devicemanager_js.cpp b/interfaces/kits/js/src/native_devicemanager_js.cpp new file mode 100644 index 000000000..d7a85771a --- /dev/null +++ b/interfaces/kits/js/src/native_devicemanager_js.cpp @@ -0,0 +1,886 @@ +/* + * 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 "native_devicemanager_js.h" + +#include + +#include "device_manager.h" +#include "device_manager_log.h" + +using namespace OHOS::DistributedHardware; + +namespace { +#define GET_PARAMS(env, info, num) \ + size_t argc = num; \ + napi_value argv[num] = { nullptr }; \ + napi_value thisVar = nullptr; \ + void *data = nullptr; \ + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data)) + +const std::string DM_NAPI_EVENT_DEVICE_STATE_CHANGE = "deviceStateChange"; +const std::string DM_NAPI_EVENT_DEVICE_FOUND = "deviceFound"; +const std::string DM_NAPI_EVENT_DEVICE_DISCOVER_FAIL = "discoverFail"; +const std::string DM_NAPI_EVENT_DEVICE_AUTH_RESULT = "authResult"; +const std::string DM_NAPI_EVENT_DEVICE_SERVICE_DIE = "serviceDie"; + +const std::string DEVICE_MANAGER_NAPI_CLASS_NAME = "DeviceManager"; + +const int DM_NAPI_ARGS_ONE = 1; +const int DM_NAPI_ARGS_TWO = 2; +const int DM_NAPI_SUB_ID_MAX = 65535; + +std::map g_deviceManagerMap; +std::map> g_initCallbackMap; +std::map> g_deviceStateCallbackMap; +std::map> g_discoverCallbackMap; +std::map> g_authCallbackMap; +} + +enum DmNapiSubscribeCap { + DM_NAPI_SUBSCRIBE_CAPABILITY_DDMP = 0 +}; + +napi_ref DeviceManagerNapi::sConstructor_ = nullptr; + +void DmNapiInitCallback::OnRemoteDied() +{ + DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(bundleName_); + if (deviceManagerNapi == nullptr) { + HILOGE("OnRemoteDied, deviceManagerNapi not find for bunderName %{public}s", bundleName_.c_str()); + return; + } + deviceManagerNapi->OnEvent("serviceDie", 0, nullptr); +} + +void DmNapiDeviceStateCallback::OnDeviceOnline(const OHOS::DistributedHardware::DmDeviceInfo &deviceInfo) +{ + DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(bundleName_); + if (deviceManagerNapi == nullptr) { + HILOGE("OnDeviceOnline, deviceManagerNapi not find for bunderName %{public}s", bundleName_.c_str()); + return; + } + deviceManagerNapi->OnDeviceStateChange(DmNapiDevStateChangeAction::ONLINE, deviceInfo); +} + +void DmNapiDeviceStateCallback::OnDeviceReady(const OHOS::DistributedHardware::DmDeviceInfo &deviceInfo) +{ + DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(bundleName_); + if (deviceManagerNapi == nullptr) { + HILOGE("OnDeviceOnline, deviceManagerNapi not find for bunderName %{public}s", bundleName_.c_str()); + return; + } + deviceManagerNapi->OnDeviceStateChange(DmNapiDevStateChangeAction::READY, deviceInfo); +} + +void DmNapiDeviceStateCallback::OnDeviceOffline(const OHOS::DistributedHardware::DmDeviceInfo &deviceInfo) +{ + DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(bundleName_); + if (deviceManagerNapi == nullptr) { + HILOGE("OnDeviceOffline, deviceManagerNapi not find for bunderName %{public}s", bundleName_.c_str()); + return; + } + deviceManagerNapi->OnDeviceStateChange(DmNapiDevStateChangeAction::OFFLINE, deviceInfo); +} + +void DmNapiDeviceStateCallback::OnDeviceChanged(const OHOS::DistributedHardware::DmDeviceInfo &deviceInfo) +{ + DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(bundleName_); + if (deviceManagerNapi == nullptr) { + HILOGE("OnDeviceChanged, deviceManagerNapi not find for bunderName %{public}s", bundleName_.c_str()); + return; + } + deviceManagerNapi->OnDeviceStateChange(DmNapiDevStateChangeAction::CHANGE, deviceInfo); +} + +void DmNapiDiscoverCallback::OnDeviceFound(uint16_t subscribeId, + OHOS::DistributedHardware::DmDeviceInfo &deviceInfo) +{ + DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(bundleName_); + if (deviceManagerNapi == nullptr) { + HILOGE("OnDeviceFound, deviceManagerNapi not find for bunderName %{public}s", bundleName_.c_str()); + return; + } + + HILOGI("OnDeviceFound for %{public}s, subscribeId %{public}d", bundleName_.c_str(), (int32_t)subscribeId); + deviceManagerNapi->OnDeviceFound(subscribeId, deviceInfo); +} + +void DmNapiDiscoverCallback::OnDiscoverFailed(uint16_t subscribeId, int32_t failedReason) +{ + DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(bundleName_); + if (deviceManagerNapi == nullptr) { + HILOGE("OnDiscoverFailed, deviceManagerNapi not find for bunderName %{public}s", bundleName_.c_str()); + return; + } + + deviceManagerNapi->OnDiscoverFailed(subscribeId, failedReason); +} + +void DmNapiDiscoverCallback::OnDiscoverySuccess(uint16_t subscribeId) +{ + DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(bundleName_); + if (deviceManagerNapi == nullptr) { + HILOGE("OnDiscoverySuccess, deviceManagerNapi not find for bunderName %{public}s", bundleName_.c_str()); + return; + } + HILOGE("DiscoverySuccess for %{public}s, subscribeId %{public}d", bundleName_.c_str(), (int32_t)subscribeId); +} + +void DmNapiDiscoverCallback::IncreaseRefCount() +{ + refCount_++; +} + +void DmNapiDiscoverCallback::DecreaseRefCount() +{ + refCount_--; +} + +int32_t DmNapiDiscoverCallback::GetRefCount() +{ + return refCount_; +} + +void DmNapiAuthenticateCallback::OnAuthResult(std::string &deviceId, int32_t status, int32_t reason) +{ + DeviceManagerNapi *deviceManagerNapi = DeviceManagerNapi::GetDeviceManagerNapi(bundleName_); + if (deviceManagerNapi == nullptr) { + HILOGE("OnAuthResult, deviceManagerNapi not find for bunderName %{public}s", bundleName_.c_str()); + return; + } + deviceManagerNapi->OnAuthResult(deviceId, status, reason); +} + +DeviceManagerNapi::DeviceManagerNapi(napi_env env, napi_value thisVar) : DmNativeEvent(env, thisVar) +{ + env_ = env; + wrapper_ = nullptr; +} + +DeviceManagerNapi::~DeviceManagerNapi() +{ + if (wrapper_ != nullptr) { + napi_delete_reference(env_, wrapper_); + } +} + +DeviceManagerNapi *DeviceManagerNapi::GetDeviceManagerNapi(std::string &buldleName) +{ + auto iter = g_deviceManagerMap.find(buldleName); + if (iter == g_deviceManagerMap.end()) { + return nullptr; + } + return iter->second; +} + +void DeviceManagerNapi::OnDeviceStateChange(DmNapiDevStateChangeAction action, + const OHOS::DistributedHardware::DmDeviceInfo &deviceInfo) +{ + napi_value result; + napi_create_object(env_, &result); + SetValueInt32(env_, "action", (int)action, result); + + napi_value device; + napi_create_object(env_, &device); + SetValueUtf8String(env_, "deviceId", deviceInfo.deviceId, device); + SetValueUtf8String(env_, "deviceName", deviceInfo.deviceName, device); + SetValueInt32(env_, "deviceType", (int)deviceInfo.deviceTypeId, device); + + napi_set_named_property(env_, result, "device", device); + OnEvent("deviceStateChange", DM_NAPI_ARGS_ONE, &result); +} + +void DeviceManagerNapi::OnDeviceFound(uint16_t subscribeId, const OHOS::DistributedHardware::DmDeviceInfo &deviceInfo) +{ + HILOGI("OnDeviceFound for subscribeId %{public}d", (int32_t)subscribeId); + napi_value result; + napi_create_object(env_, &result); + SetValueInt32(env_, "subscribeId", (int)subscribeId, result); + + napi_value device; + napi_create_object(env_, &device); + SetValueUtf8String(env_, "deviceId", deviceInfo.deviceId, device); + SetValueUtf8String(env_, "deviceName", deviceInfo.deviceName, device); + SetValueInt32(env_, "deviceType", (int)deviceInfo.deviceTypeId, device); + + napi_set_named_property(env_, result, "device", device); + OnEvent("deviceFound", DM_NAPI_ARGS_ONE, &result); +} + +void DeviceManagerNapi::OnDiscoverFailed(uint16_t subscribeId, int32_t failedReason) +{ + HILOGI("OnDiscoverFailed for subscribeId %{public}d", (int32_t)subscribeId); + napi_value result; + napi_create_object(env_, &result); + SetValueInt32(env_, "subscribeId", (int)subscribeId, result); + SetValueInt32(env_, "reason", (int)failedReason, result); + OnEvent("discoverFail", DM_NAPI_ARGS_ONE, &result); +} + +void DeviceManagerNapi::OnAuthResult(const std::string& deviceId, int32_t status, int32_t reason) +{ + HILOGI("OnAuthResult for status: %{public}d, reason: %{public}d", status, reason); + napi_value result; + napi_create_object(env_, &result); + + SetValueUtf8String(env_, "deviceId", deviceId, result); + SetValueInt32(env_, "status", (int)status, result); + SetValueInt32(env_, "reason", (int)reason, result); + OnEvent("authResult", DM_NAPI_ARGS_ONE, &result); +} + +void DeviceManagerNapi::SetValueUtf8String(const napi_env &env, const std::string& fieldStr, const std::string& str, + napi_value& result) +{ + napi_value value; + napi_create_string_utf8(env, str.c_str(), NAPI_AUTO_LENGTH, &value); + napi_set_named_property(env, result, fieldStr.c_str(), value); +} + +void DeviceManagerNapi::SetValueInt32(const napi_env& env, const std::string& fieldStr, const int intValue, + napi_value& result) +{ + napi_value value; + napi_create_int32(env, intValue, &value); + napi_set_named_property(env, result, fieldStr.c_str(), value); +} + +void DeviceManagerNapi::DeviceInfoToJsArray(const napi_env& env, + const std::vector& vecDevInfo, + const int idx, napi_value& arrayResult) +{ + napi_value result; + napi_create_object(env, &result); + + SetValueUtf8String(env, "deviceId", vecDevInfo[idx].deviceId.c_str(), result); + SetValueUtf8String(env, "deviceName", vecDevInfo[idx].deviceName.c_str(), result); + SetValueInt32(env, "deviceType", (int)vecDevInfo[idx].deviceTypeId, result); + + napi_status status = napi_set_element(env, arrayResult, idx, result); + if (status != napi_ok) { + HILOGE("DmDeviceInfo To JsArray set element error: %{public}d", status); + } +} + +void DeviceManagerNapi::JsObjectToString(const napi_env& env, const napi_value& object, + const std::string& fieldStr, const int bufLen, std::string& fieldRef) +{ + bool hasProperty = false; + NAPI_CALL_RETURN_VOID(env, napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty)); + if (hasProperty) { + napi_value field; + napi_valuetype valueType; + + napi_get_named_property(env, object, fieldStr.c_str(), &field); + NAPI_CALL_RETURN_VOID(env, napi_typeof(env, field, &valueType)); + NAPI_ASSERT_RETURN_VOID(env, valueType == napi_string, "Wrong argument type. String expected."); + if (bufLen <= 0) { + HILOGE("js object to str bufLen invalid"); + return; + } + std::unique_ptr buf = std::make_unique(bufLen); + if (buf == nullptr) { + HILOGE("js object to str malloc failed"); + return; + } + (void)memset_s(buf.get(), bufLen, 0, bufLen); + size_t result = 0; + NAPI_CALL_RETURN_VOID(env, napi_get_value_string_utf8(env, field, buf.get(), bufLen, &result)); + fieldRef = buf.get(); + } else { + HILOGE("devicemanager napi js to str no property: %{public}s", fieldStr.c_str()); + } +} + +void DeviceManagerNapi::JsObjectToInt(const napi_env& env, const napi_value& object, + const std::string& fieldStr, int& fieldRef) +{ + bool hasProperty = false; + NAPI_CALL_RETURN_VOID(env, napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty)); + if (hasProperty) { + napi_value field; + napi_valuetype valueType; + + napi_get_named_property(env, object, fieldStr.c_str(), &field); + NAPI_CALL_RETURN_VOID(env, napi_typeof(env, field, &valueType)); + NAPI_ASSERT_RETURN_VOID(env, valueType == napi_number, "Wrong argument type. Number expected."); + napi_get_value_int32(env, field, &fieldRef); + } else { + HILOGE("devicemanager napi js to int no property: %{public}s", fieldStr.c_str()); + } +} + +void DeviceManagerNapi::JsObjectToBool(const napi_env& env, const napi_value& object, + const std::string& fieldStr, bool& fieldRef) +{ + bool hasProperty = false; + NAPI_CALL_RETURN_VOID(env, napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty)); + if (hasProperty) { + napi_value field; + napi_valuetype valueType; + + napi_get_named_property(env, object, fieldStr.c_str(), &field); + NAPI_CALL_RETURN_VOID(env, napi_typeof(env, field, &valueType)); + NAPI_ASSERT_RETURN_VOID(env, valueType == napi_boolean, "Wrong argument type. Bool expected."); + napi_get_value_bool(env, field, &fieldRef); + } else { + HILOGE("devicemanager napi js to bool no property: %{public}s", fieldStr.c_str()); + } +} + +int32_t DeviceManagerNapi::JsToDmSubscribeInfo(const napi_env& env, const napi_value& object, + OHOS::DistributedHardware::DmSubscribeInfo& info) +{ + int subscribeId = -1; + JsObjectToInt(env, object, "subscribeId", subscribeId); + if (subscribeId < 0 || subscribeId > DM_NAPI_SUB_ID_MAX) { + HILOGE("DeviceManagerNapi::JsToDmSubscribeInfo, subscribeId error, subscribeId: %{public}d ", subscribeId); + return -1; + } + + info.subscribeId = (uint16_t)subscribeId; + + int mode = -1; + JsObjectToInt(env, object, "mode", mode); + info.mode = (DmDiscoverMode)mode; + + int medium = -1; + JsObjectToInt(env, object, "medium", medium); + info.medium = (DmExchangeMedium)medium; + + int freq = -1; + JsObjectToInt(env, object, "freq", freq); + info.freq = (DmExchangeFreq)freq; + + JsObjectToBool(env, object, "isSameAccount", info.isSameAccount); + JsObjectToBool(env, object, "isWakeRemote", info.isWakeRemote); + + int capability = -1; + JsObjectToInt(env, object, "capability", capability); + if (capability == DmNapiSubscribeCap::DM_NAPI_SUBSCRIBE_CAPABILITY_DDMP) { + info.capability = std::string(DM_CAPABILITY_DDMP); + } + return 0; +} + +void DeviceManagerNapi::JsToDmDeviceInfo(const napi_env& env, const napi_value& object, + OHOS::DistributedHardware::DmDeviceInfo& info) +{ + JsObjectToString(env, object, "deviceId", DM_NAPI_BUF_LENGTH, info.deviceId); + JsObjectToString(env, object, "deviceName", DM_NAPI_BUF_LENGTH, info.deviceName); + int deviceType = -1; + JsObjectToInt(env, object, "deviceType", deviceType); + info.deviceTypeId = (DMDeviceType)deviceType; +} + + +void DeviceManagerNapi::CreateDmCallback(std::string &bundleName, std::string &eventType) +{ + HILOGE("CreateDmCallback for bunderName %{public}s eventType %{public}s", bundleName.c_str(), eventType.c_str()); + if (eventType == DM_NAPI_EVENT_DEVICE_STATE_CHANGE) { + auto iter = g_deviceStateCallbackMap.find(bundleName); + if (iter == g_deviceStateCallbackMap.end()) { + auto callback = std::make_shared(bundleName); + std::string extra = ""; + int32_t ret = DeviceManager::GetInstance().RegisterDevStateCallback(bundleName, extra, callback); + if (ret != 0) { + HILOGE("RegisterDevStateCallback failed for bunderName %{public}s", bundleName.c_str()); + return; + } + g_deviceStateCallbackMap[bundleName] = callback; + } + return; + } + + if (eventType == DM_NAPI_EVENT_DEVICE_FOUND || eventType == DM_NAPI_EVENT_DEVICE_DISCOVER_FAIL) { + std::shared_ptr discoverCallback = nullptr; + auto iter = g_discoverCallbackMap.find(bundleName); + if (iter == g_discoverCallbackMap.end()) { + auto callback = std::make_shared(bundleName); + g_discoverCallbackMap[bundleName] = callback; + discoverCallback = callback; + } else { + discoverCallback = iter->second; + } + + discoverCallback->IncreaseRefCount(); + return; + } + + if (eventType == DM_NAPI_EVENT_DEVICE_AUTH_RESULT) { + auto iter = g_authCallbackMap.find(bundleName); + if (iter == g_authCallbackMap.end()) { + auto callback = std::make_shared(bundleName); + g_authCallbackMap[bundleName] = callback; + } + return; + } +} + +void DeviceManagerNapi::ReleaseDmCallback(std::string &bundleName, std::string &eventType) +{ + if (eventType == DM_NAPI_EVENT_DEVICE_STATE_CHANGE) { + auto iter = g_deviceStateCallbackMap.find(bundleName); + if (iter == g_deviceStateCallbackMap.end()) { + HILOGE("ReleaseDmCallback: cannot find stateCallback for bunderName %{public}s", bundleName.c_str()); + return; + } + int32_t ret = DeviceManager::GetInstance().UnRegisterDevStateCallback(bundleName); + if (ret != 0) { + HILOGE("RegisterDevStateCallback failed for bunderName %{public}s", bundleName.c_str()); + return; + } + g_deviceStateCallbackMap.erase(bundleName); + return; + } + + if (eventType == DM_NAPI_EVENT_DEVICE_FOUND || eventType == DM_NAPI_EVENT_DEVICE_DISCOVER_FAIL) { + std::shared_ptr discoverCallback = nullptr; + auto iter = g_discoverCallbackMap.find(bundleName); + if (iter == g_discoverCallbackMap.end()) { + return; + } + + discoverCallback = iter->second; + discoverCallback->DecreaseRefCount(); + if (discoverCallback->GetRefCount() == 0) { + g_discoverCallbackMap.erase(bundleName); + } + return; + } + + if (eventType == DM_NAPI_EVENT_DEVICE_AUTH_RESULT) { + auto iter = g_authCallbackMap.find(bundleName); + if (iter == g_authCallbackMap.end()) { + return; + } + + g_authCallbackMap.erase(bundleName); + } +} + +napi_value DeviceManagerNapi::GetTrustedDeviceListSync(napi_env env, napi_callback_info info) +{ + HILOGI("GetTrustedDeviceList in"); + size_t argc = 0; + napi_value thisVar = nullptr; + napi_value array = nullptr; + + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr)); + NAPI_ASSERT(env, argc == 0, "Wrong number of arguments"); + + DeviceManagerNapi *deviceManagerWrapper = nullptr; + napi_unwrap(env, thisVar, reinterpret_cast(&deviceManagerWrapper)); + std::string extra = ""; + std::vector devList; + int32_t ret = DeviceManager::GetInstance().GetTrustedDeviceList(deviceManagerWrapper->bundleName_, extra, devList); + if (ret != 0) { + HILOGE("GetTrustedDeviceList for bunderName %{public}s failed, ret %{public}d", + deviceManagerWrapper->bundleName_.c_str(), ret); + return array; + } + + if (devList.size() > 0) { + bool isArray = false; + napi_create_array(env, &array); + napi_is_array(env, array, &isArray); + if (isArray == false) { + HILOGE("napi_create_array fail"); + } + + for (size_t i = 0; i != devList.size(); ++i) { + DeviceInfoToJsArray(env, devList, i, array); + } + } else { + HILOGE("devList is null"); + } + + return array; +} + +napi_value DeviceManagerNapi::StartDeviceDiscoverSync(napi_env env, napi_callback_info info) +{ + HILOGI("StartDeviceDiscoverSync in"); + GET_PARAMS(env, info, DM_NAPI_ARGS_ONE); + napi_value result = nullptr; + napi_valuetype valueType; + napi_typeof(env, argv[0], &valueType); + NAPI_ASSERT(env, valueType == napi_object, "Wrong argument type. Object expected."); + + DeviceManagerNapi *deviceManagerWrapper = nullptr; + napi_unwrap(env, thisVar, reinterpret_cast(&deviceManagerWrapper)); + + std::shared_ptr discoverCallback = nullptr; + auto iter = g_discoverCallbackMap.find(deviceManagerWrapper->bundleName_); + if (iter == g_discoverCallbackMap.end()) { + discoverCallback = std::make_shared(deviceManagerWrapper->bundleName_); + g_discoverCallbackMap[deviceManagerWrapper->bundleName_] = discoverCallback; + } else { + discoverCallback = iter->second; + } + DmSubscribeInfo subInfo; + int32_t res = JsToDmSubscribeInfo(env, argv[0], subInfo); + NAPI_ASSERT(env, res == 0, "Wrong subscribeId "); + + int32_t ret = DeviceManager::GetInstance().StartDeviceDiscovery(deviceManagerWrapper->bundleName_, + subInfo, discoverCallback); + if (ret != 0) { + HILOGE("StartDeviceDiscovery for bunderName %{public}s failed, ret %{public}d", + deviceManagerWrapper->bundleName_.c_str(), ret); + return result; + } + + napi_get_undefined(env, &result); + return result; +} + +napi_value DeviceManagerNapi::StopDeviceDiscoverSync(napi_env env, napi_callback_info info) +{ + HILOGI("StopDeviceDiscoverSync in"); + GET_PARAMS(env, info, DM_NAPI_ARGS_ONE); + napi_value result = nullptr; + napi_valuetype valueType; + napi_typeof(env, argv[0], &valueType); + NAPI_ASSERT(env, valueType == napi_number, "Wrong argument type. Object expected."); + + int32_t subscribeId = 0; + napi_get_value_int32(env, argv[0], &subscribeId); + NAPI_ASSERT(env, subscribeId <= DM_NAPI_SUB_ID_MAX, "Wrong argument. subscribeId Too Big."); + + DeviceManagerNapi *deviceManagerWrapper = nullptr; + napi_unwrap(env, thisVar, reinterpret_cast(&deviceManagerWrapper)); + int32_t ret = DeviceManager::GetInstance().StopDeviceDiscovery(deviceManagerWrapper->bundleName_, + (int16_t)subscribeId); + if (ret != 0) { + HILOGE("StopDeviceDiscovery for bunderName %{public}s failed, ret %{public}d", + deviceManagerWrapper->bundleName_.c_str(), ret); + return result; + } + + napi_get_undefined(env, &result); + return result; +} + +napi_value DeviceManagerNapi::AuthenticateDeviceSync(napi_env env, napi_callback_info info) +{ + HILOGI("AuthenticateDeviceSync in"); + GET_PARAMS(env, info, DM_NAPI_ARGS_ONE); + napi_value result = nullptr; + napi_valuetype valueType; + napi_typeof(env, argv[0], &valueType); + NAPI_ASSERT(env, valueType == napi_object, "Wrong argument type. Object expected."); + + DeviceManagerNapi *deviceManagerWrapper = nullptr; + napi_unwrap(env, thisVar, reinterpret_cast(&deviceManagerWrapper)); + + std::shared_ptr authCallback = nullptr; + auto iter = g_authCallbackMap.find(deviceManagerWrapper->bundleName_); + if (iter == g_authCallbackMap.end()) { + authCallback = std::make_shared(deviceManagerWrapper->bundleName_); + g_authCallbackMap[deviceManagerWrapper->bundleName_] = authCallback; + } else { + authCallback = iter->second; + } + DmDeviceInfo deviceInfo; + JsToDmDeviceInfo(env, argv[0], deviceInfo); + + std::string extra = ""; + int32_t ret = DeviceManager::GetInstance().AuthenticateDevice(deviceManagerWrapper->bundleName_, deviceInfo, + extra, authCallback); + if (ret != 0) { + HILOGE("AuthenticateDevice for bunderName %{public}s failed, ret %{public}d", + deviceManagerWrapper->bundleName_.c_str(), ret); + return result; + } + + napi_get_undefined(env, &result); + return result; +} + +napi_value DeviceManagerNapi::JsOn(napi_env env, napi_callback_info info) +{ + HILOGI("JsOn in"); + GET_PARAMS(env, info, DM_NAPI_ARGS_TWO); + NAPI_ASSERT(env, argc >= DM_NAPI_ARGS_TWO, "Wrong number of arguments, required 2"); + + napi_valuetype eventValueType = napi_undefined; + napi_typeof(env, argv[0], &eventValueType); + NAPI_ASSERT(env, eventValueType == napi_string, "type mismatch for parameter 1"); + + napi_valuetype eventHandleType = napi_undefined; + napi_typeof(env, argv[1], &eventHandleType); + NAPI_ASSERT(env, eventHandleType == napi_function, "type mismatch for parameter 2"); + + size_t typeLen = 0; + napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typeLen); + + NAPI_ASSERT(env, typeLen > 0, "typeLen == 0"); + std::unique_ptr type = std::make_unique(typeLen + 1); + napi_get_value_string_utf8(env, argv[0], type.get(), typeLen + 1, &typeLen); + + std::string eventType = type.get(); + DeviceManagerNapi *deviceManagerWrapper = nullptr; + napi_unwrap(env, thisVar, reinterpret_cast(&deviceManagerWrapper)); + + HILOGI("JsOn for bunderName %{public}s, eventType %{public}s ", deviceManagerWrapper->bundleName_.c_str(), + eventType.c_str()); + deviceManagerWrapper->On(eventType, argv[1]); + CreateDmCallback(deviceManagerWrapper->bundleName_, eventType); + + napi_value result = nullptr; + napi_get_undefined(env, &result); + return result; +} + +napi_value DeviceManagerNapi::JsOff(napi_env env, napi_callback_info info) +{ + HILOGI("JsOff in"); + GET_PARAMS(env, info, DM_NAPI_ARGS_TWO); + size_t requireArgc = 1; + NAPI_ASSERT(env, argc >= requireArgc, "Wrong number of arguments, required 1"); + + napi_valuetype eventValueType = napi_undefined; + napi_typeof(env, argv[0], &eventValueType); + NAPI_ASSERT(env, eventValueType == napi_string, "type mismatch for parameter 1"); + + if (argc > requireArgc) { + napi_valuetype eventHandleType = napi_undefined; + napi_typeof(env, argv[1], &eventHandleType); + NAPI_ASSERT(env, eventValueType == napi_function, "type mismatch for parameter 2"); + } + + size_t typeLen = 0; + napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typeLen); + + NAPI_ASSERT(env, typeLen > 0, "typeLen == 0"); + std::unique_ptr type = std::make_unique(typeLen + 1); + napi_get_value_string_utf8(env, argv[0], type.get(), typeLen + 1, &typeLen); + + std::string eventType = type.get(); + DeviceManagerNapi *deviceManagerWrapper = nullptr; + napi_unwrap(env, thisVar, reinterpret_cast(&deviceManagerWrapper)); + + HILOGI("JsOff for bunderName %{public}s, eventType %{public}s ", deviceManagerWrapper->bundleName_.c_str(), + eventType.c_str()); + deviceManagerWrapper->Off(eventType); + ReleaseDmCallback(deviceManagerWrapper->bundleName_, eventType); + + napi_value result = nullptr; + napi_get_undefined(env, &result); + return result; +} + +napi_value DeviceManagerNapi::ReleaseDeviceManager(napi_env env, napi_callback_info info) +{ + HILOGI("ReleaseDeviceManager in"); + size_t argc = 0; + napi_value thisVar = nullptr; + napi_value result = nullptr; + + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr)); + NAPI_ASSERT(env, argc == 0, "Wrong number of arguments"); + + DeviceManagerNapi *deviceManagerWrapper = nullptr; + napi_unwrap(env, thisVar, reinterpret_cast(&deviceManagerWrapper)); + HILOGI("ReleaseDeviceManager for bunderName %{public}s", deviceManagerWrapper->bundleName_.c_str()); + int32_t ret = DeviceManager::GetInstance().UnInitDeviceManager(deviceManagerWrapper->bundleName_); + if (ret != 0) { + HILOGE("ReleaseDeviceManager for bunderName %{public}s failed, ret %{public}d", + deviceManagerWrapper->bundleName_.c_str(), ret); + napi_create_uint32(env, ret, &result); + return result; + } + + g_deviceManagerMap.erase(deviceManagerWrapper->bundleName_); + g_initCallbackMap.erase(deviceManagerWrapper->bundleName_); + g_deviceStateCallbackMap.erase(deviceManagerWrapper->bundleName_); + g_discoverCallbackMap.erase(deviceManagerWrapper->bundleName_); + g_authCallbackMap.erase(deviceManagerWrapper->bundleName_); + napi_get_undefined(env, &result); + return result; +} + +void DeviceManagerNapi::HandleCreateDmCallBack(const napi_env &env, AsyncCallbackInfo *asCallbackInfo) +{ + napi_value resourceName; + napi_create_string_latin1(env, "createDeviceManagerCallback", NAPI_AUTO_LENGTH, &resourceName); + napi_create_async_work( + env, nullptr, resourceName, + [](napi_env env, void *data) { + (void)env; + AsyncCallbackInfo *asCallbackInfo = (AsyncCallbackInfo *)data; + std::string bundleName = std::string(asCallbackInfo->bundleName); + std::shared_ptr initCallback = std::make_shared(bundleName); + if (DeviceManager::GetInstance().InitDeviceManager(bundleName, initCallback) != 0) { + HILOGE("InitDeviceManager for bunderName %{public}s failed", bundleName.c_str()); + return; + } + g_initCallbackMap[bundleName] = initCallback; + asCallbackInfo->status = 0; + }, + [](napi_env env, napi_status status, void *data) { + (void)status; + AsyncCallbackInfo *asCallbackInfo = (AsyncCallbackInfo *)data; + napi_value result[DM_NAPI_ARGS_TWO] = { 0 }; + napi_value ctor; + napi_value argv; + napi_get_reference_value(env, sConstructor_, &ctor); + napi_create_string_utf8(env, asCallbackInfo->bundleName, NAPI_AUTO_LENGTH, &argv); + napi_status ret = napi_new_instance(env, ctor, DM_NAPI_ARGS_ONE, &argv, &result[1]); + if (ret != napi_ok) { + HILOGE("Create DeviceManagerNapi for bunderName %{public}s failed", asCallbackInfo->bundleName); + asCallbackInfo->status = -1; + } + + if (asCallbackInfo->status == 0) { + HILOGI("InitDeviceManager for bunderName %{public}s success", asCallbackInfo->bundleName); + napi_get_undefined(env, &result[0]); + napi_value callback = nullptr; + napi_value callResult = nullptr; + napi_get_reference_value(env, asCallbackInfo->callback, &callback); + napi_call_function(env, nullptr, callback, DM_NAPI_ARGS_TWO, &result[0], &callResult); + napi_delete_reference(env, asCallbackInfo->callback); + } else { + HILOGI("InitDeviceManager for bunderName %{public}s failed", asCallbackInfo->bundleName); + napi_value message = nullptr; + napi_create_object(env, &result[0]); + napi_create_int32(env, asCallbackInfo->status, &message); + napi_set_named_property(env, result[0], "code", message); + napi_get_undefined(env, &result[1]); + } + napi_delete_async_work(env, asCallbackInfo->asyncWork); + delete asCallbackInfo; + }, + (void *)asCallbackInfo, + &asCallbackInfo->asyncWork); + napi_queue_async_work(env, asCallbackInfo->asyncWork); +} + +napi_value DeviceManagerNapi::CreateDeviceManager(napi_env env, napi_callback_info info) +{ + HILOGI("CreateDeviceManager in"); + GET_PARAMS(env, info, DM_NAPI_ARGS_TWO); + NAPI_ASSERT(env, argc >= DM_NAPI_ARGS_TWO, "Wrong number of arguments, required 2"); + + napi_valuetype bundleNameValueType = napi_undefined; + napi_typeof(env, argv[0], &bundleNameValueType); + NAPI_ASSERT(env, bundleNameValueType == napi_string, "type mismatch for parameter 0"); + + napi_valuetype funcValueType = napi_undefined; + napi_typeof(env, argv[1], &funcValueType); + NAPI_ASSERT(env, funcValueType == napi_function, "type mismatch for parameter 1"); + + auto *asCallbackInfo = new AsyncCallbackInfo(); + asCallbackInfo->env = env; + napi_get_value_string_utf8(env, argv[0], asCallbackInfo->bundleName, DM_NAPI_BUF_LENGTH - 1, + &asCallbackInfo->bundleNameLen); + napi_create_reference(env, argv[1], 1, &asCallbackInfo->callback); + + HandleCreateDmCallBack(env, asCallbackInfo); + + napi_value result = nullptr; + napi_get_undefined(env, &result); + return result; +} + +napi_value DeviceManagerNapi::Constructor(napi_env env, napi_callback_info info) +{ + HILOGI("DeviceManagerNapi Constructor in"); + GET_PARAMS(env, info, DM_NAPI_ARGS_ONE); + NAPI_ASSERT(env, argc >= DM_NAPI_ARGS_ONE, "Wrong number of arguments, required 1"); + + napi_valuetype valueType = napi_undefined; + napi_typeof(env, argv[0], &valueType); + NAPI_ASSERT(env, valueType == napi_string, "type mismatch for parameter 1"); + + char bundleName[DM_NAPI_BUF_LENGTH] = { 0 }; + size_t typeLen = 0; + napi_get_value_string_utf8(env, argv[0], bundleName, sizeof(bundleName), &typeLen); + + HILOGI("create DeviceManagerNapi for packageName:%{public}s", bundleName); + DeviceManagerNapi *obj = new DeviceManagerNapi(env, thisVar); + obj->bundleName_ = std::string(bundleName); + g_deviceManagerMap[obj->bundleName_] = obj; + napi_wrap(env, thisVar, reinterpret_cast(obj), + [](napi_env env, void *data, void *hint) { + (void)env; + (void)hint; + DeviceManagerNapi *deviceManager = (DeviceManagerNapi *)data; + delete deviceManager; + }, + nullptr, &(obj->wrapper_)); + return thisVar; +} + +napi_value DeviceManagerNapi::Init(napi_env env, napi_value exports) +{ + napi_value dmClass; + napi_property_descriptor dmProperties[] = { + DECLARE_NAPI_FUNCTION("release", ReleaseDeviceManager), + DECLARE_NAPI_FUNCTION("getTrustedDeviceListSync", GetTrustedDeviceListSync), + DECLARE_NAPI_FUNCTION("startDeviceDiscover", StartDeviceDiscoverSync), + DECLARE_NAPI_FUNCTION("stopDeviceDiscover", StopDeviceDiscoverSync), + DECLARE_NAPI_FUNCTION("authenticateDevice", AuthenticateDeviceSync), + DECLARE_NAPI_FUNCTION("on", JsOn), + DECLARE_NAPI_FUNCTION("off", JsOff) + }; + + napi_property_descriptor static_prop[] = { + DECLARE_NAPI_STATIC_FUNCTION("createDeviceManager", CreateDeviceManager), + }; + + HILOGD("DeviceManagerNapi::Init() is called!"); + NAPI_CALL(env, + napi_define_class(env, DEVICE_MANAGER_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor, nullptr, + sizeof(dmProperties) / sizeof(dmProperties[0]), dmProperties, &dmClass)); + NAPI_CALL(env, napi_create_reference(env, dmClass, 1, &sConstructor_)); + NAPI_CALL(env, napi_set_named_property(env, exports, DEVICE_MANAGER_NAPI_CLASS_NAME.c_str(), dmClass)); + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(static_prop) / sizeof(static_prop[0]), static_prop)); + HILOGI("All props and functions are configured.."); + return exports; +} + +/* + * Function registering all props and functions of ohos.distributedhardware + */ +static napi_value Export(napi_env env, napi_value exports) +{ + HILOGI("Export() is called!"); + DeviceManagerNapi::Init(env, exports); + return exports; +} + +/* + * module define + */ +static napi_module g_dmModule = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Export, + .nm_modname = "distributedhardware.devicemanager", + .nm_priv = ((void *)0), + .reserved = {0} + }; + +/* + * module register + */ +extern "C" __attribute__((constructor)) void RegisterModule(void) +{ + HILOGI("RegisterModule() is called!"); + napi_module_register(&g_dmModule); +} diff --git a/ohos.build b/ohos.build index 53e4aec2d..66b59c67a 100644 --- a/ohos.build +++ b/ohos.build @@ -2,12 +2,27 @@ "parts": { "device_manager_base": { "variants": ["phone", "wearable", "ivi"], - "inner_kits": [], - "module_list": [], + "inner_kits": [ + { + "type": "so", + "name": "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp:devicemanagersdk", + "header": { + "header_base": "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp/include", + "header_files": [ + "device_manager_proxy.h", + "idevice_manager.h" + ] + } + } + ], + "module_list": [ + "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp:devicemanagersdk", + "//foundation/distributedhardware/devicemanager/interfaces/kits/js:devicemanager_native_js", + "//foundation/distributedhardware/devicemanager/services/devicemanagerservice:devicemanagerservice", + "//foundation/distributedhardware/devicemanager/sa_profile:dm_sa_profile" + ], "system_kits": [] } }, "subsystem": "distributedhardware" } - - diff --git a/sa_profile/4802.xml b/sa_profile/4802.xml new file mode 100644 index 000000000..398977926 --- /dev/null +++ b/sa_profile/4802.xml @@ -0,0 +1,27 @@ + + + + foundation + + 4802 + libdevicemanagerservice.z.so + + + true + false + 1 + + diff --git a/sa_profile/BUILD.gn b/sa_profile/BUILD.gn new file mode 100644 index 000000000..89d88fa4c --- /dev/null +++ b/sa_profile/BUILD.gn @@ -0,0 +1,20 @@ +# 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/sa_profile/sa_profile.gni") + +ohos_sa_profile("dm_sa_profile") { + sources = [ "4802.xml" ] + + part_name = "device_manager_base" +} diff --git a/services/devicemanagerservice/BUILD.gn b/services/devicemanagerservice/BUILD.gn new file mode 100644 index 000000000..35ff65151 --- /dev/null +++ b/services/devicemanagerservice/BUILD.gn @@ -0,0 +1,93 @@ +# 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/distributedhardware/devicemanager/devicemanager.gni") + +config("dmservice_config") { + visibility = [ ":*" ] + include_dirs = [ + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "include", + "include/softbus", + "include/authdemo", + "include/util", + "${common_path}/log/include", + "${common_path}/utils/include", + "${innerkits_path}/native_cpp/include", + "//base/security/deviceauth/interfaces/innerkits", + "//third_party/json/include", + "//base/startup/syspara_lite/adapter/native/syspara/include", + ] + + cflags = [ + "-Wall", + "-Werror", + "-Wdate-time", + "-Wfloat-equal", + "-Wshadow", + "-Wformat=2", + "-fvisibility=hidden", + "-fdata-sections", + "-ffunction-sections", + "-Os", + ] + + cflags_cc = [ + "-fvisibility-inlines-hidden", + "-Os", + ] +} + +ohos_shared_library("devicemanagerservice") { + sources = [ + "src/device_manager_service.cpp", + "src/device_manager_stub.cpp", + "src/device_manager_listener_proxy.cpp", + "src/softbus/softbus_adapter.cpp", + "src/authdemo/device_client_channel.cpp", + "src/authdemo/device_server_channel.cpp", + "src/authdemo/hichain_adapter.cpp", + "src/util/anonymous_string.cpp", + ] + + configs = [ ":dmservice_config" ] + + deps = [ + "//utils/native/base:utils", + "${innerkits_path}/native_cpp:devicemanagersdk", + "//base/security/deviceauth/services:deviceauth_sdk", + ] + + defines = [ + "DH_LOG_TAG=\"devicemanager\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "appexecfwk_standard:appexecfwk_base", + "appexecfwk_standard:appexecfwk_core", + "appexecfwk_standard:libeventhandler", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_L2:samgr_proxy", + "dsoftbus_standard:softbus_client", + "startup_l2:syspara", + ] + + subsystem_name = "distributedhardware" + + part_name = "device_manager_base" +} diff --git a/services/devicemanagerservice/include/authdemo/device_client_channel.h b/services/devicemanagerservice/include/authdemo/device_client_channel.h new file mode 100644 index 000000000..dac934e17 --- /dev/null +++ b/services/devicemanagerservice/include/authdemo/device_client_channel.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 OHOS_DEVICE_CLIENT_CHANNEL_H +#define OHOS_DEVICE_CLIENT_CHANNEL_H + +#include +#include + +#include "device_auth.h" + +namespace OHOS { +namespace DistributedHardware { +class DeviceClientChannel { +public: + DeviceClientChannel(int64_t requestId, const DeviceGroupManager& deviceGroupManager, + std::function onError) + : requestId_(requestId), socketFd_(-1), deviceGroupManager_(deviceGroupManager), onError_(onError) {} + ~DeviceClientChannel(); + + DeviceClientChannel()=delete; + DeviceClientChannel(const DeviceClientChannel&)=delete; + DeviceClientChannel &operator=(const DeviceClientChannel&)=delete; + +public: + int32_t Connect(const std::string& ip, short port); + bool Send(const char* data, const int32_t dataLen); + void Receive(void); + void OnDataReceived(const char* data, const int32_t dataLen); + void ResetConnection(); + +private: + int64_t requestId_; + int32_t socketFd_; + const DeviceGroupManager& deviceGroupManager_; + // call back for socket channel + std::function onError_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/devicemanagerservice/include/authdemo/device_server_channel.h b/services/devicemanagerservice/include/authdemo/device_server_channel.h new file mode 100644 index 000000000..6e3b279fc --- /dev/null +++ b/services/devicemanagerservice/include/authdemo/device_server_channel.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 OHOS_DEVICE_SERVER_CHANNEL_H +#define OHOS_DEVICE_SERVER_CHANNEL_H + +#include +#include +#include + +#include "device_auth.h" + +namespace OHOS { +namespace DistributedHardware { +class DeviceServerChannel { +public: + DeviceServerChannel(const DeviceGroupManager& deviceGroupManager, + std::function onError) + : socketFd_(-1), clientFd_(-1), deviceGroupManager_(deviceGroupManager), onError_(onError) {} + ~DeviceServerChannel(); + + DeviceServerChannel()=delete; + DeviceServerChannel(const DeviceServerChannel&)=delete; + DeviceServerChannel &operator=(const DeviceServerChannel&)=delete; + +public: + int32_t Start(const int32_t port); + bool Send(const char* data, const int32_t dataLen); + void Receive(); + void OnDataReceived(const char* data, const int32_t dataLen); + void ResetConnection(); + +private: + int32_t socketFd_; + int32_t clientFd_; + const DeviceGroupManager& deviceGroupManager_; + std::function onError_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/devicemanagerservice/include/authdemo/hichain_adapter.h b/services/devicemanagerservice/include/authdemo/hichain_adapter.h new file mode 100644 index 000000000..bc9b23ea6 --- /dev/null +++ b/services/devicemanagerservice/include/authdemo/hichain_adapter.h @@ -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. + */ + +#ifndef OHOS_HICHAIN_ADAPTER_H +#define OHOS_HICHAIN_ADAPTER_H + +#include +#include +#include +#include +#include + +#include "device_auth.h" +#include "event_handler.h" +#include "nlohmann/json.hpp" +#include "thread_pool.h" + +#include "device_client_channel.h" +#include "device_server_channel.h" +#include "single_instance.h" + +namespace OHOS { +namespace DistributedHardware { +enum { + SUCCESS = 0, + GROUP_CREATE_FAILED = 1, + MEMBER_ADD_FAILED = 2, + CREATE_CHANNEL_FAILED = 3, +}; + +struct DeviceReqInfo { + std::string deviceId; + std::string ipAddr; + short port; +}; + +class BindCallback { +public: + virtual void onBindSuccess(std::string deviceId, const char* returnData) = 0; + virtual void onBindFailed(std::string deviceId, int32_t errorCode) = 0; + virtual void onUnBindSuccess(std::string /* deviceId */, const char* /* returnData */) {} + virtual void onUnBindFailed(std::string /* deviceId */, int32_t /* errorCode*/) {} + virtual ~BindCallback() {} +}; + +class HichainAuthCallBack { +public: + static bool onTransmit(int64_t requestId, const uint8_t *data, uint32_t dataLen); + static void onSessionKeyReturned(int64_t requestId, const uint8_t *sessionKey, uint32_t sessionKeyLen); + static void onFinish(int64_t requestId, int operationCode, const char *returnData); + static void onError(int64_t requestId, int operationCode, int errorCode, const char *errorReturn); + static char* onBindRequest(int64_t requestId, int operationCode, const char *reqParams); +}; + +class HichainAdapter { +DECLARE_SINGLE_INSTANCE(HichainAdapter); +public: + int Init(); + + int32_t Bind(const DeviceReqInfo& devReqInfo, std::shared_ptr callback, bool sync = false); + + void OnBindSuccess(int64_t requestId, const char* returnData); + void OnBindFailed(int64_t requestId, int32_t errorCode); + + void UnBind(const std::string& deviceId); + void OnUnBindFinished(); + + bool OnTransmit(int64_t requestId, const uint8_t *data, uint32_t dataLen); + + void OnGroupCreated(int64_t requestId, const char *groupInfo); + + char* OnBindRequest(int64_t requestId, int operationCode, const char *reqParams); + +private: + std::string GetGroupIdByName(int32_t groupType, const std::string& groupName); + int32_t CreateGroup(int64_t requestId); + int32_t AddMemeber(int64_t requestId, std::string& groupId, const std::string& pinCode); + int64_t GenRequestId(); + +private: + std::atomic requestIdIndex_ {0}; + nlohmann::json bindRequestJsonObj_; + std::map bindingDeviceMap_; + std::map> clientBindReqMap_; + std::map> bindCallBackMap_; + const DeviceGroupManager* deviceGroupManager_ = nullptr; + std::unique_ptr deviceServerInst_; + mutable ThreadPool threadPool_; + + DeviceAuthCallback deviceAuthCallback_ = { + .onTransmit = HichainAuthCallBack::onTransmit, + .onSessionKeyReturned = HichainAuthCallBack::onSessionKeyReturned, + .onFinish = HichainAuthCallBack::onFinish, + .onError = HichainAuthCallBack::onError, + .onRequest = HichainAuthCallBack::onBindRequest, + }; + + // call back for socket channel + std::function onError_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_HICHAIN_ADAPTER_H \ No newline at end of file diff --git a/services/devicemanagerservice/include/device_manager_listener_proxy.h b/services/devicemanagerservice/include/device_manager_listener_proxy.h new file mode 100644 index 000000000..d32f7837a --- /dev/null +++ b/services/devicemanagerservice/include/device_manager_listener_proxy.h @@ -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. + */ + +#ifndef OHOS_DEVICE_MANAGER_LISTENER_PROXY_H +#define OHOS_DEVICE_MANAGER_LISTENER_PROXY_H + +#include "idevice_manager_listener.h" +#include "iremote_proxy.h" + +namespace OHOS { +namespace DistributedHardware { +class DeviceManagerListenerProxy : public IRemoteProxy { +public: + explicit DeviceManagerListenerProxy(const sptr& impl) + : IRemoteProxy(impl) {}; + ~DeviceManagerListenerProxy() {}; + int32_t OnDeviceOnline(std::string &packageName, const DmDeviceInfo &deviceInfo) override; + int32_t OnDeviceOffline(std::string &packageName, const DmDeviceInfo &deviceInfo) override; + int32_t OnDeviceChanged(std::string &packageName, const DmDeviceInfo &deviceInfo) override; + int32_t OnDeviceFound(std::string &packageName, uint16_t subscribeId, const DmDeviceInfo &deviceInfo) override; + int32_t OnDiscoverFailed(std::string &packageName, uint16_t subscribeId, int32_t failedReason) override; + int32_t OnDiscoverySuccess(std::string &packageName, uint16_t subscribeId) override; + int32_t OnAuthResult(std::string &packageName, std::string &deviceId, int32_t status, int32_t reason) override; +private: + bool WriteInterfaceToken(MessageParcel &data); + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DEVICE_MANAGER_LISTENER_PROXY_H diff --git a/services/devicemanagerservice/include/device_manager_service.h b/services/devicemanagerservice/include/device_manager_service.h new file mode 100644 index 000000000..af19ab97e --- /dev/null +++ b/services/devicemanagerservice/include/device_manager_service.h @@ -0,0 +1,98 @@ +/* + * 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 OHOS_DEVICE_MANAGER_SERVICE_H +#define OHOS_DEVICE_MANAGER_SERVICE_H + +#include +#include +#include +#include +#include +#include "system_ability.h" +#include "thread_pool.h" +#include "iremote_stub.h" +#include "idevice_manager.h" +#include "idevice_manager_listener.h" +#include "device_manager_stub.h" +#include "single_instance.h" +#include "hichain_adapter.h" + +namespace OHOS { +namespace DistributedHardware { +enum class ServiceRunningState { + STATE_NOT_START, + STATE_RUNNING +}; + +enum DmBindStatus : uint32_t { + STATE_BIND_SUCCESS, + STATE_BIND_FAILD +}; + +class AppDeathRecipient : public IRemoteObject::DeathRecipient { +public: + void OnRemoteDied(const wptr& remote) override; + AppDeathRecipient() = default; + ~AppDeathRecipient() = default; +}; + +class HiChainBindCallback : public BindCallback { +public: + void onBindSuccess(std::string deviceId, const char* returnData) override; + void onBindFailed(std::string deviceId, int32_t errorCode) override; +}; + +class DeviceManagerService : public SystemAbility, public DeviceManagerStub { +friend class HiChainBindCallback; +DECLARE_SYSTEM_ABILITY(DeviceManagerService); +DECLARE_SINGLE_INSTANCE_BASE(DeviceManagerService); +public: + DeviceManagerService(); + ~DeviceManagerService() = default; + void OnStart() override; + void OnStop() override; + ServiceRunningState QueryServiceState() const; + + int32_t GetTrustedDeviceList(std::string &packageName, std::string &extra, + std::vector &deviceList) override; + int32_t RegisterDeviceManagerListener(std::string &packageName, sptr listener) override; + int32_t UnRegisterDeviceManagerListener(std::string &packageName) override; + int32_t RegisterDeviceStateCallback(std::string &packageName, std::string &extra) override; + int32_t UnRegisterDeviceStateCallback(std::string &packageName) override; + int32_t StartDeviceDiscovery(std::string &packageName, DmSubscribeInfo &subscribeInfo) override; + int32_t StopDeviceDiscovery(std::string &packageName, uint16_t subscribeId) override; + int32_t AuthenticateDevice(std::string &packageName, const DmDeviceInfo &deviceInfo, std::string &extra) override; + const std::map>& GetDmListener(); + const sptr GetDmListener(std::string packageName) const; + +private: + bool Init(); + void RegisterDeviceStateListener(); + +private: + bool registerToService_; + ServiceRunningState state_; + mutable ThreadPool threadPool_; + std::mutex listenerLock_; + std::shared_ptr hichainBindCallback_; + std::map> appRecipient_; + std::map> dmListener_; + std::map devStateCallbackParas_; + std::map authCallbackParas_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DEVICE_MANAGER_SERVICE_H diff --git a/services/devicemanagerservice/include/device_manager_stub.h b/services/devicemanagerservice/include/device_manager_stub.h new file mode 100644 index 000000000..db5555468 --- /dev/null +++ b/services/devicemanagerservice/include/device_manager_stub.h @@ -0,0 +1,48 @@ +/* + * 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 OHOS_DEVICE_MANAGER_STUB_H +#define OHOS_DEVICE_MANAGER_STUB_H + +#include +#include "iremote_stub.h" +#include "idevice_manager.h" + +namespace OHOS { +namespace DistributedHardware { +class DeviceManagerStub : public IRemoteStub { +public: + DeviceManagerStub(); + ~DeviceManagerStub(); + int32_t OnRemoteRequest(uint32_t code, + MessageParcel &data, MessageParcel &reply, MessageOption &option) override; +private: + int32_t RegisterDeviceManagerListenerInner(MessageParcel &data, MessageParcel &reply); + int32_t UnRegisterDeviceManagerListenerInner(MessageParcel &data, MessageParcel &reply); + int32_t RegisterDeviceStateCallbackInner(MessageParcel &data, MessageParcel &reply); + int32_t UnRegisterDeviceStateCallbackInner(MessageParcel &data, MessageParcel &reply); + int32_t GetTrustedDeviceListInner(MessageParcel &data, MessageParcel &reply); + int32_t StartDeviceDiscoveryInner(MessageParcel &data, MessageParcel &reply); + int32_t StopDeviceDiscoveryInner(MessageParcel &data, MessageParcel &reply); + int32_t AuthenticateDeviceInner(MessageParcel &data, MessageParcel &reply); + template + int32_t GetParcelableInfo(MessageParcel &reply, T &parcelableInfo); + bool EnforceInterceToken(MessageParcel &data); + using CmdProcFunc = int32_t (DeviceManagerStub::*)(MessageParcel &data, MessageParcel &reply); + std::map memberFuncMap_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DEVICE_MANAGER_STUB_H diff --git a/services/devicemanagerservice/include/softbus/softbus_adapter.h b/services/devicemanagerservice/include/softbus/softbus_adapter.h new file mode 100644 index 000000000..932dcfe14 --- /dev/null +++ b/services/devicemanagerservice/include/softbus/softbus_adapter.h @@ -0,0 +1,85 @@ +/* + * 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 OHOS_DEVICE_MANAGER_SOFTBUS_ADAPTER_H +#define OHOS_DEVICE_MANAGER_SOFTBUS_ADAPTER_H + +#include +#include +#include +#include "softbus_bus_center.h" +#include "discovery_service.h" +#include "dm_device_info.h" +#include "dm_subscribe_info.h" +#include "single_instance.h" + +namespace OHOS { +namespace DistributedHardware { +struct SubscribeInfoAdapter { + SubscribeInfo info; + uint16_t subscribeIdOrigin; + uint16_t subscribeIdPrefix; +}; + +class SoftbusAdapter { +DECLARE_SINGLE_INSTANCE(SoftbusAdapter); +public: + static int32_t GetSoftbusTrustDevices(const std::string &packageName, std::string &extra, + std::vector &deviceList); + void RegSoftBusDeviceStateListener(); + int32_t StartSoftbusDiscovery(std::string &packageName, DmSubscribeInfo &info); + int32_t StopSoftbusDiscovery(std::string &packageName, uint16_t subscribeId); + static void OnSoftbusDeviceOffline(NodeBasicInfo *info); + static void OnSoftBusDeviceOnline(NodeBasicInfo *info); + static void OnSoftbusDeviceInfoChanged(NodeBasicInfoType type, NodeBasicInfo *info); + static void OnSoftbusDeviceFound(const DeviceInfo *device); + static void OnSoftbusDiscoverFailed(int subscribeId, DiscoveryFailReason failReason); + static void OnSoftbusDiscoverySuccess(int subscribeId); + static void OnSoftbusJoinLNNResult(ConnectionAddr *addr, const char *networkId, int32_t retCode); + static void OnSoftbusLeaveLNNResult(const char *networkId, int32_t retCode); + const std::map>>& GetsubscribeInfos(); + int32_t SoftbusJoinLnn(std::string devId); + int32_t SoftbusLeaveLnn(std::string networkId); + int32_t GetConnectionIpAddr(std::string deviceId, std::string &ipAddr); + +private: + static void OnSoftBusDeviceStateChange(DmDeviceState state, NodeBasicInfo *info); + static bool IsDeviceOnLine(std::string &deviceId); + std::string GetPackageNameBySubscribeId(uint16_t subscribeId); + bool GetsubscribeIdAdapter(std::string packageName, int16_t originId, int32_t &adapterId); + bool GetPackageNameBySubscribeId(int32_t adapterId, std::string &packageName); + void SaveDiscoverDeviceInfo(const DeviceInfo *deviceInfo); + void RemoveDiscoverDeviceInfo(const std::string deviceId); + +private: + std::map>> subscribeInfos_; + std::map> discoverDeviceInfoMap_; + std::vector> discoverDeviceInfoVector_; + std::atomic subscribeIdPrefix {0}; + INodeStateCb softbusNodeStateCb = { + .events = EVENT_NODE_STATE_ONLINE | EVENT_NODE_STATE_OFFLINE | EVENT_NODE_STATE_INFO_CHANGED, + .onNodeOnline = OnSoftBusDeviceOnline, + .onNodeOffline = OnSoftbusDeviceOffline, + .onNodeBasicInfoChanged = OnSoftbusDeviceInfoChanged + }; + IDiscoveryCallback softbusDiscoverCallback = { + .OnDeviceFound = OnSoftbusDeviceFound, + .OnDiscoverFailed = OnSoftbusDiscoverFailed, + .OnDiscoverySuccess = OnSoftbusDiscoverySuccess + }; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DEVICE_MANAGER_SOFTBUS_ADAPTER_H diff --git a/services/devicemanagerservice/include/util/anonymous_string.h b/services/devicemanagerservice/include/util/anonymous_string.h new file mode 100644 index 000000000..dd58b7384 --- /dev/null +++ b/services/devicemanagerservice/include/util/anonymous_string.h @@ -0,0 +1,26 @@ +/* + * 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 ANONYMOUS_STRING_H +#define ANONYMOUS_STRING_H +#include + +namespace OHOS { +namespace DistributedHardware { +std::string GetAnonyString(const std::string &value); +std::string GetAnonyInt32(const int32_t value); +} +} +#endif \ No newline at end of file diff --git a/services/devicemanagerservice/src/authdemo/device_client_channel.cpp b/services/devicemanagerservice/src/authdemo/device_client_channel.cpp new file mode 100644 index 000000000..f1ccaea7b --- /dev/null +++ b/services/devicemanagerservice/src/authdemo/device_client_channel.cpp @@ -0,0 +1,166 @@ +/* + * 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_client_channel.h" + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include "device_manager_log.h" + +namespace OHOS { +namespace DistributedHardware { +namespace { + constexpr int32_t CLIENT_DATA_BUFFER_LENGTH = 2048; + const int32_t RECV_DATA_TIMEOUT = 5; + const int32_t REQUEST_ID_LENGTH = 10; +} + +DeviceClientChannel::~DeviceClientChannel() +{ + if (socketFd_ != -1) { + close(socketFd_); + socketFd_ = -1; + } +} + +int32_t DeviceClientChannel::Connect(const std::string& ip, short port) +{ + HILOGI("DeviceClientChannel::Connect begin to connect to server."); + int32_t socketFd = socket(AF_INET, SOCK_STREAM, 0); + if (socketFd == -1) { + HILOGE("DeviceClientChannel::Connect create socket failed, errMsg: %{public}s.", strerror(errno)); + return -1; + } + + struct sockaddr_in addr; + if (memset_s(&addr, sizeof(addr), 0, sizeof(addr)) != EOK) { + HILOGE("DeviceClientChannel::Connect error init addr."); + close(socketFd); + return -1; + } + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(ip.c_str()); + addr.sin_port = htons(port); + + int32_t ret = connect(socketFd, (struct sockaddr*) &addr, sizeof(addr)); + if (ret == -1) { + HILOGE("DeviceClientChannel::Connect connet server failed, errMsg: %{public}s.", strerror(errno)); + close(socketFd); + return -1; + } + + socketFd_ = socketFd; + HILOGI("DeviceClientChannel::Connect connect to server, fd: %{public}d.", socketFd_); + + // wait five seconds, if recv none, release the connection + struct timeval timeout = {RECV_DATA_TIMEOUT, 0}; + setsockopt(socketFd_, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval)); + return 0; +} + +bool DeviceClientChannel::Send(const char* data, const int32_t dataLen) +{ + // The client needs to add requestId to the header of the data + std::stringstream reqIdStr; + reqIdStr << requestId_; + + int32_t sendDataLen = dataLen + REQUEST_ID_LENGTH; + std::unique_ptr sendData = std::make_unique(sendDataLen); + if (memset_s(sendData.get(), sendDataLen, 0, sendDataLen) != EOK) { + HILOGE("DeviceClientChannel::Send error init send data."); + return false; + } + + if (memcpy_s(sendData.get(), sendDataLen, reqIdStr.str().c_str(), REQUEST_ID_LENGTH) != EOK) { + HILOGE("DeviceClientChannel::Send error init requestId."); + return false; + } + + if (memcpy_s(sendData.get() + REQUEST_ID_LENGTH, sendDataLen - REQUEST_ID_LENGTH, data, dataLen) != EOK) { + HILOGE("DeviceClientChannel::Send error init data."); + return false; + } + + int32_t ret = send(socketFd_, sendData.get(), sendDataLen, 0); + if (ret == -1) { + HILOGE("DeviceClientChannel::send data failed, errMsg: %{public}s.", strerror(errno)); + return false; + } + + HILOGI("DeviceClientChannel::send data, size:%{public}d.", ret); + return true; +} + +void DeviceClientChannel::Receive() +{ + HILOGI("DeviceClientChannel::Receive data, socketFd:%{public}d.", socketFd_); + char dataBuf[CLIENT_DATA_BUFFER_LENGTH] = {0}; + + while (socketFd_ != -1) { + (void)memset_s(dataBuf, sizeof(dataBuf), 0, sizeof(dataBuf)); + int32_t rc = recv(socketFd_, dataBuf, sizeof(dataBuf), 0); + if (rc == 0) { + HILOGE("DeviceClientChannel::Receive error, client shutdown, socketFd_:%{public}d, errMsg: %{public}s.", + socketFd_, strerror(errno)); + close(socketFd_); + socketFd_ = -1; + break; + } else if (rc == -1 || rc == EAGAIN) { + HILOGE("DeviceClientChannel::Receive data failed, socketFd_:%{public}d, errMsg: %{public}s.", + socketFd_, strerror(errno)); + close(socketFd_); + socketFd_ = -1; + break; + } else { + HILOGI("DeviceClientChannel::Receive data, socketFd_:%{public}d, size:%{public}d.", socketFd_, rc); + OnDataReceived(dataBuf, rc); + } + } + HILOGI("DeviceClientChannel::Receive data end, socketFd:%{public}d.", socketFd_); +} + +void DeviceClientChannel::OnDataReceived(const char* data, const int32_t dataLen) +{ + int ret = deviceGroupManager_.processData(requestId_, (uint8_t *) data, dataLen); + HILOGI("DeviceClientChannel::OnDataReceived process data, ret:%{public}d, dataLen:%{public}d.", ret, dataLen); + if (ret != 0) { + close(socketFd_); + socketFd_ = -1; + onError_(requestId_, 0, ret, nullptr); + } +} + +void DeviceClientChannel::ResetConnection() +{ + HILOGI("DeviceClientChannel::ResetConnection bind finished, release connection."); + close(socketFd_); + socketFd_ = -1; +} +} +} \ No newline at end of file diff --git a/services/devicemanagerservice/src/authdemo/device_server_channel.cpp b/services/devicemanagerservice/src/authdemo/device_server_channel.cpp new file mode 100644 index 000000000..af142ff3c --- /dev/null +++ b/services/devicemanagerservice/src/authdemo/device_server_channel.cpp @@ -0,0 +1,205 @@ +/* + * 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_server_channel.h" + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include + +#include "device_manager_log.h" + +namespace OHOS { +namespace DistributedHardware { +namespace { + const int32_t DATA_BUFFER_LENGTH = 2048; + const int32_t REQUEST_ID_LENGTH = 10; + const int32_t LISTENING_QUEUE_LEN = 10; + const int64_t MIN_REQUEST_ID = 1000000000; + const int32_t RECV_DATA_TIMEOUT = 5; +} + +DeviceServerChannel::~DeviceServerChannel() +{ + if (socketFd_ != -1) { + close(socketFd_); + socketFd_ = -1; + } + + if (clientFd_ != -1) { + close(clientFd_); + clientFd_ = -1; + } +} + +int32_t DeviceServerChannel::Start(const int32_t port) +{ + HILOGI("DeviceServerChannel::Start begin to start server."); + if (port <= 0) { + HILOGE("DeviceServerChannel::start port is invalid."); + return -1; + } + + int32_t socketFd = socket(AF_INET, SOCK_STREAM, 0); + if (socketFd == -1) { + HILOGE("DeviceServerChannel::start create socket failed, errMsg: %{public}s.", strerror(errno)); + return -1; + } + + struct sockaddr_in addr; + if (memset_s(&addr, sizeof(addr), 0, sizeof(addr)) != EOK) { + HILOGE("DeviceServerChannel::Start error init addr."); + close(socketFd); + return -1; + } + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = htons(port); + + int32_t ret = bind(socketFd, (struct sockaddr*) &addr, sizeof(addr)); + if (ret == -1) { + HILOGE("DeviceServerChannel::start bind addr failed, errMsg: %{public}s.", strerror(errno)); + close(socketFd); + return -1; + } + + socketFd_ = socketFd; + HILOGI("DeviceServerChannel::start bind addr success, fd:%{public}d.", socketFd_); + + ret = listen(socketFd_, LISTENING_QUEUE_LEN); + if (ret == -1) { + HILOGE("DeviceServerChannel::start listen port failed, errMsg: %{public}s.", strerror(errno)); + close(socketFd_); + socketFd_ = -1; + return -1; + } + + return 0; +} + +void DeviceServerChannel::Receive() +{ + HILOGI("DeviceServerChannel::receive begin to listen client connecting."); + struct sockaddr_in client_addr; + socklen_t len = sizeof(client_addr); + + while (true) { + int32_t fd = accept(socketFd_, (struct sockaddr*) &client_addr, &len); + if (fd == -1) { + HILOGE("DeviceServerChannel::receive accept connect failed, errMsg: %{public}s.", strerror(errno)); + continue; + } + + if (clientFd_ != -1) { + HILOGW("DeviceServerChannel::receive another client is connected, close new connect."); + close(fd); + continue; + } + + HILOGI("DeviceServerChannel::receive new client in."); + clientFd_ = fd; + + // wait five seconds, if recv none, release the connection + struct timeval timeout = {RECV_DATA_TIMEOUT, 0}; + setsockopt(clientFd_, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval)); + + // demo project, blocked here to receive data, informal solution, will be discard later + char dataBuf[DATA_BUFFER_LENGTH] = {0}; + while (clientFd_ != -1) { + if (memset_s(dataBuf, sizeof(dataBuf), 0, sizeof(dataBuf)) != EOK) { + HILOGE("DeviceServerChannel::receive error init data buf."); + close(clientFd_); + clientFd_ = -1; + break; + } + + int32_t rc = recv(clientFd_, dataBuf, sizeof(dataBuf), 0); + if (rc == 0) { + HILOGE("DeviceServerChannel::receive error, client shutdown."); + close(clientFd_); + clientFd_ = -1; + break; + } else if (rc == -1 || rc == EAGAIN) { + HILOGE("DeviceServerChannel::receive receive data failed, errMsg: %{public}s.", strerror(errno)); + close(clientFd_); + clientFd_ = -1; + break; + } else { + HILOGI("DeviceServerChannel::receive receive data, size:%{public}d.", rc); + OnDataReceived(dataBuf, rc); + } + } + } +} + +void DeviceServerChannel::OnDataReceived(const char* data, const int32_t dataLen) +{ + HILOGI("DeviceServerChannel::OnDataReceived dataLen:%{public}d.", dataLen); + if (dataLen < REQUEST_ID_LENGTH) { + HILOGI("DeviceServerChannel::OnDataReceived error, data is invalid."); + return; + } + + // the client adds requestId to the header of data, the server needs to parse the original data + char reqIdChar[REQUEST_ID_LENGTH + 1] = {0}; + (void)memcpy_s(reqIdChar, sizeof(reqIdChar), data, REQUEST_ID_LENGTH); + reqIdChar[REQUEST_ID_LENGTH] = '\0'; + int64_t requestId = strtoll(reqIdChar, nullptr, REQUEST_ID_LENGTH); + if (requestId < MIN_REQUEST_ID) { + HILOGI("DeviceServerChannel::OnDataReceived error, requestId is invalid."); + return; + } + + const char* newData = data + REQUEST_ID_LENGTH; + int len = dataLen - REQUEST_ID_LENGTH; + int ret = deviceGroupManager_.processData(requestId, (const uint8_t *) newData, len); + HILOGI("DeviceServerChannel::OnDataReceived process data, ret:%{public}d, dataLen:%{public}d.", ret, len); + if (ret != 0) { + onError_(requestId, 0, ret, nullptr); + close(clientFd_); + clientFd_ = -1; + } +} + +bool DeviceServerChannel::Send(const char* data, const int32_t dataLen) +{ + int32_t ret = send(clientFd_, data, dataLen, 0); + if (ret == -1) { + HILOGE("DeviceServerChannel::send failed,socket:%{public}d,errMsg: %{public}s.", clientFd_, strerror(errno)); + return false; + } + + HILOGI("DeviceServerChannel::send data,socket:%{public}d, size:%{public}d.", clientFd_, ret); + return true; +} + +void DeviceServerChannel::ResetConnection() +{ + HILOGI("DeviceServerChannel::ResetConnection bind finished, release connection."); + close(clientFd_); + clientFd_ = -1; +} +} +} \ No newline at end of file diff --git a/services/devicemanagerservice/src/authdemo/hichain_adapter.cpp b/services/devicemanagerservice/src/authdemo/hichain_adapter.cpp new file mode 100644 index 000000000..7d2c0b806 --- /dev/null +++ b/services/devicemanagerservice/src/authdemo/hichain_adapter.cpp @@ -0,0 +1,379 @@ +/* + * 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 "hichain_adapter.h" + +#include +#include +#include + +#include "parameter.h" + +#include "anonymous_string.h" +#include "device_client_channel.h" +#include "device_manager_log.h" +#include "device_server_channel.h" + +namespace OHOS { +namespace DistributedHardware { +namespace { +// demo solution, may has security issues, later will be replaced by a formal plan +const std::string PIN_CODE = "123456"; +const int32_t PORT = 9999; + +const std::string DEVICE_MANAGER_APP = "ohos.distributedhardware.devicemanager"; +const std::string DEVICE_MANAGER_GROUPNAME = "DMPeerToPeerGroup"; + +const int64_t MIN_REQUEST_ID = 1000000000; +const int64_t MAX_REQUEST_ID = 9999999999; + +const int32_t DEVICE_UUID_LENGTH = 65; +const int32_t PEER_TO_PEER_GROUP = 256; +const int32_t FIELD_EXPIRE_TIME_VALUE = 90; + +const int32_t THREAD_POOL_NUMBER = 20; +} + +IMPLEMENT_SINGLE_INSTANCE(HichainAdapter); + +int HichainAdapter::Init() +{ + HILOGI("HichainAdapter::init, begin to init hichain adapter."); + if (threadPool_.GetThreadsNum() == 0) { + threadPool_.Start(THREAD_POOL_NUMBER); + } + + bindingDeviceMap_.clear(); + bindCallBackMap_.clear(); + clientBindReqMap_.clear(); + + // call back for socket channel + using std::placeholders::_1; + using std::placeholders::_2; + using std::placeholders::_3; + using std::placeholders::_4; + onError_ = std::bind(HichainAuthCallBack::onError, _1, _2, _3, _4); + + HILOGI("HichainAdapter::init, init device auth service."); + InitDeviceAuthService(); + + // get group auth manager instance, and register callback + deviceGroupManager_ = GetGmInstance(); + if (deviceGroupManager_ == nullptr) { + HILOGE("HichainAdapter::init, failed to init group manager!"); + return -1; + } + deviceGroupManager_->regCallback(DEVICE_MANAGER_APP.c_str(), &deviceAuthCallback_); + + HILOGI("HichainAdapter::init, start socket server channel."); + deviceServerInst_ = std::make_unique(*deviceGroupManager_, onError_); + if (deviceServerInst_->Start(PORT) == -1) { + HILOGE("HichainAdapter::init, failed to start server!"); + return -1; + } + + // start the server channel to receive data + auto receiveFunc = [this]() { + this->deviceServerInst_->Receive(); + }; + threadPool_.AddTask(receiveFunc); + + HILOGI("HichainAdapter::init, init hichain adapter success."); + return 0; +} + +int32_t HichainAdapter::Bind(const DeviceReqInfo& devReqInfo, std::shared_ptr callback, bool sync) +{ + (void)sync; + HILOGI("HichainAdapter::Bind, begin to bind device: %{public}s.", GetAnonyString(devReqInfo.deviceId).c_str()); + for (auto &item : bindingDeviceMap_) { + if (item.second == devReqInfo.deviceId) { + HILOGW("HichainAdapter::bind device is binding, update call back."); + } + } + + int64_t requestId = GenRequestId(); + std::shared_ptr clientChannel = + std::make_shared(requestId, *deviceGroupManager_, onError_); + if (clientChannel->Connect(devReqInfo.ipAddr, PORT) == -1) { + HILOGE("HichainAdapter::bind failed to connect to server, create channel failed."); + return CREATE_CHANNEL_FAILED; + } + + // start the client channel to recevice data + auto receiveFunc = [&clientChannel]() { + clientChannel->Receive(); + }; + threadPool_.AddTask(receiveFunc); + + std::string groupId = GetGroupIdByName(PEER_TO_PEER_GROUP, DEVICE_MANAGER_GROUPNAME); + if (groupId == "") { + HILOGE("HichainAdapter::bind group not exist, begin to create group."); + int32_t ret = CreateGroup(requestId); + if (ret != 0) { + HILOGE("HichainAdapter::bind faild to start create group task, ret: %{public}d.", ret); + return GROUP_CREATE_FAILED; + } + } else { + HILOGE("HichainAdapter::bind group exist, begin to add member."); + int ret = AddMemeber(requestId, groupId, PIN_CODE); + if (ret != 0) { + HILOGE("HichainAdapter::bind faild to start add member task, ret: %{public}d.", ret); + return MEMBER_ADD_FAILED; + } + } + + clientBindReqMap_[requestId] = clientChannel; + bindingDeviceMap_[requestId] = devReqInfo.deviceId; + bindCallBackMap_[requestId] = callback; + return SUCCESS; +} + +std::string HichainAdapter::GetGroupIdByName(int32_t groupType, const std::string& groupName) +{ + HILOGI("HichainAdapter::GetGroupIdByName get group info."); + if (deviceGroupManager_ == nullptr) { + HILOGE("HichainAdapter::GetGroupIdByName group manager is null."); + return ""; + } + + nlohmann::json reqParam; + reqParam[FIELD_GROUP_TYPE] = groupType; + reqParam[FIELD_GROUP_NAME] = groupName; + + char* returnGroupVec = nullptr; + uint32_t groupNum = 0; + int32_t ret = deviceGroupManager_->getGroupInfo(DEVICE_MANAGER_APP.c_str(), reqParam.dump().c_str(), + &returnGroupVec, &groupNum); + if (ret != 0) { + HILOGE("HichainAdapter::GetGroupIdByName failed to get group info, ret=%{public}d.", ret); + return ""; + } + + if (groupNum == 0) { + HILOGE("HichainAdapter::GetGroupIdByName group not exist, return empty."); + return ""; + } + + nlohmann::json groupObj = nlohmann::json::parse(returnGroupVec, nullptr, false); + if (groupObj.is_discarded()) { + HILOGE("HichainAdapter::GetGroupIdByName parse group info error, json invalid."); + return ""; + } + + for (auto& item : groupObj) { + if (item.contains(FIELD_GROUP_ID)) { + return item.at(FIELD_GROUP_ID); + } + } + + HILOGI("HichainAdapter::GetGroupIdByName group info not found, return empty"); + return ""; +} + +int32_t HichainAdapter::CreateGroup(int64_t requestId) +{ + HILOGE("HichainAdapter::CreateGroup requestId:%{public}lld.", requestId); + if (deviceGroupManager_ == nullptr) { + HILOGE("HichainAdapter::CreateGroup group manager is null."); + return -1; + } + + nlohmann::json jsonObj; + jsonObj[FIELD_GROUP_TYPE] = PEER_TO_PEER_GROUP; + jsonObj[FIELD_GROUP_NAME] = DEVICE_MANAGER_GROUPNAME; + + char localDeviceId[DEVICE_UUID_LENGTH] = {0}; + GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); + + jsonObj[FIELD_DEVICE_ID] = localDeviceId; + jsonObj[FIELD_USER_TYPE] = 0; + jsonObj[FIELD_GROUP_VISIBILITY] = -1; + jsonObj[FIELD_EXPIRE_TIME] = FIELD_EXPIRE_TIME_VALUE; + + return deviceGroupManager_->createGroup(requestId, DEVICE_MANAGER_APP.c_str(), jsonObj.dump().c_str()); +} + +int32_t HichainAdapter::AddMemeber(int64_t requestId, std::string& groupId, const std::string& pinCode) +{ + HILOGE("HichainAdapter::AddMemeber requestId:%{public}lld.", requestId); + if (deviceGroupManager_ == nullptr) { + HILOGE("HichainAdapter::AddMemeber group manager is null."); + return -1; + } + + nlohmann::json jsonObj; + jsonObj[FIELD_GROUP_ID] = groupId; + jsonObj[FIELD_GROUP_TYPE] = PEER_TO_PEER_GROUP; + jsonObj[FIELD_PIN_CODE] = pinCode; + jsonObj[FIELD_IS_ADMIN] = true; + return deviceGroupManager_->addMemberToGroup(requestId, DEVICE_MANAGER_APP.c_str(), jsonObj.dump().c_str()); +} + +bool HichainAdapter::OnTransmit(int64_t requestId, const uint8_t *data, uint32_t dataLen) +{ + HILOGI("HichainAdapter::OnTransmit requestId:%{public}lld, size:%{public}d.", requestId, dataLen); + if (clientBindReqMap_.count(requestId) > 0) { + HILOGI("HichainAdapter::OnTransmit client send to server."); + return clientBindReqMap_[requestId]->Send((const char*) data, dataLen); + } else { + HILOGI("HichainAdapter::OnTransmit server send to client."); + return deviceServerInst_->Send((const char*) data, dataLen); + } +} + +void HichainAdapter::OnGroupCreated(int64_t requestId, const char *groupInfo) +{ + nlohmann::json jsonObject = nlohmann::json::parse(groupInfo); + if (jsonObject.find(FIELD_GROUP_ID) == jsonObject.end()) { + HILOGE("HichainAdapter::onGroupCreated failed to get groupId."); + OnBindFailed(requestId, GROUP_CREATE_FAILED); + return; + } + + std::string groupId = jsonObject.at(FIELD_GROUP_ID).get(); + HILOGI("HichainAdapter::onGroupCreated group create success,groupId:%{public}s.", GetAnonyString(groupId).c_str()); + + // group创建成功之后,需要添加把对端设备添加到创建好的群组中 + int ret = AddMemeber(requestId, groupId, PIN_CODE); + if (ret != 0) { + HILOGE("HichainAdapter::onGroupCreated faild to start add member task, ret: %{public}d.", ret); + OnBindFailed(requestId, MEMBER_ADD_FAILED); + return; + } +} + +char* HichainAdapter::OnBindRequest(int64_t requestId, int operationCode, const char *reqParams) +{ + (void)requestId; + (void)operationCode; + (void)reqParams; + + HILOGI("HichainAdapter::OnBindRequest."); + bindRequestJsonObj_.clear(); + bindRequestJsonObj_[FIELD_CONFIRMATION] = REQUEST_ACCEPTED; + bindRequestJsonObj_[FIELD_PIN_CODE] = PIN_CODE; + char localDeviceId[DEVICE_UUID_LENGTH] = {0}; + GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); + bindRequestJsonObj_[FIELD_DEVICE_ID] = localDeviceId; + return (char*) bindRequestJsonObj_.dump().c_str(); +} + +void HichainAdapter::OnBindSuccess(int64_t requestId, const char* returnData) +{ + HILOGI("HichainAdapter::OnBindSuccess requestId:%{public}lld,dataLen:%{public}d.", requestId, strlen(returnData)); + if (bindCallBackMap_.count(requestId) == 1) { + bindCallBackMap_[requestId]->onBindSuccess(bindingDeviceMap_[requestId], returnData); + bindCallBackMap_.erase(requestId); + } + + if (clientBindReqMap_.count(requestId) == 1) { + clientBindReqMap_[requestId]->ResetConnection(); + clientBindReqMap_[requestId].reset(); + clientBindReqMap_.erase(requestId); + } + + if (bindingDeviceMap_.count(requestId) == 1) { + bindingDeviceMap_.erase(requestId); + } + + deviceServerInst_->ResetConnection(); +} + +int64_t HichainAdapter::GenRequestId() +{ + int64_t requestId = 0; + do { + requestId = (int64_t)requestIdIndex_ + MIN_REQUEST_ID; + if (requestId > MAX_REQUEST_ID) { + requestId = MIN_REQUEST_ID; + requestIdIndex_ = 0; + } else { + requestIdIndex_++; + } + } while (clientBindReqMap_.count(requestId) != 0); + return requestId; +} + +void HichainAdapter::OnBindFailed(int64_t requestId, int32_t errorCode) +{ + HILOGI("HichainAdapter::OnBindFailed requestId:%{public}lld, errorCode:%{public}d.", requestId, errorCode); + if (bindCallBackMap_.count(requestId) == 1) { + bindCallBackMap_[requestId]->onBindFailed(bindingDeviceMap_[requestId], errorCode); + bindCallBackMap_.erase(requestId); + } + + if (clientBindReqMap_.count(requestId) == 1) { + clientBindReqMap_[requestId].reset(); + clientBindReqMap_.erase(requestId); + } + + if (bindingDeviceMap_.count(requestId) == 1) { + bindingDeviceMap_.erase(requestId); + } +} + +void HichainAdapter::UnBind(const std::string& deviceId) +{ + // reserved interface, to be implemented + (void)deviceId; +} + +void HichainAdapter::OnUnBindFinished() +{ + // reserved interface, to be implemented +} + +bool HichainAuthCallBack::onTransmit(int64_t requestId, const uint8_t *data, uint32_t dataLen) +{ + HILOGI("HichainAuthCallBack::onTransmit requestId:%{public}lld,size:%{public}d.", requestId, dataLen); + return HichainAdapter::GetInstance().OnTransmit(requestId, data, dataLen); +} + +void HichainAuthCallBack::onSessionKeyReturned(int64_t requestId, const uint8_t *sessionKey, uint32_t sessionKeyLen) +{ + (void)requestId; + (void)sessionKey; + HILOGI("HichainAuthCallBack::onSessionKeyReturned size:%{public}d.", sessionKeyLen); +} + +void HichainAuthCallBack::onFinish(int64_t requestId, int operationCode, const char *returnData) +{ + HILOGI("HichainAuthCallBack::onFinish reqId:%{public}lld, operation:%{public}d.", requestId, operationCode); + if (operationCode == GroupOperationCode::GROUP_CREATE) { + HichainAdapter::GetInstance().OnGroupCreated(requestId, returnData); + return; + } + + if (operationCode == GroupOperationCode::MEMBER_INVITE || operationCode == GroupOperationCode::MEMBER_JOIN) { + HichainAdapter::GetInstance().OnBindSuccess(requestId, returnData); + } +} + +void HichainAuthCallBack::onError(int64_t requestId, int operationCode, int errorCode, const char *errorReturn) +{ + (void)errorReturn; + HILOGI("HichainAuthCallBack::onError reqId:%{public}lld, operation:%{public}d, errorCode:%{public}d.", + requestId, operationCode, errorCode); + HichainAdapter::GetInstance().OnBindFailed(requestId, errorCode); +} + +char* HichainAuthCallBack::onBindRequest(int64_t requestId, int operationCode, const char *reqParams) +{ + HILOGI("HichainAuthCallBack::onBindRequest reqId:%{public}lld, operation:%{public}d.", requestId, operationCode); + return HichainAdapter::GetInstance().OnBindRequest(requestId, operationCode, reqParams); +} +} +} \ No newline at end of file diff --git a/services/devicemanagerservice/src/device_manager_listener_proxy.cpp b/services/devicemanagerservice/src/device_manager_listener_proxy.cpp new file mode 100644 index 000000000..d721ef705 --- /dev/null +++ b/services/devicemanagerservice/src/device_manager_listener_proxy.cpp @@ -0,0 +1,294 @@ +/* + * 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_manager_listener_proxy.h" + +#include "ipc_types.h" + +#include "device_manager_log.h" + +namespace OHOS { +namespace DistributedHardware { +bool DeviceManagerListenerProxy::WriteInterfaceToken(MessageParcel &data) +{ + if (!data.WriteInterfaceToken(DeviceManagerListenerProxy::GetDescriptor())) { + HILOGE("write interface token failed"); + return false; + } + return true; +} + +int32_t DeviceManagerListenerProxy::OnDeviceOnline(std::string &packageName, const DmDeviceInfo &deviceInfo) +{ + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("remote service null"); + return ERR_NULL_OBJECT; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!WriteInterfaceToken(data)) { + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteString(packageName)) { + HILOGE("write packageName failed"); + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteParcelable(&deviceInfo)) { + HILOGE("write deviceInfo failed"); + return ERR_FLATTEN_OBJECT; + } + + int32_t error = remote->SendRequest(ON_DEVICE_ONLINE, data, reply, option); + if (error != ERR_NONE) { + HILOGE("OnDeviceOnline SendRequest fail, error: %{public}d", error); + return error; + } + + return ERR_NONE; +} + +int32_t DeviceManagerListenerProxy::OnDeviceOffline(std::string &packageName, const DmDeviceInfo &deviceInfo) +{ + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("remote service null"); + return ERR_NULL_OBJECT; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!WriteInterfaceToken(data)) { + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteString(packageName)) { + HILOGE("write packageName failed"); + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteParcelable(&deviceInfo)) { + HILOGE("write deviceInfo failed"); + return ERR_FLATTEN_OBJECT; + } + + int32_t error = remote->SendRequest(ON_DEVICE_OFFLINE, data, reply, option); + if (error != ERR_NONE) { + HILOGE("OnDeviceOffline SendRequest fail, error: %{public}d", error); + return error; + } + + return ERR_NONE; +} + +int32_t DeviceManagerListenerProxy::OnDeviceChanged(std::string &packageName, const DmDeviceInfo &deviceInfo) +{ + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("remote service null"); + return ERR_NULL_OBJECT; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!WriteInterfaceToken(data)) { + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteString(packageName)) { + HILOGE("write packageName failed"); + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteParcelable(&deviceInfo)) { + HILOGE("write deviceInfo failed"); + return ERR_FLATTEN_OBJECT; + } + + int32_t error = remote->SendRequest(ON_DEVICE_CHANGE, data, reply, option); + if (error != ERR_NONE) { + HILOGE("OnDeviceChanged SendRequest fail, error: %{public}d", error); + return error; + } + + return ERR_NONE; +} + +int32_t DeviceManagerListenerProxy::OnDeviceFound(std::string &packageName, uint16_t subscribeId, + const DmDeviceInfo &deviceInfo) +{ + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("remote service null"); + return ERR_NULL_OBJECT; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!WriteInterfaceToken(data)) { + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteString(packageName)) { + HILOGE("write packageName failed"); + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteInt16(subscribeId)) { + HILOGE("write subscribeId failed"); + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteParcelable(&deviceInfo)) { + HILOGE("write deviceInfo failed"); + return ERR_FLATTEN_OBJECT; + } + + int32_t error = remote->SendRequest(ON_DEVICE_FOUND, data, reply, option); + if (error != ERR_NONE) { + HILOGE("OnDeviceFound SendRequest fail, error: %{public}d", error); + return error; + } + + return ERR_NONE; +} + +int32_t DeviceManagerListenerProxy::OnDiscoverFailed(std::string &packageName, uint16_t subscribeId, + int32_t failedReason) +{ + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("remote service null"); + return ERR_NULL_OBJECT; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!WriteInterfaceToken(data)) { + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteString(packageName)) { + HILOGE("write packageName failed"); + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteInt16(subscribeId)) { + HILOGE("write subscribeId failed"); + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteInt32(failedReason)) { + HILOGE("write packageName failed"); + return ERR_FLATTEN_OBJECT; + } + + int32_t error = remote->SendRequest(ON_DISCOVER_FAILED, data, reply, option); + if (error != ERR_NONE) { + HILOGE("OnDiscoverFailed SendRequest fail, error: %{public}d", error); + return error; + } + + return ERR_NONE; +} + +int32_t DeviceManagerListenerProxy::OnDiscoverySuccess(std::string &packageName, uint16_t subscribeId) +{ + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("remote service null"); + return ERR_NULL_OBJECT; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!WriteInterfaceToken(data)) { + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteString(packageName)) { + HILOGE("write packageName failed"); + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteInt16(subscribeId)) { + HILOGE("write subscribeId failed"); + return ERR_FLATTEN_OBJECT; + } + + int32_t error = remote->SendRequest(ON_DISCOVER_SUCCESS, data, reply, option); + if (error != ERR_NONE) { + HILOGE("OnDiscoverySuccess SendRequest fail, error: %{public}d", error); + return error; + } + + return ERR_NONE; +} + +int32_t DeviceManagerListenerProxy::OnAuthResult(std::string &packageName, std::string &deviceId, int32_t status, + int32_t reason) +{ + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("remote service null"); + return ERR_NULL_OBJECT; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!WriteInterfaceToken(data)) { + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteString(packageName)) { + HILOGE("write packageName failed"); + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteString(deviceId)) { + HILOGE("write packageName failed"); + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteInt32(status)) { + HILOGE("write status failed"); + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteInt32(reason)) { + HILOGE("write reason failed"); + return ERR_FLATTEN_OBJECT; + } + + int32_t error = remote->SendRequest(ON_AUTH_RESULT, data, reply, option); + if (error != ERR_NONE) { + HILOGE("OnAuthResult SendRequest fail, error: %{public}d", error); + return error; + } + + return ERR_NONE; +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/services/devicemanagerservice/src/device_manager_service.cpp b/services/devicemanagerservice/src/device_manager_service.cpp new file mode 100644 index 000000000..80cbd3616 --- /dev/null +++ b/services/devicemanagerservice/src/device_manager_service.cpp @@ -0,0 +1,280 @@ +/* + * 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_manager_service.h" + +#include "if_system_ability_manager.h" +#include "ipc_skeleton.h" +#include "ipc_types.h" +#include "iservice_registry.h" +#include "string_ex.h" +#include "system_ability_definition.h" + +#include "anonymous_string.h" +#include "device_manager_log.h" +#include "softbus_adapter.h" + +#include "hichain_adapter.h" + +namespace OHOS { +namespace DistributedHardware { +namespace { + const int32_t THREAD_POOL_TASK_NUM = 1; +} + +IMPLEMENT_SINGLE_INSTANCE(DeviceManagerService); + +const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(&DeviceManagerService::GetInstance()); + +DeviceManagerService::DeviceManagerService() : SystemAbility(DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID, true) +{ + registerToService_ = false; + state_ = ServiceRunningState::STATE_NOT_START; + hichainBindCallback_ = std::make_shared(); +} + +void DeviceManagerService::OnStart() +{ + HILOGI("DeviceManagerService::OnStart start"); + if (state_ == ServiceRunningState::STATE_RUNNING) { + HILOGD("DeviceManagerService has already started."); + return; + } + if (!Init()) { + HILOGE("failed to init DeviceManagerService"); + return; + } + state_ = ServiceRunningState::STATE_RUNNING; +} + +bool DeviceManagerService::Init() +{ + HILOGI("DeviceManagerService::Init ready to init."); + if (!registerToService_) { + bool ret = Publish(this); + if (!ret) { + HILOGE("DeviceManagerService::Init Publish failed!"); + return false; + } + registerToService_ = true; + } + if (threadPool_.GetThreadsNum() == 0) { + threadPool_.Start(THREAD_POOL_TASK_NUM); + } + RegisterDeviceStateListener(); + return true; +} + +void DeviceManagerService::OnStop() +{ + HILOGI("DeviceManagerService::OnStop ready to stop service."); + state_ = ServiceRunningState::STATE_NOT_START; + registerToService_ = false; +} + +ServiceRunningState DeviceManagerService::QueryServiceState() const +{ + return state_; +} + +void DeviceManagerService::RegisterDeviceStateListener() +{ + auto registerFunc = []() { + SoftbusAdapter::GetInstance().RegSoftBusDeviceStateListener(); + HichainAdapter::GetInstance().Init(); + }; + threadPool_.AddTask(registerFunc); +} + +int32_t DeviceManagerService::RegisterDeviceManagerListener(std::string &packageName, sptr listener) +{ + if (packageName.empty() || listener == nullptr) { + HILOGE("Error: parameter invalid"); + return ERR_NULL_OBJECT; + } + + HILOGI("In, packageName: %{public}s", packageName.c_str()); + std::lock_guard autoLock(listenerLock_); + auto iter = dmListener_.find(packageName); + if (iter != dmListener_.end()) { + HILOGI("RegisterDeviceManagerListener: listener already exists"); + return ERR_NONE; + } + + sptr appRecipient = sptr(new AppDeathRecipient()); + if (!listener->AddDeathRecipient(appRecipient)) { + HILOGE("RegisterDeviceManagerListener: AddDeathRecipient Failed"); + } + dmListener_[packageName] = listener; + appRecipient_[packageName] = appRecipient; + return ERR_NONE; +} + +int32_t DeviceManagerService::UnRegisterDeviceManagerListener(std::string &packageName) +{ + if (packageName.empty()) { + HILOGE("Error: parameter invalid"); + return ERR_NULL_OBJECT; + } + + HILOGI("In, packageName: %{public}s", packageName.c_str()); + std::lock_guard autoLock(listenerLock_); + auto listenerIter = dmListener_.find(packageName); + if (listenerIter == dmListener_.end()) { + HILOGI("UnRegisterDeviceManagerListener: listener not exists"); + return ERR_NONE; + } + + auto recipientIter = appRecipient_.find(packageName); + if (recipientIter == appRecipient_.end()) { + HILOGI("UnRegisterDeviceManagerListener: appRecipient not exists"); + dmListener_.erase(packageName); + return ERR_NONE; + } + + auto listener = listenerIter->second; + auto appRecipient = recipientIter->second; + listener->RemoveDeathRecipient(appRecipient); + appRecipient_.erase(packageName); + dmListener_.erase(packageName); + return ERR_NONE; +} + +int32_t DeviceManagerService::RegisterDeviceStateCallback(std::string &packageName, std::string &extra) +{ + HILOGI("In, packageName: %{public}s", packageName.c_str()); + devStateCallbackParas_[packageName] = extra; + return ERR_NONE; +} + +int32_t DeviceManagerService::UnRegisterDeviceStateCallback(std::string &packageName) +{ + HILOGI("In, packageName: %{public}s", packageName.c_str()); + devStateCallbackParas_.erase(packageName); + return ERR_NONE; +} + +int32_t DeviceManagerService::GetTrustedDeviceList(std::string &packageName, std::string &extra, + std::vector &deviceList) +{ + HILOGI("In, packageName: %{public}s", packageName.c_str()); + return SoftbusAdapter::GetSoftbusTrustDevices(packageName, extra, deviceList); +} + +int32_t DeviceManagerService::StartDeviceDiscovery(std::string &packageName, DmSubscribeInfo &subscribeInfo) +{ + HILOGI("In, packageName: %{public}s, subscribeId %{public}d", packageName.c_str(), + (int32_t)subscribeInfo.subscribeId); + return SoftbusAdapter::GetInstance().StartSoftbusDiscovery(packageName, subscribeInfo); +} + +int32_t DeviceManagerService::StopDeviceDiscovery(std::string &packageName, uint16_t subscribeId) +{ + HILOGI("In, packageName: %{public}s, subscribeId %{public}d", packageName.c_str(), (int32_t)subscribeId); + return SoftbusAdapter::GetInstance().StopSoftbusDiscovery(packageName, subscribeId); +} + +int32_t DeviceManagerService::AuthenticateDevice(std::string &packageName, const DmDeviceInfo &deviceInfo, + std::string &extra) +{ + (void)extra; + DeviceReqInfo devReqInfo; + devReqInfo.deviceId = deviceInfo.deviceId; + HILOGI("AuthenticateDevice In, packageName: %{public}s, deviceId %{public}s", packageName.c_str(), + GetAnonyString(deviceInfo.deviceId).c_str()); + int32_t ret = SoftbusAdapter::GetInstance().GetConnectionIpAddr(deviceInfo.deviceId, devReqInfo.ipAddr); + if (ret != ERR_OK) { + HILOGE("AuthenticateDevice Error: can not find ip by deviceId."); + return ret; + } + + authCallbackParas_[deviceInfo.deviceId] = packageName; + return HichainAdapter::GetInstance().Bind(devReqInfo, hichainBindCallback_, false); +} + +const std::map>& DeviceManagerService::GetDmListener() +{ + return dmListener_; +} + +const sptr DeviceManagerService::GetDmListener(std::string packageName) const +{ + auto iter = dmListener_.find(packageName); + if (iter == dmListener_.end()) { + return nullptr; + } + auto remote = iter->second; + sptr dmListener = iface_cast(remote); + return dmListener; +} + +void AppDeathRecipient::OnRemoteDied(const wptr& remote) +{ + HILOGW("AppDeathRecipient: OnRemoteDied"); + std::map> listeners = DeviceManagerService::GetInstance().GetDmListener(); + std::string packageName; + for (auto iter : listeners) { + if (iter.second == remote.promote()) { + packageName = iter.first; + break; + } + } + + if (packageName.empty()) { + HILOGE("AppDeathRecipient: OnRemoteDied, no packageName matched"); + return; + } + + HILOGI("AppDeathRecipient: OnRemoteDied for %{public}s", packageName.c_str()); + DeviceManagerService::GetInstance().UnRegisterDeviceManagerListener(packageName); +} + + +void HiChainBindCallback::onBindSuccess(std::string deviceId, const char *returnData) +{ + (void)returnData; + HILOGI("onBindSuccess, DM bind succeed, deviceId: %{public}s", GetAnonyString(deviceId).c_str()); + auto res = DeviceManagerService::GetInstance().authCallbackParas_; + auto iter = res.find(deviceId); + if (iter == res.end()) { + HILOGE("onBindSuccess deviceInfo not found by deviceId."); + return; + } + + std::string packageName = iter->second; + sptr dmListener = DeviceManagerService::GetInstance().GetDmListener(packageName); + dmListener->OnAuthResult(packageName, deviceId, DmBindStatus::STATE_BIND_SUCCESS, ERR_NONE); + int32_t ret = SoftbusAdapter::GetInstance().SoftbusJoinLnn(deviceId); + HILOGI("onBindSuccess, DM bind succeed, joinlnn ret=%{public}d.", ret); +} + +void HiChainBindCallback::onBindFailed(std::string deviceId, int32_t errorCode) +{ + HILOGI("onBindFailed, DM bind failed, deviceId: %{public}s, errorCode: %{public}d", + GetAnonyString(deviceId).c_str(), errorCode); + auto res = DeviceManagerService::GetInstance().authCallbackParas_; + auto iter = res.find(deviceId); + if (iter == res.end()) { + HILOGE("onBindFailed deviceInfo not found by deviceId."); + return; + } + + std::string packageName = iter->second; + sptr dmListener = DeviceManagerService::GetInstance().GetDmListener(packageName); + + dmListener->OnAuthResult(packageName, deviceId, DmBindStatus::STATE_BIND_FAILD, errorCode); +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/services/devicemanagerservice/src/device_manager_stub.cpp b/services/devicemanagerservice/src/device_manager_stub.cpp new file mode 100644 index 000000000..9ab1bf5ca --- /dev/null +++ b/services/devicemanagerservice/src/device_manager_stub.cpp @@ -0,0 +1,205 @@ +/* + * 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_manager_stub.h" + +#include "ipc_skeleton.h" +#include "ipc_types.h" + + +#include "device_manager_log.h" + +using namespace std; + +namespace OHOS { +namespace DistributedHardware { +DeviceManagerStub::DeviceManagerStub() +{ + memberFuncMap_[GET_TRUST_DEVICE_LIST] = &DeviceManagerStub::GetTrustedDeviceListInner; + memberFuncMap_[REGISTER_DEVICE_MANAGER_LISTENER] = &DeviceManagerStub::RegisterDeviceManagerListenerInner; + memberFuncMap_[UNREGISTER_DEVICE_MANAGER_LISTENER] = &DeviceManagerStub::UnRegisterDeviceManagerListenerInner; + memberFuncMap_[REGISTER_DEVICE_STATE_CALLBACK] = &DeviceManagerStub::RegisterDeviceStateCallbackInner; + memberFuncMap_[UNREGISTER_DEVICE_STATE_CALLBACK] = &DeviceManagerStub::UnRegisterDeviceStateCallbackInner; + memberFuncMap_[START_DEVICE_DISCOVER] = &DeviceManagerStub::StartDeviceDiscoveryInner; + memberFuncMap_[STOP_DEVICE_DISCOVER] = &DeviceManagerStub::StopDeviceDiscoveryInner; + memberFuncMap_[AUTHENTICATE_DEVICE] = &DeviceManagerStub::AuthenticateDeviceInner; +} + +DeviceManagerStub::~DeviceManagerStub() +{ + memberFuncMap_.clear(); +} + +int32_t DeviceManagerStub::OnRemoteRequest(uint32_t code, + MessageParcel& data, MessageParcel &reply, MessageOption &option) +{ + HILOGI("code = %{public}d, flags= %{public}d.", code, option.GetFlags()); + auto itFunc = memberFuncMap_.find(code); + if (itFunc != memberFuncMap_.end()) { + auto memberFunc = itFunc->second; + if (memberFunc != nullptr) { + if (!EnforceInterceToken(data)) { + HILOGE("interface token check failed!"); + return ERR_INVALID_STATE; + } + return (this->*memberFunc)(data, reply); + } + } + HILOGW("unsupport code: %{public}d", code); + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); +} + +int32_t DeviceManagerStub::RegisterDeviceManagerListenerInner(MessageParcel& data, MessageParcel& reply) +{ + string packageName = data.ReadString(); + sptr listener = data.ReadRemoteObject(); + int32_t result = RegisterDeviceManagerListener(packageName, listener); + if (!reply.WriteInt32(result)) { + HILOGE("write result failed"); + return ERR_INVALID_VALUE; + } + return ERR_NONE; +} + +int32_t DeviceManagerStub::UnRegisterDeviceManagerListenerInner(MessageParcel& data, MessageParcel& reply) +{ + string packageName = data.ReadString(); + int32_t result = UnRegisterDeviceManagerListener(packageName); + if (!reply.WriteInt32(result)) { + HILOGE("write result failed"); + return ERR_INVALID_VALUE; + } + return ERR_NONE; +} + +int32_t DeviceManagerStub::RegisterDeviceStateCallbackInner(MessageParcel& data, MessageParcel& reply) +{ + string packageName = data.ReadString(); + string extra = data.ReadString(); + HILOGI("packageName:%{public}s, extra:%{public}s", packageName.c_str(), extra.c_str()); + int32_t result = RegisterDeviceStateCallback(packageName, extra); + if (!reply.WriteInt32(result)) { + HILOGE("write result failed"); + return ERR_INVALID_VALUE; + } + return ERR_NONE; +} + +int32_t DeviceManagerStub::UnRegisterDeviceStateCallbackInner(MessageParcel& data, MessageParcel& reply) +{ + string packageName = data.ReadString(); + HILOGI("packageName:%{public}s", packageName.c_str()); + int32_t result = UnRegisterDeviceStateCallback(packageName); + if (!reply.WriteInt32(result)) { + HILOGE("write result failed"); + return ERR_INVALID_VALUE; + } + return ERR_NONE; +} + +int32_t DeviceManagerStub::GetTrustedDeviceListInner(MessageParcel& data, MessageParcel& reply) +{ + string packageName = data.ReadString(); + string extra = data.ReadString(); + HILOGI("packageName:%{public}s, extra:%{public}s", packageName.c_str(), extra.c_str()); + std::vector devInfos; + int32_t result = GetTrustedDeviceList(packageName, extra, devInfos); + reply.WriteInt32(devInfos.size()); + for (auto &it : devInfos) { + if (!reply.WriteParcelable(&it)) { + return ERR_INVALID_VALUE; + } + } + if (!reply.WriteInt32(result)) { + HILOGE("write result failed"); + return ERR_INVALID_VALUE; + } + return ERR_NONE; +} + +template +int32_t DeviceManagerStub::GetParcelableInfo(MessageParcel &reply, T &parcelableInfo) +{ + std::unique_ptr info(reply.ReadParcelable()); + if (!info) { + HILOGE("readParcelableInfo failed"); + return ERR_INVALID_VALUE; + } + parcelableInfo = *info; + return ERR_NONE; +} + +int32_t DeviceManagerStub::StartDeviceDiscoveryInner(MessageParcel& data, MessageParcel& reply) +{ + string packageName = data.ReadString(); + DmSubscribeInfo subscribeInfo; + int32_t result = GetParcelableInfo(data, subscribeInfo); + if (result != ERR_NONE) { + HILOGE("GetParcelableInfo fail, result: %{public}d", result); + reply.WriteInt32(result); + return result; + } + + HILOGI("packageName:%{public}s, subscribeId: %{public}d", packageName.c_str(), subscribeInfo.subscribeId); + result = StartDeviceDiscovery(packageName, subscribeInfo); + if (!reply.WriteInt32(result)) { + HILOGE("write result failed"); + return ERR_INVALID_VALUE; + } + return ERR_NONE; +} + +int32_t DeviceManagerStub::StopDeviceDiscoveryInner(MessageParcel& data, MessageParcel& reply) +{ + string packageName = data.ReadString(); + uint16_t subscribeId = data.ReadInt32(); + HILOGI("packageName:%{public}s, subscribeId: %{public}d", packageName.c_str(), subscribeId); + int32_t result = StopDeviceDiscovery(packageName, subscribeId); + if (!reply.WriteInt32(result)) { + HILOGE("write result failed"); + return ERR_INVALID_VALUE; + } + return ERR_NONE; +} + +int32_t DeviceManagerStub::AuthenticateDeviceInner(MessageParcel& data, MessageParcel& reply) +{ + string packageName = data.ReadString(); + DmDeviceInfo deviceInfo; + int32_t result = GetParcelableInfo(data, deviceInfo); + if (result != ERR_NONE) { + HILOGE("GetParcelableInfo fail, result: %{public}d", result); + reply.WriteInt32(result); + return result; + } + + string extra = data.ReadString(); + HILOGI("packageName:%{public}s, extra:%{public}s", packageName.c_str(), extra.c_str()); + result = AuthenticateDevice(packageName, deviceInfo, extra); + if (!reply.WriteInt32(result)) { + HILOGE("write result failed"); + return ERR_INVALID_VALUE; + } + return ERR_NONE; +} + +bool DeviceManagerStub::EnforceInterceToken(MessageParcel& data) +{ + u16string interfaceToken = data.ReadInterfaceToken(); + u16string descriptor = DeviceManagerStub::GetDescriptor(); + return interfaceToken == descriptor; +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/services/devicemanagerservice/src/softbus/softbus_adapter.cpp b/services/devicemanagerservice/src/softbus/softbus_adapter.cpp new file mode 100644 index 000000000..17f72e881 --- /dev/null +++ b/services/devicemanagerservice/src/softbus/softbus_adapter.cpp @@ -0,0 +1,524 @@ +/* + * 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 "softbus_adapter.h" + +#include +#include +#include +#include + +#include + +#include "dm_device_info.h" + +#include "anonymous_string.h" +#include "device_manager_errno.h" +#include "device_manager_log.h" +#include "device_manager_service.h" + +namespace OHOS { +namespace DistributedHardware { +namespace { +const std::string DEVICE_MANAGER_PACKAGE_NAME = "ohos.distributedhardware.devicemanager"; +const int32_t CHECK_INTERVAL = 100000; // 100ms +const int32_t SUBSCRIBE_ID_PREFIX_LEN = 16; +const int32_t SUBSCRIBE_ID_MASK = 0x0000FFFF; +const int32_t DISCOVER_DEVICEINFO_MAX_SIZE = 20; +} + +IMPLEMENT_SINGLE_INSTANCE(SoftbusAdapter); +void SoftbusAdapter::OnSoftBusDeviceOnline(NodeBasicInfo *info) +{ + if (info == nullptr) { + HILOGE("SoftbusAdapter::OnSoftBusDeviceOnline NodeBasicInfo is nullptr"); + return; + } + + std::string networkId = info->networkId; + HILOGI("device online, networkId: %{public}s", GetAnonyString(networkId).c_str()); + OnSoftBusDeviceStateChange(DmDeviceState::DEVICE_STATE_ONLINE, info); + + uint8_t udid[UDID_BUF_LEN] = {0}; + int32_t ret = GetNodeKeyInfo(DEVICE_MANAGER_PACKAGE_NAME.c_str(), info->networkId, + NodeDeivceInfoKey::NODE_KEY_UDID, udid, sizeof(udid)); + if (ret != ERR_OK) { + HILOGE("GetNodeKeyInfo failed"); + return; + } + std::string deviceId = (char *)udid; + SoftbusAdapter::GetInstance().RemoveDiscoverDeviceInfo(deviceId); +} + +void SoftbusAdapter::OnSoftbusDeviceOffline(NodeBasicInfo *info) +{ + if (info == nullptr) { + HILOGE("SoftbusAdapter::OnSoftbusDeviceOffline NodeBasicInfo is nullptr"); + return; + } + + std::string networkId = info->networkId; + HILOGI("device offline, networkId: %{public}s", GetAnonyString(networkId).c_str()); + OnSoftBusDeviceStateChange(DmDeviceState::DEVICE_STATE_OFFLINE, info); +} + +void SoftbusAdapter::OnSoftBusDeviceStateChange(DmDeviceState state, NodeBasicInfo *info) +{ + DmDeviceInfo deviceInfo; + deviceInfo.deviceId = info->networkId; + deviceInfo.deviceName = info->deviceName; + deviceInfo.deviceTypeId = (DMDeviceType)info->deviceTypeId; + + std::map> listeners = DeviceManagerService::GetInstance().GetDmListener(); + for (auto iter : listeners) { + auto packageName = iter.first; + auto remote = iter.second; + sptr dmListener = iface_cast(remote); + if (state == DmDeviceState::DEVICE_STATE_ONLINE) { + HILOGI("SoftbusAdapter::OnSoftBusDeviceStateChange listenr handle device online."); + dmListener->OnDeviceOnline(packageName, deviceInfo); + } else { + HILOGI("SoftbusAdapter::OnSoftBusDeviceStateChange listenr handle device offline."); + dmListener->OnDeviceOffline(packageName, deviceInfo); + } + } +} + +void SoftbusAdapter::OnSoftbusDeviceInfoChanged(NodeBasicInfoType type, NodeBasicInfo *info) +{ + HILOGI("SoftbusAdapter::OnSoftbusDeviceInfoChanged."); + // currently do nothing + (void)type; + (void)info; +} + +void SoftbusAdapter::OnSoftbusDeviceFound(const DeviceInfo *device) +{ + if (device == nullptr) { + HILOGE("deviceinfo is null"); + return; + } + + std::string deviceId = device->devId; + HILOGI("SoftbusAdapter::OnSoftbusDeviceFound device %{public}s found.", GetAnonyString(deviceId).c_str()); + if (IsDeviceOnLine(deviceId)) { + return; + } + + SoftbusAdapter::GetInstance().SaveDiscoverDeviceInfo(device); + DmDeviceInfo deviceInfo; + deviceInfo.deviceId = deviceId; + deviceInfo.deviceName = device->devName; + deviceInfo.deviceTypeId = (DMDeviceType)device->devType; + + // currently, only care ddmpCapability + if (!((device->capabilityBitmap[0] >> DDMP_CAPABILITY_BITMAP) & 0x1)) { + HILOGE("capBitmap Invalid, not contain ddmpCap"); + return; + } + + auto subscribeInfos = SoftbusAdapter::GetInstance().GetsubscribeInfos(); + for (auto iter = subscribeInfos.begin(); iter != subscribeInfos.end(); iter++) { + auto subInfovector = iter->second; + for (auto vectorIter = subInfovector.begin(); vectorIter != subInfovector.end(); ++vectorIter) { + auto info = vectorIter->get(); + HILOGI("subscribe info capability:%{public}s.", info->info.capability); + if (strcmp(DM_CAPABILITY_DDMP.c_str(), info->info.capability) != 0) { + HILOGE("subscribe info capability invalid."); + } + std::string packageName = iter->first; + sptr listener = DeviceManagerService::GetInstance().GetDmListener(packageName); + if (listener == nullptr) { + HILOGI("cannot get listener for package:%{public}s.", packageName.c_str()); + continue; + } + + uint16_t originId = (uint16_t)(((uint32_t)info->info.subscribeId) & SUBSCRIBE_ID_MASK); + HILOGI("call OnDeviceFound for %{public}s, originId %{public}d, deviceId %{public}s", + packageName.c_str(), originId, GetAnonyString(deviceInfo.deviceId).c_str()); + listener->OnDeviceFound(packageName, originId, deviceInfo); + } + } +} + +void SoftbusAdapter::OnSoftbusDiscoverFailed(int subscribeId, DiscoveryFailReason failReason) +{ + HILOGI("In, subscribeId %{public}d, failReason %{public}d", subscribeId, (int32_t)failReason); + std::string packageName; + if (!SoftbusAdapter::GetInstance().GetPackageNameBySubscribeId(subscribeId, packageName)) { + HILOGE("OnSoftbusDiscoverFailed: packageName not found"); + return; + } + sptr listener = DeviceManagerService::GetInstance().GetDmListener(packageName); + if (listener == nullptr) { + HILOGE("OnSoftbusDiscoverFailed: listener not found for packageName %{public}s", packageName.c_str()); + return; + } + uint16_t originId = (uint16_t)(((uint32_t)subscribeId) & SUBSCRIBE_ID_MASK); + listener->OnDiscoverFailed(packageName, originId, (int32_t)failReason); +} + +void SoftbusAdapter::OnSoftbusDiscoverySuccess(int subscribeId) +{ + HILOGI("In, subscribeId %{public}d", subscribeId); + std::string packageName; + if (!SoftbusAdapter::GetInstance().GetPackageNameBySubscribeId(subscribeId, packageName)) { + HILOGE("OnSoftbusDiscoverySuccess: packageName not found"); + return; + } + sptr listener = DeviceManagerService::GetInstance().GetDmListener(packageName); + if (listener == nullptr) { + HILOGE("OnSoftbusDiscoverySuccess: listener not found for packageName %{public}s", packageName.c_str()); + return; + } + uint16_t originId = (uint16_t)(((uint32_t)subscribeId) & SUBSCRIBE_ID_MASK); + listener->OnDiscoverySuccess(packageName, originId); +} + +void SoftbusAdapter::OnSoftbusJoinLNNResult(ConnectionAddr *addr, const char *networkId, int32_t retCode) +{ + (void)addr; + if (retCode != 0) { + HILOGE("OnSoftbusJoinLNNResult: failed, retCode %{public}d", retCode); + return; + } + + if (networkId == nullptr) { + HILOGE("OnSoftbusJoinLNNResult: success, but networkId is nullptr"); + return; + } + + std::string netIdStr = networkId; + HILOGI("OnSoftbusJoinLNNResult: success, networkId %{public}s, retCode %{public}d", + GetAnonyString(netIdStr).c_str(), retCode); +} + +void SoftbusAdapter::OnSoftbusLeaveLNNResult(const char *networkId, int32_t retCode) +{ + if (retCode != 0) { + HILOGE("OnSoftbusLeaveLNNResult: failed, retCode %{public}d", retCode); + return; + } + + if (networkId == nullptr) { + HILOGE("OnSoftbusLeaveLNNResult: success, but networkId is nullptr"); + return; + } + + std::string netIdStr = networkId; + HILOGI("OnSoftbusLeaveLNNResult: success, networkId %{public}s, retCode %{public}d", + GetAnonyString(netIdStr).c_str(), retCode); +} + +int32_t SoftbusAdapter::GetSoftbusTrustDevices(const std::string &packageName, std::string &extra, + std::vector &deviceList) +{ + // extra not used yet + (void) packageName; + (void) extra; + + HILOGI("GetSoftbusTrustDevices start, packageName: %{public}s", packageName.c_str()); + NodeBasicInfo *info = nullptr; + int32_t infoNum = 0; + int32_t ret = GetAllNodeDeviceInfo(DEVICE_MANAGER_PACKAGE_NAME.c_str(), &info, &infoNum); + if (ret != 0) { + HILOGE("GetAllNodeDeviceInfo failed with ret %{public}d", ret); + return ret; + } + + for (int32_t i = 0; i < infoNum; i++) { + NodeBasicInfo *nodeBasicInfo = info + i; + if (nodeBasicInfo == nullptr) { + HILOGE("nodeBasicInfo is empty for index %{public}d, infoNum %{public}d.", i, infoNum); + continue; + } + DmDeviceInfo deviceInfo; + deviceInfo.deviceId = nodeBasicInfo->networkId; + deviceInfo.deviceName = nodeBasicInfo->deviceName; + deviceInfo.deviceTypeId = (DMDeviceType)nodeBasicInfo->deviceTypeId; + deviceList.push_back(deviceInfo); + } + FreeNodeInfo(info); + HILOGI("success, packageName: %{public}s, deviceCount %{public}d", packageName.c_str(), deviceList.size()); + return ERR_OK; +} + +bool SoftbusAdapter::IsDeviceOnLine(std::string &deviceId) +{ + std::vector deviceList; + std::string extra = ""; + if (GetSoftbusTrustDevices(DEVICE_MANAGER_PACKAGE_NAME, extra, deviceList) != ERR_OK) { + HILOGE("SoftbusAdapter::IsDeviceOnLine GetSoftbusTrustDevices failed"); + return false; + } + + for (auto iter = deviceList.begin(); iter != deviceList.end(); ++iter) { + std::string& networkId = iter->deviceId; + if (networkId == deviceId) { + HILOGI("SoftbusAdapter::IsDeviceOnLine devccie %{public}s online", GetAnonyString(deviceId).c_str()); + return true; + } + + uint8_t udid[UDID_BUF_LEN] = {0}; + int32_t ret = GetNodeKeyInfo(DEVICE_MANAGER_PACKAGE_NAME.c_str(), networkId.c_str(), + NodeDeivceInfoKey::NODE_KEY_UDID, udid, sizeof(udid)); + if (ret != ERR_OK) { + HILOGE("SoftbusAdapter::IsDeviceOnLine GetNodeKeyInfo failed"); + return false; + } + + if (strcmp((char *)udid, deviceId.c_str()) == 0) { + HILOGI("SoftbusAdapter::IsDeviceOnLine devccie %{public}s online", GetAnonyString(deviceId).c_str()); + return true; + } + } + return false; +} + +void SoftbusAdapter::RegSoftBusDeviceStateListener() +{ + int32_t ret; + int32_t retryTimes = 0; + do { + ret = RegNodeDeviceStateCb(DEVICE_MANAGER_PACKAGE_NAME.c_str(), &softbusNodeStateCb); + if (ret != ERR_OK) { + ++retryTimes; + HILOGE("RegNodeDeviceStateCb failed with ret %{public}d, retryTimes %{public}d", ret, retryTimes); + usleep(CHECK_INTERVAL); + } + } while (ret != ERR_OK); + HILOGI("RegNodeDeviceStateCb success."); +} + +int32_t SoftbusAdapter::StartSoftbusDiscovery(std::string &packageName, DmSubscribeInfo &info) +{ + std::shared_ptr subinfo = nullptr; + if (subscribeInfos_.find(packageName) == subscribeInfos_.end()) { + subscribeInfos_[packageName] = {}; + } + + auto iter = subscribeInfos_.find(packageName); + std::vector> &subinfoVector = iter->second; + auto vectorIter = subinfoVector.begin(); + for (; vectorIter != subinfoVector.end(); ++vectorIter) { + if (vectorIter->get()->subscribeIdOrigin == info.subscribeId) { + subinfo = *vectorIter; + break; + } + } + + if (subinfo == nullptr) { + subinfo = std::make_shared(); + subinfo->subscribeIdOrigin = info.subscribeId; + subinfo->subscribeIdPrefix = subscribeIdPrefix++; + subinfo->info.subscribeId = (subinfo->subscribeIdPrefix << SUBSCRIBE_ID_PREFIX_LEN) | info.subscribeId; + subinfo->info.mode = (DiscoverMode)info.mode; + subinfo->info.medium = (ExchanageMedium)info.medium; + subinfo->info.freq = (ExchangeFreq)info.freq; + subinfo->info.isSameAccount = info.isSameAccount; + subinfo->info.isWakeRemote = info.isWakeRemote; + subinfo->info.capability = info.capability.c_str(); + subinfo->info.capabilityData = nullptr; + subinfo->info.dataLen = 0; + } + + if (vectorIter == subinfoVector.end()) { + subinfoVector.push_back(subinfo); + } + + HILOGI("StartDiscovery, packageName: %{public}s, subscribeId %{public}d, prefix %{public}d, origin %{public}d", + packageName.c_str(), subinfo->info.subscribeId, subinfo->subscribeIdPrefix, subinfo->subscribeIdOrigin); + int ret = StartDiscovery(DEVICE_MANAGER_PACKAGE_NAME.c_str(), &subinfo->info, &softbusDiscoverCallback); + if (ret != ERR_OK) { + HILOGE("StartDiscovery failed with ret %{public}d.", ret); + } + return ret; +} + +bool SoftbusAdapter::GetPackageNameBySubscribeId(int32_t adapterId, std::string &packageName) +{ + for (auto iter = subscribeInfos_.begin(); iter != subscribeInfos_.end(); ++iter) { + std::vector> &subinfoVector = iter->second; + auto vectorIter = subinfoVector.begin(); + for (; vectorIter != subinfoVector.end(); ++vectorIter) { + if (vectorIter->get()->info.subscribeId == adapterId) { + packageName = iter->first; + return true; + } + } + } + return false; +} + +bool SoftbusAdapter::GetsubscribeIdAdapter(std::string packageName, int16_t originId, int32_t &adapterId) +{ + HILOGI("GetsubscribeIdAdapter in, packageName: %{public}s, originId:%{public}d", packageName.c_str(), + (int32_t)originId); + auto iter = subscribeInfos_.find(packageName); + if (iter == subscribeInfos_.end()) { + HILOGE("subscribeInfo not find for packageName: %{public}s", packageName.c_str()); + return false; + } + + std::vector> &subinfoVector = iter->second; + auto vectorIter = subinfoVector.begin(); + for (; vectorIter != subinfoVector.end(); ++vectorIter) { + if (vectorIter->get()->subscribeIdOrigin == originId) { + HILOGE("find adapterId:%{public}d for packageName: %{public}s, originId:%{public}d", + vectorIter->get()->info.subscribeId, packageName.c_str(), (int32_t)originId); + adapterId = vectorIter->get()->info.subscribeId; + return true; + } + } + HILOGE("subscribe not find. packageName: %{public}s, originId:%{public}d", packageName.c_str(), (int32_t)originId); + return false; +} + +int32_t SoftbusAdapter::StopSoftbusDiscovery(std::string &packageName, uint16_t subscribeId) +{ + int32_t subscribeIdAdapter = -1; + if (!GetsubscribeIdAdapter(packageName, subscribeId, subscribeIdAdapter)) { + HILOGE("StopDiscovery failed, subscribeId not match"); + return ERR_INVALID_OPERATION; + } + + HILOGI("StopDiscovery begin, packageName: %{public}s, subscribeId:%{public}d, subscribeIdAdapter:%{public}d", + packageName.c_str(), (int32_t)subscribeId, subscribeIdAdapter); + int ret = StopDiscovery(DEVICE_MANAGER_PACKAGE_NAME.c_str(), subscribeIdAdapter); + if (ret != ERR_OK) { + HILOGE("StopDiscovery failed with ret %{public}d", ret); + return ret; + } + + auto iter = subscribeInfos_.find(packageName); + auto subinfoVector = iter->second; + auto vectorIter = subinfoVector.begin(); + while (vectorIter != subinfoVector.end()) { + if (vectorIter->get()->subscribeIdOrigin == subscribeId) { + vectorIter = subinfoVector.erase(vectorIter); + break; + } else { + ++vectorIter; + } + } + if (subinfoVector.empty()) { + subscribeInfos_.erase(packageName); + } + HILOGI("SoftbusAdapter::StopSoftbusDiscovery completed, packageName: %{public}s", packageName.c_str()); + return ERR_OK; +} + +int32_t SoftbusAdapter::SoftbusJoinLnn(std::string devId) +{ + auto iter = discoverDeviceInfoMap_.find(devId); + if (iter == discoverDeviceInfoMap_.end()) { + HILOGE("SoftbusAdapter::SoftbusJoinLnn deviceInfo not found: %{public}s", GetAnonyString(devId).c_str()); + return ERR_INVALID_OPERATION; + } + + DeviceInfo *deviceInfo = iter->second.get(); + if (deviceInfo->addrNum <= 0 || deviceInfo->addrNum >= CONNECTION_ADDR_MAX) { + HILOGE("deviceInfo addrNum not valid, addrNum %{public}d", deviceInfo->addrNum); + return ERR_DEVICEMANAGER_OPERATION_FAILED; + } + + for (unsigned int i = 0; i < deviceInfo->addrNum; i++) { + // currently, only support CONNECT_ADDR_WLAN + if (deviceInfo->addr[i].type != ConnectionAddrType::CONNECTION_ADDR_WLAN && + deviceInfo->addr[i].type != ConnectionAddrType::CONNECTION_ADDR_ETH) { + continue; + } + + HILOGI("SoftbusAdapter::SoftbusJoinLnn call softbus JoinLNN."); + return JoinLNN(DEVICE_MANAGER_PACKAGE_NAME.c_str(), &deviceInfo->addr[i], OnSoftbusJoinLNNResult); + } + + return ERR_DEVICEMANAGER_OPERATION_FAILED; +} + +int32_t SoftbusAdapter::SoftbusLeaveLnn(std::string networkId) +{ + return LeaveLNN(networkId.c_str(), OnSoftbusLeaveLNNResult); +} + +int32_t SoftbusAdapter::GetConnectionIpAddr(std::string deviceId, std::string &ipAddr) +{ + auto iter = discoverDeviceInfoMap_.find(deviceId); + if (iter == discoverDeviceInfoMap_.end()) { + HILOGE("deviceInfo not found by deviceId %{public}s", GetAnonyString(deviceId).c_str()); + return ERR_INVALID_OPERATION; + } + + DeviceInfo *deviceInfo = iter->second.get(); + if (deviceInfo->addrNum <= 0 || deviceInfo->addrNum >= CONNECTION_ADDR_MAX) { + HILOGE("deviceInfo addrNum not valid, addrNum %{public}d", deviceInfo->addrNum); + return ERR_DEVICEMANAGER_OPERATION_FAILED; + } + + for (unsigned int i = 0; i < deviceInfo->addrNum; ++i) { + // currently, only support CONNECT_ADDR_WLAN + if (deviceInfo->addr[i].type != ConnectionAddrType::CONNECTION_ADDR_WLAN && + deviceInfo->addr[i].type != ConnectionAddrType::CONNECTION_ADDR_ETH) { + continue; + } + ipAddr = deviceInfo->addr[i].info.ip.ip; + HILOGI("SoftbusAdapter::GetConnectionIpAddr get ip ok."); + return ERR_OK; + } + HILOGE("failed to get ipAddr for deviceId %{public}s", GetAnonyString(deviceId).c_str()); + return ERR_DEVICEMANAGER_OPERATION_FAILED; +} + +const std::map>>& SoftbusAdapter::GetsubscribeInfos() +{ + return subscribeInfos_; +} + +void SoftbusAdapter::SaveDiscoverDeviceInfo(const DeviceInfo *deviceInfo) +{ + std::shared_ptr info = std::make_shared(); + DeviceInfo *infoPtr = info.get(); + if (memcpy_s(infoPtr, sizeof(DeviceInfo), deviceInfo, sizeof(DeviceInfo)) != 0) { + HILOGE("SoftbusAdapter::SaveDiscoverDeviceInfo failed."); + return; + } + + std::string deviceId = deviceInfo->devId; + discoverDeviceInfoMap_[deviceId] = info; + discoverDeviceInfoVector_.push_back(info); + + // Remove the earliest element when reached the max size + if (discoverDeviceInfoVector_.size() == DISCOVER_DEVICEINFO_MAX_SIZE) { + auto iter = discoverDeviceInfoVector_.begin(); + std::string delDevId = iter->get()->devId; + discoverDeviceInfoMap_.erase(delDevId); + discoverDeviceInfoVector_.erase(iter); + } +} + +void SoftbusAdapter::RemoveDiscoverDeviceInfo(const std::string deviceId) +{ + discoverDeviceInfoMap_.erase(deviceId); + auto iter = discoverDeviceInfoVector_.begin(); + while (iter != discoverDeviceInfoVector_.end()) { + if (strcmp(iter->get()->devId, deviceId.c_str()) == 0) { + iter = discoverDeviceInfoVector_.erase(iter); + } else { + ++iter; + } + } +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/services/devicemanagerservice/src/util/anonymous_string.cpp b/services/devicemanagerservice/src/util/anonymous_string.cpp new file mode 100644 index 000000000..69ed71a76 --- /dev/null +++ b/services/devicemanagerservice/src/util/anonymous_string.cpp @@ -0,0 +1,71 @@ +/* + * 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 "anonymous_string.h" + +#include "securec.h" + +namespace OHOS { +namespace DistributedHardware { +namespace { + const int INT32_STRING_LENGTH = 40; + const int INT32_SHORT_ID_LENGTH = 20; + const int INT32_PLAINTEXT_LENGTH = 4; + const int INT32_MIN_ID_LENGTH = 3; +} + +std::string GetAnonyString(const std::string &value) +{ + std::string res; + std::string tmpStr("******"); + int32_t strLen = value.length(); + if (strLen < INT32_MIN_ID_LENGTH) { + return tmpStr; + } + + if (strLen <= INT32_SHORT_ID_LENGTH) { + res += value[0]; + res += tmpStr; + res += value[strLen - 1]; + } else { + res.append(value, 0, INT32_PLAINTEXT_LENGTH); + res += tmpStr; + res.append(value, strLen - INT32_PLAINTEXT_LENGTH, INT32_PLAINTEXT_LENGTH); + } + + return res; +} + +std::string GetAnonyInt32(const int32_t value) +{ + char tempBuffer[INT32_STRING_LENGTH] = ""; + int32_t secRet = sprintf_s(tempBuffer, INT32_STRING_LENGTH, "%d", value); + if (secRet <= 0) { + std::string nullString(""); + return nullString; + } + int32_t length = strlen(tempBuffer); + for (int32_t i = 1; i < length - 1; i++) { + tempBuffer[i] = '*'; + } + if (length == 0x01) { + tempBuffer[0] = '*'; + } + + std::string tempSting(tempBuffer); + return tempSting; +} +} +} \ No newline at end of file -- Gitee