From 831b40a6dfdf30cc29c20ffc6076268f11472520 Mon Sep 17 00:00:00 2001 From: mamingshuai Date: Wed, 2 Jun 2021 00:03:17 +0800 Subject: [PATCH] update OpenHarmony 2.0 Canary --- .gitattributes | 15 + LICENSE | 177 +++++ README.en.md | 36 -- README.md | 153 ++++- README_zh.md | 140 ++++ common/BUILD.gn | 49 ++ .../account_error/include/account_error_no.h | 72 +++ common/log/include/account_log_wrapper.h | 67 ++ common/log/src/account_log_wrapper.cpp | 44 ++ common/perf_stat/include/perf_stat.h | 90 +++ common/perf_stat/src/perf_stat.cpp | 236 +++++++ common/test/BUILD.gn | 31 + .../unittest/common_account_log_test/BUILD.gn | 42 ++ .../account_log_test.cpp | 97 +++ .../common_account_perf_test/BUILD.gn | 45 ++ .../account_perf_stat_test.cpp | 161 +++++ figures/en-us_image_0000001123704367.png | Bin 0 -> 20706 bytes figures/zh-cn_image_0000001123704367.png | Bin 0 -> 17180 bytes interfaces/innerkits/account_kits_headers.gni | 23 + interfaces/innerkits/accountmgr/BUILD.gn | 62 ++ .../accountmgr/src/account_proxy.cpp | 132 ++++ .../accountmgr/src/ohos_account_kits.cpp | 26 + .../accountmgr/src/ohos_account_kits_impl.cpp | 148 +++++ interfaces/innerkits/include/account_info.h | 124 ++++ .../innerkits/include/device_account_info.h | 215 ++++++ interfaces/innerkits/include/iaccount.h | 50 ++ .../innerkits/include/ohos_account_kits.h | 80 +++ .../include/ohos_account_kits_impl.h | 60 ++ interfaces/innerkits/test/BUILD.gn | 19 + .../moduletests/account_mgr_test/BUILD.gn | 76 +++ .../account_mgr_inner_sdk_func_test.cpp | 97 +++ kits/js/impl/napi/distributedaccount/BUILD.gn | 51 ++ .../napi_distributed_account.cpp | 280 ++++++++ .../napi_distributed_account.h | 38 ++ ohos.build | 32 + os_account.gni | 20 + sa_profile/200.xml | 24 + sa_profile/BUILD.gn | 19 + services/BUILD.gn | 16 + services/accountmgr/BUILD.gn | 82 +++ services/accountmgr/accountmgr.rc | 22 + .../accountmgr/include/account_dump_helper.h | 45 ++ .../accountmgr/include/account_helper_data.h | 29 + .../accountmgr/include/account_mgr_service.h | 72 +++ services/accountmgr/include/account_proxy.h | 44 ++ .../accountmgr/include/account_state_action.h | 57 ++ .../include/account_state_machine.h | 175 +++++ services/accountmgr/include/account_stub.h | 52 ++ .../accountmgr/include/iaccount_context.h | 45 ++ .../include/ohos_account_data_deal.h | 52 ++ .../accountmgr/include/ohos_account_manager.h | 187 ++++++ .../accountmgr/src/account_dump_helper.cpp | 192 ++++++ .../accountmgr/src/account_helper_data.cpp | 61 ++ .../accountmgr/src/account_mgr_service.cpp | 204 ++++++ .../accountmgr/src/account_state_machine.cpp | 179 +++++ services/accountmgr/src/account_stub.cpp | 272 ++++++++ services/accountmgr/src/iaccount.cpp | 23 + .../accountmgr/src/ohos_account_data_deal.cpp | 144 +++++ .../accountmgr/src/ohos_account_manager.cpp | 340 ++++++++++ services/accountmgr/test/BUILD.gn | 41 ++ .../mock/include/mock_account_mgr_service.h | 48 ++ .../mock/src/mock_account_mgr_service.cpp | 67 ++ .../account_dump_helper_test/BUILD.gn | 74 +++ .../account_dump_helper_test.cpp | 126 ++++ .../account_mgr_service_test/BUILD.gn | 87 +++ .../account_mgr_service_test.cpp | 211 ++++++ .../account_state_machine_test.cpp | 612 ++++++++++++++++++ .../ohos_account_manager_test.cpp | 71 ++ .../unittest/account_mgr_stub_test/BUILD.gn | 85 +++ .../account_mgr_stub_test.cpp | 142 ++++ .../ohos_account_data_deal_test/BUILD.gn | 63 ++ .../ohos_account_data_deal_test.cpp | 172 +++++ .../accountmgrservice/data_deal/empty.json | 0 .../data_deal/invalid_format.json | 1 + .../accountmgrservice/data_deal/valid.json | 1 + test/resource/accountmgrservice/ohos_test.xml | 21 + 76 files changed, 7085 insertions(+), 61 deletions(-) create mode 100644 .gitattributes create mode 100644 LICENSE delete mode 100644 README.en.md mode change 100644 => 100755 README.md create mode 100755 README_zh.md create mode 100755 common/BUILD.gn create mode 100755 common/account_error/include/account_error_no.h create mode 100755 common/log/include/account_log_wrapper.h create mode 100755 common/log/src/account_log_wrapper.cpp create mode 100755 common/perf_stat/include/perf_stat.h create mode 100755 common/perf_stat/src/perf_stat.cpp create mode 100755 common/test/BUILD.gn create mode 100755 common/test/unittest/common_account_log_test/BUILD.gn create mode 100755 common/test/unittest/common_account_log_test/account_log_test.cpp create mode 100755 common/test/unittest/common_account_perf_test/BUILD.gn create mode 100755 common/test/unittest/common_account_perf_test/account_perf_stat_test.cpp create mode 100755 figures/en-us_image_0000001123704367.png create mode 100755 figures/zh-cn_image_0000001123704367.png create mode 100755 interfaces/innerkits/account_kits_headers.gni create mode 100755 interfaces/innerkits/accountmgr/BUILD.gn create mode 100755 interfaces/innerkits/accountmgr/src/account_proxy.cpp create mode 100755 interfaces/innerkits/accountmgr/src/ohos_account_kits.cpp create mode 100755 interfaces/innerkits/accountmgr/src/ohos_account_kits_impl.cpp create mode 100755 interfaces/innerkits/include/account_info.h create mode 100755 interfaces/innerkits/include/device_account_info.h create mode 100755 interfaces/innerkits/include/iaccount.h create mode 100755 interfaces/innerkits/include/ohos_account_kits.h create mode 100755 interfaces/innerkits/include/ohos_account_kits_impl.h create mode 100755 interfaces/innerkits/test/BUILD.gn create mode 100755 interfaces/innerkits/test/moduletests/account_mgr_test/BUILD.gn create mode 100755 interfaces/innerkits/test/moduletests/account_mgr_test/account_mgr_inner_sdk_func_test.cpp create mode 100755 kits/js/impl/napi/distributedaccount/BUILD.gn create mode 100755 kits/js/impl/napi/distributedaccount/napi_distributed_account.cpp create mode 100755 kits/js/impl/napi/distributedaccount/napi_distributed_account.h create mode 100755 ohos.build create mode 100755 os_account.gni create mode 100755 sa_profile/200.xml create mode 100755 sa_profile/BUILD.gn create mode 100755 services/BUILD.gn create mode 100755 services/accountmgr/BUILD.gn create mode 100755 services/accountmgr/accountmgr.rc create mode 100755 services/accountmgr/include/account_dump_helper.h create mode 100755 services/accountmgr/include/account_helper_data.h create mode 100755 services/accountmgr/include/account_mgr_service.h create mode 100755 services/accountmgr/include/account_proxy.h create mode 100755 services/accountmgr/include/account_state_action.h create mode 100755 services/accountmgr/include/account_state_machine.h create mode 100755 services/accountmgr/include/account_stub.h create mode 100755 services/accountmgr/include/iaccount_context.h create mode 100755 services/accountmgr/include/ohos_account_data_deal.h create mode 100755 services/accountmgr/include/ohos_account_manager.h create mode 100755 services/accountmgr/src/account_dump_helper.cpp create mode 100755 services/accountmgr/src/account_helper_data.cpp create mode 100755 services/accountmgr/src/account_mgr_service.cpp create mode 100755 services/accountmgr/src/account_state_machine.cpp create mode 100755 services/accountmgr/src/account_stub.cpp create mode 100755 services/accountmgr/src/iaccount.cpp create mode 100755 services/accountmgr/src/ohos_account_data_deal.cpp create mode 100755 services/accountmgr/src/ohos_account_manager.cpp create mode 100755 services/accountmgr/test/BUILD.gn create mode 100755 services/accountmgr/test/mock/include/mock_account_mgr_service.h create mode 100755 services/accountmgr/test/mock/src/mock_account_mgr_service.cpp create mode 100755 services/accountmgr/test/unittest/account_dump_helper_test/BUILD.gn create mode 100755 services/accountmgr/test/unittest/account_dump_helper_test/account_dump_helper_test.cpp create mode 100755 services/accountmgr/test/unittest/account_mgr_service_test/BUILD.gn create mode 100755 services/accountmgr/test/unittest/account_mgr_service_test/account_mgr_service_test.cpp create mode 100755 services/accountmgr/test/unittest/account_mgr_service_test/account_state_machine_test.cpp create mode 100755 services/accountmgr/test/unittest/account_mgr_service_test/ohos_account_manager_test.cpp create mode 100755 services/accountmgr/test/unittest/account_mgr_stub_test/BUILD.gn create mode 100755 services/accountmgr/test/unittest/account_mgr_stub_test/account_mgr_stub_test.cpp create mode 100755 services/accountmgr/test/unittest/ohos_account_data_deal_test/BUILD.gn create mode 100755 services/accountmgr/test/unittest/ohos_account_data_deal_test/ohos_account_data_deal_test.cpp create mode 100755 test/resource/accountmgrservice/data_deal/empty.json create mode 100755 test/resource/accountmgrservice/data_deal/invalid_format.json create mode 100644 test/resource/accountmgrservice/data_deal/valid.json create mode 100755 test/resource/accountmgrservice/ohos_test.xml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..51c63e295 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,15 @@ +*.tgz filter=lfs diff=lfs merge=lfs -text +*.trp filter=lfs diff=lfs merge=lfs -text +*.apk filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.mp4 filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.asm filter=lfs diff=lfs merge=lfs -text +*.8svn filter=lfs diff=lfs merge=lfs -text +*.9svn filter=lfs diff=lfs merge=lfs -text +*.dylib filter=lfs diff=lfs merge=lfs -text +*.exe filter=lfs diff=lfs merge=lfs -text +*.a filter=lfs diff=lfs merge=lfs -text +*.so filter=lfs diff=lfs merge=lfs -text +*.bin filter=lfs diff=lfs merge=lfs -text +*.dll filter=lfs diff=lfs merge=lfs -text diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..4947287f7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 4fb09b480..000000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# account_os_account - -#### Description -Allowing apps to use OS account-related functions | 允许您的应用程序使用操作系统帐号相关功能 - -#### 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 old mode 100644 new mode 100755 index 5476ab3b1..4286d62b4 --- a/README.md +++ b/README.md @@ -1,37 +1,140 @@ -# account_os_account +# os\_account -#### 介绍 -Allowing apps to use OS account-related functions | 允许您的应用程序使用操作系统帐号相关功能 +- [Introduction](#section11660541593) +- [Architecture](#section1412183212132) +- [Directory Structure](#section161941989596) +- [Usage](#section1312121216216) + - [Available APIs](#section1551164914237) -#### 软件架构 -软件架构说明 +- [Repositories Involved](#section1371113476307) + +## Introduction + +In a standard system, the OS account module supports login status management of distributed cloud accounts, interconnection with vendors' cloud account apps on the device side, and query and update of the cloud account login status. + +## Architecture + +**Figure 1** OS account architecture -#### 安装教程 +![](figures/en-us_image_0000001123704367.png) -1. xxxx -2. xxxx -3. xxxx +## Directory Structure -#### 使用说明 +``` +/base/account/os_account +├── common # Common basic code +│ ├── account_error # Error codes +│ ├── log # Code for printing logs +│ ├── perf_stat # Performance statistics +│ └── test # Test code of common modules +├── interfaces # APIs exposed externally +│ └── innerkits # Header files for internal modules +├── kits # Development framework +├── sa_profile # SA profile +├── services # Service code +│ └── accountmgr # Account manager service +└── test # Test code + └── resource # Test resources +``` -1. xxxx -2. xxxx -3. xxxx +## Usage -#### 参与贡献 +### Available APIs -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request +The APIs available for distributed accounts can be called to query and update the account login status, and are supported only by system apps. +**Table 1** Description of the distributed account module -#### 特技 + + + + + + + + + +

Module

+

Description

+

distributedAccount

+

Provides methods for managing the distributed account module.

+
+ +**Table 2** Classes for distributed accounts + + + + + + + + + + + + + +

Class

+

Description

+

DistributedAccountAbility

+

Provides methods for querying and updating the login status of distributed accounts.

+

DistributedInfo

+

Provides methods for querying distributed account information, including the account name, UID, and login status.

+
+ +**Table 3** Methods for the distributed account module + + + + + + + + + + +

Method

+

Description

+

function getDistributedAccountAbility(): DistributedAccountAbility

+

Obtains a singleton of a distributed account.

+
+ +**Table 4** DistributedAccountAbility description + + + + + + + + + + + + + + + + + + + +

Method

+

Description

+

queryOsAccountDistributedInfo(callback: AsyncCallback<DistributedInfo>): void

+

Queries information about the distributed account.

+

queryOsAccountDistributedInfo(): Promise<DistributedInfo>

+

Queries information about the distributed account.

+

updateOsAccountDistributedInfo(accountInfo: DistributedInfo, callback: AsyncCallback<boolean>): void

+

Updates information about the distributed account.

+

updateOsAccountDistributedInfo(accountInfo: DistributedInfo): Promise<boolean>

+

Updates information about the distributed account.

+
+ +## Repositories Involved + +Account subsystem + +**account\_os\_account** -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 100755 index 000000000..dbbd00701 --- /dev/null +++ b/README_zh.md @@ -0,0 +1,140 @@ +# 系统帐号组件 + +- [简介](#section11660541593) +- [组件架构图](#section1412183212132) +- [目录](#section161941989596) +- [说明](#section1312121216216) + - [接口说明](#section1551164914237) + +- [相关仓](#section1371113476307) + +## 简介 + +在标准系统上,系统帐号组件主要提供分布式帐号登录状态管理能力,支持在端侧对接厂商云帐号应用,提供云帐号登录状态查询和更新的管理能力。 + +## 组件架构图 + +**图 1** 系统帐号组件架构图 + + +![](figures/zh-cn_image_0000001123704367.png) + +## 目录 + +``` +/base/account/os_account +├── common # 公共基础模块 +│ ├── account_error # 错误码定义 +│ ├── log # 日志打印代码 +│ ├── perf_stat # 性能统计 +│ └── test # 公共模块测试代码 +├── interfaces # 对外接口存放目录 +│ └── innerkits # 对内部组件暴露的头文件存放目录 +├── kits # 系统帐号组件开发框架 +├── sa_profile # 帐号SA配置文件定义目录 +├── services # 系统帐号组件服务代码 +│ └── accountmgr # 帐号管理服务目录 +└── test # 系统帐号组件测试代码 + └── resource # 系统帐号组件测试资源 +``` + +## 说明 + +### 接口说明 + +分布式帐号的功能主要包括查询和更新帐号登录状态,仅支持系统应用。 + +**表 1** 分布式帐号模块说明 + + + + + + + + + + +

模块名

+

描述

+

distributedAccount

+

提供分布式帐号模块管理方法

+
+ +**表 2** 分布式帐号类说明 + + + + + + + + + + + + + +

类名

+

描述

+

DistributedAccountAbility

+

提供查询和更新分布式帐号登录状态方法

+

DistributedInfo

+

提供分布式帐号信息,主要包括帐号名、帐号UID和帐号登录状态。

+
+ +**表 3** 分布式帐号模块方法说明 + + + + + + + + + + +

方法

+

描述

+

function getDistributedAccountAbility(): DistributedAccountAbility

+

获取分布式帐号单实例对象

+
+ +**表 4** DistributedAccountAbility方法说明 + + + + + + + + + + + + + + + + + + + +

方法

+

描述

+

queryOsAccountDistributedInfo(callback: AsyncCallback<DistributedInfo>): void

+

查询分布式帐号信息

+

queryOsAccountDistributedInfo(): Promise<DistributedInfo>

+

查询分布式帐号信息

+

updateOsAccountDistributedInfo(accountInfo: DistributedInfo, callback: AsyncCallback<boolean>): void

+

更新分布式帐号信息

+

updateOsAccountDistributedInfo(accountInfo: DistributedInfo): Promise<boolean>

+

更新分布式帐号信息

+
+ +## 相关仓 + +帐号子系统 + +**account\_os\_account** + diff --git a/common/BUILD.gn b/common/BUILD.gn new file mode 100755 index 000000000..f701e895b --- /dev/null +++ b/common/BUILD.gn @@ -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. + +import("//base/account/os_account/os_account.gni") +import("//build/ohos.gni") + +group("common_target") { + deps = [ ":libaccount_common" ] +} + +config("account_common_config") { + include_dirs = [ + "log/include", + "perf_stat/include", + "//utils/native/base/include", + ] +} + +ohos_shared_library("libaccount_common") { + sources = [ + "log/src/account_log_wrapper.cpp", + "perf_stat/src/perf_stat.cpp", + ] + + defines = [ + "ACCOUNT_LOG_TAG = \"ACCOUNT_COMMON\"", + "LOG_DOMAIN = 0xD001B00", + ] + + public_configs = [ + ":account_common_config", + "//utils/native/base:utils_config", + ] + + public_deps = [ "//utils/native/base:utils" ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + part_name = "os_account_standard" +} diff --git a/common/account_error/include/account_error_no.h b/common/account_error/include/account_error_no.h new file mode 100755 index 000000000..462e7b69f --- /dev/null +++ b/common/account_error/include/account_error_no.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BASE_ACCOUNT_INCLUDE_ACCOUNT_ERROR_NO_H +#define BASE_ACCOUNT_INCLUDE_ACCOUNT_ERROR_NO_H + +#include "errors.h" + +namespace OHOS { + enum { + ACCOUNT_MODULE_COMMON = 0x00, + ACCOUNT_MODULE_ACCOUNTMGR, + ACCOUNT_MODULE_DATADEAL, + ACCOUNT_MODULE_IACCOUNT + }; + + /* Error code for common */ + constexpr ErrCode ACCOUNT_COMMON_ERR_OFFSET = ErrCodeOffset(SUBSYS_ACCOUNT, ACCOUNT_MODULE_COMMON); + + /* Error code for AccountMgr */ + constexpr ErrCode ACCOUNT_ACCOUNTMGR_ERR_OFFSET = ErrCodeOffset(SUBSYS_ACCOUNT, ACCOUNT_MODULE_ACCOUNTMGR); + enum { + ERR_ACCOUNT_MGR_DUMP_ERROR = ACCOUNT_ACCOUNTMGR_ERR_OFFSET + 0x0001, + ERR_ACCOUNT_MGR_GET_REMOTE_SA_ERROR, + ERR_ACCOUNT_MGR_CONNECT_SA_ERROR, + ERR_ACCOUNT_MGR_ADD_TO_SA_ERROR + }; + + /* Error code for DataDeal module */ + constexpr ErrCode ACCOUNT_DATADEAL_ERR_OFFSET = ErrCodeOffset(SUBSYS_ACCOUNT, ACCOUNT_MODULE_DATADEAL); + enum { + ERR_ACCOUNT_DATADEAL_INPUT_FILE_ERROR = ACCOUNT_DATADEAL_ERR_OFFSET + 0x0001, + ERR_ACCOUNT_DATADEAL_FILE_PARSE_FAILED, + ERR_ACCOUNT_DATADEAL_DIGEST_ERROR, + ERR_ACCOUNT_DATADEAL_FILE_WRITE_FAILED, + ERR_ACCOUNT_DATADEAL_JSON_KEY_NOT_EXIST, + ERR_ACCOUNT_DATADEAL_NOT_READY, + ERR_ACCOUNT_DATADEAL_JSON_FILE_CORRUPTION + }; + + /* Error code for IAccount */ + constexpr ErrCode ACCOUNT_IACCOUNT_ERR_OFFSET = ErrCodeOffset(SUBSYS_ACCOUNT, ACCOUNT_MODULE_IACCOUNT); + enum { + ERR_ACCOUNT_ZIDL_ACCOUNT_INFO_CHECK_ERROR = ACCOUNT_IACCOUNT_ERR_OFFSET + 0x0001, + ERR_ACCOUNT_ZIDL_WRITE_DESCRIPTOR_ERROR, + ERR_ACCOUNT_ZIDL_READ_RESULT_ERROR, + ERR_ACCOUNT_ZIDL_WRITE_RESULT_ERROR, + ERR_ACCOUNT_ZIDL_ACCOUNT_STUB_ERROR, + ERR_ACCOUNT_ZIDL_ACCOUNT_SEND_REQUEST_ERROR, + ERR_ACCOUNT_ZIDL_WRITE_NAME_ERROR, + ERR_ACCOUNT_ZIDL_WRITE_UID_ERROR, + ERR_ACCOUNT_ZIDL_WRITE_ACCOUNT_STATUS_ERROR, + ERR_ACCOUNT_ZIDL_MGR_NOT_READY_ERROR, + ERR_ACCOUNT_ZIDL_CHECK_PERMISSION_ERROR, + ERR_ACCOUNT_ZIDL_WRITE_PARCEL_DATA_ERROR, + ERR_ACCOUNT_ZIDL_INVALID_RESULT_ERROR + }; +} + +#endif /* BASE_ACCOUNT_INCLUDE_ACCOUNT_ERROR_NO_H */ diff --git a/common/log/include/account_log_wrapper.h b/common/log/include/account_log_wrapper.h new file mode 100755 index 000000000..b8b993437 --- /dev/null +++ b/common/log/include/account_log_wrapper.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 BASE_ACCOUNT_COMMON_LOG_INCLUDE_ACCOUNT_LOG_WRAPPER_H +#define BASE_ACCOUNT_COMMON_LOG_INCLUDE_ACCOUNT_LOG_WRAPPER_H + +#include "hilog/log.h" +#include + +namespace OHOS { +namespace AccountSA { +enum class AccountLogLevel { + DEBUG = 0, + INFO, + WARN, + ERROR, + FATAL +}; + +static constexpr OHOS::HiviewDFX::HiLogLabel ACCOUNT_LABEL = {LOG_CORE, LOG_DOMAIN, ACCOUNT_LOG_TAG}; + +class AccountLogWrapper { +public: + static bool JudgeLevel(const AccountLogLevel& level); + + static void SetLogLevel(const AccountLogLevel& level) + { + level_ = level; + } + + static const AccountLogLevel& GetLogLevel() + { + return level_; + } + + static std::string GetBriefFileName(const std::string &file); + +private: + static AccountLogLevel level_; +}; + +#define PRINT_LOG(LEVEL, Level, fmt, ...) \ + if (AccountLogWrapper::JudgeLevel(AccountLogLevel::LEVEL)) \ + OHOS::HiviewDFX::HiLog::Level(ACCOUNT_LABEL, "[%{public}s(%{public}s)] " fmt, \ + AccountLogWrapper::GetBriefFileName(std::string(__FILE__)).c_str(), __FUNCTION__, ##__VA_ARGS__) + +#define ACCOUNT_LOGD(fmt, ...) PRINT_LOG(DEBUG, Debug, fmt, ##__VA_ARGS__) +#define ACCOUNT_LOGI(fmt, ...) PRINT_LOG(INFO, Info, fmt, ##__VA_ARGS__) +#define ACCOUNT_LOGW(fmt, ...) PRINT_LOG(WARN, Warn, fmt, ##__VA_ARGS__) +#define ACCOUNT_LOGE(fmt, ...) PRINT_LOG(ERROR, Error, fmt, ##__VA_ARGS__) +#define ACCOUNT_LOGF(fmt, ...) PRINT_LOG(FATAL, Fatal, fmt, ##__VA_ARGS__) +} // namespace AccountSA +} // namespace OHOS + +#endif // BASE_ACCOUNT_COMMON_LOG_INCLUDE_ACCOUNT_LOG_WRAPPER_H \ No newline at end of file diff --git a/common/log/src/account_log_wrapper.cpp b/common/log/src/account_log_wrapper.cpp new file mode 100755 index 000000000..bd909f4c2 --- /dev/null +++ b/common/log/src/account_log_wrapper.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "account_log_wrapper.h" +#include + +namespace OHOS { +namespace AccountSA { +// initial static member object +AccountLogLevel AccountLogWrapper::level_ = AccountLogLevel::INFO; + +bool AccountLogWrapper::JudgeLevel(const AccountLogLevel& level) +{ + return (level >= AccountLogWrapper::GetLogLevel()); +} + +std::string AccountLogWrapper::GetBriefFileName(const std::string &file) +{ + auto pos = file.find_last_of("/"); + if (pos != std::string::npos) { + return file.substr(pos + 1); + } + + pos = file.find_last_of("\\"); + if (pos != std::string::npos) { + return file.substr(pos + 1); + } + + return file; +} +} // namespace AccountSA +} // namespace OHOS \ No newline at end of file diff --git a/common/perf_stat/include/perf_stat.h b/common/perf_stat/include/perf_stat.h new file mode 100755 index 000000000..3ee546692 --- /dev/null +++ b/common/perf_stat/include/perf_stat.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BASE_ACCOUNT_SERVICES_COMMON_INCLUDE_PERF_STAT_H +#define BASE_ACCOUNT_SERVICES_COMMON_INCLUDE_PERF_STAT_H + +#include +#include +#include "singleton.h" + +namespace OHOS { +namespace AccountSA { +class PerfStat : public Singleton { + DECLARE_SINGLETON(PerfStat); + +public: + int64_t GetAccountBindStartTime() const; + void SetAccountBindStartTime(int64_t time); + + int64_t GetAccountBindEndTime() const; + void SetAccountBindEndTime(int64_t time); + + int64_t GetAccountAddStartTime() const; + void SetAccountAddStartTime(int64_t time); + + int64_t GetAccountAddEndTime() const; + void SetAccountAddEndTime(int64_t time); + + int64_t GetAccountDelStartTime() const; + void SetAccountDelStartTime(int64_t time); + + int64_t GetAccountDelEndTime() const; + void SetAccountDelEndTime(int64_t time); + + int64_t GetAccountQueryStartTime() const; + void SetAccountQueryStartTime(int64_t time); + + int64_t GetAccountQueryEndTime() const; + void SetAccountQueryEndTime(int64_t time); + + void SetInstanceStopTime(int64_t); + void SetInstanceStartTime(int64_t); + void SetInstanceInitTime(int64_t); + void SetInstanceCreateTime(int64_t); + void SetAccountStateChangeTime(const std::string &stateStr, int64_t time); + + bool GetPerfStatEnabled() const; + void SetPerfStatEnabled(bool enable); + + void Reset(); + void Dump(std::string& result) const; + +private: + int64_t accountBindBegin_ = 0; + int64_t accountBindEnd_ = 0; + + int64_t accountAddBegin_ = 0; + int64_t accountAddEnd_ = 0; + + int64_t accountDelBegin_ = 0; + int64_t accountDelEnd_ = 0; + + int64_t accountQueryBegin_ = 0; + int64_t accountQueryEnd_ = 0; + + int64_t instanceCreate_ = 0; + int64_t serviceOnStart_ = 0; + int64_t serviceOnStop_ = 0; + int64_t serviceInit_ = 0; + + std::map accountStateChangeRecords_; + + bool enableStat_ = true; +}; +} // namespace AccountSA +} // namespace OHOS + +#endif // BASE_ACCOUNT_SERVICES_COMMON_INCLUDE_PERF_STAT_H diff --git a/common/perf_stat/src/perf_stat.cpp b/common/perf_stat/src/perf_stat.cpp new file mode 100755 index 000000000..f2281b5af --- /dev/null +++ b/common/perf_stat/src/perf_stat.cpp @@ -0,0 +1,236 @@ +/* + * 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 "perf_stat.h" + +#include "account_log_wrapper.h" + +namespace OHOS { +namespace AccountSA { +PerfStat::PerfStat() +{ + ACCOUNT_LOGD("create"); +} + +PerfStat::~PerfStat() +{ + ACCOUNT_LOGD("destroy"); + Reset(); +} + +/* Account Bind process statistic */ +int64_t PerfStat::GetAccountBindStartTime() const +{ + return accountBindBegin_; +} + +void PerfStat::SetAccountBindStartTime(int64_t time) +{ + accountBindBegin_ = (time > 0) ? time : 0; +} + +int64_t PerfStat::GetAccountBindEndTime() const +{ + return accountBindEnd_; +} + +void PerfStat::SetAccountBindEndTime(int64_t time) +{ + accountBindEnd_ = (time > 0 && time > accountBindBegin_) ? time : accountBindBegin_; +} + +/* Account Add process statistic */ +int64_t PerfStat::GetAccountAddStartTime() const +{ + return accountAddBegin_; +} + +void PerfStat::SetAccountAddStartTime(int64_t time) +{ + accountAddBegin_ = (time > 0) ? time : 0; +} + +int64_t PerfStat::GetAccountAddEndTime() const +{ + return accountAddEnd_; +} + +void PerfStat::SetAccountAddEndTime(int64_t time) +{ + accountAddEnd_ = (time > 0 && time > accountAddBegin_) ? time : accountAddBegin_; +} + +/* Account Delete process statistic */ +int64_t PerfStat::GetAccountDelStartTime() const +{ + return accountDelBegin_; +} + +void PerfStat::SetAccountDelStartTime(int64_t time) +{ + accountDelBegin_ = (time > 0) ? time : 0; +} + +int64_t PerfStat::GetAccountDelEndTime() const +{ + return accountDelEnd_; +} + +void PerfStat::SetAccountDelEndTime(int64_t time) +{ + accountDelEnd_ = (time > 0 && time > accountDelBegin_) ? time : accountDelBegin_; +} + +/* Account Query process statistic */ +int64_t PerfStat::GetAccountQueryStartTime() const +{ + return accountQueryBegin_; +} + +void PerfStat::SetAccountQueryStartTime(int64_t time) +{ + accountQueryBegin_ = (time > 0) ? time : 0; +} + +int64_t PerfStat::GetAccountQueryEndTime() const +{ + return accountQueryEnd_; +} + +void PerfStat::SetAccountQueryEndTime(int64_t time) +{ + accountQueryEnd_ = (time > 0 && time > accountQueryBegin_) ? time : accountQueryBegin_; +} + +/* Account Service process statistic */ +void PerfStat::SetInstanceStartTime(int64_t time) +{ + serviceOnStart_ = time; +} + +void PerfStat::SetInstanceStopTime(int64_t time) +{ + serviceOnStop_ = time; +} + +void PerfStat::SetInstanceCreateTime(int64_t time) +{ + instanceCreate_ = time; +} + +void PerfStat::SetInstanceInitTime(int64_t time) +{ + serviceInit_ = time; +} + +/* Account state machine process statistic */ +void PerfStat::SetAccountStateChangeTime(const std::string &stateStr, int64_t time) +{ + accountStateChangeRecords_[stateStr] = time; +} + +/* Set/Get perf statistic enable state */ +bool PerfStat::GetPerfStatEnabled() const +{ + return enableStat_; +} + +void PerfStat::SetPerfStatEnabled(bool enable) +{ + enableStat_ = enable; +} + +/* reset to default */ +void PerfStat::Reset() +{ + accountBindBegin_ = 0; + accountBindEnd_ = 0; + + accountAddBegin_ = 0; + accountAddEnd_ = 0; + + accountDelBegin_ = 0; + accountDelEnd_ = 0; + + accountQueryBegin_ = 0; + accountQueryEnd_ = 0; + + instanceCreate_ = 0; + serviceOnStart_ = 0; + serviceOnStop_ = 0; + serviceInit_ = 0; + + accountStateChangeRecords_.clear(); + + enableStat_ = true; +} + +void PerfStat::Dump(std::string& result) const +{ + if (!enableStat_) { + ACCOUNT_LOGI("statistics disabled!"); + return; + } + + if (instanceCreate_ > 0) { + result.append("InstanceCreateTick: ").append(std::to_string(instanceCreate_)).append("\n"); + } + + if (serviceInit_ > 0) { + result.append("ServiceInitTick: ").append(std::to_string(serviceInit_)).append("\n"); + } + + if (serviceOnStart_ > 0) { + result.append("ServiceStartTick: ").append(std::to_string(serviceOnStart_)).append("\n"); + } + + if (serviceOnStop_ > 0) { + result.append("ServiceStopTick: ").append(std::to_string(serviceOnStop_)).append("\n"); + } + + if (accountBindEnd_ > accountBindBegin_) { + result.append("AccountBindTime: ") + .append(std::to_string(accountBindEnd_ - accountBindBegin_)) + .append("\n"); + } + + if (accountAddEnd_ > accountAddBegin_) { + result.append("AccountAddTime: ") + .append(std::to_string(accountAddEnd_ - accountAddBegin_)) + .append("\n"); + } + + if (accountDelEnd_ > accountDelBegin_) { + result.append("AccountDelTime: ") + .append(std::to_string(accountDelEnd_ - accountDelBegin_)) + .append("\n"); + } + + if (accountQueryEnd_ > accountQueryBegin_) { + result.append("AccountQueryTime: ") + .append(std::to_string((accountQueryEnd_ - accountQueryBegin_))) + .append("\n"); + } + + auto iter = accountStateChangeRecords_.begin(); + for (; iter != accountStateChangeRecords_.end(); iter++) { + result.append(iter->first.c_str()) + .append(": ") + .append(std::to_string(iter->second)) + .append(" Ticks\n"); + } +} +} // namespace AccountSA +} // namespace OHOS diff --git a/common/test/BUILD.gn b/common/test/BUILD.gn new file mode 100755 index 000000000..7b1afb95a --- /dev/null +++ b/common/test/BUILD.gn @@ -0,0 +1,31 @@ +# 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("//base/account/os_account/os_account.gni") +import("//build/ohos.gni") + +config("common_test_config") { + defines = [ + "ACCOUNT_LOG_TAG = \"ACCOUNT_TEST\"", + "LOG_DOMAIN = 0xD001B00", + ] +} + +group("unittest") { + testonly = true + + deps = [ + "unittest/common_account_log_test:unittest", + "unittest/common_account_perf_test:unittest", + ] +} diff --git a/common/test/unittest/common_account_log_test/BUILD.gn b/common/test/unittest/common_account_log_test/BUILD.gn new file mode 100755 index 000000000..be33f0a76 --- /dev/null +++ b/common/test/unittest/common_account_log_test/BUILD.gn @@ -0,0 +1,42 @@ +# 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("//base/account/os_account/os_account.gni") +import("//build/ohos.gni") +import("//build/test.gni") + +module_output_path = "os_account_standard/accountdfx" + +ohos_unittest("AccountSALogTest") { + module_out_path = module_output_path + + sources = [ "${common_path}/log/src/account_log_wrapper.cpp" ] + + sources += [ "account_log_test.cpp" ] + + configs = [ + "${common_path}:account_common_config", + "${common_path}/test:common_test_config", + ] + + deps = [ "//third_party/googletest:gtest_main" ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + part_name = "os_account_standard" +} + +group("unittest") { + testonly = true + + deps = [ ":AccountSALogTest" ] +} diff --git a/common/test/unittest/common_account_log_test/account_log_test.cpp b/common/test/unittest/common_account_log_test/account_log_test.cpp new file mode 100755 index 000000000..0af756a7e --- /dev/null +++ b/common/test/unittest/common_account_log_test/account_log_test.cpp @@ -0,0 +1,97 @@ +/* + * 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 + +#include "account_log_wrapper.h" + +using namespace testing::ext; +using namespace OHOS::AccountSA; + +class AccountLogTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void AccountLogTest::SetUpTestCase() {} + +void AccountLogTest::TearDownTestCase() {} + +void AccountLogTest::SetUp() {} + +void AccountLogTest::TearDown() {} + +/** + * @tc.name: AccountLogLevel001 + * @tc.desc: Dynamically control log print level + * @tc.type: FUNC + * @tc.require: AR000CUF6K + */ +HWTEST_F(AccountLogTest, AccountLogLevel001, TestSize.Level0) +{ + /** + * @tc.steps: step1. Get default log level + * @tc.expected: step1. The default log level is AccountLogLevel::INFO + */ + EXPECT_EQ(AccountLogLevel::INFO, AccountLogWrapper::GetLogLevel()); + + /** + * @tc.steps: step2. Set log level with DEBUG + * @tc.expected: step2. Get log level is AccountLogLevel::DEBUG + */ + AccountLogWrapper::SetLogLevel(AccountLogLevel::DEBUG); + EXPECT_EQ(AccountLogLevel::DEBUG, AccountLogWrapper::GetLogLevel()); +} + +/** + * @tc.name: AccountLogFileName002 + * @tc.desc: splice filename + * @tc.type: FUNC + * @tc.require: AR000CUF6L + */ +HWTEST_F(AccountLogTest, AccountLogFileName002, TestSize.Level0) +{ + /** + * @tc.steps: step1. Constructor fileName and execeptStr strings + */ + std::string fileName = "../base/account/test.cpp"; + std::string exceptStr = "test.cpp"; + + /** + * @tc.steps: step2. Call the GetBriefFileName method to split the string + * @tc.expected: step2. The result string is "test.cpp" + */ + std::string result = AccountLogWrapper::GetBriefFileName(fileName); + EXPECT_EQ(exceptStr, result); +} + +/** + * @tc.name: AccountLogFileName003 + * @tc.desc: splice filename + * @tc.type: FUNC + * @tc.require: AR000CUF6M + */ +HWTEST_F(AccountLogTest, AccountLogFileName003, TestSize.Level0) +{ + std::string fileName = "test.cpp"; + std::string result = AccountLogWrapper::GetBriefFileName(fileName); + EXPECT_EQ(fileName, result); + fileName = ""; + result = AccountLogWrapper::GetBriefFileName(fileName); + EXPECT_EQ(fileName, result); +} \ No newline at end of file diff --git a/common/test/unittest/common_account_perf_test/BUILD.gn b/common/test/unittest/common_account_perf_test/BUILD.gn new file mode 100755 index 000000000..81c57212b --- /dev/null +++ b/common/test/unittest/common_account_perf_test/BUILD.gn @@ -0,0 +1,45 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//base/account/os_account/os_account.gni") +import("//build/ohos.gni") +import("//build/test.gni") + +module_output_path = "os_account_standard/accountdfx" + +ohos_unittest("AccountSAPerfTest") { + module_out_path = module_output_path + + sources = [ + "${common_path}/log/src/account_log_wrapper.cpp", + "${common_path}/perf_stat/src/perf_stat.cpp", + ] + + sources += [ "account_perf_stat_test.cpp" ] + + configs = [ + "${common_path}:account_common_config", + "${common_path}/test:common_test_config", + ] + + deps = [ "//third_party/googletest:gtest_main" ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + part_name = "os_account_standard" +} + +group("unittest") { + testonly = true + + deps = [ ":AccountSAPerfTest" ] +} diff --git a/common/test/unittest/common_account_perf_test/account_perf_stat_test.cpp b/common/test/unittest/common_account_perf_test/account_perf_stat_test.cpp new file mode 100755 index 000000000..9635bd883 --- /dev/null +++ b/common/test/unittest/common_account_perf_test/account_perf_stat_test.cpp @@ -0,0 +1,161 @@ +/* + * 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 + +#include "perf_stat.h" + +using namespace testing::ext; +using namespace OHOS::AccountSA; + +namespace { +const int64_t INVALID_TIME = -1; +const int64_t ACCOUNT_BIND_START_TIME = 10; +const int64_t ACCOUNT_BIND_END_TIME = 120; +const int64_t ACCOUNT_ADD_START_TIME = 100; +const int64_t ACCOUNT_ADD_END_TIME = 10000; +const int64_t ACCOUNT_QUERY_START_TIME = 1220; +const int64_t ACCOUNT_QUERY_END_TIME = 10222; +const int64_t ACCOUNT_DEL_START_TIME = 10; +const int64_t ACCOUNT_DEL_END_TIME = 100; +} + +class AccountPerfStatTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void AccountPerfStatTest::SetUpTestCase() {} + +void AccountPerfStatTest::TearDownTestCase() {} + +void AccountPerfStatTest::SetUp() +{ + /** + * @tc.setup: reset perfStat + */ + PerfStat::GetInstance().Reset(); +} + +void AccountPerfStatTest::TearDown() {} + +/** + * @tc.name: AccountPerfEndGreaterBegin001 + * @tc.desc: Test bind start time and end + * @tc.type: FUNC + * @tc.require: AR000CUF6O + */ +HWTEST_F(AccountPerfStatTest, AccountPerfEndGreaterBegin001, TestSize.Level0) +{ + std::string result; + /** + * @tc.steps: step1. check valid bind start time + */ + PerfStat::GetInstance().SetAccountBindStartTime(ACCOUNT_BIND_START_TIME); + int64_t bindStartTime = PerfStat::GetInstance().GetAccountBindStartTime(); + EXPECT_EQ(bindStartTime, ACCOUNT_BIND_START_TIME); + + /** + * @tc.steps: step2. check valid bind end time + */ + PerfStat::GetInstance().SetAccountBindEndTime(ACCOUNT_BIND_END_TIME); + PerfStat::GetInstance().Dump(result); + int64_t bindEndTime = PerfStat::GetInstance().GetAccountBindEndTime(); + EXPECT_EQ(bindEndTime, ACCOUNT_BIND_END_TIME); + + /** + * @tc.steps: step1. check valid add start time + */ + PerfStat::GetInstance().SetAccountAddStartTime(ACCOUNT_ADD_START_TIME); + int64_t addStartTime = PerfStat::GetInstance().GetAccountAddStartTime(); + EXPECT_EQ(addStartTime, ACCOUNT_ADD_START_TIME); + + /** + * @tc.steps: step2. check valid add end time + */ + PerfStat::GetInstance().SetAccountAddEndTime(ACCOUNT_ADD_END_TIME); + PerfStat::GetInstance().Dump(result); + int64_t addEndTime = PerfStat::GetInstance().GetAccountAddEndTime(); + EXPECT_EQ(addEndTime, ACCOUNT_ADD_END_TIME); + + /** + * @tc.steps: step1. check valid add start time + */ + PerfStat::GetInstance().SetAccountDelStartTime(ACCOUNT_DEL_START_TIME); + int64_t delStartTime = PerfStat::GetInstance().GetAccountDelStartTime(); + EXPECT_EQ(delStartTime, ACCOUNT_DEL_START_TIME); + + /** + * @tc.steps: step2. check valid add end time + */ + PerfStat::GetInstance().SetAccountDelEndTime(ACCOUNT_DEL_END_TIME); + PerfStat::GetInstance().Dump(result); + int64_t delEndTime = PerfStat::GetInstance().GetAccountDelEndTime(); + EXPECT_EQ(delEndTime, ACCOUNT_DEL_END_TIME); + + /** + * @tc.steps: step1. check valid add start time + */ + PerfStat::GetInstance().SetAccountQueryStartTime(ACCOUNT_QUERY_START_TIME); + int64_t queryStartTime = PerfStat::GetInstance().GetAccountQueryStartTime(); + EXPECT_EQ(queryStartTime, ACCOUNT_QUERY_START_TIME); + + /** + * @tc.steps: step2. check valid add end time + */ + PerfStat::GetInstance().SetAccountQueryEndTime(ACCOUNT_QUERY_END_TIME); + PerfStat::GetInstance().Dump(result); + int64_t queryEndTime = PerfStat::GetInstance().GetAccountQueryEndTime(); + EXPECT_EQ(queryEndTime, ACCOUNT_QUERY_END_TIME); +} + +/** + * @tc.name: AccountPerfInvalidEndTimeTest002 + * @tc.desc: invalid end time test + * @tc.type: FUNC + * @tc.require: AR000CUF6O + */ +HWTEST_F(AccountPerfStatTest, AccountPerfInvalidEndTimeTest002, TestSize.Level0) +{ + /** + * @tc.steps: step1. set invalid end time + */ + PerfStat::GetInstance().SetAccountBindStartTime(ACCOUNT_BIND_START_TIME); + PerfStat::GetInstance().SetAccountBindEndTime(ACCOUNT_BIND_START_TIME - 1); + int64_t bindEndTime = PerfStat::GetInstance().GetAccountBindEndTime(); + int64_t bindBeginTime = PerfStat::GetInstance().GetAccountBindStartTime(); + EXPECT_EQ(bindEndTime, bindBeginTime); + + PerfStat::GetInstance().SetAccountAddStartTime(ACCOUNT_ADD_START_TIME); + PerfStat::GetInstance().SetAccountAddEndTime(INVALID_TIME); + int64_t addStartTime = PerfStat::GetInstance().GetAccountAddStartTime(); + int64_t addEndTime = PerfStat::GetInstance().GetAccountAddEndTime(); + EXPECT_EQ(addStartTime, addEndTime); + + PerfStat::GetInstance().SetAccountQueryStartTime(ACCOUNT_QUERY_START_TIME); + PerfStat::GetInstance().SetAccountQueryEndTime(INVALID_TIME); + int64_t queryBeginTime = PerfStat::GetInstance().GetAccountQueryStartTime(); + int64_t queryEndTime = PerfStat::GetInstance().GetAccountQueryEndTime(); + EXPECT_EQ(queryEndTime, queryBeginTime); + + PerfStat::GetInstance().SetAccountDelEndTime(ACCOUNT_DEL_START_TIME); + PerfStat::GetInstance().SetAccountDelEndTime(INVALID_TIME); + int64_t delStartTime = PerfStat::GetInstance().GetAccountDelStartTime(); + int64_t delEndTime = PerfStat::GetInstance().GetAccountDelEndTime(); + EXPECT_EQ(delEndTime, delStartTime); +} diff --git a/figures/en-us_image_0000001123704367.png b/figures/en-us_image_0000001123704367.png new file mode 100755 index 0000000000000000000000000000000000000000..8bf6e6c606816a5ad4d1621b6e5942eb1db6bbc7 GIT binary patch literal 20706 zcma%h1y~#Fwl)w5Ed*$3fd+Re+TgA&1eX>m-UfH~B54CH?(R^aI20*PQy@6Sy|}wu z;m_Xt-gD1B=lu8o^E`PbD>L)WH*39Xt@nFpKB}wA6X22KVPIeoKo#UPF)#oi3=FK9 zdjJd!OtP)68}trL7fpE?jIsgBO|*e+A*~{ffl(QWe`AV+w!f+?zkH6~J`^=V{T%c4 z^@S>{=H}*pjEv#o;Q_J9;N#;%AdrB70D1;S1}~(iU%KPvWMpJ?PBl-SJh{8On_OI#l#~n)4?noN!^6j~si~QtpO1-&v9-0u z0^X;#EEJWHbZ~HBU|?Vgp0c!aU}R)mU0rQ$Z3RA}QC3z)&q`HQl?b9i_T-74p>c9n zZbn81_cI8kNlHgY2OdyI8+`<(tEQ?JhSb`mIoi1IsG#S9fkF20k1u8q^RXlbhT0dX zob*diquq1@*(JrqQVZK5!Dy?-!1god;RlCQ%a~UU->gM%?(W>q=W76q3{PkkvbTl( z6f}!QC%(jgky5^023S&4cGEi+2YF5MW)+;_|^JPB0E6LV@#i^;t++= zO+4`B%+`70H&5AeXomAsf4{w@)-dN&;Hy?|uCo%Cr+Sk+f|1nqeGO9g*<(K_ zFX{un^zwJUWI1upD*K_;GH_1;z8-iO@Oh6|_Ir={!>&iqgxy-_7sjOu2EgOeJ!pKF6=BDyUZ*ie(AEjtOsLF_pNI z`htIjKf2~OH?+RCsB9DCKPL!;5T!AgUYke1{qv&qA7$C>V>mLTNOj3rO_{1DDPS5g z9#w@8(3?oq(t)mO@Y@90v59G3q2Pk;HNoyh5r6pzJqvCFMa^KzH22tzk14H&v~Qym zz|&Qax$^0$IEF=p5-*7qkCcYtB_-|oUu6kHOB#dt3>1CVD=-s>Sq9sI#-?UArr#^f zA6tlZOIuKi`DL#1Pa0S1&uoqKWe?tE1U3xT)1#w2Mi(@w>rC5Hl-Dac$SFrGL zp;wb-ezOys-x}o?l;TjfaP;WJ_NW2nQeIEV|^!{^YH)tae#)u=wMsb_K4egWKY zo#-XoLb8AGwR_ILI!MVXQ=~}{)0NHd8C7j({zg)q{4eyTsN*K~(|a9<*M(HYeu zIFR7gvnusbd6h9ZVU~f)NnPe+Dvsh)MqWNe;o#`mY;k8^fpf!YiBiUH+ey1PRC~*v z@t|m9GO_SZxY8!?x;j-RJ?;YT=dQ(z3d(msWBWMv_x8LZyjH(Im2r;Bn``19dS2uI zvA|7e_G{9moFYwB4&~0{Rx+-9J7?CW_Vj|QZAUh{SU`V^b^d^h{4I8j;JYFH@QHD= zCC%xAc*ox+(P!WD-%|=KYfeYO`yG!_PPHNyDp}a^sCM(s!;pq&-TClYN$z%2navQu z=PQeJQcKsb;R3{j@|%5Cr4F--%dBvE_>nEwgh@`jMM8a7y&(o4=LztU}q> zPE*0fjwZr5R5KrCvn`>|vgXx_u;t9a?WnHqgxxq$QGJv02k{X+%(0Mije~Jb*%L(x zIqRiMe{UIlKdZ^}zCstu`5eoBod7LSt~ zKN)c;SCd54HNmdIwJJhZ-R?kKXN<{w#I^XF|6fncWuq z33W=JF)k@KEBvlqT;6gNQpc5)qT<6zeZzgY*OHUo*O{)QV89+(h#do<(}2m4&Sh_rgF zwLsm+Uk>Q*_oED43R&V?!6uF=2gAl%t_v#&i<=tDEm^9a)`^KHdUAdB)Mzrfjd6`D zj#%}_+m&_%VHg1>Ekb5!C+!U8w@@9pF9Vjg7N{TR8u!oINIguldD$gDx>z#qli?qK z!ePur5X?PzbPBqoI1`oqLg4c|k(z*FblIQ#swsBHwA-T8SBh$-_F<9i*(>6SfIFY< zQ)_~GPjJlmqIQelmYYZ!VYzIPY(LWh^@h^B0FevKtt_^kfsA1GnD_DWQ>BDwOx0_??YMLNvc!E8HHuYQa$QksTFP-UQdCXuJ#^&HJ!y?#6o>W|(v~EK_`7fMi@fw^$1%+DM z#^}hM_O_5RwTjhq?WYTIqQ7Ve1p41J;ixqtYX@zFu6J9$TNAyRc^tAclIbnzmK z@Lh!tm2Z1buB{#}_vK?Z3=ChczL|osV!%%tL(*UME4*cd9w(Dc-f{8@KjY`rKC6X{ zljEpdxv{XfENvb9_^|q2(uj{HRW0(WgMDIgGdks5?drr{WX0y~+3NAd;@8U{w>Ext zH(xobm5KN7_OlmTvK+)R2~KrFsKpNuH`p56=SJ2i!=e-|0!H4yUA%_8OFN5KF9Jk1 z`b!24)Qe`8_Gt3 z{*z?F^hZXnWfXI_kUvDSNaVe#a`cT^Uwz-Vv5ub>kNbq)QGH@9gi8>7&lJJ7N?(^2 zlR_o?Pp^)M53+JGP?Yp0?5w!z_G)Z7`u^dfV!{@aRgKybcp^Ib2W(ph;EIMcNFki2 zUSwt8@!)dejU1IsJPs=DVm0^c>cS|+ft?jY10Y{vZjf5u) z)I0iZpZ)etI-Fo`x=;75H>ncjgjeqWI9h)*N}(zHuG3GHriXjtD7Q?aD#SxlNh)&y zaaHnp7=4jykvL=wYw)=AuU<%8-PGK)kDkK3Iai=&@D8;11gYI)+Tlc5ML3$+@0MVU+M*$IlG~BQ663v83t5qmb*Ha z3nG1!MT9t6gnCpFk$=pIl7Kw|;3h<_P1!|O0{<=I>x#ZT&g})J%p5{AfxJ?UB*2p?u2vO!;qgZ zY1hVu6B$9$RheJF`7!tHA1?a9(F(PT)Q=y3gZA=g!ol_C*SFeCMY6fZJ`{waRX-gC zdrzzlgvs5>t98n!mi*9jL5>D)xGieu6FRtwh>Nhy@1Y3vh~*`G9GV47bKaQlqsOJ} zAv${EHYV-xs%J}zzev`2yCV~8qJ5Kg5ONL;_K22G+kumGIpvA$g#P`Oakm`#N`weU z7cJ4jG_EB)%bg_L@%Sn`jE<`N7xoCi%UL)L+spR_H;lH+hn=4ZY}Wl)D-4%{=?C%ctBG_hWSF`&TWmq=7;b zT!6>hnH<7h&&SG|emOGak(Mz(q}d5$U)nR^Z(Hfx2Px?*E5r(s7XUnx{-RgdUyXF=rx z8Q(fFp+o!jT;%IpdjorgpV=f%?ujKx#yw4){ijVU?vw>T!cig{J}qKRo#HyBhjM5$!af%@nI*bC0S!mdmuaRbp|LGgQBb;R&hC7oogt8Ztnde90=Fx| zD4SnVjnn>d^P*$zz*MTqeaqlKr~Wc{`Ol#Lkrz@_5eSm5L!51sg1SGT@JF+drn!Gv^4vLgqa)YWSW=wd ze_nyl*vW4b`sp@N$-lo>UJoUn01ED{-aFZZ&F8q)M`_-zl5ka=JuO8F-bc;9vv4~i zE&zx_oxX8Hv!@=Z;x;r6x48cD#p6pUs2AaxzGb&OKT6l5QhoAQ7q|#=t0*7%1H6A_ z$g-51ZcDnTkC^2v^nC`8EUq@)(fY3p5>?lt7=H09wMQF|Jz`lQBSCTZ{{z+kT%vYf;x^LR z@p4%wqeu_ul1Nql3+A4s9yx=1ipHJKS7SD{-Ipb+ohcfg_s!j-UdtI2dP&v!Hsysu zBs5Wyi~E@0S!10^iKR5@JME{DJs9N=Cq4qs+UI=}($nTVG4l5ZwZvXhCGo8KZa`E= zDw`h7o^d298*TPu9qjStx10QshVQ5hk~&oqDvK;WId07sHZjIyc4E)7993L(;I0oO zAmi78%P3h+`mseYc8awF#!Mfwtx%Hj8&}bDEcrZ>%p(k~FU+hYobCAF zINv|fu_D3jKha@8Jvm}EO_=9XO}8a?--28{%{<>lqdKPYqyA~uoaz)1I{mpKV@q}b zCv@Y@3p!DzrE0)TsNusNnxgQp^ua~4%1g~WsvoCqrSE?-_YYgoF?XwHj9`4eI5HVG zaaq!BLx?_4ky7F^R0D%+hqHGM9r+O$>6REmla8qogaM zrJS{a(hs^n&fieOeAQoUO5F;~+;Ry8hk6sc-CNmj9=U&biaE&VTwlnd5&Y4>{D?1T zn@4<1qyi66Ci?`}H{444Q)t6$NZE#rpe6uytERNc%>2$r{Cfe-K%gt zje36CNQl3}9Z5hoHX}kw^WSacZ+C$v)GeFB=$_w|;C4X#S8hrDnfCBO^*-x)G{_w<6|ApH(&maAS0QPca>1-v&~jh%9`G5`B?^kx?pZNX?T;{r_4VN@%Q zS|=E~E*I?e7sm5$hConr(MNfYtgf%|4GlJ`S#{wyQ*LuNehls8YMJy$)KR9<#E>X4 z{5H*rCbO?h$~zL}8ktQlec|B!iI=O~I-%UYp;I1}~S-@||iQ9AB$XtpA){ z_p-a7Z^vCe?sjCi-#9rgy?`W|lDePK7Zb1mXq=0)sbWn@`~5Onn`Rr@0Ed^b!Uq$3 zxVFE+Xg|=x$)teX0U#p`a1#c^6BF$qB3MPax6&KjXQb-Hq6(E+rIWu={kjd~T*ba= zAa@H#wj+qHIvc53MH?q7rB{F*0I}`Ri81Baum4&XL|S14Jh!;#mEf?$9V0z|pcitT z3pCRM`n~&MT}#+2)}NoAw|zU_rUah8Dmd##-4chsX1EmnI&KnU6Qu$H1;u@Kdf*O! zzpdQFf5)5C4^gK7sPyRat-tm2*Fi}@K8H1WumM+l9)CVxQl}~3{k--f{`*Ug!wI-f z>cvWjjByNnyF3cQ5sS^BE2WHDdA^K0vngiq*WDFq{8@rk?(=+nbK3;z>A1Y(EmO)u z=w^ckD}3#HW?4Pum)|X_qw#MP@GzgR$e1auCKc>tgZA?BsGJ{f7HlURS*C*;NQr!^KZUA10%tzaRNM?U zDF+4Db~1o#zZ1UU$YOMldLyl0c^#cv=~`;2eaQnxgBklTF#i=qp%_pW$6q0x6b-~g z_c-(?>q+A~40)VCBOCM$q~^>rnz^=bB}8{Y@30NATc7)&aTGL2htykcUJreFa1+h(QC6&H#Rb*IxqRDvvk)0yz$otO z+AMf8zs<+E^KD|g>6`d3QPOVl?)6%_OmCC@-I@un`qlb!BIL1e(C?nitz$M=6tnP% zwn$>|t5Pv0tEBFs=<#*8dGA+X1l2@d(^gJ~StQf)py0=hL^`FYizi;zT5cw`N$tCS zeE$LD|Liz4`WFI0@shzg*wr_Y(OwZHlu?U?Qb1f73RQ<)vra^;ue5jRR$ahhcaF`F zuYiF5PXFPo){|1&;-R2DH2XFiaua6?31LY*G-Ho|7fCdP+6WP@#4gFvd|QVN6{tCt zdKMAA9%1pQL=f+!JSSQ;iO_IhiWXy2MTTR6r=umTA{e$@`d^ReY3_O12i7!W_kKA6 z&-LGZXDm^wu<_v9Y&#o6RstOZ;gw~5hnk2YKJJ?5Kw>aG+p#jx9wXND=|ef-{Lh%P zfsv5xu+gBTbGl#OA4|3cv(1=t0=^3&U6&nuX>EU~sdFsb*! z(6X_fbFXoIFe&8wRNKb>^p*LnmH4HSZ*jtTSUEs zS<|lOhsRppZ+6jX6Ir!icifk`w*2-O;n6*k-+opC&e`vke3%k%GD=`VGmgTLp#JAu zLL>nw0p1RhBFIZ>zeJ>siZ;z`Bjo_&*1>a$>*o1wrQqBHN$84b@R?!Z zPFa{59g@f^87uuG$S-;^In|a6Ub`CvqWYM;yBMGoyU2-eVsz3>n09cfK7TpHpgPfQ zl1*Oxlt-Y?vEQHa{|)+oF8PIfmwoI@+EK0@R-`AAl4i7C3r+8AJ3ceVdf>vibte&; z5QU}U5`1w^@DkUZg~N+1Pcf^yrCzJ)2wW@Cu-KjW`@KyJNTDYMiHEECqTU?k?-hon z4P8F1az1Rh$GyBaO8BOyo7P|dk=k^c3{M1u(()tJkTubplxZ9N>EV@Ao-Z!Q%^9{T zDy1d{!1BCl`*s?=e-)@HxhFWJEs)a-{Ni>De--A4Z~gH>m=aQkOo$CUFJ0V#&{U~q zA}P2`hOuHnZ12N#S9*IYT$i{+2IG~q9_cH8Zw|Hk5F0Jsxe&m8)GY5Lc{AuU{RfkmuGJTdLGEn>1qx0 zy#i(kg#+fdM8G*#V&ENGfSU8%>zHwtSt}t{2)OgG&@TrP=cPf0)OqN8zoN|??4G;C z_d6a_3aIvvt{jL9nfxWA9hfhK3_AZFlVaN5_@;Pl1sDT2 zUqv(M+hag%p={tKD}^gUyB8}%y+0Z6&UTq-kqL3=mdsz)ZyZ@r)kOKj)LS@wTZwFt zw?`2C@VT9#`sC_LC;mR)AOKuzjt{=LE4sbt4rA;2z4Z+nHkq;u3z26Aqz3uvV4y8d zn8L`z%;1*@ZT5(f{C(?nTP8q3*WGslW7UlJAgjk6?W_?jKWMBThb=Q^c~i=3karn2 zgvByG3I8a+dA|n65R*#3v(V#Hriq?9oh<9GJ{G803+0DBr5mB-jWqsv!nB@9h?uc6 z#mYPKq+$$ktywjwl$9wqa5!X1oA3UTRg|V^tf{hBBj?%Y9t zF6>`i6$nC;8?1k@zkh3(|H^^>O8OnDtp!vP+l?hNM;o3|N**YtqQ0CW3$LOVnbV!z{voB)kLh^^9nutDtcy0|EP zl*HifosLH(sMRx4&XH!K-@y?{7#FqJdFs@Vm`p4xZLYXPbU!wBm|IWCbPu+@0U1I@ z4fr7AJqi+h)(e`-Pmyf=augy0A)p3bnY_s$Ku^{__%k;fGS@)e7D;F3h@X)C)6>aW zeZNL>XFK8+5PVuVUU;}Ao2%nPJzPpD+pL;+@CwPM zcuMzzd(%U4kCoF|_wivt=U%P^>9-b7nF#VH{`e;*cpSLDFkEAj#u^v6xu4j*` z{aE$;?+v>VOG$T3SHK*D>EqkQR!~qWH<`Yky|QqA{t~UQ?#vKVp>3SB#P=UmY(XO@NKjps9me+f!geQoq zSV3^YCOZgx?{#H#(-KG|H@3&bsL$&eyTd0SKOQBssVsZbTIkL@vRLh@+1IJl%Az>J z37E_l0Qxqah;i1XDVf7bp3gr+miu8LaL4cX6cnG2=(*bj`{d(lKgL~V!7`@xzQ(MSUufs z5((%0_U)Ufind0`V|5uscwDTh4=qw#3V}l_8_$8NAaQ^27L%zG{uqDyQ#z3^ZekgK zFS&#=5CeSkUyHo|8`gqyyD>;B(5R9&!!Qf{=VhS}6Vrdwxxcn;dz1Tw|FJfr>0P^? zbhQ_!($$phd~fk^X05NW$Ygjjs9o^#q8oxDH7o|HFT#_$rTpiHyAQ(U5WoI34}u5f zJeph~e9wV}2c|2CjbDOt9$w&$pf0?Fhbu6X3%M28f*P0tRtThN^R=x|V?p-E_BhJx zkT)@$)xBu@W8%sPeCpitO(V1V#s#A2cE26aEw)pjrvJ73Z-vO&^V0_Df#<4$CYg(v z5RL#z)an1Eoi8zXU~_yN&$D`!+La@Gafq{cB^D)RL7>l$0V&D1246_t`fg^PUl9?7 z8|`|bZWnmA2q?G*9V`Z?-A`_0_~I54ac4$+Y%E7#=W@4)zmD8^z9eAn;4sL)H8)&g zy!}W0`o+<1TK>~B`sT~B3rbydf2`%4+Q_GQoyHcQWVP0z)SWA{jKxN3e^);EdH0#) zHc@anzn3sA`=u-^68(gcme#APLjC* zwwJNqlYmL*9E~>b9kRhTdaYK{DEu#OhPNlIf7{x6T8Zhul@wEuvwLB`t0VDi5a#J+ z3G%Y_^jRxSd?EYhUNXquR%oBd%ytOd%XZ;eXUCTiHHe&!bPYixRaCn)5?8pI3jhCx zyZ?#8f9SRUtW%&@YG?AEG@+}0d9yCMY$bZ*2d0o8G-|3qd|~3Kc1$n`g#o6O1;P&0 zfOxj~_o|p;OFw@sjVn+`uqNKV9$%peuH~Q&t>dziG_#C!w?sTO%Yx30q9J*39>8Q-C# zVav8)Rc5%a=;Q9TZ!U}yA)nLSctYTN?_HL}*a+c#3b-l$sXE(LijStK2xRu|8+;#^ z>$lCn|GMcrNtRHw?4t-ta;Pq$q*;{nwqzNjpuEj!0w>$IcSg<~{N%VwL;2$wb8XoM zhdb{{4<%#ip3G$5`2QZ>HU9)#2)R)sBzK!4)kqh8zC8>}if2;Q=Q`3oHW5q$5q}YV z3Dn?!b(-(8Vb5i17}?5dg zkhv!tJT6U*r^&L|OMZZ0cI7QWKWt(CRibx8%O0#SSZiF$!{tT;;s$XHlaj?vOx8=n z0yiv?CE7CD-%F#Id{3DYn{7tj=qikG(lJ|jvuS@jwA2AlZ~>Gz;5j}7I%}scmV$1c zQBX|V+ZG-dy|ST$C~$HKW9=*HH?4F&snOT4`9V_Wa?F~B&7sm`VFso+@g3Y$T^-S& zg?EMmebw7Clyeg(C_Lkj1;LE|(3*~7JEJ3T6tIc@b80lK>1 z)g_C$FpQ}7NB{4omm?pz4QrgkMyT)~n$3U4{Vn>%yT5@O%C`$HRP>#YUK?Kir2ab_T~i$sDuRNM~r{hM3oxp?32$}aD^GE43`;PkU= ze0+Y{q5tbbtTR-S_?^55@ntl!o$$|s{Ue->K&9VdxcL=u_inVQeqD{w1#<74tYP0F z%T&_8{|393g$3YJPJXj;+#ee;QH2&WR#uSD(m)=VKM8tixAX7?`uV$-bxm;B-pZa` zo{W?V(A1>c@#)4%WBDK2*LKYk^wEeuw(Uk&dWiyqN15IyVRx>%E-Vtz->Y{t@K@ln zk7l&gkISl_!5MB5pvGsCY=)Au?x zN^PLe3nBG?!9u%5bl_F3Ciavw_fsg0DpL+o-RZ;WT0vU!UX31kJmpn7Q7leWbPh+j z&g3SpBLu`x6=Z_>R>Do+PWlJ&>$DMqHwg9IhzK_3Qd;gxs?^;zux0i#2IugtggLr*UmAqqBIt%)=@PS?XiE~Vy~M6)Zzb{EYPRtl3Y-S$H80rJHmO^^m|q#86Qdv?aFCqYMFK57 zzcJ61>c<%(5_UxYr~Z;I6J}e8P0bU519RjfUxMdi{<|3UpOfidV)4InZnO&CMe;I; zDcLmJ#}wLMd0<%ilJrm-Q4i6ERUC-xGQfAI!ee6s&1v*2p+I`_a63O$u1Ln3c$}W@ zEdRT=+o{5A;GkY1>M+|}F$%MaySltQP_2Q9-2$}xfinqf*fLioHG|@^(*xzd7RV1h z^yezSUqc*4mXls<2<2<1k7Ri&{uIhk*O`qvq9>HKZj^n`347ug&06-zg9gf=w;eeW zL${Pbxa>&oQ4s4y2^9xi(w=9Fa@a?Bz@EUMVarh@3b0o)IqvK&Y0R4@#A^KPw}~2> zK;~8Cbga`4%|<@wqCR0x@Mn0tP#Bxah@-N!IQ39Sqb1~LkJAUU;Ew)E4Fn$vdw!7s zAC0X_#|snxif6H%(tvqW^o-W7QZ z1N_|=_a>1x!4_HXU%`*Z`YvUKQ%{g2;(SNP% zX9+`7m;JymQdEtADat|53epZHrPwIc(2J+Iz`1S)Qi6*+Z6Rl?uyK`URYgR^D^ukyQ;Sm6O{y1W2)lA`XIDFmM#WN-OSDKb8 zuw{5f!-lTI^>^aSOnJl`#ojjbd#T<>H4++jcOBZsd13%PVQ{KbX65pkqtU6s8PV0Z4BMowo~G84CvtpG)Y-s8O}H^12t7~$kMWX0Tus> zNQ(iLZ7h3^+7m2w#|bjuzYZFtI(p^-xYIYu1sRGbX{Ge?q*Ntw6vRsR)x_-hKw!Um z2FxDlgqv|fXBg_3@4`l+=|;;BRy=@v8IR7SDUakuvlyvSkpO129N2HOKFJEt_|BOB z4dj$qy%FOJWh&)oDtIX|bq;fE)sPb_ECf0I_(0PgFiuZRancq1;jx-LP`@SErV2-( zx8e~6Z1TRpnQoBnCH0-s-7U9%x+&CLcf&|m(}lxVha>*ESk&LNvVTqL11Vr5svKJh zf|U6~I(xhLhjg|C2c6~X;FO?D7JbkRc&3^n%9MpxR=MaVMAV7Gu36rLH_BA02NhMj zT+h@xSkH-4M?a9U>?Lw=B4;wy*(*q@&#c7y=9hzks$epMncQFD!mvA0pUr{{0d>%z zV`G5dxQoS0x>#yFMiZgZ)$2FrfBr4o13%6ifLI<|KsI(C;lw4-(b21>&vm|wUCH71 z|C%F(@RT}Q=am-8I;fIhwin9~W_tXXe~J`xP{^wu{OnZ2*J`Bl6)p12mI>~X^k5AC zHxAg{#0Gqk#>gA+hJ+SLXv+zAk@e6N+K@$1O{yTQ9z=SAUK7D4GmaqdtrWFlrB$K% zEXEYQ>~&qviWCD*nc6_nO4fWc)V@Te7wV{4cTn zk6Pb<7FsA(fE5Agr7_`C04x6gLxK5s!u8)!!^8lXW3&Z;F?dXX7@(y8F~?IE1%Jkt zCIoIwk7EcKj;Abs3c|m#qhJaEw^^8!g6%iX#{{Tuo|sp(7Gax+kE_+1rh_v!5(nb; zT(>jc;kX_uoUqQ2o%}#{_Al}EBrks4SX&AT*-Pzjo%-3jp6Wu{0s}5CsS0iBWK7J5t zmTah@;Q>raJvU#tKWuDxe|GB5XyD{K_Z6FYg_gHT<@+hV&8w^1kMaal4N=Hj^{isC zH}}M(6uimEJ=9Eq6@j1n9-y|#2`Z)acn<=IZyN4?ca=Di9bh=-!UL|}0Q)cq)%eX( z=JI`lR1AA;L!15rD$a&pZYgmDL}CQP@iq;YY-AwoM}p6mdWn)SeX-+{0tpt%d~sSB zTb2fTt0|HfEooX7IGY0oGIuN(;0BV%1Ig?=PiG9JW?r4^2qLGH;2YoEnYU%httWvY zw)w;eD*elymu{HNKWtO-`aVPVUE*oPp03OFAEc8@!ltq%xFx4SvO!=0M^@fh^gFxP zgqu8RpTUTeH#T*@gZn^rNQ<009V1?s`i@9k!r#%n$X)y{pR&0g?_duJo0aOWe0Dxng!?Qy_SPgU3WOz&8&=C%WChH4yf+K~9ez_f= z1b}bW8&5^ob{Ca>ZbZ#JQ>0^B%;%}UNpG9?(b4g;2CC4TghmbsU+Wz(R5rY4by=>SXP~Iz%LD@pu+Nd$)!KXUOY`tms)1A^{;O}^ez$v9 z`(R@RL8EmB_|EpkyQVEBL}NgL{T5f&sc#wCkT=`VGW#2Ep;-8_dHrhcPLNP0xpDI` zM%KizZ+080wXSKsfx}Yl2s%X@7uV!^EG~~o&_6MGg-n14;J|-R+JDL6e>2-N+I=5z zgyPsvNLO%ZSIpsdRXyVP;ZRb7)kk}CtmaGmsn4X5-69su(Ic(5Wk9;c&4a|_k$u$$ zVgd9yTACnYG0lbec#z!{>EIZs9G`WKoeN9tGg-x=QWBZ$(#MshU>QYQJN>Q1+Nw4m za|LsLR*f04UVb(Fp3)AyZo4L;zKZV+5yYAv9KDQLfxsQP4s*{$B3{|5mI_>6B(atB zH~dep?x7DNAItHwsVnTTVD_kT3T+Pw2HCmc;bN*ZkP3&mM!&V-Wi-sO%yFkw!}`Sa z>fNT|eWpY)n96vBu1~V5QK@IoR3xznqJPYN{9d+Lgr`dD%rNM(q5gB&vVe}@hN@v+ zNRYPSn=Pkd*7o-vnHvrPiYAs&uVXX!m+!FD=w&ZWt zPHgls9L$X}C4TXK3vg*mfeHrGB|#79KBZ^Dwu6p)7*P3c+=FU&5Fy(X;GfRmq%@ zhk;L9EUSG~6L?GPm13uTFVj8VI1_x{3SDQ+^e~j6RHM<`N4V+CZtHkk%3-;_A9!~!UJKdI7=DZ;mg^fUB$!GNJ;@Yay`pq(KZBZ6f*`WWq;uvxy3LC-9j z#Z+Q;3Vslz3&K-*BIJ)dqm5d1?LQ`R9<_nkOZHjM#;pDF2>S51Y7KpQ^7Y~r^#}Xf zVp*n)%td)&2M8mnIzH&PoUpA@KyrJOeZEeby>iqJa??^ z)Ls?azC~bRi6cuJuk?|%=DLHU{TEylDmMbhE#TTL3ai#g?bgIXP?G6~=KcruB71=32u7=`5j)br8xBJA$(ip{@T7nVEw^y<>i*+G1I1QW;a(h6} z3*U*UTxMNJw>JThG5K!wl6wh?b?&!q467_`9TOS`S7>W{Z5Lh9*sb-DrRdxPu_kr&~3KU3to8m)W)Jl z;?$dtmmwaA}zQ80mzM%^4BSVfP=^(q#qqQYhqhO-x@Z+u%d(m}doy2;q$}l6z zyf!0lZ(p>Ux~2{hZ`~-W>YL$P1kFjw=Gg3^5f<--44mBId$ntsY|>)<)h|&<;%h!6 zKL3E1tVl`Uh{2AYvG&onSzneDsiIIH-V#3#oTX_4ChNIe_I4x>sHQ*5x0%*B`z`g` zftmX_*iA-j97L27m5N-6*xYVf4GsfcT4_pDhnp{Kh}?OtMe$P28Ia;Lt;jk5^u;kh z0POkHGV?y(tMR`4QcdcCS;}ii;A-K}{7F1^AX5-YL>MoTX1Cs-6@2g$Qn3;ly*(YQ zBV6g?+7j??Sq@eJJ1a??OhuR2Fq+wTC;3mOvhZW3xSuMy-=2Em^a|2$#}bHOlkwf?Q27GfEy-V8{o`2Qy^G7 z5ZuDbgM7+^B*QV+#WBCgX#*8MJ`V|CuB~Oadc*G3X{euEDe!vC)&ZfEQ(L;H@OxOB zRQG;*t*sdgF`ivNYcgeDg`#QXhNdDw|5te2_~}uUEz?`SuV1F7L0Z;0(WUz@WQs~x z^#~02`e!QNAY!`P(N{PPiQ`(<7*~nq(#RvPWx>RWtt=sYA;&<#IMHert?mqdsB)3^ zgYH4|>$mgVj%`f1*mG8-{fus*9L@-s$d^zn(wuOu0k)ED_vxGk$i0)K%?3I< zecmuQZJEVyMVFZGuS=QKCLWU~HQbhl^4Kc9J+xws`(#FCOs|y~*(*~(OxvHRD1};_ ze%TPUM#!9!9#!tD_|^*Kk?_SukGU+Ww|kYm03*pXK8QN{!Jv7k+;HQxH0}2gRR$^! zxl_y!RSxvuxss%p-IVoTj1 zedVf@hL;l=Lv{SJ3I>s+n{mih#^iCUA2sH=Vap+T1uAB4?I3awMFYg_lPGH#fnzoU zRKi|~&*SM}GTo@Q8oY#Moju+9+ByG`ux<||W+8sXIa~{)ucGIQ`Wdr$_jrvPizD zChhuK?IZ^Dw1$TIUcqux= z!}?tB86fsKX%)}M#LxsB{OVJ#8rk^;dK`q6wTh$`XN_dT|2 z%uS{N8E3Fxd@E1;y$Zp33Z$gmBPUE!ll2AZ{X)Fz^`)(RUij!`$W@x(_!n zx4={V)Sq>XC+y@>HLZ^|<|;x1o-~+B%8V?jr}NL!%J$+LP_w{#h&xzA^r9L`I@JRb zkc4?o3)W&CgoQM=sK&yyiLJDh&02fs$IP3-X@>PB#K}6`{Ld#~10XJh_AvkYXg}!( zgM2NWfRLGTaUvrXu8F^Zh*~31J-M!PuOFYl94;D{pv~q#g>8sgyrFeeG2s@0f0`M-HBKgQrKsWL5F08f22VaQJ7oT!Wk z-TuUCfum9G5FZfd)|c@)4+ z^zTfmasV`;CMeh5Q71aXwX~O5ig5te!hoeNi0fQY|s5Zd&{aNfy2lEKylhP?)#)kTPA@8bRxu$nT{el$45PbBImh=iO z(DSF+JPbNtiMc}J8lfZz7`<~SltRN#Ef0m;*Iu<*!6-0%AJ~+E%icvFu{OW#43^jP zjWu1$cxSCk%Ult?7?i=cL-cU)3)hB>fM+K4?-9GFI%LFwm-$5%U{|Hc!KGg~RZUr~ zRfjA|G@!P2J#79kZiAh zNER&#MHFa8O755M8!P~Mc|82h$jxQ%W6-pJ0$<>@sYK?zZ2;f#&)vk~12Yz8>!qa| ztKBXr8v9!CVe3F%*tRW~1#rCqt#ov4@@;N?FXMAn##(^urZdk?F#(pj9^_HX+!(3t zc~^4iV;W-|duEdjO|9#8xi z<CFn&(5wS8CfoRuFXjDCc@lUdCwgyCv_u^V->|8O?|g`b!zyzo7$V!(LSD#}NvC zb+#48q_luRp>{5o(WMm&yE*tW0;FhtO^wf6Ox@f0X;~M&0)!l zH15$0g*dsF{UE!P>jx@nYiOGman;^YJB2Ah^5(ET>YKb&MASfUL0fGV+U?_?}B#1!) z<%I#A>&(3Me!Q~YdTYJk`<{Kz*>`{6-Q}!33BPKMe#%}V_T&FXLb@(?O(%R#Sh=<% zs~~%%&dXab4QM#fh>!Aaw*zntrg< zNC^V%7=hLkkMs`@o<9#$`RRQRV<>bcbN(k#&@(B9X$f0oP~$~( zSkCM=ed)`pITLhk6Bl#oi&kp5%HI7dxgrD{gDn`z1g-sFiS;bn+A|X zXXaLKHmM3~t;C2q_m(_auLL|x^SSpS4%PWnhZa4rjcAoWkaLf3cgRogV~T4@p&s0V zwmvcn1ihHC%BI|YVpK5aeCv2XS+r)s{^W{gyK}jbFQ0tA9V$!;8yN@Kk6mMe6Q?i- zu(M6fcw?^%PbMaviHR;)4s!Ah9yHm;UB&xMEj^)@>zc*{TFUTi;N+b3J2_7kq1l)R zr{zTLs}eGzo9xe5jWZUfAb-^wJ7qMzmV^Kc3(1r>=lQ9w}=I3VaxC_8dy0ry`?R z5_G(DZ`$s7ngMYDeH07h4-S0PLXKgf}1fnbUti?f=4`rEmb?4Lm5>$emLjs zwmH?3tgqE3f;&?L6*Dx65%pW;(TKLYM^y^)liCA&-uYUoD>iIQM+GSAQVz7w?;SnL zvOQrQNQITG#HdX^Kil2S<z`+Rz63-TBrZ7IAgAxTn@BHeG52O|qsP|i!i$YXJ5Ri@^Vr@S zqIuL)Xbz@3++V~xVH#N8uv%S1ICGKttla8kW0>(A8~T(RSw zrDA^OxYpC%kvGJAU>-KKc(G9&jo|V01-;d5QGV|R?0hSWm|4!sZ)Z-bj`RU&7~j#d z7 zjPlMPg{*5p2$px@;56iYZRD=M-tZJiZ(7?DbkNQkrkNqBO-$N5he`uZK!_Tp7%a~x z=1Pr;)DgaZQL@P~{MY=$=V>FVh%PewH0tkL*|f4sPcx;hEHZ|x&jWyXQsVhDbWj~~tTMyNz?sG_=;|E@r z_J-{$bY_k>w)HX`Q!n1RKlQ8hccOvw2^SU>N1@n{rtV9johyI*09ygJKzDiEz^Y~Y zb>?6Ku4f~5cyT%oIhJB-arvAtM=iYjGkc-HhXC^^RM4mD!dLY_mt@P=YPZcgJXQ62`FbZJ{ORW_)7`>F+u7u= z{rdD17FQQTXRlZUhZ;zZKj(xSl{nBTk?wiFDoqdH@cWBm*;s1YpvWBBy*9nCIAD#E z@uR%2Zj3PI{+#m|WvF-&hCXB!riaLMDdgFNGDyCW2I^@5Tmqy}d8}oHESBeiAse_E zP$%xoQ*haj>a4lVef$}y9}`*Hkc#w&J5bNjGQcnEi^g(X_&k?P9CmgHW1_%Ymq!@V zdmma}dYEYz?s|~geBHL(Not`z9x1&U3=d3+N#QhfXocsOCu6`Os-J|BUcS?lr1EIP zn+IeUFG$bO_FiIA*N*T=^-BW25yujd#?JQGg(k-T_^qq(e?51;rC~5`JTaA MncE*{9U~Tg>s;4$&ilO2`G~$~q{Gc2%mD&{ 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 literal 0 HcmV?d00001 diff --git a/interfaces/innerkits/account_kits_headers.gni b/interfaces/innerkits/account_kits_headers.gni new file mode 100755 index 000000000..0b8aba136 --- /dev/null +++ b/interfaces/innerkits/account_kits_headers.gni @@ -0,0 +1,23 @@ +# 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. + +account_sdk_headers = { + header_files = [ + "account_info.h", + "device_account_info.h", + "iaccount.h", + "ohos_account_kits.h", + ] + + header_base = "interfaces/innerkits/include" +} diff --git a/interfaces/innerkits/accountmgr/BUILD.gn b/interfaces/innerkits/accountmgr/BUILD.gn new file mode 100755 index 000000000..6c9137415 --- /dev/null +++ b/interfaces/innerkits/accountmgr/BUILD.gn @@ -0,0 +1,62 @@ +# 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("//base/account/os_account/os_account.gni") +import("//build/ohos.gni") + +config("public_account_config") { + include_dirs = [ "../include" ] +} + +config("accountkits_config") { + defines = [ + "ACCOUNT_LOG_TAG = \"ACCOUNT_INNER_KITS\"", + "LOG_DOMAIN = 0xD001B00", + ] + include_dirs = [ + "../include", + "${common_path}/log/include", + "${common_path}/perf_stat/include", + "${common_path}/account_error/include", + "${services_path}/accountmgr/include", + "${innerkits_path}/include", + "//third_party/json/include", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + ] +} + +ohos_shared_library("libaccountkits") { + sources = [ + "src/account_proxy.cpp", + "src/ohos_account_kits.cpp", + "src/ohos_account_kits_impl.cpp", + ] + + configs = [ ":accountkits_config" ] + + public_configs = [ ":public_account_config" ] + + deps = [ "${common_path}:libaccount_common" ] + + external_deps = [ + "aafwk_standard:base", + "aafwk_standard:intent", + "appexecfwk_standard:appexecfwk_base", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_L2:samgr_proxy", + ] + part_name = "os_account_standard" +} diff --git a/interfaces/innerkits/accountmgr/src/account_proxy.cpp b/interfaces/innerkits/accountmgr/src/account_proxy.cpp new file mode 100755 index 000000000..e0f31d881 --- /dev/null +++ b/interfaces/innerkits/accountmgr/src/account_proxy.cpp @@ -0,0 +1,132 @@ +/* + * 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 "account_proxy.h" +#include +#include +#include "account_error_no.h" +#include "account_log_wrapper.h" + +namespace OHOS { +namespace AccountSA { +bool AccountProxy::UpdateOhosAccountInfo(const std::string& accountName, const std::string& uid, + const std::string& eventStr) +{ + ACCOUNT_LOGI("UpdateOhosAccountInfo enter"); + MessageParcel data; + if (!data.WriteInterfaceToken(AccountProxy::GetDescriptor())) { + ACCOUNT_LOGE("Write descriptor failed"); + return false; + } + if (!data.WriteString16(Str8ToStr16(accountName.c_str()))) { + return false; + } + if (!data.WriteString16(Str8ToStr16(uid.c_str()))) { + return false; + } + if (!data.WriteString16(Str8ToStr16(eventStr.c_str()))) { + return false; + } + + MessageParcel reply; + MessageOption option; + auto ret = Remote()->SendRequest(UPDATE_OHOS_ACCOUNT_INFO, data, reply, option); + if (ret != ERR_NONE) { + ACCOUNT_LOGE("SendRequest failed %d", ret); + return false; + } + + std::int32_t result = ERR_OK; + if (!reply.ReadInt32(result)) { + ACCOUNT_LOGE("reply ReadInt32 failed"); + return false; + } + + if (result != ERR_OK) { + ACCOUNT_LOGE("UpdateOhosAccountInfo failed: %{public}d", result); + return false; + } + + ACCOUNT_LOGI("UpdateOhosAccountInfo exit"); + return true; +} + +std::pair AccountProxy::QueryOhosAccountInfo(void) +{ + ACCOUNT_LOGI("QueryOhosAccountInfo enter"); + MessageParcel data; + if (!data.WriteInterfaceToken(AccountProxy::GetDescriptor())) { + ACCOUNT_LOGE("Write descriptor failed"); + return std::make_pair(false, OhosAccountInfo()); + } + MessageParcel reply; + MessageOption option; + auto ret = Remote()->SendRequest(QUERY_OHOS_ACCOUNT_INFO, data, reply, option); + if (ret != ERR_NONE) { + ACCOUNT_LOGE("SendRequest failed %d", ret); + return std::make_pair(false, OhosAccountInfo()); + } + + std::u16string name = reply.ReadString16(); + std::u16string uid = reply.ReadString16(); + std::int32_t status = reply.ReadInt32(); + ACCOUNT_LOGI("QueryOhosAccountInfo exit"); + return std::make_pair(true, OhosAccountInfo(Str16ToStr8(name), Str16ToStr8(uid), status)); +} + +std::int32_t AccountProxy::QueryDeviceAccountIdFromUid(std::int32_t uid) +{ + ACCOUNT_LOGI("QueryDeviceAccountIdFromUid enter"); + MessageParcel data; + if (!data.WriteInterfaceToken(AccountProxy::GetDescriptor())) { + ACCOUNT_LOGE("Write descriptor failed"); + return ERR_ACCOUNT_ZIDL_WRITE_DESCRIPTOR_ERROR; + } + if (!data.WriteInt32(uid)) { + return ERR_ACCOUNT_ZIDL_WRITE_PARCEL_DATA_ERROR; + } + + MessageParcel reply; + MessageOption option; + auto ret = Remote()->SendRequest(QUERY_DEVICE_ACCOUNT_ID_FROM_UID, data, reply, option); + if (ret != ERR_NONE) { + ACCOUNT_LOGE("SendRequest failed %d", ret); + return ERR_ACCOUNT_ZIDL_ACCOUNT_SEND_REQUEST_ERROR; + } + + return reply.ReadInt32(); +} + +std::int32_t AccountProxy::QueryDeviceAccountId(std::int32_t& accountId) +{ + ACCOUNT_LOGI("QueryDeviceAccountId enter"); + MessageParcel data; + if (!data.WriteInterfaceToken(AccountProxy::GetDescriptor())) { + ACCOUNT_LOGE("Write descriptor failed"); + return ERR_ACCOUNT_ZIDL_WRITE_DESCRIPTOR_ERROR; + } + MessageParcel reply; + MessageOption option; + auto ret = Remote()->SendRequest(QUERY_DEVICE_ACCOUNT_ID, data, reply, option); + if (ret != ERR_NONE) { + ACCOUNT_LOGE("SendRequest failed %d", ret); + return ERR_ACCOUNT_ZIDL_ACCOUNT_SEND_REQUEST_ERROR; + } + + accountId = reply.ReadInt32(); + return ERR_OK; +} +} // namespace AccountSA +} // namespace OHOS diff --git a/interfaces/innerkits/accountmgr/src/ohos_account_kits.cpp b/interfaces/innerkits/accountmgr/src/ohos_account_kits.cpp new file mode 100755 index 000000000..1174064fd --- /dev/null +++ b/interfaces/innerkits/accountmgr/src/ohos_account_kits.cpp @@ -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. + */ + +#include "ohos_account_kits.h" +#include "ohos_account_kits_impl.h" + +namespace OHOS { +namespace AccountSA { +OhosAccountKits& OhosAccountKits::GetInstance() +{ + return DelayedRefSingleton::GetInstance(); +} +} // namespace AccountSA +} // namespace OHOS diff --git a/interfaces/innerkits/accountmgr/src/ohos_account_kits_impl.cpp b/interfaces/innerkits/accountmgr/src/ohos_account_kits_impl.cpp new file mode 100755 index 000000000..4ebd51522 --- /dev/null +++ b/interfaces/innerkits/accountmgr/src/ohos_account_kits_impl.cpp @@ -0,0 +1,148 @@ +/* + * 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 "ohos_account_kits_impl.h" +#include "account_error_no.h" +#include "account_log_wrapper.h" +#include "account_proxy.h" +#include "if_system_ability_manager.h" +#include "iservice_registry.h" +#include "system_ability_definition.h" + +namespace OHOS { +namespace AccountSA { +OhosAccountKitsImpl::OhosAccountKitsImpl() {} +OhosAccountKitsImpl::~OhosAccountKitsImpl() {} + +void OhosAccountKitsImpl::ResetService(const wptr& remote) +{ + ACCOUNT_LOGI("Remote is dead, reset service instance"); + + std::lock_guard lock(accountProxyLock_); + if (accountProxy_ != nullptr) { + sptr object = accountProxy_->AsObject(); + if ((object != nullptr) && (remote == object)) { + object->RemoveDeathRecipient(deathRecipient_); + accountProxy_ = nullptr; + } + } +} + +sptr OhosAccountKitsImpl::GetService() +{ + std::lock_guard lock(accountProxyLock_); + if (accountProxy_ != nullptr) { + return accountProxy_; + } + + sptr samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgr == nullptr) { + ACCOUNT_LOGE("Get samgr failed"); + return nullptr; + } + sptr object = samgr->GetSystemAbility(SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN); + if (object == nullptr) { + ACCOUNT_LOGE("Get account object from samgr failed"); + return nullptr; + } + + if (deathRecipient_ == nullptr) { + deathRecipient_ = new DeathRecipient(); + } + + if ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient_))) { + ACCOUNT_LOGE("Failed to add death recipient"); + } + + ACCOUNT_LOGI("get remote object ok"); + accountProxy_ = iface_cast(object); + if (accountProxy_ == nullptr) { + ACCOUNT_LOGE("account iface_cast failed"); + } + return accountProxy_; +} + +void OhosAccountKitsImpl::DeathRecipient::OnRemoteDied(const wptr& remote) +{ + DelayedRefSingleton::GetInstance().ResetService(remote); +} + +template +ErrCode OhosAccountKitsImpl::CallService(F func, Args&&... args) +{ + auto service = GetService(); + if (service == nullptr) { + ACCOUNT_LOGE("get service failed"); + return ERR_DEAD_OBJECT; + } + + ErrCode result = (service->*func)(std::forward(args)...); + if (SUCCEEDED(result)) { + return ERR_OK; + } + + // Reset service instance if 'ERR_DEAD_OBJECT' happened. + if (result == ERR_DEAD_OBJECT) { + ResetService(service); + } + + ACCOUNT_LOGE("Callservice failed with: %{public}d", result); + return result; +} + +bool OhosAccountKitsImpl::UpdateOhosAccountInfo(const std::string& accountName, const std::string& uid, + const std::string& eventStr) +{ + auto accountProxy = GetService(); + if (accountProxy == nullptr) { + ACCOUNT_LOGE("Get proxy failed"); + return false; + } + + return accountProxy->UpdateOhosAccountInfo(accountName, uid, eventStr); +} + +std::pair OhosAccountKitsImpl::QueryOhosAccountInfo() +{ + auto accountProxy = GetService(); + if (accountProxy == nullptr) { + ACCOUNT_LOGE("Get proxy failed"); + return std::make_pair(false, OhosAccountInfo()); + } + + return accountProxy->QueryOhosAccountInfo(); +} + +ErrCode OhosAccountKitsImpl::QueryDeviceAccountId(std::int32_t& accountId) +{ + auto ret = CallService(&IAccount::QueryDeviceAccountId, accountId); + if (ret != ERR_OK) { + ACCOUNT_LOGE("Query device account id failed: %{public}d", ret); + } + return ret; +} + +std::int32_t OhosAccountKitsImpl::GetDeviceAccountIdByUID(std::int32_t& uid) +{ + auto accountProxy = GetService(); + if (accountProxy == nullptr) { + ACCOUNT_LOGE("Get proxy failed"); + return ERR_DEAD_OBJECT; + } + + return accountProxy->QueryDeviceAccountIdFromUid(uid); +} +} // namespace AccountSA +} // namespace OHOS diff --git a/interfaces/innerkits/include/account_info.h b/interfaces/innerkits/include/account_info.h new file mode 100755 index 000000000..98b9b419b --- /dev/null +++ b/interfaces/innerkits/include/account_info.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BASE_ACCOUNT_ACCOUNT_INFO_H +#define BASE_ACCOUNT_ACCOUNT_INFO_H + +#include +#include + +namespace OHOS { +namespace AccountSA { +/** + * Account state type . + */ +typedef enum : std::int32_t { + // invalid state + ACCOUNT_STATE_INVALID = -1, + // no account bound + ACCOUNT_STATE_UNBOUND = 0, + // account login + ACCOUNT_STATE_LOGIN, + // account logout but not unbound + ACCOUNT_STATE_NOTLOGIN, + // account logoff, all the data of this account will be deleted in the network + ACCOUNT_STATE_LOGOFF, +} OHOS_ACCOUNT_STATE; + +// event string +const std::string OHOS_ACCOUNT_EVENT_LOGIN = "Ohos.account.event.LOGIN"; +const std::string OHOS_ACCOUNT_EVENT_LOGOUT = "Ohos.account.event.LOGOUT"; +const std::string OHOS_ACCOUNT_EVENT_TOKEN_INVALID = "Ohos.account.event.TOKEN_INVALID"; +const std::string OHOS_ACCOUNT_EVENT_LOGOFF = "Ohos.account.event.LOGOFF"; +/** + * Account operation events + */ +typedef enum : std::int32_t { + ACCOUNT_INVALID_EVT = -1, // invalid account event + ACCOUNT_BIND_SUCCESS_EVT = 0, // bind account successfully + ACCOUNT_BIND_FAILED_EVT, // bind account failed + ACCOUNT_AUTHENTICATE_SUCCESS_EVT, // authenticate account successfully + ACCOUNT_AUTHENTICATE_FAILED_EVT, // authenticate account failed + ACCOUNT_TOKEN_EXPIRED_EVT, // local token of account expired + ACCOUNT_PASSWORD_CHANGED_EVT, // account password changed in remount server + ACCOUNT_MANUAL_LOGOUT_EVT, // account logout manually + ACCOUNT_MANUAL_UNBOUND_EVT, // account unbound manually + ACCOUNT_MANUAL_LOGOFF_EVT, // account logoff manually +} ACCOUNT_INNER_EVENT_TYPE; + +const std::string DEFAULT_OHOS_ACCOUNT_NAME = "anonymous"; // default name +const std::string DEFAULT_OHOS_ACCOUNT_UID = "ohosAnonymousUid"; // default UID + +class OhosAccountInfo { +public: + std::string name_; + std::string uid_; + std::int32_t status_; + OhosAccountInfo(const std::string &name, const std::string &id, std::int32_t status) + : name_(name), uid_(id), status_(status) + { + } + OhosAccountInfo() + { + status_ = ACCOUNT_STATE_UNBOUND; + }; + ~OhosAccountInfo() {}; +}; + +class AccountInfo { +public: + std::string ohosAccountName_; + std::string ohosAccountUid_; + std::int32_t ohosAccountStatus_; + std::time_t bindTime_; + std::int32_t userId_; + std::string digest_; + AccountInfo() + { + ohosAccountName_.clear(); + ohosAccountUid_.clear(); + digest_.clear(); + ohosAccountStatus_ = ACCOUNT_STATE_UNBOUND; + bindTime_ = 0; + userId_ = 0; + } + AccountInfo(const std::string& name, const std::string& id, const std::int32_t& status) + : ohosAccountName_(name), ohosAccountUid_(id), ohosAccountStatus_(status) + { + bindTime_ = 0; + userId_ = 0; + } + + bool operator==(const AccountInfo &info) + { + return ohosAccountUid_ == info.ohosAccountUid_; + } + + void clear(std::int32_t clrStatus = ACCOUNT_STATE_UNBOUND) + { + ohosAccountName_ = DEFAULT_OHOS_ACCOUNT_NAME; + ohosAccountUid_ = DEFAULT_OHOS_ACCOUNT_UID; + digest_.clear(); + ohosAccountStatus_ = clrStatus; + bindTime_ = 0; + userId_ = 0; + } + + ~AccountInfo() {}; +}; +} // namespace AccountSA +} // namespace OHOS + +#endif // BASE_ACCOUNT_ACCOUNT_INFO_H diff --git a/interfaces/innerkits/include/device_account_info.h b/interfaces/innerkits/include/device_account_info.h new file mode 100755 index 000000000..c96bbcca8 --- /dev/null +++ b/interfaces/innerkits/include/device_account_info.h @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BASE_ACCOUNT_DEVICE_ACCOUNT_INFO_H +#define BASE_ACCOUNT_DEVICE_ACCOUNT_INFO_H + +#include "string_ex.h" +#include "message_parcel.h" + +namespace OHOS { +namespace AccountSA { +/** + * Device account type. + */ +enum class DeviceAccountType { + DEVICE_ACCOUNT_TYPE_INVALID = -1, // invalid type + DEVICE_ACCOUNT_TYPE_OWNER = 0, // device owner account + DEVICE_ACCOUNT_TYPE_NORMAL, // device normal account + DEVICE_ACCOUNT_TYPE_HIDDEN_SPACE, // device hidden space account + DEVICE_ACCOUNT_TYPE_REPAIR_MODE, // device repair account + DEVICE_ACCOUNT_TYPE_GUEST, // device guest account +}; + +/** + * Device account state. + */ +enum class DeviceAccountState { + DEVICE_ACCOUNT_STATE_INVALID = -1, // invalid state + DEVICE_ACCOUNT_STATE_BOOTING = 0, // device account is booting + DEVICE_ACCOUNT_STATE_RUNNING_LOCKED, // device account is locked + DEVICE_ACCOUNT_STATE_RUNNING_UNLOCKING, // device account is unlocking + DEVICE_ACCOUNT_STATE_RUNNING_UNLOCKED, // device account is unlocked + DEVICE_ACCOUNT_STATE_STOPPING, // device account is stopping + DEVICE_ACCOUNT_STATE_SHUTDOWN, // device account is shutdown +}; + +/** + * Invalid device account id. + */ +constexpr std::int32_t DEVICE_ACCOUNT_ID_INVALID = -1; + +/** + * Device account owner + */ +constexpr std::int32_t DEVICE_ACCOUNT_OWNER = 0; + +/** + * no error + */ +constexpr std::int32_t ERROR_NONE = 0; + +/** + * error + */ +constexpr std::int32_t ERROR_HAPPEN = -1; + +class DeviceAccountInfo { +public: + /** + * Device account ID. + */ + std::int32_t id_; + + /** + * Device account type. + */ + DeviceAccountType type_; + + /** + * Device account name. + */ + std::string name_; + + /** + * Device account icon path. + */ + std::string iconPath_; + + /** + * Device account state. + */ + DeviceAccountState state_; + + /** + * Device account flags, like admin or system flag. + */ + std::int32_t flags_; + + /** + * Device account create time. + */ + int64_t creationTime_; + + /** + * Device account last logged time. + */ + int64_t lastLoggedInTime_; + + /** + * Guest device account to be removed. + */ + bool guestToRemoved_; + + /** + * Device account information class default Constructor. + */ + DeviceAccountInfo() + { + id_ = DEVICE_ACCOUNT_ID_INVALID; + type_ = DeviceAccountType::DEVICE_ACCOUNT_TYPE_INVALID; + name_.clear(); + iconPath_.clear(); + state_ = DeviceAccountState::DEVICE_ACCOUNT_STATE_INVALID; + flags_ = 0; + creationTime_ = 0; + lastLoggedInTime_ = 0; + guestToRemoved_ = false; + } + + /** + * Device account information class Constructor. + */ + DeviceAccountInfo(const std::int32_t accountId, const DeviceAccountType accountType, const std::string &accountName) + : id_(accountId), type_(accountType), name_(accountName) + { + iconPath_.clear(); + state_ = DeviceAccountState::DEVICE_ACCOUNT_STATE_INVALID; + flags_ = 0; + creationTime_ = 0; + lastLoggedInTime_ = 0; + guestToRemoved_ = false; + } + + /** + * Device account information class Constructor. + */ + DeviceAccountInfo(const std::int32_t accountId, const DeviceAccountType accountType, + const std::string &accountName, const std::string &path) + : id_(accountId), type_(accountType), name_(accountName), iconPath_(path) + { + state_ = DeviceAccountState::DEVICE_ACCOUNT_STATE_INVALID; + flags_ = 0; + creationTime_ = 0; + lastLoggedInTime_ = 0; + guestToRemoved_ = false; + } + + /** + * Device account information class default Destructor. + */ + ~DeviceAccountInfo() {} + + /** + * == redefinition + * + * @return whether id is equal + */ + bool operator==(const DeviceAccountInfo &source) + { + return ((id_ == source.id_) && (id_ != DEVICE_ACCOUNT_ID_INVALID)); + } + + /** + * write device account info to parcel + * + * @return 0 when succeeded, otherwise -1 + */ + std::int32_t WriteDataToParcel(MessageParcel &data) + { + if (!data.WriteInt32(id_)) { + return ERROR_HAPPEN; + } + + if (!data.WriteInt32(static_cast(type_))) { + return ERROR_HAPPEN; + } + + if (!data.WriteString16(Str8ToStr16(name_))) { + return ERROR_HAPPEN; + } + + if (!data.WriteInt32(static_cast(state_))) { + return ERROR_HAPPEN; + } + + return ERROR_NONE; + } + + /** + * read device account info from parcel + * + */ + void ReadDataFromParcel(MessageParcel &data) + { + id_ = data.ReadInt32(); + type_ = static_cast(data.ReadInt32()); + name_ = Str16ToStr8(data.ReadString16()); + state_ = static_cast(data.ReadInt32()); + } +}; +} // namespace AccountSA +} // namespace OHOS +#endif // BASE_ACCOUNT_DEVICE_ACCOUNT_INFO_H diff --git a/interfaces/innerkits/include/iaccount.h b/interfaces/innerkits/include/iaccount.h new file mode 100755 index 000000000..5d52a4ed9 --- /dev/null +++ b/interfaces/innerkits/include/iaccount.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 BASE_ACCOUNT_IACCOUNT_H +#define BASE_ACCOUNT_IACCOUNT_H + +#include +#include +#include +#include "account_info.h" +#include "device_account_info.h" + +namespace OHOS { +namespace AccountSA { +const std::string ACCOUNT_SERVICE_NAME = "AccountService"; + +class IAccount : public IRemoteBroker { +public: + enum { + UPDATE_OHOS_ACCOUNT_INFO = 1, + QUERY_OHOS_ACCOUNT_INFO = 2, + QUERY_OHOS_ACCOUNT_QUIT_TIPS = 3, + QUERY_DEVICE_ACCOUNT_ID = 104, + QUERY_DEVICE_ACCOUNT_ID_FROM_UID = 105, + }; + + virtual bool UpdateOhosAccountInfo(const std::string& accountName, const std::string& uid, + const std::string& eventStr) = 0; + virtual std::pair QueryOhosAccountInfo(void) = 0; + virtual std::int32_t QueryDeviceAccountId(std::int32_t& accountId) = 0; + virtual std::int32_t QueryDeviceAccountIdFromUid(std::int32_t uid) = 0; +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.AccountSA.IAccount"); +}; +} // namespace AccountSA +} // namespace OHOS + +#endif // BASE_ACCOUNT_IACCOUNT_H diff --git a/interfaces/innerkits/include/ohos_account_kits.h b/interfaces/innerkits/include/ohos_account_kits.h new file mode 100755 index 000000000..b94c76470 --- /dev/null +++ b/interfaces/innerkits/include/ohos_account_kits.h @@ -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. + */ + +#ifndef BASE_ACCOUNT_OHOS_ACCOUNT_KITS_H +#define BASE_ACCOUNT_OHOS_ACCOUNT_KITS_H + +#include "nocopyable.h" +#include "iaccount.h" + +namespace OHOS { +namespace AccountSA { +/** + * Interfaces for ohos account subsystem. + */ +class OhosAccountKits { +public: + virtual ~OhosAccountKits() = default; + DISALLOW_COPY_AND_MOVE(OhosAccountKits); + + /** + * Get instance of ohos account manager. + * + * @return Instance of ohos account manager. + */ + static OhosAccountKits& GetInstance(); + + /** + * Query OHOS Account Info. + * + * @param VOID. + * @return Return a pair of operation result and ohos account info. + */ + virtual std::pair QueryOhosAccountInfo() = 0; + + /** + * Update OHOS Account Info. + * + * @param accountName Indicates the name of the OS account used for a distributed system. + * @param uid Uniquely identifies the OS account used for a distributed system. + * @param eventStr Indicates the event of the OS account used for a distributed system. + * @return Returns {@code true} if the distributed information of the account is updated; + * returns {@code false} otherwise. + */ + virtual bool UpdateOhosAccountInfo(const std::string& accountName, const std::string& uid, + const std::string& eventStr) = 0; + + /** + * Query Device Account Id. + * + * @param device account id. + * @return if succeed, return ERR_OK and device account Id. + */ + virtual ErrCode QueryDeviceAccountId(std::int32_t& accountId) = 0; + + /** + * Transform uid to device account id. + * + * @param process calling uid. + * @return transformed device account Id + */ + virtual std::int32_t GetDeviceAccountIdByUID(std::int32_t& uid) = 0; +protected: + OhosAccountKits() = default; +}; +} // namespace AccountSA +} // namespace OHOS + +#endif // BASE_ACCOUNT_OHOS_ACCOUNT_KITS_H diff --git a/interfaces/innerkits/include/ohos_account_kits_impl.h b/interfaces/innerkits/include/ohos_account_kits_impl.h new file mode 100755 index 000000000..1f67662b4 --- /dev/null +++ b/interfaces/innerkits/include/ohos_account_kits_impl.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BASE_ACCOUNT_OHOS_ACCOUNT_KITS_IMPL_H +#define BASE_ACCOUNT_OHOS_ACCOUNT_KITS_IMPL_H + +#include +#include "ipc_skeleton.h" +#include "ohos_account_kits.h" +#include "singleton.h" + +namespace OHOS { +namespace AccountSA { +class OhosAccountKitsImpl final : public OhosAccountKits, public DelayedRefSingleton { + DECLARE_DELAYED_REF_SINGLETON(OhosAccountKitsImpl); + +public: + DISALLOW_COPY_AND_MOVE(OhosAccountKitsImpl); + bool UpdateOhosAccountInfo(const std::string& accountName, const std::string& uid, + const std::string& eventStr) final; + std::pair QueryOhosAccountInfo() final; + ErrCode QueryDeviceAccountId(std::int32_t& accountId) final; + std::int32_t GetDeviceAccountIdByUID(std::int32_t& uid) final; +private: + // For death event procession + class DeathRecipient final : public IRemoteObject::DeathRecipient { + public: + DeathRecipient() = default; + ~DeathRecipient() final = default; + DISALLOW_COPY_AND_MOVE(DeathRecipient); + + void OnRemoteDied(const wptr& remote) final; + }; + + template + ErrCode CallService(F func, Args&&... args); + + void ResetService(const wptr& remote); + sptr GetService(); + + sptr deathRecipient_{}; + std::mutex accountProxyLock_; + sptr accountProxy_{}; +}; +} // namespace AccountSA +} // namespace OHOS + +#endif // BASE_ACCOUNT_OHOS_ACCOUNT_KITS_IMPL_H diff --git a/interfaces/innerkits/test/BUILD.gn b/interfaces/innerkits/test/BUILD.gn new file mode 100755 index 000000000..cf2518e66 --- /dev/null +++ b/interfaces/innerkits/test/BUILD.gn @@ -0,0 +1,19 @@ +# 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("//base/account/os_account/os_account.gni") + +group("moduletest") { + testonly = true + deps = [ "moduletests/account_mgr_test:moduletest" ] +} diff --git a/interfaces/innerkits/test/moduletests/account_mgr_test/BUILD.gn b/interfaces/innerkits/test/moduletests/account_mgr_test/BUILD.gn new file mode 100755 index 000000000..afc49e96f --- /dev/null +++ b/interfaces/innerkits/test/moduletests/account_mgr_test/BUILD.gn @@ -0,0 +1,76 @@ +# 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( + "//base/account/os_account/interfaces/innerkits/account_kits_headers.gni") +import("//base/account/os_account/os_account.gni") +import("//build/ohos.gni") +import("//build/test.gni") + +module_output_path = "os_account_standard/mstaccountmgr" + +# mst test common config defines here +config("accountmgr_mst_test_config") { + include_dirs = [ + "${common_path}/log/include", + "${common_path}/perf_stat/include", + "${common_path}/account_error/include", + "${services_path}/accountmgr/include", + "//third_party/json/include", + "${innerkits_path}/include", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + ] + configs = [] +} + +ohos_moduletest("AccountInnerSdkModuleTest") { + module_out_path = module_output_path + + sources = [ + "${common_path}/log/src/account_log_wrapper.cpp", + "${innerkits_path}/accountmgr/src/account_proxy.cpp", + "${innerkits_path}/accountmgr/src/ohos_account_kits.cpp", + "${innerkits_path}/accountmgr/src/ohos_account_kits_impl.cpp", + ] + + sources += [ "account_mgr_inner_sdk_func_test.cpp" ] + + configs = [ + ":accountmgr_mst_test_config", + "${services_path}/accountmgr/test:accountmgr_test_config", + ] + + deps = [ + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + external_deps = [ + "aafwk_standard:base", + "aafwk_standard:intent", + "appexecfwk_standard:appexecfwk_base", + "appexecfwk_standard:libeventhandler", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "os_account_standard:libaccountkits", + "safwk:system_ability_fwk", + "samgr_L2:samgr_proxy", + ] + part_name = "os_account_standard" +} + +group("moduletest") { + testonly = true + deps = [ ":AccountInnerSdkModuleTest" ] +} diff --git a/interfaces/innerkits/test/moduletests/account_mgr_test/account_mgr_inner_sdk_func_test.cpp b/interfaces/innerkits/test/moduletests/account_mgr_test/account_mgr_inner_sdk_func_test.cpp new file mode 100755 index 000000000..88d45b1a1 --- /dev/null +++ b/interfaces/innerkits/test/moduletests/account_mgr_test/account_mgr_inner_sdk_func_test.cpp @@ -0,0 +1,97 @@ +/* + * 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 + +#include "account_proxy.h" +#include "iaccount.h" +#include "if_system_ability_manager.h" +#include "iservice_registry.h" +#include "ohos_account_kits.h" +#include "system_ability_definition.h" + +using namespace testing::ext; +using namespace OHOS; +using namespace OHOS::AccountSA; + +class AccountMgrInnerSdkFuncTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void AccountMgrInnerSdkFuncTest::SetUpTestCase(void) +{} + +void AccountMgrInnerSdkFuncTest::TearDownTestCase(void) +{} + +void AccountMgrInnerSdkFuncTest::SetUp(void) +{} + +void AccountMgrInnerSdkFuncTest::TearDown(void) +{} + +/** + * @tc.name: GetDeviceAccountIdTest + * @tc.desc: get device account info test + * @tc.type: FUNC + * @tc.require: AR000CUF64 +*/ +HWTEST_F(AccountMgrInnerSdkFuncTest, GetDeviceAccountIdTest, TestSize.Level0) +{ + std::int32_t id; + auto ret = OhosAccountKits::GetInstance().QueryDeviceAccountId(id); + EXPECT_EQ(ERR_OK, ret); +} + +/** + * @tc.name: GetOhosAccountInfoTest + * @tc.desc: get ohos account info test + * @tc.type: FUNC + * @tc.require: AR000CUF64 + */ +HWTEST_F(AccountMgrInnerSdkFuncTest, GetOhosAccountInfoTest, TestSize.Level0) +{ + auto ret = OhosAccountKits::GetInstance().QueryOhosAccountInfo(); + EXPECT_EQ(true, ret.first); +} + +/** + * @tc.name: GetDefaultOhosAccountInfoTest + * @tc.desc: get default ohos account info test + * @tc.type: FUNC + * @tc.require: AR000DIJ27 + */ +HWTEST_F(AccountMgrInnerSdkFuncTest, GetDefaultOhosAccountInfoTest, TestSize.Level1) +{ + std::unique_ptr accountInfo = std::make_unique(); + ASSERT_TRUE(accountInfo != nullptr); +} + +/** + * @tc.name: UidTranslateTest + * @tc.desc: translate uid to deviceAccountId + * @tc.type: FUNC + * @tc.require: AR000CUF64 + */ +HWTEST_F(AccountMgrInnerSdkFuncTest, UidTranslateTest, TestSize.Level0) +{ + std::int32_t uid = 1000000; + auto ret = OhosAccountKits::GetInstance().GetDeviceAccountIdByUID(uid); + EXPECT_EQ(10, ret); +} diff --git a/kits/js/impl/napi/distributedaccount/BUILD.gn b/kits/js/impl/napi/distributedaccount/BUILD.gn new file mode 100755 index 000000000..2c7dad343 --- /dev/null +++ b/kits/js/impl/napi/distributedaccount/BUILD.gn @@ -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. + +import("//base/account/os_account/os_account.gni") +import("//build/ohos.gni") + +ohos_shared_library("distributedaccount") { + include_dirs = [ + "//third_party/libuv/include", + "//third_party/node/src", + "//foundation/ace/napi/interfaces/kits", + ] + + cflags = [ + "-fPIC", + "-g3", + ] + + sources = [ "napi_distributed_account.cpp" ] + + defines = [ + "ACCOUNT_LOG_TAG = \"AccountJsKit\"", + "LOG_DOMAIN = 0xD001B00", + ] + + deps = [ + "${common_path}:libaccount_common", + "//foundation/ace/napi/:ace_napi", + "//utils/native/base:utils", + ] + + relative_install_dir = "module/account" + + subsystem_name = "account" + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "os_account_standard:libaccountkits", + ] + part_name = "os_account_standard" +} diff --git a/kits/js/impl/napi/distributedaccount/napi_distributed_account.cpp b/kits/js/impl/napi/distributedaccount/napi_distributed_account.cpp new file mode 100755 index 000000000..dd12e9960 --- /dev/null +++ b/kits/js/impl/napi/distributedaccount/napi_distributed_account.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 "napi_distributed_account.h" +#include +#include +#include +#include "account_log_wrapper.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "ohos_account_kits.h" + +using namespace OHOS::AccountSA; + +namespace OHOS { +namespace AccountJsKit { +namespace { +constexpr std::int32_t MAX_VALUE_LEN = 4096; +constexpr std::int32_t QUERY_ARGC = 1; +constexpr std::int32_t UPDATE_ARGC = 2; +const std::string DISTRIBUTED_ACCOUNT_CLASS_NAME = "DistributedAccountAbility"; +const std::string PROPERTY_KEY_NAME = "name"; +const std::string PROPERTY_KEY_ID = "id"; +const std::string PROPERTY_KEY_EVENT = "event"; +const std::string PROPERTY_KEY_SCALABLE = "scalableData"; + +struct DistributedAccountAsyncContext { + napi_env env; + napi_async_work work; + + std::string name; + std::string id; + std::string event; + std::map scalableData; + + napi_deferred deferred; + napi_ref callbackRef; + napi_status status; +}; + +std::string GetNamedProperty(napi_env env, napi_value obj, const std::string &keyStr) +{ + napi_value value = nullptr; + napi_get_named_property(env, obj, keyStr.c_str(), &value); + char propValue[MAX_VALUE_LEN] = {0}; + size_t propLen; + napi_get_value_string_utf8(env, value, propValue, MAX_VALUE_LEN, &propLen); + return std::string(propValue); +} + +void ParseAsyncContextFromArgs(napi_env env, napi_callback_info cbInfo, DistributedAccountAsyncContext *asyncContext, + bool isUpdate) +{ + ACCOUNT_LOGI("enter"); + size_t argc = isUpdate ? UPDATE_ARGC : QUERY_ARGC; + napi_value argv[UPDATE_ARGC] = {0}; + napi_get_cb_info(env, cbInfo, &argc, argv, nullptr, nullptr); + for (size_t i = 0; i < argc; i++) { + napi_valuetype valueType = napi_undefined; + napi_typeof(env, argv[i], &valueType); + if (i == 0 && valueType == napi_object) { + asyncContext->name = GetNamedProperty(env, argv[i], PROPERTY_KEY_NAME); + asyncContext->id = GetNamedProperty(env, argv[i], PROPERTY_KEY_ID); + asyncContext->event = GetNamedProperty(env, argv[i], PROPERTY_KEY_EVENT); + } else if (valueType == napi_function) { + napi_create_reference(env, argv[i], 1, &asyncContext->callbackRef); + break; + } else { + ACCOUNT_LOGE("type mismatch"); + } + } +} + +void ProcessCallbackOrPromise(napi_env env, DistributedAccountAsyncContext *asyncContext, napi_value result) +{ + napi_value args[1] = { result }; + if (asyncContext->deferred) { + ACCOUNT_LOGI("Promise"); + if (asyncContext->status == napi_ok) { + napi_resolve_deferred(env, asyncContext->deferred, result); + } else { + napi_reject_deferred(env, asyncContext->deferred, result); + } + } else { + ACCOUNT_LOGI("Callback"); + napi_value callback = nullptr; + napi_get_reference_value(env, asyncContext->callbackRef, &callback); + napi_value returnVal = nullptr; + napi_call_function(env, nullptr, callback, 1, args, &returnVal); + napi_delete_reference(env, asyncContext->callbackRef); + } +} +} + +napi_ref NapiDistributedAccount::constructorRef_; + +napi_value NapiDistributedAccount::Init(napi_env env, napi_value exports) +{ + ACCOUNT_LOGI("enter"); + napi_property_descriptor descriptor[] = { + DECLARE_NAPI_FUNCTION("getDistributedAccountAbility", GetDistributedAccountAbility), + }; + napi_define_properties(env, exports, sizeof(descriptor) / sizeof(napi_property_descriptor), descriptor); + + napi_property_descriptor properties[] = { + DECLARE_NAPI_FUNCTION("queryOsAccountDistributedInfo", QueryOhosAccountInfo), + DECLARE_NAPI_FUNCTION("updateOsAccountDistributedInfo", UpdateOsAccountDistributedInfo), + }; + napi_value cons = nullptr; + napi_define_class(env, DISTRIBUTED_ACCOUNT_CLASS_NAME.c_str(), DISTRIBUTED_ACCOUNT_CLASS_NAME.size(), + JsConstructor, nullptr, sizeof(properties) / sizeof(napi_property_descriptor), properties, &cons); + napi_create_reference(env, cons, 1, &constructorRef_); + napi_set_named_property(env, exports, DISTRIBUTED_ACCOUNT_CLASS_NAME.c_str(), cons); + + return exports; +} + +napi_value NapiDistributedAccount::JsConstructor(napi_env env, napi_callback_info cbinfo) +{ + napi_value thisVar = nullptr; + napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, nullptr); + return thisVar; +} + +napi_value NapiDistributedAccount::GetDistributedAccountAbility(napi_env env, napi_callback_info cbInfo) +{ + ACCOUNT_LOGI("enter"); + napi_value instance = nullptr; + napi_value cons = nullptr; + if (napi_get_reference_value(env, constructorRef_, &cons) != napi_ok) { + return nullptr; + } + + if (napi_new_instance(env, cons, 0, nullptr, &instance) != napi_ok) { + return nullptr; + } + + return instance; +} + +napi_value NapiDistributedAccount::QueryOhosAccountInfo(napi_env env, napi_callback_info cbInfo) +{ + ACCOUNT_LOGI("enter"); + auto *asyncContext = new DistributedAccountAsyncContext(); + asyncContext->env = env; + asyncContext->callbackRef = nullptr; + ParseAsyncContextFromArgs(env, cbInfo, asyncContext, false); + + napi_value result = nullptr; + if (asyncContext->callbackRef == nullptr) { + napi_create_promise(env, &asyncContext->deferred, &result); + } else { + napi_get_undefined(env, &result); + } + + napi_value resource = nullptr; + napi_create_string_utf8(env, "QueryOhosAccountInfo", NAPI_AUTO_LENGTH, &resource); + + napi_create_async_work( + env, nullptr, resource, + [](napi_env env, void *data) { + DistributedAccountAsyncContext *asyncContext = (DistributedAccountAsyncContext*)data; + std::pair accountInfo = OhosAccountKits::GetInstance().QueryOhosAccountInfo(); + if (accountInfo.first) { + asyncContext->name = accountInfo.second.name_; + asyncContext->id = accountInfo.second.uid_; + asyncContext->status = napi_ok; + } else { + asyncContext->status = napi_generic_failure; + } + }, + [](napi_env env, napi_status status, void *data) { + DistributedAccountAsyncContext *asyncContext = (DistributedAccountAsyncContext*)data; + napi_value queryResult = nullptr; + if (asyncContext->status == napi_ok) { + napi_create_object(env, &queryResult); + napi_value value = nullptr; + napi_create_string_utf8(env, asyncContext->name.c_str(), asyncContext->name.size(), &value); + napi_set_named_property(env, queryResult, PROPERTY_KEY_NAME.c_str(), value); + + napi_create_string_utf8(env, asyncContext->id.c_str(), asyncContext->id.size(), &value); + napi_set_named_property(env, queryResult, PROPERTY_KEY_ID.c_str(), value); + } else { + napi_value message = nullptr; + napi_create_string_utf8(env, "query ohos account info failed", NAPI_AUTO_LENGTH, &message); + napi_create_error(env, nullptr, message, &queryResult); + } + + ProcessCallbackOrPromise(env, asyncContext, queryResult); + napi_delete_async_work(env, asyncContext->work); + delete asyncContext; + }, + (void*)asyncContext, &asyncContext->work); + napi_queue_async_work(env, asyncContext->work); + + return result; +} + +napi_value NapiDistributedAccount::UpdateOsAccountDistributedInfo(napi_env env, napi_callback_info cbInfo) +{ + ACCOUNT_LOGI("enter"); + auto *asyncContext = new DistributedAccountAsyncContext(); + asyncContext->env = env; + asyncContext->callbackRef = nullptr; + ParseAsyncContextFromArgs(env, cbInfo, asyncContext, true); + + napi_value result = nullptr; + if (asyncContext->callbackRef == nullptr) { + napi_create_promise(env, &asyncContext->deferred, &result); + } else { + napi_get_undefined(env, &result); + } + + napi_value resource = nullptr; + napi_create_string_utf8(env, "UpdateOsAccountDistributedInfo", NAPI_AUTO_LENGTH, &resource); + + napi_create_async_work( + env, nullptr, resource, + [](napi_env env, void *data) { + DistributedAccountAsyncContext *asyncContext = (DistributedAccountAsyncContext*)data; + asyncContext->status = OhosAccountKits::GetInstance().UpdateOhosAccountInfo(asyncContext->name, + asyncContext->id, asyncContext->event) ? napi_ok : napi_generic_failure; + }, + [](napi_env env, napi_status status, void *data) { + DistributedAccountAsyncContext *asyncContext = (DistributedAccountAsyncContext*)data; + napi_value updateResult = nullptr; + napi_get_boolean(env, asyncContext->status == napi_ok, &updateResult); + ProcessCallbackOrPromise(env, asyncContext, updateResult); + napi_delete_async_work(env, asyncContext->work); + delete asyncContext; + }, + (void*)asyncContext, &asyncContext->work); + napi_queue_async_work(env, asyncContext->work); + + return result; +} +} // namespace AccountJsKit +} // namespace OHOS + +EXTERN_C_START +/* + * function for module exports + */ +static napi_value Init(napi_env env, napi_value exports) +{ + return OHOS::AccountJsKit::NapiDistributedAccount::Init(env, exports); +} +EXTERN_C_END + +/* + * module define + */ +static napi_module _module = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "account.distributedAccount", + .nm_priv = ((void*)0), + .reserved = {0} +}; +/* + * module register + */ +extern "C" __attribute__((constructor)) void Register() +{ + napi_module_register(&_module); +} \ No newline at end of file diff --git a/kits/js/impl/napi/distributedaccount/napi_distributed_account.h b/kits/js/impl/napi/distributedaccount/napi_distributed_account.h new file mode 100755 index 000000000..293c4ad8f --- /dev/null +++ b/kits/js/impl/napi/distributedaccount/napi_distributed_account.h @@ -0,0 +1,38 @@ +/* + * 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 NAPI_DISTRIBUTED_ACCOUNT_H +#define NAPI_DISTRIBUTED_ACCOUNT_H + +#include "napi/native_api.h" + +namespace OHOS { +namespace AccountJsKit { +class NapiDistributedAccount { +public: + static napi_value Init(napi_env env, napi_value exports); + +private: + static napi_value GetDistributedAccountAbility(napi_env env, napi_callback_info cbInfo); + static napi_value QueryOhosAccountInfo(napi_env env, napi_callback_info cbInfo); + static napi_value UpdateOsAccountDistributedInfo(napi_env env, napi_callback_info cbInfo); + static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo); + + static napi_ref constructorRef_; +}; +} // namespace AccountJsKit +} // namespace OHOS + +#endif // NAPI_DISTRIBUTED_ACCOUNT_H diff --git a/ohos.build b/ohos.build new file mode 100755 index 000000000..5a0dfa250 --- /dev/null +++ b/ohos.build @@ -0,0 +1,32 @@ +{ + "subsystem": "account", + "parts": { + "os_account_standard": { + "module_list": [ + "//base/account/os_account/common:common_target", + "//base/account/os_account/services:services_target", + "//base/account/os_account/sa_profile:account_sa_profile", + "//base/account/os_account/kits/js/impl/napi/distributedaccount:distributedaccount" + ], + "inner_kits": [ + { + "name": "//base/account/os_account/interfaces/innerkits/accountmgr:libaccountkits", + "header": { + "header_files": [ + "account_info.h", + "device_account_info.h", + "iaccount.h", + "ohos_account_kits.h" + ], + "header_base": "//base/account/os_account/interfaces/innerkits/include" + } + } + ], + "test_list": [ + "//base/account/os_account/common/test:unittest", + "//base/account/os_account/services/accountmgr/test:unittest", + "//base/account/os_account/interfaces/innerkits/test:moduletest" + ] + } + } +} \ No newline at end of file diff --git a/os_account.gni b/os_account.gni new file mode 100755 index 000000000..dfeca4e7e --- /dev/null +++ b/os_account.gni @@ -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. + +os_account_path = "//base/account/os_account" + +common_path = "${os_account_path}/common" + +services_path = "${os_account_path}/services" + +innerkits_path = "${os_account_path}/interfaces/innerkits" diff --git a/sa_profile/200.xml b/sa_profile/200.xml new file mode 100755 index 000000000..b803a4cec --- /dev/null +++ b/sa_profile/200.xml @@ -0,0 +1,24 @@ + + + + accountmgr + + 200 + libaccountmgr.z.so + true + false + 1 + + diff --git a/sa_profile/BUILD.gn b/sa_profile/BUILD.gn new file mode 100755 index 000000000..e6ca0dcf0 --- /dev/null +++ b/sa_profile/BUILD.gn @@ -0,0 +1,19 @@ +# 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("account_sa_profile") { + sources = [ "200.xml" ] + part_name = "os_account_standard" +} diff --git a/services/BUILD.gn b/services/BUILD.gn new file mode 100755 index 000000000..296feee45 --- /dev/null +++ b/services/BUILD.gn @@ -0,0 +1,16 @@ +# 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. + +group("services_target") { + deps = [ "accountmgr:accountmgr_target" ] +} diff --git a/services/accountmgr/BUILD.gn b/services/accountmgr/BUILD.gn new file mode 100755 index 000000000..88e0fb44b --- /dev/null +++ b/services/accountmgr/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("//base/account/os_account/os_account.gni") +import("//build/ohos.gni") + +ohos_prebuilt_etc("accountmgr.rc") { + source = "accountmgr.rc" + relative_install_dir = "init" + part_name = "os_account_standard" +} + +config("accountmgr_config") { + include_dirs = [ + "./include", + "${common_path}/log/include", + "${common_path}/perf_stat/include", + "${common_path}/account_error/include", + "${innerkits_path}/include", + "//third_party/json/include", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + ] +} + +group("accountmgr_target") { + deps = [ + ":accountmgr", + ":accountmgr.rc", + ] +} + +ohos_shared_library("accountmgr") { + visibility = [ "${os_account_path}/*" ] + + sources = [ + "src/account_dump_helper.cpp", + "src/account_helper_data.cpp", + "src/account_mgr_service.cpp", + "src/account_state_machine.cpp", + "src/account_stub.cpp", + "src/ohos_account_data_deal.cpp", + "src/ohos_account_manager.cpp", + ] + + defines = [ + "ACCOUNT_LOG_TAG = \"AccountMgrService\"", + "LOG_DOMAIN = 0xD001B00", + ] + + configs = [ ":accountmgr_config" ] + + deps = [ + "${common_path}:libaccount_common", + "//utils/native/base:utils", + ] + + external_deps = [ + "aafwk_standard:base", + "aafwk_standard:intent", + "aafwk_standard:want", + "appexecfwk_standard:appexecfwk_base", + "appexecfwk_standard:appexecfwk_core", + "hisysevent_native:libhisysevent", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_L2:samgr_proxy", + "startup_l2:syspara", + ] + part_name = "os_account_standard" +} diff --git a/services/accountmgr/accountmgr.rc b/services/accountmgr/accountmgr.rc new file mode 100755 index 000000000..311bb2fc1 --- /dev/null +++ b/services/accountmgr/accountmgr.rc @@ -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. + +on post-fs-data + start accountmgr + +service accountmgr /system/bin/sa_main /system/profile/accountmgr.xml + class z_core + user system + group system shell + seclabel u:r:accountmgr:s0 + writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks /dev/blkio/foreground/tasks diff --git a/services/accountmgr/include/account_dump_helper.h b/services/accountmgr/include/account_dump_helper.h new file mode 100755 index 000000000..586f5b12e --- /dev/null +++ b/services/accountmgr/include/account_dump_helper.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BASE_ACCOUNT_SERVICES_INCLUDE_DUMP_HELPER_H +#define BASE_ACCOUNT_SERVICES_INCLUDE_DUMP_HELPER_H + +#include +#include +#include "ohos_account_manager.h" + +namespace OHOS { +namespace AccountSA { +class AccountMgrService; + +class AccountDumpHelper { +public: + explicit AccountDumpHelper(const std::shared_ptr& accountMgr); + ~AccountDumpHelper() = default; + bool Dump(const std::vector& args, std::string& result) const; + +private: + void ShowIllegalInformation(std::string& result) const; + void ShowHelp(std::string& result) const; + bool ProcessOneParameter(const std::string& arg, std::string& result) const; + bool ProcessTwoParameter(const std::string& arg1, const std::string& arg2, std::string& result) const; + std::weak_ptr accountMgr_; + void ShowAccountInfo(std::string &result) const; + bool SimulateInputEvent(const std::string &eventStr, std::string &result) const; + bool SetLogLevel(const std::string& levelStr, std::string& result) const; +}; +} // namespace AccountSA +} // namespace OHOS +#endif // BASE_ACCOUNT_SERVICES_INCLUDE_DUMP_HELPER_H diff --git a/services/accountmgr/include/account_helper_data.h b/services/accountmgr/include/account_helper_data.h new file mode 100755 index 000000000..21de6a1bb --- /dev/null +++ b/services/accountmgr/include/account_helper_data.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ACCOUNT_HELPER_DATA_H +#define ACCOUNT_HELPER_DATA_H + +#include + +namespace OHOS { +namespace AccountSA { +class AccountHelperData { +public: + static std::vector GetBundleNameTrustList(); +}; +} // namespace AccountSA +} // namespace OHOS +#endif // ACCOUNT_HELPER_DATA_H diff --git a/services/accountmgr/include/account_mgr_service.h b/services/accountmgr/include/account_mgr_service.h new file mode 100755 index 000000000..624c5ea99 --- /dev/null +++ b/services/accountmgr/include/account_mgr_service.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BASE_ACCOUNT_INCLUDE_ACCOUNT_SERVICE_H +#define BASE_ACCOUNT_INCLUDE_ACCOUNT_SERVICE_H + +#include +#include +#include +#include "account_dump_helper.h" +#include "account_info.h" +#include "account_stub.h" +#include "iaccount.h" +#include "iremote_object.h" +#include "ohos_account_manager.h" +#include "singleton.h" +#include "system_ability.h" + +namespace OHOS { +namespace AccountSA { +enum ServiceRunningState { + STATE_NOT_START, + STATE_RUNNING +}; + +class AccountMgrService : public SystemAbility, public AccountStub, + public OHOS::DelayedRefSingleton { +public: + AccountMgrService(); + ~AccountMgrService(); + DISALLOW_COPY_AND_MOVE(AccountMgrService); + DECLARE_SYSTEM_ABILITY(AccountMgrService); + bool UpdateOhosAccountInfo(const std::string& accountName, const std::string& uid, + const std::string& eventStr) override; + std::pair QueryOhosAccountInfo(void) override; + std::int32_t QueryDeviceAccountId(std::int32_t& accountId) override; + std::int32_t QueryDeviceAccountIdFromUid(std::int32_t uid) override; + virtual void OnStart() override; + virtual void OnStop() override; + bool IsServiceStarted(void) const override; + static AccountMgrService& GetInstance() + { + return DelayedRefSingleton::GetInstance(); + } + int Dump(std::int32_t fd, const std::vector& args) override; + void HandleNotificationEvents(const std::string &eventStr) override; + +private: + bool Init(); + void SelfClean(); + std::int32_t GetDeviceAccountIdFromCurrentProcess(); + + bool registerToService_ = false; + ServiceRunningState state_ = ServiceRunningState::STATE_NOT_START; + std::unique_ptr dumpHelper_{}; + std::shared_ptr ohosAccountMgr_{}; +}; +} // namespace AccountSA +} // namespace OHOS +#endif // BASE_ACCOUNT_INCLUDE_ACCOUNT_SERVICE_H diff --git a/services/accountmgr/include/account_proxy.h b/services/accountmgr/include/account_proxy.h new file mode 100755 index 000000000..78f8ccfd4 --- /dev/null +++ b/services/accountmgr/include/account_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 ACCOUNT_PROXY_H +#define ACCOUNT_PROXY_H + +#include "iaccount.h" +#include "account_info.h" +#include + +namespace OHOS { +namespace AccountSA { +class AccountProxy : public IRemoteProxy { +public: + explicit AccountProxy(const sptr& impl) + : IRemoteProxy(impl) { + } + ~AccountProxy() { } + bool UpdateOhosAccountInfo(const std::string& accountName, const std::string& uid, + const std::string& eventStr) override; + std::pair QueryOhosAccountInfo(void) override; + std::int32_t QueryDeviceAccountId(std::int32_t& accountId) override; + std::int32_t QueryDeviceAccountIdFromUid(std::int32_t uid) override; + +private: + std::int32_t DeviceAccountRequest(std::uint32_t code, std::int32_t accountId); + static inline BrokerDelegator delegator_; +}; +} // namespace AccountSA +} // namespace OHOS + +#endif // ACCOUNT_PROXY_H diff --git a/services/accountmgr/include/account_state_action.h b/services/accountmgr/include/account_state_action.h new file mode 100755 index 000000000..71247d3a4 --- /dev/null +++ b/services/accountmgr/include/account_state_action.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BASE_ACCOUNT_INCLUDE_ACCOUNT_STATE_ACTION_H +#define BASE_ACCOUNT_INCLUDE_ACCOUNT_STATE_ACTION_H + +namespace OHOS { +namespace AccountSA { +/** + * Base class of state change process. + */ +class AccountStateAction { +public: + /** + * Constructor. + * + * @param nextStateId the unique State ID. It should be a non-negative number. + */ + explicit AccountStateAction(const int nextStateId) : nextState_(nextStateId) {} + + /** + * Destructor. + * + */ + virtual ~AccountStateAction() {} + + /** + * Get the next State ID. + * + * @return the next State ID + */ + int GetNextState() const + { + return nextState_; + } + +private: + /** + * the next State ID + */ + int nextState_; +}; +} // namespace AccountSA +} // namespace OHOS +#endif // BASE_ACCOUNT_INCLUDE_ACCOUNT_STATE_ACTION_H diff --git a/services/accountmgr/include/account_state_machine.h b/services/accountmgr/include/account_state_machine.h new file mode 100755 index 000000000..c1a799dfa --- /dev/null +++ b/services/accountmgr/include/account_state_machine.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BASE_ACCOUNT_INCLUDE_ACCOUNT_STATE_MACHINE_H +#define BASE_ACCOUNT_INCLUDE_ACCOUNT_STATE_MACHINE_H + +#include +#include +#include "account_state_action.h" +#include "account_info.h" + +namespace OHOS { +namespace AccountSA { +/** + * Account state machine + */ +class AccountStateMachine { +public: + + /** + * exception event action, to re-init state machine, and get account state from account server. + */ + class ExceptionAction : public AccountStateAction { + public: + /** + * exception event action Constructor. + */ + explicit ExceptionAction(int status) : AccountStateAction(status) {} + + /** + * exception event action Destructor. + */ + ~ExceptionAction() {} + }; + + /** + * unbound state action. + */ + class UnboundAction : public AccountStateAction { + public: + /** + * unbound state action Constructor. + */ + explicit UnboundAction(int status) : AccountStateAction(status) {} + + /** + * unbound state action Destructor. + */ + ~UnboundAction() {} + }; + + /** + * login state action. + */ + class LoginAction : public AccountStateAction { + public: + /** + * login state action Constructor. + */ + explicit LoginAction(int status) : AccountStateAction(status) {} + + /** + * login state action Destructor. + */ + ~LoginAction() {} + }; + + /** + * logout state action. + */ + class LogoutAction : public AccountStateAction { + public: + /** + * logout state action Constructor. + */ + explicit LogoutAction(int status) : AccountStateAction(status) {} + + /** + * logout state action Destructor. + */ + ~LogoutAction() {} + }; + + /** + * logoff state action. + */ + class LogoffAction : public AccountStateAction { + public: + /** + * logoff state action Constructor. + */ + explicit LogoffAction(int status) : AccountStateAction(status) {} + + /** + * logoff state action Destructor. + */ + ~LogoffAction() {} + }; + + /** + * Account state machine Constructor. + */ + AccountStateMachine() : currentState_(ACCOUNT_STATE_UNBOUND) + { + OnInitialize(); + } + + /** + * Account state machine Destructor. + */ + ~AccountStateMachine() + { + Clean(); + } + + /** + * Account state machine initialize. + */ + void OnInitialize(); + + /** + * Account state machine clean. + */ + void Clean(); + + /** + * Get account current state + * + * @return account current state + */ + int GetAccountState() + { + return currentState_; + } + + /** + * Set account current state + * + * @param current state + */ + void SetAccountState(int currentState) + { + currentState_ = currentState; + } + + /** + * Process an state change event. + * + * @param evt the event info + * @return true if the processing was completed, otherwise false + */ + bool StateChangeProcess(int evt); + +private: + /** + * Account current state. + */ + int currentState_; + std::map> stateMachineMap_; +}; +} // namespace AccountSA +} // namespace OHOS +#endif // BASE_ACCOUNT_INCLUDE_ACCOUNT_STATE_MACHINE_H diff --git a/services/accountmgr/include/account_stub.h b/services/accountmgr/include/account_stub.h new file mode 100755 index 000000000..08a55e8bb --- /dev/null +++ b/services/accountmgr/include/account_stub.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 ACCOUNT_STUB_H +#define ACCOUNT_STUB_H + +#include "iaccount.h" +#include "iaccount_context.h" +#include +#include +#include +#include + +namespace OHOS { +namespace AccountSA { +class AccountStub; +using AccountStubFunc = std::int32_t (AccountStub::*)(MessageParcel &data, MessageParcel &reply); +class AccountStub : public IRemoteStub, public IAccountContext { +public: + virtual std::int32_t OnRemoteRequest(std::uint32_t code, + MessageParcel &data, + MessageParcel &reply, + MessageOption &option) override; +private: + std::int32_t CmdUpdateOhosAccountInfo(MessageParcel &data, MessageParcel &reply); + std::int32_t CmdQueryOhosAccountInfo(MessageParcel &data, MessageParcel &reply); + std::int32_t CmdQueryOhosQuitTips(MessageParcel &data, MessageParcel &reply); + std::int32_t CmdQueryDeviceAccountId(MessageParcel &data, MessageParcel &reply); + std::int32_t CmdQueryDeviceAccountIdFromUid(MessageParcel &data, MessageParcel &reply); + bool HasAccountRequestPermission(const std::string &permissionName); + bool IsRootOrSystemAccount(); + bool CheckCallerForTrustList(); + +private: + static const std::map stubFuncMap_; +}; +} // namespace AccountSA +} // namespace OHOS + +#endif // ACCOUNT_STUB_H diff --git a/services/accountmgr/include/iaccount_context.h b/services/accountmgr/include/iaccount_context.h new file mode 100755 index 000000000..7c485d0b6 --- /dev/null +++ b/services/accountmgr/include/iaccount_context.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BASE_ACCOUNT_CONTEXT_H +#define BASE_ACCOUNT_CONTEXT_H + +#include "message_parcel.h" + +namespace OHOS { +namespace AccountSA { +class IAccountContext { +public: + static IAccountContext *GetInstance() + { + return IAccountContext::instance_; + } + + virtual ~IAccountContext() = default; + virtual void HandleNotificationEvents(const std::string &eventStr) = 0; + virtual bool IsServiceStarted(void) const = 0; + +protected: + static void SetInstance(IAccountContext *instance) + { + IAccountContext::instance_ = instance; + } + +private: + static IAccountContext *instance_; +}; +} // namespace AccountSA +} // namespace OHOS +#endif // BASE_ACCOUNT_CONTEXT_H diff --git a/services/accountmgr/include/ohos_account_data_deal.h b/services/accountmgr/include/ohos_account_data_deal.h new file mode 100755 index 000000000..9d8712c18 --- /dev/null +++ b/services/accountmgr/include/ohos_account_data_deal.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 BASE_ACCOUNT_INCLUDE_OHOS_ACCOUNT_DATA_DEAL_H +#define BASE_ACCOUNT_INCLUDE_OHOS_ACCOUNT_DATA_DEAL_H + +#include +#include +#include "account_info.h" +#include "account_error_no.h" + +namespace OHOS { +namespace AccountSA { +using json = nlohmann::json; + +const std::string DATADEAL_JSON_KEY_ACCOUNT_NAME = "account_name"; +const std::string DATADEAL_JSON_KEY_OPENID = "openId"; +const std::string DATADEAL_JSON_KEY_UID = "uid"; +const std::string DATADEAL_JSON_KEY_BIND_TIME = "bind_time"; +const std::string DATADEAL_JSON_KEY_STATUS = "bind_status"; + +class OhosAccountDataDeal { +public: + explicit OhosAccountDataDeal(const std::string &configFile); + ErrCode Init(); + ErrCode AccountInfoFromJson(AccountInfo &accountInfo); + ErrCode AccountInfoToJson(AccountInfo &accountInfo); + ~OhosAccountDataDeal() {}; + +private: + json jsonData_; + bool initOk_; + std::string configFile_; + void BuildJsonFileFromScratch(); + void CreateDefaultAccountInfo(AccountInfo &accountInfo); + void SaveAccountInfo(AccountInfo &accountInfo); +}; +} +} +#endif // BASE_ACCOUNT_INCLUDE_OHOS_ACCOUNT_DATA_DEAL_H diff --git a/services/accountmgr/include/ohos_account_manager.h b/services/accountmgr/include/ohos_account_manager.h new file mode 100755 index 000000000..750afdb42 --- /dev/null +++ b/services/accountmgr/include/ohos_account_manager.h @@ -0,0 +1,187 @@ +/* + * 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 ACCOUNT_OHOSACCOUNTMANAGER_H +#define ACCOUNT_OHOSACCOUNTMANAGER_H + +#include +#include +#include +#include "account_state_machine.h" +#include "account_info.h" +#include "ohos_account_data_deal.h" + +namespace OHOS { +namespace AccountSA { +const std::string ACCOUNT_CFG_DIR_ROOT_PATH = "/data/system/users/"; +const std::string ACCOUNT_CFG_FILE_NAME = "/account.json"; +class OhosAccountManager; +using OhosAccountEventFunc = bool (OhosAccountManager::*)(const std::string &name, const std::string &uid, + const std::string &eventStr); +/** + * Ohos account manager + */ +class OhosAccountManager { +public: + /** + * Get current account information. + * + * @return current account information. + */ + AccountInfo GetAccountInfo(); + + /** + * Get current account state. + * + * @return current account state id. + */ + int GetAccountState() const; + + /** + * Init ohos account manager. + * + */ + bool OnInitialize(); + + /** + * Process an account event. + * + * @param eventStr ohos account state change event + * @return true if the processing was completed, otherwise false + */ + bool HandleEvent(const std::string &eventStr); + + /** + * login ohos (for distributed network) account. + * + * @param name ohos account name + * @param uid ohos account uid + * @param eventStr ohos account state change event + * @return true if the processing was completed, otherwise false + */ + bool LoginOhosAccount(const std::string &name, const std::string &uid, const std::string &eventStr); + + /** + * logout ohos (for distributed network) account. + * + * @param name ohos account name + * @param uid ohos account uid + * @param eventStr ohos account state change event + * @return true if the processing was completed, otherwise false + */ + bool LogoutOhosAccount(const std::string &name, const std::string &uid, const std::string &eventStr); + + /** + * logoff ohos (for distributed network) account. + * + * @param name ohos account name + * @param uid ohos account uid + * @param eventStr ohos account state change event + * @return true if the processing was completed, otherwise false + */ + bool LogoffOhosAccount(const std::string &name, const std::string &uid, const std::string &eventStr); + + /** + * Handle token_invalid event of ohos (for distributed network) account . + * + * @param name ohos account name + * @param uid ohos account uid + * @param eventStr ohos account state change event + * @return true if the processing was completed, otherwise false + */ + bool HandleOhosAccountTokenInvalidEvent(const std::string &name, + const std::string &uid, const std::string &eventStr); + + /** + * Handle device account switch event. + * + * @param None + * @return None + */ + void HandleDevAccountSwitchEvent(); + + /** + * Ohos account state change. + * + * @param name ohos account name + * @param uid ohos account uid + * @param eventStr ohos account state change event + * @return true if the processing was completed, otherwise false + */ + bool OhosAccountStateChange(const std::string &name, const std::string &uid, const std::string &eventStr); + +private: + /** + * Get Current user Id. + */ + std::int32_t GetUserId(); + + /** + * Account state machine. + */ + std::unique_ptr accountState_{}; + + /** + * Current account. + */ + AccountInfo currentAccount_; + + /** + * Deal with file storage. + */ + std::unique_ptr dataDealer_{}; + + /** + * event mapper. + */ + std::map eventMap_; + + /** + * mutex lock for synchronization. + */ + std::mutex mgrMutex_; + + /** + * build event mapper. + */ + void BuildEventsMapper(); + + /** + * Records dfx event of ohos account status + */ + void ReportPublishFailureEvent(std::int32_t errCode, std::int32_t oldStatus); + + /** + * Config current account config. + * + * @param account account information. + * @return true if success. + */ + bool SetAccount(AccountInfo &account); + + /** + * Clear current account config. + * @param clrStatus account status. + */ + bool ClearAccount(std::int32_t clrStatus = ACCOUNT_STATE_UNBOUND); + + /** + * event function map + */ + std::map eventFuncMap_; +}; +} // namespace AccountSA +} // namespace OHOS +#endif // ACCOUNT_OHOSACCOUNTMANAGER_H diff --git a/services/accountmgr/src/account_dump_helper.cpp b/services/accountmgr/src/account_dump_helper.cpp new file mode 100755 index 000000000..03922b91f --- /dev/null +++ b/services/accountmgr/src/account_dump_helper.cpp @@ -0,0 +1,192 @@ +/* + * 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 "account_dump_helper.h" +#include +#include +#include "account_error_no.h" +#include "account_info.h" +#include "account_log_wrapper.h" +#include "ohos_account_manager.h" +#include "perf_stat.h" +#include "string_ex.h" + +namespace OHOS { +namespace AccountSA { +namespace { +const std::int32_t ARGS_SIZE_ONE = 1; +const std::int32_t ARGS_SIZE_TWO = 2; +const std::int32_t FIRST_PARAMETER = 0; +const std::int32_t SECOND_PARAMETER = 1; +const std::string ARGS_HELP = "-h"; +const std::string ARGS_ACCOUNT_INFO = "-account_info"; +const std::string ARGS_INPUT_SIMULATE = "-input_simulate"; +const std::string ARGS_OUTPUT_SIMULATE = "-output_simulate"; +const std::string ARGS_SHOW_LOG_LEVEL = "-show_log_level"; +const std::string ARGS_SET_LOG_LEVEL = "-set_log_level"; +const std::string ARGS_DUMP_PERF_STAT = "-perf_dump"; +const std::string ILLEGAL_INFORMATION = "Ohos Account Manager service, enter '-h' for usage.\n"; +const std::string SYSTEM_ERROR = "system error\n"; +const std::string NO_INFORMATION = "no such information\n"; +} // namespace + +AccountDumpHelper::AccountDumpHelper(const std::shared_ptr& accountMgr) +{ + accountMgr_ = accountMgr; +} + +bool AccountDumpHelper::Dump(const std::vector& args, std::string& result) const +{ + result.clear(); + bool retRes = false; + auto argsSize = args.size(); + if (argsSize == ARGS_SIZE_ONE) { + retRes = ProcessOneParameter(args[FIRST_PARAMETER], result); + } else if (argsSize == ARGS_SIZE_TWO) { + retRes = ProcessTwoParameter(args[FIRST_PARAMETER], args[SECOND_PARAMETER], result); + } else { + ShowIllegalInformation(result); + } + + return retRes; +} + +void AccountDumpHelper::ShowHelp(std::string& result) const +{ + result.append("Usage:dump [options]\n") + .append("Description:\n") + .append("-account_info ") + .append("dump all account information in the system\n") + .append("-input_simulate ") + .append("simulate event from ohos account, supported events: login/logout/token_invalid\n") + .append("-output_simulate ") + .append("simulate event output\n") + .append("-show_log_level ") + .append("show account SA's log level\n") + .append("-set_log_level ") + .append("set account SA's log level\n") + .append("-perf_dump ") + .append("dump performance statistics\n"); +} + +void AccountDumpHelper::ShowIllegalInformation(std::string& result) const +{ + result.append(ILLEGAL_INFORMATION); +} + +void AccountDumpHelper::ShowAccountInfo(std::string& result) const +{ + auto lockPtr = accountMgr_.lock(); + if (lockPtr == nullptr) { + ACCOUNT_LOGE("Invalid lockPtr"); + return; + } + + AccountInfo accountInfo = lockPtr->GetAccountInfo(); + result.append("Ohos account name: "); + result.append(accountInfo.ohosAccountName_.c_str()); + result.append(", Ohos account uid: "); + result.append(accountInfo.ohosAccountUid_.c_str()); + result.append(", Local user Id: "); + result.append(std::to_string(accountInfo.userId_)); + result.append(", Ohos account status: "); + result.append(std::to_string(accountInfo.ohosAccountStatus_)); + result.append(", Ohos account bind time: " + std::to_string(accountInfo.bindTime_)); + result.append("\n"); +} + +bool AccountDumpHelper::ProcessOneParameter(const std::string& arg, std::string& result) const +{ + if (accountMgr_.expired()) { + result.append("Internal error!\n"); + return false; + } + bool retRes = true; + if (arg == ARGS_HELP) { + ShowHelp(result); + } else if (arg == ARGS_ACCOUNT_INFO) { + ShowAccountInfo(result); + } else if (arg == ARGS_SHOW_LOG_LEVEL) { + auto logLevel = static_cast(AccountLogWrapper::GetLogLevel()); + result.append("Current Log Level: " + std::to_string(logLevel) + "\n"); + } else if (arg == ARGS_DUMP_PERF_STAT) { + PerfStat::GetInstance().Dump(result); + } else { + ShowHelp(result); + retRes = false; + } + + return retRes; +} + +bool AccountDumpHelper::SimulateInputEvent(const std::string& eventStr, std::string& result) const +{ + auto lockPtr = accountMgr_.lock(); + if (lockPtr == nullptr) { + return false; + } + + bool retRes = lockPtr->HandleEvent(eventStr); + if (retRes) { + result.append("process event success"); + } else { + result.append("process event failed"); + } + + return retRes; +} + +bool AccountDumpHelper::SetLogLevel(const std::string& levelStr, std::string& result) const +{ + if (!regex_match(levelStr, std::regex("^\\d+$"))) { + ACCOUNT_LOGE("Invalid format of log level"); + result.append("Invalid format of log level\n"); + return false; + } + auto level = std::stoi(levelStr); + if ((level < static_cast(AccountLogLevel::DEBUG)) || + (level > static_cast(AccountLogLevel::FATAL))) { + result.append("Invalid logLevel\n"); + } else { + AccountLogLevel logLevel = static_cast(level); + AccountLogWrapper::SetLogLevel(logLevel); + result.append("Set logLevel success\n"); + return true; + } + return false; +} + +bool AccountDumpHelper::ProcessTwoParameter(const std::string& arg1, const std::string& arg2, std::string& result) const +{ + if (accountMgr_.expired()) { + result.append("Internal error!\n"); + return false; + } + bool retRes = false; + if (arg1 == ARGS_INPUT_SIMULATE) { + retRes = SimulateInputEvent(arg2, result); + if (retRes) { + result.append("handle input simulate event ok\n"); + } + } else if (arg1 == ARGS_SET_LOG_LEVEL) { + retRes = SetLogLevel(arg2, result); + } else { + ShowHelp(result); + } + + return retRes; +} +} // namespace AccountSA +} // namespace OHOS diff --git a/services/accountmgr/src/account_helper_data.cpp b/services/accountmgr/src/account_helper_data.cpp new file mode 100755 index 000000000..7b733112d --- /dev/null +++ b/services/accountmgr/src/account_helper_data.cpp @@ -0,0 +1,61 @@ +/* + * 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 "account_helper_data.h" +#include +#include +#include +#include +#include "account_log_wrapper.h" +#include "file_ex.h" + +namespace OHOS { +namespace AccountSA { +using json = nlohmann::json; +namespace { +const std::string ACCOUNTMGR_HELPER_JSON_FILE = "/system/etc/account/accountmgr_helper.json"; +const std::string KEY_BUNDLE_NAME_LIST = "BundleNameTrustList"; +} + +std::vector AccountHelperData::GetBundleNameTrustList() +{ + std::vector result = {""}; + if (!FileExists(ACCOUNTMGR_HELPER_JSON_FILE)) { + ACCOUNT_LOGI("file %{public}s not exist, empty default!", ACCOUNTMGR_HELPER_JSON_FILE.c_str()); + return result; + } + + std::ifstream fin(ACCOUNTMGR_HELPER_JSON_FILE); + if (!fin) { + ACCOUNT_LOGE("Failed to open file %{public}s", ACCOUNTMGR_HELPER_JSON_FILE.c_str()); + return result; + } + + nlohmann::json jsonData = json::parse(fin, nullptr, false); + if (!jsonData.is_structured()) { + ACCOUNT_LOGE("not valid json file!"); + fin.close(); + return result; + } + fin.close(); + + if (jsonData.find(KEY_BUNDLE_NAME_LIST) != jsonData.end() && jsonData.at(KEY_BUNDLE_NAME_LIST).is_array()) { + result = jsonData.at(KEY_BUNDLE_NAME_LIST).get>(); + } + + return result; +} +} // namespace AccountSA +} // namespace OHOS diff --git a/services/accountmgr/src/account_mgr_service.cpp b/services/accountmgr/src/account_mgr_service.cpp new file mode 100755 index 000000000..07c0e81af --- /dev/null +++ b/services/accountmgr/src/account_mgr_service.cpp @@ -0,0 +1,204 @@ +/* + * 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 "account_mgr_service.h" +#include "account_dump_helper.h" +#include "account_log_wrapper.h" +#include "datetime_ex.h" +#include "device_account_info.h" +#include "directory_ex.h" +#include "file_ex.h" +#include "hisysevent.h" +#include "if_system_ability_manager.h" +#include "ipc_skeleton.h" +#include "iservice_registry.h" +#include "perf_stat.h" +#include "string_ex.h" +#include "system_ability_definition.h" + +namespace OHOS { +namespace AccountSA { +const std::string DEVICE_OWNER_DIR = "/data/system/users/0/"; + +constexpr std::int32_t UID_TRANSFORM_DIVISOR = 100000; +IAccountContext *IAccountContext::instance_ = nullptr; + +const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility( + &DelayedRefSingleton::GetInstance()); + +AccountMgrService::AccountMgrService() : SystemAbility(SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN, true) +{ + PerfStat::GetInstance().SetInstanceCreateTime(GetTickCount()); +} + +AccountMgrService::~AccountMgrService() +{ +} + +bool AccountMgrService::UpdateOhosAccountInfo(const std::string& accountName, const std::string& uid, + const std::string& eventStr) +{ + ACCOUNT_LOGI("Account event %s", eventStr.c_str()); + if (!ohosAccountMgr_->OhosAccountStateChange(accountName, uid, eventStr)) { + ACCOUNT_LOGE("Ohos account state change failed"); + return false; + } + + ACCOUNT_LOGI("Successful"); + return true; +} + +std::pair AccountMgrService::QueryOhosAccountInfo(void) +{ + AccountInfo accountInfo = ohosAccountMgr_->GetAccountInfo(); + if (accountInfo.ohosAccountUid_.empty()) { + ACCOUNT_LOGE("invalid id"); + accountInfo.clear(); + } + std::string name = accountInfo.ohosAccountName_; + std::string id = accountInfo.ohosAccountUid_; + std::int32_t status = accountInfo.ohosAccountStatus_; + return std::make_pair(true, OhosAccountInfo(name, id, status)); +} + +std::int32_t AccountMgrService::QueryDeviceAccountIdFromUid(std::int32_t uid) +{ + return uid / UID_TRANSFORM_DIVISOR; +} + +std::int32_t AccountMgrService::QueryDeviceAccountId(std::int32_t& accountId) +{ + accountId = DEVICE_ACCOUNT_OWNER; + return ERR_OK; +} + +bool AccountMgrService::IsServiceStarted(void) const +{ + return (state_ == STATE_RUNNING); +} + +void AccountMgrService::OnStart() +{ + if (state_ == ServiceRunningState::STATE_RUNNING) { + ACCOUNT_LOGI("AccountMgrService has already started."); + return; + } + + PerfStat::GetInstance().SetInstanceStartTime(GetTickCount()); + ACCOUNT_LOGI("start is triggered"); + if (!Init()) { + ACCOUNT_LOGE("failed to init AccountMgrService"); + return; + } + state_ = ServiceRunningState::STATE_RUNNING; + ACCOUNT_LOGI("AccountMgrService::OnStart start service success."); +} + +void AccountMgrService::OnStop() +{ + PerfStat::GetInstance().SetInstanceStopTime(GetTickCount()); + ACCOUNT_LOGI("onstop is called"); + IAccountContext::SetInstance(nullptr); + SelfClean(); +} + +bool AccountMgrService::Init() +{ + if (state_ == ServiceRunningState::STATE_RUNNING) { + ACCOUNT_LOGW("Service is already running!"); + return false; + } + + if (!OHOS::FileExists(DEVICE_OWNER_DIR)) { + ACCOUNT_LOGI("Device owner dir not exist, create!"); + if (!OHOS::ForceCreateDirectory(DEVICE_OWNER_DIR)) { + ACCOUNT_LOGW("Create device owner dir failure!"); + } + } + + bool ret = false; + if (!registerToService_) { + ret = Publish(&DelayedRefSingleton::GetInstance()); + if (!ret) { + HiviewDFX::HiSysEvent::Write(HiviewDFX::HiSysEvent::Domain::ACCOUNT, "AccountServiceStartFailed", + HiviewDFX::HiSysEvent::EventType::FAULT, "ERROR_TYPE", ERR_ACCOUNT_MGR_ADD_TO_SA_ERROR); + ACCOUNT_LOGE("AccountMgrService::Init Publish failed!"); + return false; + } + registerToService_ = true; + } + + PerfStat::GetInstance().SetInstanceInitTime(GetTickCount()); + + ohosAccountMgr_ = std::make_shared(); + ret = ohosAccountMgr_->OnInitialize(); + if (!ret) { + ACCOUNT_LOGE("Ohos account manager initialize failed"); + HiviewDFX::HiSysEvent::Write(HiviewDFX::HiSysEvent::Domain::ACCOUNT, "AccountServiceStartFailed", + HiviewDFX::HiSysEvent::EventType::FAULT, "ERROR_TYPE", ret); + return ret; + } + dumpHelper_ = std::make_unique(ohosAccountMgr_); + IAccountContext::SetInstance(this); + ACCOUNT_LOGI("init end success"); + return true; +} + +int AccountMgrService::Dump(std::int32_t fd, const std::vector& args) +{ + if (fd < 0) { + ACCOUNT_LOGE("dump fd invalid"); + return ERR_ACCOUNT_MGR_DUMP_ERROR; + } + + std::vector argsInStr; + for (const auto& arg : args) { + ACCOUNT_LOGI("Dump args: %s", Str16ToStr8(arg).c_str()); + argsInStr.emplace_back(Str16ToStr8(arg)); + } + + std::string result; + if (dumpHelper_ && dumpHelper_->Dump(argsInStr, result)) { + ACCOUNT_LOGI("%s", result.c_str()); + std::int32_t ret = dprintf(fd, "%s", result.c_str()); + if (ret < 0) { + ACCOUNT_LOGE("dprintf to dump fd failed"); + return ERR_ACCOUNT_MGR_DUMP_ERROR; + } + return ERR_OK; + } + + ACCOUNT_LOGW("dumpHelper failed"); + return ERR_ACCOUNT_MGR_DUMP_ERROR; +} + +void AccountMgrService::SelfClean() +{ + state_ = ServiceRunningState::STATE_NOT_START; + registerToService_ = false; + ACCOUNT_LOGI("selfclean finished"); +} + +void AccountMgrService::HandleNotificationEvents(const std::string &eventStr) +{ + if (state_ == ServiceRunningState::STATE_NOT_START) { + ACCOUNT_LOGW("service not running for handling event: %{public}s", eventStr.c_str()); + return; + } + + ACCOUNT_LOGI("Unhandled event: %{public}s", eventStr.c_str()); +} +} // namespace AccountSA +} // namespace OHOS diff --git a/services/accountmgr/src/account_state_machine.cpp b/services/accountmgr/src/account_state_machine.cpp new file mode 100755 index 000000000..dad358181 --- /dev/null +++ b/services/accountmgr/src/account_state_machine.cpp @@ -0,0 +1,179 @@ +/* + * 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 "account_state_machine.h" +#include "account_info.h" +#include "account_log_wrapper.h" +#include "datetime_ex.h" +#include "perf_stat.h" + +namespace OHOS { +namespace AccountSA { +/** + * Account state machine initialize. + */ +void AccountStateMachine::OnInitialize() +{ + stateMachineMap_ = { + // ACCOUNT_STATE_UNBOUND state + std::make_pair(ACCOUNT_STATE_UNBOUND, std::map { + // normal event, transform to login state + std::make_pair(ACCOUNT_BIND_SUCCESS_EVT, new LoginAction(ACCOUNT_STATE_LOGIN)), + // normal event, keep in unbound state + std::make_pair(ACCOUNT_BIND_FAILED_EVT, new ExceptionAction(ACCOUNT_STATE_UNBOUND)), + // unexpected event, re-initial state machine, check the state from account server + std::make_pair(ACCOUNT_AUTHENTICATE_SUCCESS_EVT, new LoginAction(ACCOUNT_STATE_LOGIN)), + // unexpected event, re-initial state machine, check the state from account server + std::make_pair(ACCOUNT_AUTHENTICATE_FAILED_EVT, nullptr), + // unexpected event, re-initial state machine, check the state from account server + std::make_pair(ACCOUNT_TOKEN_EXPIRED_EVT, nullptr), + // unexpected event, re-initial state machine, check the state from account server + std::make_pair(ACCOUNT_PASSWORD_CHANGED_EVT, nullptr), + // unexpected event, re-initial state machine, check the state from account server + std::make_pair(ACCOUNT_MANUAL_LOGOUT_EVT, nullptr), + // unexpected event, keep in unbound state + std::make_pair(ACCOUNT_MANUAL_UNBOUND_EVT, nullptr), + // unexpected event, keep in unbound state + std::make_pair(ACCOUNT_MANUAL_LOGOFF_EVT, nullptr)} + ), + // ACCOUNT_STATE_LOGIN state + std::make_pair(ACCOUNT_STATE_LOGIN, std::map { + // expected event, keep in login state + std::make_pair(ACCOUNT_BIND_SUCCESS_EVT, nullptr), + // unexpected event, re-initial state machine, check the state from account server + std::make_pair(ACCOUNT_BIND_FAILED_EVT, new ExceptionAction(ACCOUNT_STATE_LOGIN)), + // normal event, keep in login state + std::make_pair(ACCOUNT_AUTHENTICATE_SUCCESS_EVT, nullptr), + // normal event, transform to logout state + std::make_pair(ACCOUNT_AUTHENTICATE_FAILED_EVT, nullptr), + // expected event, transform to logout state + std::make_pair(ACCOUNT_TOKEN_EXPIRED_EVT, new LogoutAction(ACCOUNT_STATE_NOTLOGIN)), + // expected event, transform to logout state + std::make_pair(ACCOUNT_PASSWORD_CHANGED_EVT, new LogoutAction(ACCOUNT_STATE_NOTLOGIN)), + // expected event, transform to logout state + std::make_pair(ACCOUNT_MANUAL_LOGOUT_EVT, new LogoutAction(ACCOUNT_STATE_NOTLOGIN)), + // expected event, transform to unbound state + std::make_pair(ACCOUNT_MANUAL_UNBOUND_EVT, new UnboundAction(ACCOUNT_STATE_UNBOUND)), + // expected event, transform to logoff state + std::make_pair(ACCOUNT_MANUAL_LOGOFF_EVT, new LogoffAction(ACCOUNT_STATE_LOGOFF))} + ), + // ACCOUNT_STATE_NOTLOGIN state + std::make_pair(ACCOUNT_STATE_NOTLOGIN, std::map { + // normal event, transform to login state + std::make_pair(ACCOUNT_BIND_SUCCESS_EVT, new LoginAction(ACCOUNT_STATE_LOGIN)), + // unexpected event, re-initial state machine, check the state from account server + std::make_pair(ACCOUNT_BIND_FAILED_EVT, new ExceptionAction(ACCOUNT_STATE_NOTLOGIN)), + // expected event, transform to login state + std::make_pair(ACCOUNT_AUTHENTICATE_SUCCESS_EVT, new LoginAction(ACCOUNT_STATE_LOGIN)), + // expected event, keep in logout state + std::make_pair(ACCOUNT_AUTHENTICATE_FAILED_EVT, nullptr), + // unexpected event, re-initial state machine, check the state from account server + std::make_pair(ACCOUNT_TOKEN_EXPIRED_EVT, nullptr), + // unexpected event, re-initial state machine, check the state from account server + std::make_pair(ACCOUNT_PASSWORD_CHANGED_EVT, nullptr), + // unexpected event, re-initial state machine, check the state from account server + std::make_pair(ACCOUNT_MANUAL_LOGOUT_EVT, nullptr), + // expected event, transform to unbound state + std::make_pair(ACCOUNT_MANUAL_UNBOUND_EVT, new UnboundAction(ACCOUNT_STATE_UNBOUND)), + // expected event, transform to logoff state + std::make_pair(ACCOUNT_MANUAL_LOGOFF_EVT, new LogoffAction(ACCOUNT_STATE_LOGOFF))} + ), + // ACCOUNT_STATE_LOGOFF state + std::make_pair(ACCOUNT_STATE_LOGOFF, std::map { + // normal event, transform to login state + std::make_pair(ACCOUNT_BIND_SUCCESS_EVT, new LoginAction(ACCOUNT_STATE_LOGIN)), + // unexpected event, re-initial state machine, check the state from account server + std::make_pair(ACCOUNT_BIND_FAILED_EVT, new ExceptionAction(ACCOUNT_STATE_LOGOFF)), + // expected event, transform to login state + std::make_pair(ACCOUNT_AUTHENTICATE_SUCCESS_EVT, nullptr), + // expected event, keep in logoff state + std::make_pair(ACCOUNT_AUTHENTICATE_FAILED_EVT, nullptr), + // unexpected event, re-initial state machine, check the state from account server + std::make_pair(ACCOUNT_TOKEN_EXPIRED_EVT, nullptr), + // unexpected event, re-initial state machine, check the state from account server + std::make_pair(ACCOUNT_PASSWORD_CHANGED_EVT, nullptr), + // unexpected event, re-initial state machine, check the state from account server + std::make_pair(ACCOUNT_MANUAL_LOGOUT_EVT, nullptr), + // expected event, transform to logoff state + std::make_pair(ACCOUNT_MANUAL_UNBOUND_EVT, nullptr), + // expected event, transform to logoff state + std::make_pair(ACCOUNT_MANUAL_LOGOFF_EVT, nullptr)} + ) + }; +} + +/** + * Account state machine clean. + */ +void AccountStateMachine::Clean() +{ + for (auto ¤tStateIter : stateMachineMap_) { + for (auto &eventIter : currentStateIter.second) { + if (eventIter.second != nullptr) { + delete eventIter.second; + eventIter.second = nullptr; + } + } + } +} + +/** + * Process a state change event + * + * @param evt the event info + * @return true if the processing was completed, otherwise false + */ +bool AccountStateMachine::StateChangeProcess(int evt) +{ + // for performance record + std::string stateRecordStr; + int64_t processTicks = GetTickCount(); + stateRecordStr.append("state from[").append(std::to_string(currentState_)).append("] to ["); + + // get all the current state event action + auto stateIter = stateMachineMap_.find(currentState_); + if (stateIter == stateMachineMap_.end()) { + ACCOUNT_LOGE("current state %d is not in state machine map.", currentState_); + return false; + } + + // get the current event action + auto eventIter = stateIter->second.find(evt); + if (eventIter == stateIter->second.end()) { + ACCOUNT_LOGE("event %d is not in state machine map.", evt); + return false; + } + + // maybe action is null + if (eventIter->second == nullptr) { + ACCOUNT_LOGI("event %d has no action.", evt); + return true; + } + + int nextState = eventIter->second->GetNextState(); + if (currentState_ != nextState) { + ACCOUNT_LOGI("account state change, (oldstate, newstate) = (%d, %d)", currentState_, nextState); + currentState_ = nextState; + } + + // Record state change performance + processTicks = GetTickCount() - processTicks; + stateRecordStr.append(std::to_string(nextState)).append("], event[").append(std::to_string(evt)).append("] Cost"); + PerfStat::GetInstance().SetAccountStateChangeTime(stateRecordStr, processTicks); + + return true; +} +} // namespace AccountSA +} // namespace OHOS diff --git a/services/accountmgr/src/account_stub.cpp b/services/accountmgr/src/account_stub.cpp new file mode 100755 index 000000000..a5174d21c --- /dev/null +++ b/services/accountmgr/src/account_stub.cpp @@ -0,0 +1,272 @@ +/* + * 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 "account_stub.h" +#include +#include +#include "account_error_no.h" +#include "account_helper_data.h" +#include "account_info.h" +#include "account_log_wrapper.h" +#include "account_mgr_service.h" +#include "bundlemgr/bundle_mgr_interface.h" +#include "if_system_ability_manager.h" +#include "ipc_skeleton.h" +#include "iservice_registry.h" +#include "ohos_account_kits.h" +#include "string_ex.h" +#include "system_ability_definition.h" + +namespace OHOS { +namespace AccountSA { +namespace { +const std::string OHOS_ACCOUNT_QUIT_TIPS_TITLE = ""; +const std::string OHOS_ACCOUNT_QUIT_TIPS_CONTENT = ""; +const std::string PERMISSION_MANAGE_USERS = "ohos.permission.MANAGE_LOCAL_ACCOUNTS"; +const std::string PERMISSION_INTERACT_ACROSS_USERS = "ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS"; +const std::string PERMISSION_INTERACT_ACROSS_USERS_FULL = + "ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS_EXTENSION"; +const std::string PERMISSION_DISTRIBUTED_DATASYNC = "ohos.permission.DISTRIBUTED_DATASYNC"; +const std::string DEFAULT_ACCOUNT_NAME = "no_name"; +constexpr std::int32_t SYSTEM_UID = 1000; +constexpr std::int32_t ROOT_UID = 0; + +std::int32_t GetBundleNamesForUid(std::int32_t uid, std::vector &bundleNameVec) +{ + sptr systemMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemMgr == nullptr) { + ACCOUNT_LOGE("Fail to get system ability mgr"); + return ERR_ACCOUNT_ZIDL_ACCOUNT_STUB_ERROR; + } + + sptr remoteObject = systemMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (remoteObject == nullptr) { + ACCOUNT_LOGE("Fail to get bundle manager proxy"); + return ERR_ACCOUNT_ZIDL_ACCOUNT_STUB_ERROR; + } + + sptr bundleMgrProxy = iface_cast(remoteObject); + if (bundleMgrProxy == nullptr) { + ACCOUNT_LOGE("Bundle mgr proxy is nullptr"); + return ERR_ACCOUNT_ZIDL_ACCOUNT_STUB_ERROR; + } + + std::string bundleName; + if (bundleMgrProxy->GetBundleNameForUid(uid, bundleName)) { + bundleNameVec.emplace_back(bundleName); + } + return ERR_OK; +} +} +const std::map AccountStub::stubFuncMap_ { + std::make_pair(UPDATE_OHOS_ACCOUNT_INFO, &AccountStub::CmdUpdateOhosAccountInfo), + std::make_pair(QUERY_OHOS_ACCOUNT_INFO, &AccountStub::CmdQueryOhosAccountInfo), + std::make_pair(QUERY_OHOS_ACCOUNT_QUIT_TIPS, &AccountStub::CmdQueryOhosQuitTips), + std::make_pair(QUERY_DEVICE_ACCOUNT_ID, &AccountStub::CmdQueryDeviceAccountId), + std::make_pair(QUERY_DEVICE_ACCOUNT_ID_FROM_UID, &AccountStub::CmdQueryDeviceAccountIdFromUid), +}; + +std::int32_t AccountStub::CmdUpdateOhosAccountInfo(MessageParcel &data, MessageParcel &reply) +{ + if (!IsRootOrSystemAccount() && !HasAccountRequestPermission(PERMISSION_MANAGE_USERS)) { + ACCOUNT_LOGE("Check permission failed"); + return ERR_ACCOUNT_ZIDL_CHECK_PERMISSION_ERROR; + } + + // ignore the real account name + Str16ToStr8(data.ReadString16()); + const std::string accountName = DEFAULT_ACCOUNT_NAME; + const std::string uid = Str16ToStr8(data.ReadString16()); + if (uid.empty()) { + ACCOUNT_LOGE("invalid user id"); + return ERR_ACCOUNT_ZIDL_ACCOUNT_STUB_ERROR; + } + const std::string eventStr = Str16ToStr8(data.ReadString16()); + ACCOUNT_LOGI("CmdUpdateOhosAccountInfo eventStr: %s", eventStr.c_str()); + + std::int32_t ret = ERR_OK; + bool result = UpdateOhosAccountInfo(accountName, uid, eventStr); + if (!result) { + ACCOUNT_LOGE("Update ohos account info failed"); + ret = ERR_ACCOUNT_ZIDL_ACCOUNT_STUB_ERROR; + } + if (!reply.WriteInt32(ret)) { + ACCOUNT_LOGE("Write result data failed"); + ret = ERR_ACCOUNT_ZIDL_WRITE_RESULT_ERROR; + } + return ret; +} + +std::int32_t AccountStub::CmdQueryOhosAccountInfo(MessageParcel &data, MessageParcel &reply) +{ + if (!IsRootOrSystemAccount() && !HasAccountRequestPermission(PERMISSION_MANAGE_USERS)) { + ACCOUNT_LOGE("Check permission failed"); + return ERR_ACCOUNT_ZIDL_CHECK_PERMISSION_ERROR; + } + + std::pair info = QueryOhosAccountInfo(); + if (!info.first) { + ACCOUNT_LOGE("Query ohos account info failed"); + return ERR_ACCOUNT_ZIDL_ACCOUNT_STUB_ERROR; + } + + std::string name = info.second.name_; + std::string id = info.second.uid_; + if (!reply.WriteString16(Str8ToStr16(name))) { + ACCOUNT_LOGE("Write name data failed"); + return ERR_ACCOUNT_ZIDL_WRITE_NAME_ERROR; + } + if (!reply.WriteString16(Str8ToStr16(id))) { + ACCOUNT_LOGE("Write id data failed"); + return ERR_ACCOUNT_ZIDL_WRITE_UID_ERROR; + } + if (!reply.WriteInt32(info.second.status_)) { + ACCOUNT_LOGE("Write status data failed"); + return ERR_ACCOUNT_ZIDL_WRITE_ACCOUNT_STATUS_ERROR; + } + return ERR_OK; +} + +std::int32_t AccountStub::CmdQueryOhosQuitTips(MessageParcel &data, MessageParcel &reply) +{ + if (!IsRootOrSystemAccount() && !HasAccountRequestPermission(PERMISSION_MANAGE_USERS)) { + ACCOUNT_LOGE("Check permission failed"); + return ERR_ACCOUNT_ZIDL_CHECK_PERMISSION_ERROR; + } + + if (!reply.WriteString16(Str8ToStr16(OHOS_ACCOUNT_QUIT_TIPS_TITLE))) { + ACCOUNT_LOGE("Write quit tips title failed"); + return ERR_ACCOUNT_ZIDL_WRITE_RESULT_ERROR; + } + if (!reply.WriteString16(Str8ToStr16(OHOS_ACCOUNT_QUIT_TIPS_CONTENT))) { + ACCOUNT_LOGE("Write quit tips content failed"); + return ERR_ACCOUNT_ZIDL_WRITE_RESULT_ERROR; + } + ACCOUNT_LOGI("CmdQueryOhosQuitTips exit"); + return ERR_OK; +} + +std::int32_t AccountStub::CmdQueryDeviceAccountId(MessageParcel &data, MessageParcel &reply) +{ + if (!IsRootOrSystemAccount()) { + ACCOUNT_LOGE("Check permission failed"); + return ERR_ACCOUNT_ZIDL_CHECK_PERMISSION_ERROR; + } + + std::int32_t id; + auto ret = QueryDeviceAccountId(id); + if (ret != ERR_OK) { + ACCOUNT_LOGE("QueryDevice AccountId failed: %d", ret); + return ret; + } + + if (!reply.WriteInt32(id)) { + ACCOUNT_LOGE("Write result data failed"); + return ERR_ACCOUNT_ZIDL_WRITE_RESULT_ERROR; + } + return ERR_OK; +} + +std::int32_t AccountStub::CmdQueryDeviceAccountIdFromUid(MessageParcel &data, MessageParcel &reply) +{ + std::int32_t uid = data.ReadInt32(); + auto ret = QueryDeviceAccountIdFromUid(uid); + if (ret < 0) { + ACCOUNT_LOGE("QueryDevice accountid from uid failed: %d", ret); + return ret; + } + + if (!reply.WriteInt32(ret)) { + ACCOUNT_LOGE("Write result data failed"); + return ERR_ACCOUNT_ZIDL_WRITE_RESULT_ERROR; + } + + return ERR_OK; +} + +std::int32_t AccountStub::OnRemoteRequest(std::uint32_t code, MessageParcel &data, + MessageParcel &reply, MessageOption &option) +{ + ACCOUNT_LOGI("Received stub message: %{public}d", code); + if (!IsServiceStarted()) { + ACCOUNT_LOGE("account mgr not ready"); + return ERR_ACCOUNT_ZIDL_MGR_NOT_READY_ERROR; + } + + if (!CheckCallerForTrustList()) { + const std::u16string descriptor = AccountStub::GetDescriptor(); + const std::u16string remoteDescriptor = data.ReadInterfaceToken(); + if (descriptor != remoteDescriptor) { + ACCOUNT_LOGE("Check remote descriptor failed"); + return ERR_ACCOUNT_ZIDL_ACCOUNT_STUB_ERROR; + } + } + + const auto &itFunc = stubFuncMap_.find(code); + if (itFunc != stubFuncMap_.end()) { + return (this->*(itFunc->second))(data, reply); + } + + ACCOUNT_LOGW("remote request unhandled: %{public}d", code); + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); +} + +bool AccountStub::HasAccountRequestPermission(const std::string &permissionName) +{ + if (permissionName.empty()) { + return false; + } + + ACCOUNT_LOGI("Check permission: %{public}s", permissionName.c_str()); + return true; +} + +bool AccountStub::IsRootOrSystemAccount() +{ + const auto id = IPCSkeleton::GetCallingUid(); + return (id == ROOT_UID || id == SYSTEM_UID); +} + +bool AccountStub::CheckCallerForTrustList() +{ + if (!IsServiceStarted()) { + ACCOUNT_LOGE("account mgr not ready"); + return false; + } + + const std::int32_t uid = IPCSkeleton::GetCallingUid(); + if (uid == ROOT_UID || uid == SYSTEM_UID) { + return false; + } + + std::vector bundleNameVec; + if (GetBundleNamesForUid(uid, bundleNameVec) != ERR_OK) { + return false; + } + + if (bundleNameVec.empty()) { + return false; + } + + std::vector trustList = AccountHelperData::GetBundleNameTrustList(); + for (const auto &bundleName : bundleNameVec) { + if (std::find(trustList.begin(), trustList.end(), bundleName) == trustList.end()) { + return false; + } + } + return true; +} +} // namespace AccountSA +} // namespace OHOS diff --git a/services/accountmgr/src/iaccount.cpp b/services/accountmgr/src/iaccount.cpp new file mode 100755 index 000000000..862cbe4cb --- /dev/null +++ b/services/accountmgr/src/iaccount.cpp @@ -0,0 +1,23 @@ +/* + * 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 "iaccount.h" +#include "account_proxy.h" + +namespace OHOS { +namespace AccountSA { +IMPLEMENT_META_INTERFACE(Account, ACCOUNT_SERVICE_NAME); +} // namespace AccountSA +} // namespace OHOS diff --git a/services/accountmgr/src/ohos_account_data_deal.cpp b/services/accountmgr/src/ohos_account_data_deal.cpp new file mode 100755 index 000000000..1dca94368 --- /dev/null +++ b/services/accountmgr/src/ohos_account_data_deal.cpp @@ -0,0 +1,144 @@ +/* + * 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 "ohos_account_data_deal.h" +#include +#include +#include +#include "account_error_no.h" +#include "account_info.h" +#include "account_log_wrapper.h" +#include "directory_ex.h" +#include "file_ex.h" + +namespace OHOS { +namespace AccountSA { +OhosAccountDataDeal::OhosAccountDataDeal(const std::string &configFile) : configFile_(configFile) +{ + initOk_ = false; +} + +ErrCode OhosAccountDataDeal::Init() +{ + if (!FileExists(configFile_)) { + ACCOUNT_LOGI("file %{public}s not exist, create!", configFile_.c_str()); + BuildJsonFileFromScratch(); + } + + std::ifstream fin(configFile_); + if (!fin) { + ACCOUNT_LOGE("Failed to open file %{public}s", configFile_.c_str()); + return ERR_ACCOUNT_DATADEAL_INPUT_FILE_ERROR; + } + + // NOT-allow exceptions when parse json file + nlohmann::json jsonData = json::parse(fin, nullptr, false); + if (!jsonData.is_structured()) { + ACCOUNT_LOGE("Invalid json file, remove"); + fin.close(); + if (RemoveFile(configFile_)) { + ACCOUNT_LOGE("Remove invalid json file failed"); + } + return ERR_ACCOUNT_DATADEAL_JSON_FILE_CORRUPTION; + } + + // jsonData_ keeps well-structured json key-values + jsonData_ = jsonData; + initOk_ = true; + fin.close(); + return ERR_OK; +} + +ErrCode OhosAccountDataDeal::AccountInfoFromJson(AccountInfo &accountInfo) +{ + if (!initOk_) { + return ERR_ACCOUNT_DATADEAL_NOT_READY; + } + + const auto &jsonObjectEnd = jsonData_.end(); + if (jsonData_.find(DATADEAL_JSON_KEY_ACCOUNT_NAME) != jsonObjectEnd) { + accountInfo.ohosAccountName_ = jsonData_.at(DATADEAL_JSON_KEY_ACCOUNT_NAME).get(); + } + + if (jsonData_.find(DATADEAL_JSON_KEY_OPENID) != jsonObjectEnd) { + accountInfo.ohosAccountUid_ = jsonData_.at(DATADEAL_JSON_KEY_OPENID).get(); + } + + if (jsonData_.find(DATADEAL_JSON_KEY_UID) != jsonObjectEnd) { + accountInfo.userId_ = jsonData_.at(DATADEAL_JSON_KEY_UID).get(); + } + + if (jsonData_.find(DATADEAL_JSON_KEY_BIND_TIME) != jsonObjectEnd) { + accountInfo.bindTime_ = jsonData_.at(DATADEAL_JSON_KEY_BIND_TIME).get(); + } + ACCOUNT_LOGI("AccountInfo, bindTime: %{public}ld", accountInfo.bindTime_); + + if (jsonData_.find(DATADEAL_JSON_KEY_STATUS) != jsonObjectEnd) { + accountInfo.ohosAccountStatus_ = jsonData_.at(DATADEAL_JSON_KEY_STATUS).get(); + } + ACCOUNT_LOGI("AccountInfo, ohos account status: %{public}d", accountInfo.ohosAccountStatus_); + + return ERR_OK; +} + +ErrCode OhosAccountDataDeal::AccountInfoToJson(AccountInfo &accountInfo) +{ + if (!initOk_) { + ACCOUNT_LOGE("Not init ok"); + return ERR_ACCOUNT_DATADEAL_NOT_READY; + } + + SaveAccountInfo(accountInfo); + return ERR_OK; +} + +void OhosAccountDataDeal::CreateDefaultAccountInfo(AccountInfo &accountInfo) +{ + accountInfo.userId_ = 0; + accountInfo.bindTime_ = 0; + accountInfo.ohosAccountUid_ = DEFAULT_OHOS_ACCOUNT_UID; + accountInfo.ohosAccountName_ = DEFAULT_OHOS_ACCOUNT_NAME; + accountInfo.ohosAccountStatus_ = ACCOUNT_STATE_UNBOUND; + accountInfo.digest_ = ""; +} + +void OhosAccountDataDeal::SaveAccountInfo(AccountInfo &accountInfo) +{ + jsonData_[DATADEAL_JSON_KEY_BIND_TIME] = accountInfo.bindTime_; + jsonData_[DATADEAL_JSON_KEY_UID] = accountInfo.userId_; + jsonData_[DATADEAL_JSON_KEY_OPENID] = accountInfo.ohosAccountUid_; + jsonData_[DATADEAL_JSON_KEY_ACCOUNT_NAME] = accountInfo.ohosAccountName_; + jsonData_[DATADEAL_JSON_KEY_STATUS] = accountInfo.ohosAccountStatus_; + + /* update config file */ + std::ofstream out(configFile_); + if (!out) { + ACCOUNT_LOGE("Failed to open file %{public}s", configFile_.c_str()); + return; + } + out << jsonData_; + out.close(); +} + +void OhosAccountDataDeal::BuildJsonFileFromScratch() +{ + AccountInfo accountInfo; + + CreateDefaultAccountInfo(accountInfo); + + SaveAccountInfo(accountInfo); +} +} // namespace AccountSA +} // namespace OHOS diff --git a/services/accountmgr/src/ohos_account_manager.cpp b/services/accountmgr/src/ohos_account_manager.cpp new file mode 100755 index 000000000..a5adba42d --- /dev/null +++ b/services/accountmgr/src/ohos_account_manager.cpp @@ -0,0 +1,340 @@ +/* + * 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 "ohos_account_manager.h" +#include "account_info.h" +#include "account_log_wrapper.h" +#include "account_mgr_service.h" +#include "hisysevent.h" +#include "system_ability_definition.h" + +namespace OHOS { +namespace AccountSA { +constexpr std::int32_t MAX_RETRY_TIMES = 2; // give another chance when json file corrupted + +/** + * Ohos account state change. + * + * @param name ohos account name + * @param uid ohos account uid + * @param eventStr ohos account state change event + * @return true if the processing was completed, otherwise false + */ +bool OhosAccountManager::OhosAccountStateChange(const std::string &name, const std::string &uid, + const std::string &eventStr) +{ + auto itFunc = eventFuncMap_.find(eventStr); + if (itFunc == eventFuncMap_.end()) { + ACCOUNT_LOGE("invalid event: %{public}s", eventStr.c_str()); + return false; + } + return (this->*(itFunc->second))(name, uid, eventStr); +} + +/** + * Clear current account information + * + */ +bool OhosAccountManager::ClearAccount(std::int32_t clrStatus) +{ + currentAccount_.clear(clrStatus); + ErrCode errCode = dataDealer_->AccountInfoToJson(currentAccount_); + if (errCode != ERR_OK) { + ACCOUNT_LOGE("AccountInfoToJson error"); + return false; + } + return true; +} + +/** + * Config current account config. + * + * @param account account information. + * @return true if success. + */ +bool OhosAccountManager::SetAccount(AccountInfo &account) +{ + currentAccount_ = account; + ErrCode errCode = dataDealer_->AccountInfoToJson(currentAccount_); + if (errCode != ERR_OK) { + ACCOUNT_LOGE("AccountInfoToJson error"); + return false; + } + return true; +} + +/** + * Get current account information. + * + * @return current account information. + */ +AccountInfo OhosAccountManager::GetAccountInfo() +{ + std::lock_guard mutexLock(mgrMutex_); + return currentAccount_; +} + +/** + * Get current account state. + * + * @return current account state id. + */ +std::int32_t OhosAccountManager::GetAccountState() const +{ + return currentAccount_.ohosAccountStatus_; +} + +/** + * Process an account event. + * + * @param eventStr ohos account state change event + * @return true if the processing was completed, otherwise false + */ +bool OhosAccountManager::HandleEvent(const std::string &eventStr) +{ + auto iter = eventMap_.find(eventStr); + if (iter == eventMap_.end()) { + ACCOUNT_LOGE("invalid event: %{public}s", eventStr.c_str()); + return false; + } + + int event = iter->second; + bool ret = accountState_->StateChangeProcess(event); + if (!ret) { + ACCOUNT_LOGE("Handle event %{public}d failed", event); + return false; + } + std::int32_t newState = accountState_->GetAccountState(); + if (newState != currentAccount_.ohosAccountStatus_) { + HiviewDFX::HiSysEvent::Write(HiviewDFX::HiSysEvent::Domain::ACCOUNT, "AccountServiceStateMachineEvent", + HiviewDFX::HiSysEvent::EventType::FAULT, "DEVICE_MODE", currentAccount_.userId_, + "OPERATION_TYPE", event, "OLD_STATE", currentAccount_.ohosAccountStatus_, "NEW_STATE", newState); + currentAccount_.ohosAccountStatus_ = newState; + } + return true; +} + +/** + * login ohos (for distributed network) account. + * + * @param name ohos account name + * @param uid ohos account uid + * @param eventStr ohos account state change event + * @return true if the processing was completed, otherwise false + */ +bool OhosAccountManager::LoginOhosAccount(const std::string &name, const std::string &uid, const std::string &eventStr) +{ + std::lock_guard mutexLock(mgrMutex_); + bool ret = HandleEvent(eventStr); // update account status + if (!ret) { + ACCOUNT_LOGE("LoginOhosAccount: HandleEvent %{public}s failed", eventStr.c_str()); + return false; + } + + AccountInfo accountInfo(name, uid, currentAccount_.ohosAccountStatus_); + accountInfo.bindTime_ = std::time(nullptr); + accountInfo.userId_ = GetUserId(); + ret = SetAccount(accountInfo); // set account info + if (!ret) { + ACCOUNT_LOGE("LoginOhosAccount: SetAccount failed"); + return false; + } + ACCOUNT_LOGI("LoginOhosAccount success"); + return true; +} + +/** + * logout ohos (for distributed network) account. + * + * @param name ohos account name + * @param uid ohos account uid + * @param eventStr ohos account state change event + * @return true if the processing was completed, otherwise false + */ +bool OhosAccountManager::LogoutOhosAccount(const std::string &name, const std::string &uid, const std::string &eventStr) +{ + std::lock_guard mutexLock(mgrMutex_); + bool ret = HandleEvent(eventStr); // update account status + if (!ret) { + ACCOUNT_LOGE("LogoutOhosAccount: HandleEvent %{public}s failed", eventStr.c_str()); + return false; + } + + ret = ClearAccount(); // clear account info with ACCOUNT_STATE_LOGOUT + if (!ret) { + ACCOUNT_LOGE("LogoutOhosAccount: ClearAccount failed"); + return false; + } + ACCOUNT_LOGI("LogoutOhosAccount success"); + return true; +} + +/** + * logoff ohos (for distributed network) account. + * + * @param name ohos account name + * @param uid ohos account uid + * @param eventStr ohos account state change event + * @return true if the processing was completed, otherwise false + */ +bool OhosAccountManager::LogoffOhosAccount(const std::string &name, const std::string &uid, const std::string &eventStr) +{ + std::lock_guard mutexLock(mgrMutex_); + bool ret = HandleEvent(eventStr); // update account status + if (!ret) { + ACCOUNT_LOGE("LogoffOhosAccount: HandleEvent %{public}s failed", eventStr.c_str()); + return false; + } + + ret = ClearAccount(ACCOUNT_STATE_LOGOFF); // clear account info with ACCOUNT_STATE_LOGOFF + if (!ret) { + ACCOUNT_LOGE("LogoffOhosAccount: ClearAccount failed"); + return false; + } + ACCOUNT_LOGI("LogoffOhosAccount success"); + return true; +} + +/** + * Handle token_invalid event. + * + * @param name ohos account name + * @param uid ohos account uid + * @param eventStr ohos account state change event + * @return true if the processing was completed, otherwise false + */ +bool OhosAccountManager::HandleOhosAccountTokenInvalidEvent(const std::string &name, + const std::string &uid, const std::string &eventStr) +{ + std::lock_guard mutexLock(mgrMutex_); + bool ret = HandleEvent(eventStr); // update account status + if (!ret) { + ACCOUNT_LOGE("HandleOhosAccountTokenInvalidEvent: HandleEvent %{public}s failed", eventStr.c_str()); + return false; + } + + AccountInfo accountInfo(name, uid, currentAccount_.ohosAccountStatus_); + accountInfo.userId_ = GetUserId(); + ret = SetAccount(accountInfo); + if (!ret) { + // moving on even if failed to update account info + ACCOUNT_LOGW("Handle TokenInvalid event: SetAccount failed"); + } + ACCOUNT_LOGI("HandleOhosAccountTokenInvalidEvent success"); + return true; +} + +std::int32_t OhosAccountManager::GetUserId() +{ + std::int32_t id = DEVICE_ACCOUNT_OWNER; // default to OWNER MODE + + if (!AccountMgrService::GetInstance().IsServiceStarted()) { + ACCOUNT_LOGW("account mgr not ready, default as OWNER"); + return id; + } + + auto ret = AccountMgrService::GetInstance().QueryDeviceAccountId(id); + if (ret != ERR_OK) { + ACCOUNT_LOGW("Get device account Id failed: %d", ret); + } + + return (id == DEVICE_ACCOUNT_ID_INVALID) ? DEVICE_ACCOUNT_OWNER : id; +} + + +/** + * Init event mapper. + */ +void OhosAccountManager::BuildEventsMapper() +{ + eventMap_.insert(std::pair(OHOS_ACCOUNT_EVENT_LOGIN, + ACCOUNT_BIND_SUCCESS_EVT)); + eventMap_.insert(std::pair(OHOS_ACCOUNT_EVENT_LOGOUT, + ACCOUNT_MANUAL_UNBOUND_EVT)); + eventMap_.insert(std::pair(OHOS_ACCOUNT_EVENT_TOKEN_INVALID, + ACCOUNT_TOKEN_EXPIRED_EVT)); + eventMap_.insert(std::pair(OHOS_ACCOUNT_EVENT_LOGOFF, + ACCOUNT_MANUAL_LOGOFF_EVT)); + + eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_LOGIN, &OhosAccountManager::LoginOhosAccount)); + eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_LOGOUT, &OhosAccountManager::LogoutOhosAccount)); + eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_LOGOFF, &OhosAccountManager::LogoffOhosAccount)); + eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_TOKEN_INVALID, + &OhosAccountManager::HandleOhosAccountTokenInvalidEvent)); +} + +/** + * Init ohos account manager. + * + */ +bool OhosAccountManager::OnInitialize() +{ + accountState_ = std::make_unique(); + BuildEventsMapper(); + + std::int32_t userId = GetUserId(); + std::string filePath; + filePath.append(ACCOUNT_CFG_DIR_ROOT_PATH).append(std::to_string(userId)).append(ACCOUNT_CFG_FILE_NAME); + dataDealer_ = std::make_unique(filePath); + + std::int32_t tryTimes = 0; + while (tryTimes < MAX_RETRY_TIMES) { + tryTimes++; + ErrCode errCode = dataDealer_->Init(); + if (errCode == ERR_OK) { + break; + } + + // when json file corrupted, have it another try + if ((tryTimes == MAX_RETRY_TIMES) || (errCode != ERR_ACCOUNT_DATADEAL_JSON_FILE_CORRUPTION)) { + ACCOUNT_LOGE("parse json file failed: %{public}d, tryTime: %{public}d", errCode, tryTimes); + eventMap_.clear(); + eventFuncMap_.clear(); + return false; + } + } + + // get account info from config file + dataDealer_->AccountInfoFromJson(currentAccount_); + accountState_->SetAccountState(currentAccount_.ohosAccountStatus_); + return true; +} + +/** + * Handle device account switch event. + * + * @param None + * @return None + */ +void OhosAccountManager::HandleDevAccountSwitchEvent() +{ + std::lock_guard mutexLock(mgrMutex_); + eventMap_.clear(); + eventFuncMap_.clear(); + + // Re-Init + if (!OnInitialize()) { + ACCOUNT_LOGE("Handle dev Account SwitchEvent failed"); + } +} + +void OhosAccountManager::ReportPublishFailureEvent(std::int32_t errCode, std::int32_t oldStatus) +{ + HiviewDFX::HiSysEvent::Write(HiviewDFX::HiSysEvent::Domain::ACCOUNT, "AccountServicePublishEventFailed", + HiviewDFX::HiSysEvent::EventType::FAULT, "ERROR_TYPE", errCode, "OLD_STATE", oldStatus, + "NEW_STATE", currentAccount_.ohosAccountStatus_, "DEVICE_MODE", currentAccount_.userId_); +} +} // namespace AccountSA +} // namespace OHOS diff --git a/services/accountmgr/test/BUILD.gn b/services/accountmgr/test/BUILD.gn new file mode 100755 index 000000000..301ad60f9 --- /dev/null +++ b/services/accountmgr/test/BUILD.gn @@ -0,0 +1,41 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//base/account/os_account/os_account.gni") +import("//build/ohos.gni") +import("//build/test.gni") + +config("accountmgr_test_config") { + include_dirs = [ + "//utils/native/base/include", + "mock/include", + ] + + defines = [ + "ACCOUNT_LOG_TAG = \"ACCOUNT_TEST\"", + "LOG_DOMAIN = 0xD001B00", + ] + + configs = [] +} + +group("unittest") { + testonly = true + + deps = [ + "unittest/account_dump_helper_test:unittest", + "unittest/account_mgr_service_test:unittest", + "unittest/account_mgr_stub_test:unittest", + "unittest/ohos_account_data_deal_test:unittest", + ] +} diff --git a/services/accountmgr/test/mock/include/mock_account_mgr_service.h b/services/accountmgr/test/mock/include/mock_account_mgr_service.h new file mode 100755 index 000000000..ac3a14702 --- /dev/null +++ b/services/accountmgr/test/mock/include/mock_account_mgr_service.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 BASE_MOCK_ACCOUNT_MGR_SERVICE_H +#define BASE_MOCK_ACCOUNT_MGR_SERVICE_H + +#include +#include +#include "iaccount_context.h" +#include "account_stub.h" + +namespace OHOS { +namespace AccountSA { +constexpr std::int32_t MAX_SUPPORTED_ACCOUNT_NUMBER = 4; +class MockAccountMgrService final: public AccountStub { +public: + MockAccountMgrService(); + MockAccountMgrService(const MockAccountMgrService&) = delete; + ~MockAccountMgrService() override; + + void HandleNotificationEvents(const std::string& eventStr) override; + std::int32_t QueryDeviceAccountId(std::int32_t& accountId) override; + bool UpdateOhosAccountInfo(const std::string& accountName, const std::string& uid, + const std::string& eventStr) override; + std::pair QueryOhosAccountInfo(void) override; + std::int32_t QueryDeviceAccountIdFromUid(std::int32_t uid) override; + bool IsServiceStarted() const override + { + return true; + } +private: + std::int32_t devAccountId_; +}; +} // namespace AccountSA +} // namespace OHOS +#endif // BASE_MOCK_ACCOUNT_MGR_SERVICE_H diff --git a/services/accountmgr/test/mock/src/mock_account_mgr_service.cpp b/services/accountmgr/test/mock/src/mock_account_mgr_service.cpp new file mode 100755 index 000000000..fd61879ba --- /dev/null +++ b/services/accountmgr/test/mock/src/mock_account_mgr_service.cpp @@ -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. + */ + +#include "mock_account_mgr_service.h" +#include "account_log_wrapper.h" +#include "account_error_no.h" +#include "device_account_info.h" +#include "iaccount.h" + +namespace OHOS { +namespace AccountSA { +constexpr std::int32_t UID_TRANSFORM_DIVISOR = 100000; +MockAccountMgrService::MockAccountMgrService() +{ + devAccountId_ = 0; + IAccountContext::SetInstance(this); +} + +MockAccountMgrService::~MockAccountMgrService() +{ + IAccountContext::SetInstance(nullptr); +} + +void MockAccountMgrService::HandleNotificationEvents(const std::string& eventStr) +{ + ACCOUNT_LOGI("Get event: %{public}s", eventStr.c_str()); +} + +std::int32_t MockAccountMgrService::QueryDeviceAccountId(std::int32_t& accountId) +{ + accountId = devAccountId_; + return ERR_OK; +} + +bool MockAccountMgrService::UpdateOhosAccountInfo(const std::string& accountName, const std::string& uid, + const std::string& eventStr) +{ + ACCOUNT_LOGI("MockUpdateOhosAccountInfo: success done"); + return true; +} + +std::pair MockAccountMgrService::QueryOhosAccountInfo(void) +{ + std::string name = DEFAULT_OHOS_ACCOUNT_NAME; + std::string id = DEFAULT_OHOS_ACCOUNT_UID; + std::int32_t status = ACCOUNT_STATE_UNBOUND; + return std::make_pair(true, OhosAccountInfo(name, id, status)); +} + +std::int32_t MockAccountMgrService::QueryDeviceAccountIdFromUid(std::int32_t uid) +{ + return (uid / UID_TRANSFORM_DIVISOR); +} +} // namespace AccountSA +} // namespace OHOS diff --git a/services/accountmgr/test/unittest/account_dump_helper_test/BUILD.gn b/services/accountmgr/test/unittest/account_dump_helper_test/BUILD.gn new file mode 100755 index 000000000..078c548e3 --- /dev/null +++ b/services/accountmgr/test/unittest/account_dump_helper_test/BUILD.gn @@ -0,0 +1,74 @@ +# 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("//base/account/os_account/os_account.gni") +import("//build/ohos.gni") +import("//build/test.gni") + +module_output_path = "os_account_standard/accountmgrservice" + +config("accountmgr_dump_test_config") { + include_dirs = [ + "./include", + "${common_path}/log/include", + "${common_path}/perf_stat/include", + "${common_path}/account_error/include", + "${services_path}/accountmgr/include", + "${innerkits_path}/include", + "//third_party/json/include", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + ] +} + +ohos_unittest("AccountDumpHelperTest") { + module_out_path = module_output_path + + sources = [ + "${common_path}/log/src/account_log_wrapper.cpp", + "${common_path}/perf_stat/src/perf_stat.cpp", + "${services_path}/accountmgr/src/account_dump_helper.cpp", + "${services_path}/accountmgr/src/account_state_machine.cpp", + "${services_path}/accountmgr/src/ohos_account_data_deal.cpp", + "${services_path}/accountmgr/src/ohos_account_manager.cpp", + ] + sources += [ "account_dump_helper_test.cpp" ] + + configs = [ + ":accountmgr_dump_test_config", + "${services_path}/accountmgr/test:accountmgr_test_config", + ] + + deps = [ + "//third_party/googletest:gmock_main", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + external_deps = [ + "aafwk_standard:base", + "aafwk_standard:intent", + "appexecfwk_standard:appexecfwk_base", + "hisysevent_native:libhisysevent", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + ] + part_name = "os_account_standard" +} + +group("unittest") { + testonly = true + + deps = [ ":AccountDumpHelperTest" ] +} diff --git a/services/accountmgr/test/unittest/account_dump_helper_test/account_dump_helper_test.cpp b/services/accountmgr/test/unittest/account_dump_helper_test/account_dump_helper_test.cpp new file mode 100755 index 000000000..417d1866e --- /dev/null +++ b/services/accountmgr/test/unittest/account_dump_helper_test/account_dump_helper_test.cpp @@ -0,0 +1,126 @@ +/* + * 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 +#include + +#include "account_dump_helper.h" +#include "account_error_no.h" +#include "account_info.h" +#include "account_log_wrapper.h" +#include "ohos_account_manager.h" + +using namespace testing::ext; +using namespace OHOS; +using namespace OHOS::AccountSA; + +class AccountDumpHelperTest : public testing::Test { +public: + AccountDumpHelperTest(); + ~AccountDumpHelperTest() {}; + + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); + std::shared_ptr ohosAccount_{}; +}; + +AccountDumpHelperTest::AccountDumpHelperTest() +{ + ohosAccount_ = std::make_shared(); +} + +void AccountDumpHelperTest::SetUpTestCase() {} + +void AccountDumpHelperTest::TearDownTestCase() {} + +void AccountDumpHelperTest::SetUp(){} + +void AccountDumpHelperTest::TearDown() {} + +/** + * @tc.name: AccountDumpParameterTest001 + * @tc.desc: Test account info display + * @tc.type: FUNC + * @tc.require: SR000CUF6J + */ +HWTEST_F(AccountDumpHelperTest, AccountDumpParameterTest001, TestSize.Level0) +{ + /** + * @tc.steps: step1. Input one parameter + */ + std::string out; + vector cmd = {"-account_info"}; + AccountDumpHelper accountDumpHelper(ohosAccount_); + + bool ret = accountDumpHelper.Dump(cmd, out); + EXPECT_EQ(true, ret); + auto pos = out.find("Ohos account name: ", 0); + EXPECT_NE(std::string::npos, ret); + pos = out.find("Ohos account openId: ", 0); + EXPECT_NE(std::string::npos, ret); + pos = out.find("Local user Id: ", 0); + EXPECT_NE(std::string::npos, ret); + pos = out.find("Ohos account status: ", 0); + EXPECT_NE(std::string::npos, ret); + pos = out.find("Ohos account bind time: ", 0); + EXPECT_NE(std::string::npos, ret); +} + +/** + * @tc.name: AccountDumpTwoParameterTest002 + * @tc.desc: Test account log-level set + * @tc.type: FUNC + * @tc.require: AR000CUF6N + */ +HWTEST_F(AccountDumpHelperTest, AccountDumpTwoParameterTest002, TestSize.Level0) +{ + /** + * @tc.steps: step1. Input two parameters + */ + std::string out; + std::string logLevel; + std::string prompt = "Current Log Level: "; + vector setCmd = {"-set_log_level", "1"}; + vector getCmd = {"-show_log_level"}; + AccountDumpHelper accountDumpHelper(ohosAccount_); + + bool ret = accountDumpHelper.Dump(setCmd, out); + EXPECT_EQ(true, ret); + ret = accountDumpHelper.Dump(getCmd, out); + EXPECT_EQ(true, ret); + auto pos = out.find(prompt, 0); + EXPECT_NE(std::string::npos, ret); + logLevel = out.substr(pos + prompt.length()); + EXPECT_EQ("1", logLevel.substr(0, 1)); +} + +/** + * @tc.name: AccountDumpInvalidParameterTest003 + * @tc.desc: Test account info display + * @tc.type: FUNC + * @tc.require: AR000CUF6N + */ +HWTEST_F(AccountDumpHelperTest, AccountDumpInvalidParameterTest003, TestSize.Level0) +{ + /** + * @tc.steps: step1. Input invalid parameter + */ + std::string out; + vector cmd = {"This_is_invalid_cmd"}; + AccountDumpHelper accountDumpHelper(ohosAccount_); + EXPECT_EQ(false, accountDumpHelper.Dump(cmd, out)); +} diff --git a/services/accountmgr/test/unittest/account_mgr_service_test/BUILD.gn b/services/accountmgr/test/unittest/account_mgr_service_test/BUILD.gn new file mode 100755 index 000000000..6444c75ce --- /dev/null +++ b/services/accountmgr/test/unittest/account_mgr_service_test/BUILD.gn @@ -0,0 +1,87 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//base/account/os_account/os_account.gni") +import("//build/ohos.gni") +import("//build/test.gni") + +module_output_path = "os_account_standard/accountmgrservice" + +config("accountmgr_service_test_config") { + include_dirs = [ + "./include", + "${common_path}/log/include", + "${common_path}/perf_stat/include", + "${common_path}/account_error/include", + "${innerkits_path}/include", + "//third_party/json/include", + "//utils/native/base/include", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + ] +} + +ohos_unittest("account_mgr_test") { + module_out_path = module_output_path + + sources = [ + "${common_path}/log/src/account_log_wrapper.cpp", + "${common_path}/perf_stat/src/perf_stat.cpp", + "${innerkits_path}/accountmgr/src/account_proxy.cpp", + "${services_path}/accountmgr/src/account_dump_helper.cpp", + "${services_path}/accountmgr/src/account_helper_data.cpp", + "${services_path}/accountmgr/src/account_mgr_service.cpp", + "${services_path}/accountmgr/src/account_state_machine.cpp", + "${services_path}/accountmgr/src/account_stub.cpp", + "${services_path}/accountmgr/src/ohos_account_data_deal.cpp", + "${services_path}/accountmgr/src/ohos_account_manager.cpp", + ] + + sources += [ + "account_mgr_service_test.cpp", + "account_state_machine_test.cpp", + "ohos_account_manager_test.cpp", + ] + + configs = [ + ":accountmgr_service_test_config", + "${services_path}/accountmgr:accountmgr_config", + "${services_path}/accountmgr/test:accountmgr_test_config", + ] + + deps = [ + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + external_deps = [ + "aafwk_standard:base", + "aafwk_standard:intent", + "aafwk_standard:want", + "appexecfwk_standard:appexecfwk_base", + "appexecfwk_standard:appexecfwk_core", + "hisysevent_native:libhisysevent", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_L2:samgr_proxy", + "startup_l2:syspara", + ] + part_name = "os_account_standard" +} + +group("unittest") { + testonly = true + + deps = [ ":account_mgr_test" ] +} diff --git a/services/accountmgr/test/unittest/account_mgr_service_test/account_mgr_service_test.cpp b/services/accountmgr/test/unittest/account_mgr_service_test/account_mgr_service_test.cpp new file mode 100755 index 000000000..aa1c3ad5c --- /dev/null +++ b/services/accountmgr/test/unittest/account_mgr_service_test/account_mgr_service_test.cpp @@ -0,0 +1,211 @@ +/* + * 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 + +#include "account_dump_helper.h" +#include "account_info.h" +#include "account_log_wrapper.h" +#include "account_proxy.h" +#include "iaccount.h" +#include "if_system_ability_manager.h" +#include "ipc_skeleton.h" +#include "iservice_registry.h" +#include "string_ex.h" +#include "system_ability.h" +#include "system_ability_definition.h" + +using namespace testing::ext; +using namespace OHOS; +using namespace OHOS::AccountSA; + +namespace { +static std::pair g_oldInfo; + +sptr GetAccountMgr() +{ + sptr systemMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemMgr == nullptr) { + return nullptr; + } + + sptr accountObj = systemMgr->GetSystemAbility(SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN); + return iface_cast(accountObj); +} +} + +class AccountMgrServiceTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void AccountMgrServiceTest::SetUpTestCase() +{ + sptr accountMgr = GetAccountMgr(); + if (!accountMgr) { + std::cout << "TearDownTestCase::GetAccountMgr failed" << std::endl; + return; + } + g_oldInfo = accountMgr->QueryOhosAccountInfo(); + if (!g_oldInfo.first) { + std::cout << "AccountMgrServiceTest::SetUpTestCase GET old info failed" << std::endl; + } +} + +void AccountMgrServiceTest::TearDownTestCase() +{ + if (g_oldInfo.first) { + sptr accountMgr = GetAccountMgr(); + if (!accountMgr) { + std::cout << "TearDownTestCase::GetAccountMgr failed" << std::endl; + return; + } + + auto name = g_oldInfo.second.name_; + auto uid = g_oldInfo.second.uid_; + std::string eventStr; + bool ret = false; + switch (g_oldInfo.second.status_) { + case ACCOUNT_STATE_UNBOUND: + case ACCOUNT_STATE_LOGOFF: + break; + case ACCOUNT_STATE_LOGIN: + eventStr = OHOS_ACCOUNT_EVENT_LOGIN; + ret = accountMgr->UpdateOhosAccountInfo(name, uid, eventStr); + if (!ret) { + std::cout << "TearDownTestCase RESUME to LOGIN failed" << std::endl; + } + break; + case ACCOUNT_STATE_NOTLOGIN: + eventStr = OHOS_ACCOUNT_EVENT_LOGIN; + ret = accountMgr->UpdateOhosAccountInfo(name, uid, eventStr); + if (!ret) { + std::cout << "TearDownTestCase RESUME to LOGIN failed" << std::endl; + } + eventStr = OHOS_ACCOUNT_EVENT_TOKEN_INVALID; + ret = accountMgr->UpdateOhosAccountInfo(name, uid, eventStr); + if (!ret) { + std::cout << "TearDownTestCase RESUME to NOTLOGIN failed" << std::endl; + } + break; + default: + break; + } + } +} + +void AccountMgrServiceTest::SetUp() {} + +void AccountMgrServiceTest::TearDown() {} + +/** + * @tc.name: AccountMgrServiceSetOhosIdStatusLoginTest001 + * @tc.desc: Test ohos account status + * @tc.type: FUNC + * @tc.require: AR000CUF5H SR000CUF5T + */ +HWTEST_F(AccountMgrServiceTest, AccountMgrServiceSetOhosIdStatusLoginTest001, TestSize.Level2) +{ + /** + * @tc.steps: step1. get AccountMgrService Iinterface + * @tc.expected: step1. The current account is not set + */ + sptr accountMgr = GetAccountMgr(); + ASSERT_TRUE(accountMgr != nullptr); + + std::pair info = accountMgr->QueryOhosAccountInfo(); + EXPECT_EQ(true, info.first); + bool ret = false; + switch (info.second.status_) { + case ACCOUNT_STATE_LOGIN: + case ACCOUNT_STATE_NOTLOGIN: + ret = accountMgr->UpdateOhosAccountInfo(info.second.name_, + info.second.uid_, OHOS_ACCOUNT_EVENT_LOGOUT); + EXPECT_EQ(true, ret); + info = accountMgr->QueryOhosAccountInfo(); + EXPECT_EQ(true, info.first); + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, info.second.status_); + break; + default: + break; + } + + // update status with test info + std::string name("User001"); + std::string uid("1001"); + std::string eventStr(OHOS_ACCOUNT_EVENT_LOGIN); + ret = accountMgr->UpdateOhosAccountInfo(name, uid, eventStr); + EXPECT_EQ(true, ret); + // param 1: name, param 2: UID, param 3: status + std::pair testInfo = accountMgr->QueryOhosAccountInfo(); + EXPECT_EQ(true, testInfo.first); + EXPECT_EQ(uid, testInfo.second.uid_); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, testInfo.second.status_); + + eventStr = OHOS_ACCOUNT_EVENT_LOGOUT; + ret = accountMgr->UpdateOhosAccountInfo(name, uid, eventStr); + EXPECT_EQ(true, ret); +} + +/** + * @tc.name: AccountMgrServiceSetOhosIdStatusLogoffTest002 + * @tc.desc: Test ohos account status + * @tc.type: FUNC + * @tc.require: AR000CUF64 AR000CUF5K AR000CUF5O + */ +HWTEST_F(AccountMgrServiceTest, AccountMgrServiceSetOhosIdStatusLogoffTest002, TestSize.Level2) +{ + /** + * @tc.steps: step1. get AccountMgrService Iinterface + * @tc.expected: step1. The current account is not set + */ + sptr accountMgr = GetAccountMgr(); + ASSERT_TRUE(accountMgr != nullptr); + + std::pair retInfo = accountMgr->QueryOhosAccountInfo(); + EXPECT_EQ(true, retInfo.first); + std::string name(retInfo.second.name_); + std::string uid(retInfo.second.uid_); + std::string eventStr; + bool ret = false; + switch (retInfo.second.status_) { + case ACCOUNT_STATE_LOGIN: + case ACCOUNT_STATE_NOTLOGIN: + eventStr = OHOS_ACCOUNT_EVENT_LOGOUT; + ret = accountMgr->UpdateOhosAccountInfo(name, uid, eventStr); + EXPECT_EQ(true, ret); + break; + default: + break; + } + // update status with test info + name = "User002"; + uid = "1002"; + eventStr = OHOS_ACCOUNT_EVENT_LOGIN; + // param 1: name, param 2: UID, param 3: status + ret = accountMgr->UpdateOhosAccountInfo(name, uid, eventStr); + EXPECT_EQ(true, ret); + + eventStr = OHOS_ACCOUNT_EVENT_LOGOFF; + ret = accountMgr->UpdateOhosAccountInfo(name, uid, eventStr); + EXPECT_EQ(true, ret); + + std::pair testInfo = accountMgr->QueryOhosAccountInfo(); + EXPECT_EQ(true, testInfo.first); + EXPECT_EQ(ACCOUNT_STATE_LOGOFF, testInfo.second.status_); +} diff --git a/services/accountmgr/test/unittest/account_mgr_service_test/account_state_machine_test.cpp b/services/accountmgr/test/unittest/account_mgr_service_test/account_state_machine_test.cpp new file mode 100755 index 000000000..450384091 --- /dev/null +++ b/services/accountmgr/test/unittest/account_mgr_service_test/account_state_machine_test.cpp @@ -0,0 +1,612 @@ +/* + * 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 + +#include "account_state_machine.h" + +using namespace testing::ext; +using namespace OHOS::AccountSA; + +class AccountStateMachineTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void AccountStateMachineTest::SetUpTestCase() {} + +void AccountStateMachineTest::TearDownTestCase() {} + +void AccountStateMachineTest::SetUp() {} + +void AccountStateMachineTest::TearDown() {} + +/** + * @tc.name: AccountStateMachineTestInitState001 + * @tc.desc: Account state machine initial state + * @tc.type: FUNC + * @tc.require: AR000CUF54 + */ +HWTEST_F(AccountStateMachineTest, AccountStateMachineTestInitState001, TestSize.Level0) +{ + /** + * @tc.steps: step1. AccountStateMachine init + * @tc.expected: step1. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + AccountStateMachine stateMachine; + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); +} + +/** + * @tc.name: AccountStateMachineTestUnbound2LoginState002 + * @tc.desc: Account state machine transform unbound state to login state + * @tc.type: FUNC + * @tc.require: AR000CUF54 + */ +HWTEST_F(AccountStateMachineTest, AccountStateMachineTestUnbound2LoginState002, TestSize.Level0) +{ + /** + * @tc.steps: step1. AccountStateMachine init + * @tc.expected: step1. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + AccountStateMachine stateMachine; + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); + + /** + * @tc.steps: step2. Input the event ACCOUNT_BIND_SUCCESS_EVT + * @tc.expected: step2. The current state is AccountStateMachine::ACCOUNT_STATE_LOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_SUCCESS_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, stateMachine.GetAccountState()); +} + +/** + * @tc.name: AccountStateMachineTestUnboundBindAccountFailed003 + * @tc.desc: Account state machine keep the last state + * @tc.type: FUNC + * @tc.require: AR000CUF54 + */ +HWTEST_F(AccountStateMachineTest, AccountStateMachineTestUnboundBindAccountFailed003, TestSize.Level0) +{ + /** + * @tc.steps: step1. AccountStateMachine init + * @tc.expected: step1. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + AccountStateMachine stateMachine; + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); + + /** + * @tc.steps: step2. Input the event ACCOUNT_BIND_FAILED_EVT + * @tc.expected: step2. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_FAILED_EVT)); + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); +} + +/** + * @tc.name: AccountStateMachineUnboundInputUntreatedEvent004 + * @tc.desc: Account state machine keep the last state + * @tc.type: FUNC + * @tc.require: SR000CUF50 + */ +HWTEST_F(AccountStateMachineTest, AccountStateMachineUnboundInputUntreatedEvent004, TestSize.Level0) +{ + /** + * @tc.steps: step1. AccountStateMachine init + * @tc.expected: step1. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + AccountStateMachine stateMachine; + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); + + /** + * @tc.steps: step2. Input the event ACCOUNT_PASSWORD_CHANGED_EVT + * @tc.expected: step2. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_PASSWORD_CHANGED_EVT)); + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); +} + +/** + * @tc.name: AccountStateMachineTestLoginTokenExpired005 + * @tc.desc: Account state machine transform login state to logout state + * @tc.type: FUNC + * @tc.require: AR000CUF5J + */ +HWTEST_F(AccountStateMachineTest, AccountStateMachineTestLoginTokenExpired005, TestSize.Level0) +{ + /** + * @tc.steps: step1. AccountStateMachine init + * @tc.expected: step1. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + AccountStateMachine stateMachine; + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); + + /** + * @tc.steps: step2. Input the event ACCOUNT_BIND_SUCCESS_EVT + * @tc.expected: step2. The current state is AccountStateMachine::ACCOUNT_STATE_LOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_SUCCESS_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step3. Input the event ACCOUNT_TOKEN_EXPIRED_EVT + * @tc.expected: step3. The current state is AccountStateMachine::ACCOUNT_STATE_NOTLOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_TOKEN_EXPIRED_EVT)); + EXPECT_EQ(ACCOUNT_STATE_NOTLOGIN, stateMachine.GetAccountState()); +} + +/** + * @tc.name: AccountStateMachineTestLoginPasswordChanged006 + * @tc.desc: Account state machine transform login state to logout state + * @tc.type: FUNC + * @tc.require: AR000CUF5J SR000CUF60 + */ +HWTEST_F(AccountStateMachineTest, AccountStateMachineTestLoginPasswordChanged006, TestSize.Level0) +{ + /** + * @tc.steps: step1. AccountStateMachine init + * @tc.expected: step1. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + AccountStateMachine stateMachine; + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); + + /** + * @tc.steps: step2. Input the event ACCOUNT_BIND_SUCCESS_EVT + * @tc.expected: step2. The current state is AccountStateMachine::ACCOUNT_STATE_LOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_SUCCESS_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step3. Input the event ACCOUNT_PASSWORD_CHANGED_EVT + * @tc.expected: step3. The current state is AccountStateMachine::ACCOUNT_STATE_NOTLOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_PASSWORD_CHANGED_EVT)); + EXPECT_EQ(ACCOUNT_STATE_NOTLOGIN, stateMachine.GetAccountState()); +} + +/** + * @tc.name: AccountStateMachineTestManualLogout007 + * @tc.desc: Account state machine transform login state to logout state + * @tc.type: FUNC + * @tc.require: AR000CUF5R AR000CUF64 AR000CUF66 + */ +HWTEST_F(AccountStateMachineTest, AccountStateMachineTestManualLogout007, TestSize.Level0) +{ + /** + * @tc.steps: step1. AccountStateMachine init + * @tc.expected: step1. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + AccountStateMachine stateMachine; + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); + + /** + * @tc.steps: step2. Input the event ACCOUNT_BIND_SUCCESS_EVT + * @tc.expected: step2. The current state is AccountStateMachine::ACCOUNT_STATE_LOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_SUCCESS_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step3. Input the event ACCOUNT_MANUAL_LOGOUT_EVT + * @tc.expected: step3. The current state is AccountStateMachine::ACCOUNT_STATE_NOTLOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_MANUAL_LOGOUT_EVT)); + EXPECT_EQ(ACCOUNT_STATE_NOTLOGIN, stateMachine.GetAccountState()); +} + +/** + * @tc.name: AccountStateMachineTestLoginManualUnbound008 + * @tc.desc: Account state machine transform login state to unbound state + * @tc.type: FUNC + * @tc.require: AR000CUF5M SR000CUF63 AR000CUF65 + */ +HWTEST_F(AccountStateMachineTest, AccountStateMachineTestLoginManualUnbound008, TestSize.Level0) +{ + /** + * @tc.steps: step1. AccountStateMachine init + * @tc.expected: step1. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + AccountStateMachine stateMachine; + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); + + /** + * @tc.steps: step2. Input the event ACCOUNT_BIND_SUCCESS_EVT + * @tc.expected: step2. The current state is AccountStateMachine::ACCOUNT_STATE_LOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_SUCCESS_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step3. Input the event ACCOUNT_MANUAL_UNBOUND_EVT + * @tc.expected: step3. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_MANUAL_UNBOUND_EVT)); + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); +} + +/** + * @tc.name: AccountStateMachineTestLoginInputUntreatedEvent009 + * @tc.desc: Account state machine keep the last state + * @tc.type: FUNC + * @tc.require: AR000CUF5I AR000CUF66 + */ +HWTEST_F(AccountStateMachineTest, AccountStateMachineTestLoginInputUntreatedEvent009, TestSize.Level0) +{ + /** + * @tc.steps: step1. AccountStateMachine init + * @tc.expected: step1. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + AccountStateMachine stateMachine; + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); + + /** + * @tc.steps: step2. Input the event ACCOUNT_BIND_SUCCESS_EVT + * @tc.expected: step2. The current state is AccountStateMachine::ACCOUNT_STATE_LOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_SUCCESS_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step3. Input the event ACCOUNT_BIND_FAILED_EVT + * @tc.expected: step3. The current state is AccountStateMachine::ACCOUNT_STATE_LOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_FAILED_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, stateMachine.GetAccountState()); +} + +/** + * @tc.name: AccountStateMachineTestLogoutAuthenticateSuccess010 + * @tc.desc: Account state machine transform logout state to login state + * @tc.type: FUNC + * @tc.require: AR000CUF5M AR000CUF61 + */ +HWTEST_F(AccountStateMachineTest, AccountStateMachineTestLogoutAuthenticateSuccess010, TestSize.Level0) +{ + /** + * @tc.steps: step1. AccountStateMachine init + * @tc.expected: step1. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + AccountStateMachine stateMachine; + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); + + /** + * @tc.steps: step2. Input the event ACCOUNT_BIND_SUCCESS_EVT + * @tc.expected: step2. The current state is AccountStateMachine::ACCOUNT_STATE_LOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_SUCCESS_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step3. Input the event ACCOUNT_MANUAL_LOGOUT_EVT + * @tc.expected: step3. The current state is AccountStateMachine::ACCOUNT_STATE_NOTLOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_MANUAL_LOGOUT_EVT)); + EXPECT_EQ(ACCOUNT_STATE_NOTLOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step4. Input the event ACCOUNT_AUTHENTICATE_SUCCESS_EVT + * @tc.expected: step4. The current state is AccountStateMachine::ACCOUNT_STATE_LOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_AUTHENTICATE_SUCCESS_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, stateMachine.GetAccountState()); +} + +/** + * @tc.name: AccountStateMachineTestLogoutAuthenticateFailed011 + * @tc.desc: Account state machine keep the last state + * @tc.type: FUNC + * @tc.require: AR000CUF5J AR000CUF5I + */ +HWTEST_F(AccountStateMachineTest, AccountStateMachineTestLogoutAuthenticateFailed011, TestSize.Level0) +{ + /** + * @tc.steps: step1. AccountStateMachine init + * @tc.expected: step1. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + AccountStateMachine stateMachine; + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); + + /** + * @tc.steps: step2. Input the event ACCOUNT_BIND_SUCCESS_EVT + * @tc.expected: step2. The current state is AccountStateMachine::ACCOUNT_STATE_LOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_SUCCESS_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step3. Input the event ACCOUNT_MANUAL_LOGOUT_EVT + * @tc.expected: step3. The current state is AccountStateMachine::ACCOUNT_STATE_NOTLOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_MANUAL_LOGOUT_EVT)); + EXPECT_EQ(ACCOUNT_STATE_NOTLOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step4. Input the event ACCOUNT_AUTHENTICATE_FAILED_EVT + * @tc.expected: step4. The current state is AccountStateMachine::ACCOUNT_STATE_NOTLOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_AUTHENTICATE_FAILED_EVT)); + EXPECT_EQ(ACCOUNT_STATE_NOTLOGIN, stateMachine.GetAccountState()); +} + +/** + * @tc.name: AccountStateMachineTestLogoutInputUntreatedEvent012 + * @tc.desc: Account state machine keep the last state + * @tc.type: FUNC + * @tc.require: AR000CUF5M AR000CUF5I + */ +HWTEST_F(AccountStateMachineTest, AccountStateMachineTestLogoutInputUntreatedEvent012, TestSize.Level0) +{ + /** + * @tc.steps: step1. AccountStateMachine init + * @tc.expected: step1. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + AccountStateMachine stateMachine; + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); + + /** + * @tc.steps: step2. Input the event ACCOUNT_BIND_SUCCESS_EVT + * @tc.expected: step2. The current state is AccountStateMachine::ACCOUNT_STATE_LOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_SUCCESS_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step3. Input the event ACCOUNT_MANUAL_LOGOUT_EVT + * @tc.expected: step3. The current state is AccountStateMachine::ACCOUNT_STATE_NOTLOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_MANUAL_LOGOUT_EVT)); + EXPECT_EQ(ACCOUNT_STATE_NOTLOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step4. Input the event ACCOUNT_AUTHENTICATE_FAILED_EVT + * @tc.expected: step4. The current state is AccountStateMachine::ACCOUNT_STATE_NOTLOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_AUTHENTICATE_FAILED_EVT)); + EXPECT_EQ(ACCOUNT_STATE_NOTLOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step3. Input the event ACCOUNT_BIND_FAILED_EVT + * @tc.expected: step3. The current state is AccountStateMachine::ACCOUNT_STATE_NOTLOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_FAILED_EVT)); + EXPECT_EQ(ACCOUNT_STATE_NOTLOGIN, stateMachine.GetAccountState()); +} + +/** + * @tc.name: AccountStateMachineTestLogoutManualUnbound013 + * @tc.desc: Account state machine transform logout state to unbound state + * @tc.type: FUNC + * @tc.require: AR000CUF5M + */ +HWTEST_F(AccountStateMachineTest, AccountStateMachineTestLogoutManualUnbound013, TestSize.Level0) +{ + /** + * @tc.steps: step1. AccountStateMachine init + * @tc.expected: step1. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + AccountStateMachine stateMachine; + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); + + /** + * @tc.steps: step2. Input the event ACCOUNT_BIND_SUCCESS_EVT + * @tc.expected: step2. The current state is AccountStateMachine::ACCOUNT_STATE_LOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_SUCCESS_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step3. Input the event ACCOUNT_MANUAL_LOGOUT_EVT + * @tc.expected: step3. The current state is AccountStateMachine::ACCOUNT_STATE_NOTLOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_MANUAL_LOGOUT_EVT)); + EXPECT_EQ(ACCOUNT_STATE_NOTLOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step4. Input the event ACCOUNT_MANUAL_UNBOUND_EVT + * @tc.expected: step4. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_MANUAL_UNBOUND_EVT)); + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); +} + +/** + * @tc.name: AccountStateMachineTestLoginManualLogoff014 + * @tc.desc: Account state machine transform login state to logoff state + * @tc.type: FUNC + * @tc.require: AR000CUF5M AR000CUF5O + */ +HWTEST_F(AccountStateMachineTest, AccountStateMachineTestLoginManualLogoff014, TestSize.Level0) +{ + /** + * @tc.steps: step1. AccountStateMachine init + * @tc.expected: step1. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + AccountStateMachine stateMachine; + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); + + /** + * @tc.steps: step2. Input the event ACCOUNT_BIND_SUCCESS_EVT + * @tc.expected: step2. The current state is AccountStateMachine::ACCOUNT_STATE_LOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_SUCCESS_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step3. Input the event ACCOUNT_MANUAL_LOGOFF_EVT + * @tc.expected: step3. The current state is AccountStateMachine::ACCOUNT_STATE_LOGOFF + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_MANUAL_LOGOFF_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGOFF, stateMachine.GetAccountState()); +} + +/** + * @tc.name: AccountStateMachineTestLogoutManualLogoff015 + * @tc.desc: Account state machine transform logout state to logoff state + * @tc.type: FUNC + * @tc.require: AR000CUF5M AR000CUF5O + */ +HWTEST_F(AccountStateMachineTest, AccountStateMachineTestLogoutManualLogoff015, TestSize.Level0) +{ + /** + * @tc.steps: step1. AccountStateMachine init + * @tc.expected: step1. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + AccountStateMachine stateMachine; + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); + + /** + * @tc.steps: step2. Input the event ACCOUNT_BIND_SUCCESS_EVT + * @tc.expected: step2. The current state is AccountStateMachine::ACCOUNT_STATE_LOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_SUCCESS_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step3. Input the event ACCOUNT_MANUAL_LOGOUT_EVT + * @tc.expected: step3. The current state is AccountStateMachine::ACCOUNT_STATE_NOTLOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_MANUAL_LOGOUT_EVT)); + EXPECT_EQ(ACCOUNT_STATE_NOTLOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step4. Input the event ACCOUNT_MANUAL_LOGOFF_EVT + * @tc.expected: step4. The current state is AccountStateMachine::ACCOUNT_STATE_LOGOFF + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_MANUAL_LOGOFF_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGOFF, stateMachine.GetAccountState()); +} + +/** + * @tc.name: AccountStateMachineTestLogoutBindSuccess016 + * @tc.desc: Account state machine transform logout state to login state + * @tc.type: FUNC + * @tc.require: AR000CUF5M AR000CUF62 + */ +HWTEST_F(AccountStateMachineTest, AccountStateMachineTestLogoutBindSuccess016, TestSize.Level0) +{ + /** + * @tc.steps: step1. AccountStateMachine init + * @tc.expected: step1. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + AccountStateMachine stateMachine; + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); + + /** + * @tc.steps: step2. Input the event ACCOUNT_BIND_SUCCESS_EVT + * @tc.expected: step2. The current state is AccountStateMachine::ACCOUNT_STATE_LOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_SUCCESS_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step3. Input the event ACCOUNT_MANUAL_LOGOUT_EVT + * @tc.expected: step3. The current state is AccountStateMachine::ACCOUNT_STATE_NOTLOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_MANUAL_LOGOUT_EVT)); + EXPECT_EQ(ACCOUNT_STATE_NOTLOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step4. Input the event ACCOUNT_BIND_SUCCESS_EVT + * @tc.expected: step4. The current state is AccountStateMachine::ACCOUNT_STATE_LOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_SUCCESS_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, stateMachine.GetAccountState()); +} + +/** + * @tc.name: AccountStateMachineTestLogoffBindSuccess017 + * @tc.desc: Account state machine transform logoff state to login state + * @tc.type: FUNC + * @tc.require: AR000CUF5M AR000CUF5P + */ +HWTEST_F(AccountStateMachineTest, AccountStateMachineTestLogoffBindSuccess017, TestSize.Level0) +{ + /** + * @tc.steps: step1. AccountStateMachine init + * @tc.expected: step1. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + AccountStateMachine stateMachine; + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); + + /** + * @tc.steps: step2. Input the event ACCOUNT_BIND_SUCCESS_EVT + * @tc.expected: step2. The current state is AccountStateMachine::ACCOUNT_STATE_LOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_SUCCESS_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step3. Input the event ACCOUNT_MANUAL_LOGOFF_EVT + * @tc.expected: step3. The current state is AccountStateMachine::ACCOUNT_STATE_LOGOFF + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_MANUAL_LOGOFF_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGOFF, stateMachine.GetAccountState()); + + /** + * @tc.steps: step4. Input the event ACCOUNT_BIND_SUCCESS_EVT + * @tc.expected: step4. The current state is AccountStateMachine::ACCOUNT_STATE_LOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_SUCCESS_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, stateMachine.GetAccountState()); +} + +/** + * @tc.name: AccountStateMachineTestLogoffInputUntreatedEvent018 + * @tc.desc: Account state machine keep the last state + * @tc.type: FUNC + * @tc.require: AR000CUF5M AR000CUF5I + */ +HWTEST_F(AccountStateMachineTest, AccountStateMachineTestLogoffInputUntreatedEvent018, TestSize.Level0) +{ + /** + * @tc.steps: step1. AccountStateMachine init + * @tc.expected: step1. The current state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + AccountStateMachine stateMachine; + EXPECT_EQ(ACCOUNT_STATE_UNBOUND, stateMachine.GetAccountState()); + + /** + * @tc.steps: step2. Input the event ACCOUNT_BIND_SUCCESS_EVT + * @tc.expected: step2. The current state is AccountStateMachine::ACCOUNT_STATE_LOGIN + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_SUCCESS_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGIN, stateMachine.GetAccountState()); + + /** + * @tc.steps: step3. Input the event ACCOUNT_MANUAL_LOGOFF_EVT + * @tc.expected: step3. The current state is AccountStateMachine::ACCOUNT_STATE_LOGOFF + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_MANUAL_LOGOFF_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGOFF, stateMachine.GetAccountState()); + + /** + * @tc.steps: step4. Input the event ACCOUNT_AUTHENTICATE_FAILED_EVT + * @tc.expected: step4. The current state is AccountStateMachine::ACCOUNT_STATE_LOGOFF + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_AUTHENTICATE_FAILED_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGOFF, stateMachine.GetAccountState()); + + /** + * @tc.steps: step3. Input the event ACCOUNT_BIND_FAILED_EVT + * @tc.expected: step3. The current state is AccountStateMachine::ACCOUNT_STATE_LOGOFF + */ + EXPECT_EQ(true, stateMachine.StateChangeProcess(ACCOUNT_BIND_FAILED_EVT)); + EXPECT_EQ(ACCOUNT_STATE_LOGOFF, stateMachine.GetAccountState()); +} diff --git a/services/accountmgr/test/unittest/account_mgr_service_test/ohos_account_manager_test.cpp b/services/accountmgr/test/unittest/account_mgr_service_test/ohos_account_manager_test.cpp new file mode 100755 index 000000000..b6f536b5a --- /dev/null +++ b/services/accountmgr/test/unittest/account_mgr_service_test/ohos_account_manager_test.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 + +#include "ohos_account_manager.h" +#include "account_info.h" +using namespace testing::ext; +using namespace OHOS::AccountSA; +class OhosAccountManagerTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; +void OhosAccountManagerTest::SetUpTestCase() {} +void OhosAccountManagerTest::TearDownTestCase() {} +void OhosAccountManagerTest::SetUp() {} +void OhosAccountManagerTest::TearDown() {} +/** + * @tc.name: OhosAccountManagerTestTokenInvalid004 + * @tc.desc: Account manager handle token invalid event test + * @tc.type: FUNC + * @tc.require: AR000CUF5U AR000CUF5V SR000CUF5T + */ +HWTEST_F(OhosAccountManagerTest, OhosAccountManagerTestTokenInvalid004, TestSize.Level0) +{ + /** + * @tc.steps: step1. init one account + * @tc.expected: step1. The current account state is AccountStateMachine::ACCOUNT_STATE_UNBOUND + */ + OhosAccountManager accountManager; + std::string uid("TestUid"); + std::string invalidUid("NotExistUid"); + std::string name("TestName"); + accountManager.OnInitialize(); + auto ret = accountManager.LoginOhosAccount(name, uid, OHOS_ACCOUNT_EVENT_LOGIN); + EXPECT_EQ(true, ret); + /** + * @tc.steps: step2. trigger token_invalid event for a different uid + * @tc.expected: step2. process result is true AND state changes + */ + ret = accountManager.HandleOhosAccountTokenInvalidEvent(name, invalidUid, OHOS_ACCOUNT_EVENT_TOKEN_INVALID); + EXPECT_EQ(true, ret); + EXPECT_EQ(ACCOUNT_STATE_NOTLOGIN, accountManager.GetAccountState()); + /** + * @tc.steps: step3. trigger token_invalid event with the same uid + * @tc.expected: step3. process result is true AND state changes + */ + ret = accountManager.HandleOhosAccountTokenInvalidEvent(name, uid, OHOS_ACCOUNT_EVENT_TOKEN_INVALID); + EXPECT_EQ(true, ret); + EXPECT_EQ(ACCOUNT_STATE_NOTLOGIN, accountManager.GetAccountState()); + /** + * @tc.steps: step4. logout the account + * @tc.expected: step4. The current account logout + */ + ret = accountManager.LogoutOhosAccount(name, uid, OHOS_ACCOUNT_EVENT_LOGOUT); + EXPECT_EQ(true, ret); +} diff --git a/services/accountmgr/test/unittest/account_mgr_stub_test/BUILD.gn b/services/accountmgr/test/unittest/account_mgr_stub_test/BUILD.gn new file mode 100755 index 000000000..7ff0bda33 --- /dev/null +++ b/services/accountmgr/test/unittest/account_mgr_stub_test/BUILD.gn @@ -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. + +import("//base/account/os_account/os_account.gni") +import("//build/ohos.gni") +import("//build/test.gni") + +module_output_path = "os_account_standard/accountmgrservice" + +config("accountmgr_stub_test_config") { + visibility = [ ":*" ] + + include_dirs = [ + "./include", + "${common_path}/log/include", + "${common_path}/account_error/include", + "${common_path}/perf_stat/include", + "${services_path}/accountmgr/include", + "${innerkits_path}/include", + "//third_party/json/include", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + ] +} + +ohos_unittest("AccountSAMgrStubTest") { + module_out_path = module_output_path + + sources = [ + "${common_path}/log/src/account_log_wrapper.cpp", + "${common_path}/perf_stat/src/perf_stat.cpp", + "${services_path}/accountmgr/src/account_dump_helper.cpp", + "${services_path}/accountmgr/src/account_helper_data.cpp", + "${services_path}/accountmgr/src/account_mgr_service.cpp", + "${services_path}/accountmgr/src/account_state_machine.cpp", + "${services_path}/accountmgr/src/account_stub.cpp", + "${services_path}/accountmgr/src/ohos_account_data_deal.cpp", + "${services_path}/accountmgr/src/ohos_account_manager.cpp", + "${services_path}/accountmgr/test/mock/src/mock_account_mgr_service.cpp", + ] + + sources += [ "account_mgr_stub_test.cpp" ] + + configs = [ + ":accountmgr_stub_test_config", + "${services_path}/accountmgr/test:accountmgr_test_config", + ] + + deps = [ + "//third_party/googletest:gmock_main", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + external_deps = [ + "aafwk_standard:base", + "aafwk_standard:intent", + "aafwk_standard:want", + "appexecfwk_standard:appexecfwk_base", + "appexecfwk_standard:appexecfwk_core", + "hisysevent_native:libhisysevent", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_L2:samgr_proxy", + "startup_l2:syspara", + ] + part_name = "os_account_standard" +} + +group("unittest") { + testonly = true + + deps = [ ":AccountSAMgrStubTest" ] +} diff --git a/services/accountmgr/test/unittest/account_mgr_stub_test/account_mgr_stub_test.cpp b/services/accountmgr/test/unittest/account_mgr_stub_test/account_mgr_stub_test.cpp new file mode 100755 index 000000000..ea179f485 --- /dev/null +++ b/services/accountmgr/test/unittest/account_mgr_stub_test/account_mgr_stub_test.cpp @@ -0,0 +1,142 @@ +/* + * 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 +#include + +#include "mock_account_mgr_service.h" + +using namespace testing::ext; +using namespace OHOS; +using namespace OHOS::AccountSA; +class AccountMgrStubTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void AccountMgrStubTest::SetUpTestCase() {} + +void AccountMgrStubTest::TearDownTestCase() {} + +void AccountMgrStubTest::SetUp() {} + +void AccountMgrStubTest::TearDown() {} + +/** + * @tc.name: AccountStubQuitTipsTest001 + * @tc.desc: test QUERY_OHOS_ACCOUNT_QUIT_TIPS cmd process. + * @tc.type: FUNC + * @tc.require: AR000CVBCA SR000CVBC9 + */ +HWTEST_F(AccountMgrStubTest, AccountStubQuitTipsTest001, TestSize.Level0) +{ + /** + * @tc.steps: step1. create mock instance and send QUERY_OHOS_ACCOUNT_QUIT_TIPS cmd + * @tc.expected: step1. result success, title and content are empty + */ + MessageParcel inData; + MessageParcel reply; + MessageOption msgOption; + MockAccountMgrService mockSrv{}; + inData.WriteInterfaceToken(AccountStub::GetDescriptor()); + auto ret = mockSrv.OnRemoteRequest(AccountStub::QUERY_OHOS_ACCOUNT_QUIT_TIPS, inData, reply, msgOption); + EXPECT_EQ(ret, ERR_OK); + std::u16string title = reply.ReadString16(); + std::u16string content = reply.ReadString16(); + EXPECT_EQ(true, title.empty()); + EXPECT_EQ(true, content.empty()); +} + +/** + * @tc.name: AccountStubQueryOhosInfoTest002 + * @tc.desc: test QUERY_OHOS_ACCOUNT_INFO cmd process. + * @tc.type: FUNC + * @tc.require: AR000CVBCC SR000CVBCB + */ +HWTEST_F(AccountMgrStubTest, AccountStubQueryOhosInfoTest002, TestSize.Level0) +{ + /** + * @tc.steps: step1. create mock instance and send QUERY_OHOS_ACCOUNT_QUIT_TIPS cmd + * @tc.expected: step1. result success, title and content are not empty + */ + MessageParcel data; + MessageParcel reply; + MessageOption msgOption; + MockAccountMgrService mockSrv{}; + data.WriteInterfaceToken(AccountStub::GetDescriptor()); + auto ret = mockSrv.OnRemoteRequest(AccountStub::QUERY_OHOS_ACCOUNT_INFO, data, reply, msgOption); + EXPECT_EQ(ret, ERR_OK); + std::u16string name = reply.ReadString16(); + std::u16string uid = reply.ReadString16(); + std::int32_t status = reply.ReadInt32(); + EXPECT_EQ(Str16ToStr8(name), DEFAULT_OHOS_ACCOUNT_NAME); + EXPECT_EQ(Str16ToStr8(uid), DEFAULT_OHOS_ACCOUNT_UID); + EXPECT_EQ(status, ACCOUNT_STATE_UNBOUND); +} + +/** + * @tc.name: AccountStubQueryDeviceAccountIdTest003 + * @tc.desc: test QUERY_DEVICE_ACCOUNT_ID_FROM_UID cmd process. + * @tc.type: FUNC + * @tc.require: AR000CVBCE SR000CVBCD + */ +HWTEST_F(AccountMgrStubTest, AccountStubQueryDeviceAccountIdTest003, TestSize.Level0) +{ + /** + * @tc.steps: step1. Init, create mock instance + * @tc.expected: None + */ + MockAccountMgrService mockSrv{}; + std::int32_t testUid = 1000000; + std::int32_t expectedId = 10; + + MessageParcel inData; + inData.WriteInterfaceToken(AccountStub::GetDescriptor()); + /** + * @tc.steps: step2. write UID and send QUERY_DEVICE_ACCOUNT_ID_FROM_UID cmd + * @tc.expected: result is ok, and expected device account id is 10: expectedId = testUid/100000 + */ + inData.WriteInt32(testUid); + MessageParcel outData; + MessageOption option; + auto ret = mockSrv.OnRemoteRequest(AccountStub::QUERY_DEVICE_ACCOUNT_ID_FROM_UID, inData, outData, option); + EXPECT_EQ(ret, ERR_OK); + auto result = outData.ReadInt32(); + EXPECT_EQ(result, expectedId); +} + +/** + * @tc.name: AccountStubInvalidCmdTest004 + * @tc.desc: test INVALID cmd process. + * @tc.type: FUNC + * @tc.require: AR000CUF5N SR000CUF5L + */ +HWTEST_F(AccountMgrStubTest, AccountStubInvalidCmdTest004, TestSize.Level0) +{ + /** + * @tc.steps: step1. Init, create mock instance and send an invalid cmd + * @tc.expected: result is failure + */ + MessageParcel inData; + MessageParcel outData; + MessageOption msgOption; + MockAccountMgrService mockSrv{}; + inData.WriteInterfaceToken(AccountStub::GetDescriptor()); + auto ret = mockSrv.OnRemoteRequest(0, inData, outData, msgOption); + EXPECT_NE(ret, ERR_OK); +} diff --git a/services/accountmgr/test/unittest/ohos_account_data_deal_test/BUILD.gn b/services/accountmgr/test/unittest/ohos_account_data_deal_test/BUILD.gn new file mode 100755 index 000000000..90108bd29 --- /dev/null +++ b/services/accountmgr/test/unittest/ohos_account_data_deal_test/BUILD.gn @@ -0,0 +1,63 @@ +# 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("//base/account/os_account/os_account.gni") +import("//build/ohos.gni") +import("//build/test.gni") + +module_output_path = "os_account_standard/accountmgrservice" + +config("accountmgr_data_deal_test_config") { + include_dirs = [ + "./include", + "${common_path}/log/include", + "${common_path}/account_error/include", + "${services_path}/accountmgr/include", + "//third_party/json/include", + "${innerkits_path}/include", + "//utils/native/base/include", + ] +} + +ohos_unittest("AccountSADataDealTest") { + module_out_path = module_output_path + resource_config_file = + "${os_account_path}/test/resource/accountmgrservice/ohos_test.xml" + + sources = [ + "${common_path}/log/src/account_log_wrapper.cpp", + "${services_path}/accountmgr/src/ohos_account_data_deal.cpp", + ] + + sources += [ "ohos_account_data_deal_test.cpp" ] + + configs = [ + ":accountmgr_data_deal_test_config", + "${services_path}/accountmgr/test:accountmgr_test_config", + ] + + deps = [ + "//third_party/googletest:gmock_main", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + part_name = "os_account_standard" +} + +group("unittest") { + testonly = true + + deps = [ ":AccountSADataDealTest" ] +} diff --git a/services/accountmgr/test/unittest/ohos_account_data_deal_test/ohos_account_data_deal_test.cpp b/services/accountmgr/test/unittest/ohos_account_data_deal_test/ohos_account_data_deal_test.cpp new file mode 100755 index 000000000..687ee284c --- /dev/null +++ b/services/accountmgr/test/unittest/ohos_account_data_deal_test/ohos_account_data_deal_test.cpp @@ -0,0 +1,172 @@ +/* + * 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 +#include +#include +#include + +#include "account_error_no.h" +#include "account_info.h" +#include "account_log_wrapper.h" +#include "ohos_account_data_deal.h" + +using namespace testing::ext; +using namespace OHOS; +using namespace OHOS::AccountSA; + +namespace { +const std::string RESOURCE_ROOT_PATH = "/data/test/account/data_deal/"; +const std::string ACCOUNT_SUFFIX = ".json"; +const std::string TEST_STR_ACCOUNT_NAME = "incubation"; +const std::string TEST_STR_OPEN_ID = "test open id"; +} + +class OhosAccountDataDealTest : public testing::Test { +public: + static void SetUpTestCase(); + + static void TearDownTestCase(); + + void SetUp(); + + void TearDown(); + +protected: + std::ostringstream pathStream_; +}; + +void OhosAccountDataDealTest::SetUpTestCase() {} + +void OhosAccountDataDealTest::TearDownTestCase() {} + +void OhosAccountDataDealTest::SetUp() {} + +void OhosAccountDataDealTest::TearDown() +{ + pathStream_.clear(); +} + +/** + * @tc.name: OhosAccountJsonNotInitTest001 + * @tc.desc: Test invalid event publish + * @tc.type: FUNC + * @tc.require: AR000CUF55 + */ +HWTEST_F(OhosAccountDataDealTest, OhosAccountJsonNotInitTest001, TestSize.Level0) +{ + AccountInfo accountInfo; + pathStream_ << RESOURCE_ROOT_PATH << "test" << ACCOUNT_SUFFIX; + + /** + * @tc.steps: step1. init json object + */ + OhosAccountDataDeal dataDeal(pathStream_.str()); + ErrCode errCode = dataDeal.AccountInfoFromJson(accountInfo); + EXPECT_EQ(errCode, ERR_ACCOUNT_DATADEAL_NOT_READY); +} + +/** + * @tc.name: OhosAccountJsonCreateDefaultJsonFileTest002 + * @tc.desc: Test invalid event publish + * @tc.type: FUNC + * @tc.require: AR000CUF6P + */ +HWTEST_F(OhosAccountDataDealTest, OhosAccountJsonCreateDefaultJsonFileTest002, TestSize.Level0) +{ + AccountInfo accountInfo; + ErrCode errCode = ERR_OK; + pathStream_ << RESOURCE_ROOT_PATH << "not_exist" << ACCOUNT_SUFFIX; + + /** + * @tc.steps: step1. init json object + */ + OhosAccountDataDeal dataDeal(pathStream_.str()); + errCode = dataDeal.Init(); + EXPECT_EQ(errCode, ERR_OK); + + errCode = dataDeal.AccountInfoFromJson(accountInfo); + EXPECT_EQ(errCode, ERR_OK); + EXPECT_EQ(accountInfo.ohosAccountStatus_, ACCOUNT_STATE_UNBOUND); + EXPECT_EQ(accountInfo.ohosAccountName_, DEFAULT_OHOS_ACCOUNT_NAME); +} + +/** + * @tc.name: OhosAccountInvalidFileNameTest003 + * @tc.desc: Test invalid event publish + * @tc.type: FUNC + * @tc.require: AR000CUF6Q + */ +HWTEST_F(OhosAccountDataDealTest, OhosAccountInvalidFileNameTest003, TestSize.Level0) +{ + AccountInfo accountInfo; + accountInfo.ohosAccountStatus_ = ACCOUNT_STATE_UNBOUND; + ErrCode errCode = ERR_OK; + pathStream_ << RESOURCE_ROOT_PATH << "invalid_format" << ACCOUNT_SUFFIX; + + /** + * @tc.steps: step1. init json object + */ + OhosAccountDataDeal dataDeal(pathStream_.str()); + errCode = dataDeal.Init(); + EXPECT_NE(errCode, ERR_OK); +} + +/** + * @tc.name: OhosAccountJsonFileWriteTest004 + * @tc.desc: Test invalid event publish + * @tc.type: FUNC + * @tc.require: AR000CUF55 + */ +HWTEST_F(OhosAccountDataDealTest, OhosAccountJsonFileWriteTest004, TestSize.Level0) +{ + AccountInfo accountInfo; + ErrCode errCode = ERR_OK; + pathStream_ << RESOURCE_ROOT_PATH << "valid" << ACCOUNT_SUFFIX; + + /** + * @tc.steps: step1. init json object + */ + OhosAccountDataDeal dataDeal(pathStream_.str()); + + errCode = dataDeal.Init(); + EXPECT_EQ(errCode, ERR_OK); + errCode = dataDeal.AccountInfoFromJson(accountInfo); + EXPECT_EQ(errCode, ERR_OK); + EXPECT_EQ(accountInfo.ohosAccountStatus_, ACCOUNT_STATE_UNBOUND); + EXPECT_EQ(accountInfo.ohosAccountName_, TEST_STR_ACCOUNT_NAME); + EXPECT_EQ(accountInfo.ohosAccountUid_, TEST_STR_OPEN_ID); + + /** + * @tc.steps: step2. update json object + */ + accountInfo.ohosAccountStatus_ = ACCOUNT_STATE_NOTLOGIN; + accountInfo.ohosAccountName_ = TEST_STR_ACCOUNT_NAME; + accountInfo.ohosAccountUid_ = TEST_STR_OPEN_ID; + dataDeal.AccountInfoToJson(accountInfo); + + /** + * @tc.steps: step3. read json object and validate info + */ + OhosAccountDataDeal dataDealNew(pathStream_.str()); + errCode = dataDealNew.Init(); + EXPECT_EQ(errCode, ERR_OK); + AccountInfo accountInfoNew; + errCode = dataDeal.AccountInfoFromJson(accountInfoNew); + EXPECT_EQ(errCode, ERR_OK); + EXPECT_EQ(accountInfoNew.ohosAccountStatus_, ACCOUNT_STATE_NOTLOGIN); + EXPECT_EQ(accountInfoNew.ohosAccountName_, TEST_STR_ACCOUNT_NAME); + EXPECT_EQ(accountInfoNew.ohosAccountUid_, TEST_STR_OPEN_ID); +} \ No newline at end of file diff --git a/test/resource/accountmgrservice/data_deal/empty.json b/test/resource/accountmgrservice/data_deal/empty.json new file mode 100755 index 000000000..e69de29bb diff --git a/test/resource/accountmgrservice/data_deal/invalid_format.json b/test/resource/accountmgrservice/data_deal/invalid_format.json new file mode 100755 index 000000000..405c90b25 --- /dev/null +++ b/test/resource/accountmgrservice/data_deal/invalid_format.json @@ -0,0 +1 @@ +1223243234234 \ No newline at end of file diff --git a/test/resource/accountmgrservice/data_deal/valid.json b/test/resource/accountmgrservice/data_deal/valid.json new file mode 100644 index 000000000..123aabb2c --- /dev/null +++ b/test/resource/accountmgrservice/data_deal/valid.json @@ -0,0 +1 @@ +{"account_name":"incubation","bind_status":0,"bind_time":0,"digest":[45,145,50,8,135,116,146,201,87,221,139,68,62,143,171,47,73,238,251,120,110,1],"openId":"test open id","uid":0} \ No newline at end of file diff --git a/test/resource/accountmgrservice/ohos_test.xml b/test/resource/accountmgrservice/ohos_test.xml new file mode 100755 index 000000000..4e0b3e0c0 --- /dev/null +++ b/test/resource/accountmgrservice/ohos_test.xml @@ -0,0 +1,21 @@ + + + + + + + +