update OpenHarmony 2.0 Canary

This commit is contained in:
mamingshuai 2021-06-02 00:03:37 +08:00
parent e3b2de3bdb
commit 18199abb71
170 changed files with 13760 additions and 61 deletions

15
.gitattributes vendored Normal file
View File

@ -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

126
BUILD.gn Normal file
View File

@ -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.
import("//base/hiviewdfx/hiview/build/hiview_var.gni")
import("//build/ohos.gni")
if (!build_public_version) {
oem_script = rebase_path("//base/hiviewdfx/hiview/build/run_oem_hook.py")
print(exec_script(oem_script, [], "string", []))
}
gen_plugin_script =
rebase_path("//base/hiviewdfx/hiview/build/gen_plugin_build.py")
copy_plugin_script =
rebase_path("//base/hiviewdfx/hiview/build/copy_plugin_config.py")
input_build_file =
rebase_path("//base/hiviewdfx/hiview/build/plugin_build_L2.json")
out_plugin_config_file = "${target_gen_dir}/plugin_config"
out_plugin_build_file = "${target_gen_dir}/plugin_build.gni"
out_plugin_config_file_tmp = "${target_gen_dir}/plugin_config_tmp"
if (build_with_config) {
input_build_file = rebase_path(config_path)
}
arguments = [
"--input-file",
input_build_file,
"--plugin-config-file",
rebase_path(out_plugin_config_file_tmp),
"--plugin-build-file",
rebase_path(out_plugin_build_file),
"--target_os",
target_os,
"--double_framework",
"$is_double_framework",
"--target_platform",
target_platform,
"--target_cpu",
target_cpu,
"--plugin_so",
"$plugin_so",
"--plugin_target_platform",
plugin_target_platform,
"--plugin_target_ram",
plugin_target_ram,
"--plugin_target_rom",
plugin_target_rom,
]
result_ = exec_script(gen_plugin_script, arguments, "string")
print(result_)
action("copy_plugin_config") {
script = copy_plugin_script
outputs = [ out_plugin_config_file ]
args = [
"--src-file",
rebase_path(out_plugin_config_file_tmp),
"--dst-file",
rebase_path(out_plugin_config_file),
]
}
import(out_plugin_build_file)
ohos_prebuilt_etc("plugin_config") {
source = out_plugin_config_file
deps = [ ":copy_plugin_config" ]
part_name = "hiview_L2"
subsystem_name = "hiviewdfx"
relative_install_dir = "hiview"
}
config("hiview_plus_config") {
visibility = [ ":*" ]
include_dirs = [ "include" ]
}
ohos_executable("hiview") {
install_enable = true
deps = [
"base:hiviewbase",
"core:hiview_core",
"service:hiview_service",
]
sources = [ "main.cpp" ]
deps += plugin_static_deps
part_name = "hiview_L2"
subsystem_name = "hiviewdfx"
}
group("hiview_package") {
# root of all the hiview dependencies
deps = [
":hiview",
":plugin_config",
]
deps += plugin_dynamic_deps
}
group("hiview_test_package") {
testonly = true
deps = [
"adapter:moduletest",
"adapter:unittest",
"base/test:unittest",
"core/test:unittest",
"plugins:moduletest",
"plugins:unittest",
"test:moduletest",
]
}

177
LICENSE Normal file
View File

@ -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

67
OAT.xml Normal file
View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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.
-->
<!-- OAT(OSS Audit Tool) configuration guide:
basedir: Root dir, the basedir + project path is the real source file location.
licensefile:
1.If the project don't have "LICENSE" in root dir, please define all the license files in this project in , OAT will check license files according to this rule.
tasklist(only for batch mode):
1. task: Define oat check thread, each task will start a new thread.
2. task name: Only an name, no practical effect.
3. task policy: Default policy for projects under this task, this field is required and the specified policy must defined in policylist.
4. task filter: Default filefilter for projects under this task, this field is required and the specified filefilter must defined in filefilterlist.
5. task project: Projects to be checked, the path field define the source root dir of the project.
policyList:
1. policy: All policyitems will be merged to default OAT.xml rules, the name of policy doesn't affect OAT check process.
2. policyitem: The fields type, name, path, desc is required, and the fields rule, group, filefilter is optional,the default value is:
<policyitem type="" name="" path="" desc="" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
3. policyitem type:
"compatibility" is used to check license compatibility in the specified path;
"license" is used to check source license header in the specified path;
"copyright" is used to check source copyright header in the specified path;
"import" is used to check source dependency in the specified path, such as import ... ,include ...
"filetype" is used to check file type in the specified path, supported file types: archive, binary
"filename" is used to check whether the specified file exists in the specified path(support projectroot in default OAT.xml), supported file names: LICENSE, README, README.OpenSource
4. policyitem name: This field is used for define the license, copyright, "*" means match all, the "!" prefix means could not match this value. For example, "!GPL" means can not use GPL license.
5. policyitem path: This field is used for define the source file scope to apply this policyitem, the "!" prefix means exclude the files. For example, "!.*/lib/.*" means files in lib dir will be exclude while process this policyitem.
6. policyitem rule and group: These two fields are used together to merge policy results. "may" policyitems in the same group means any one in this group passed, the result will be passed.
7. policyitem filefilter: Used to bind filefilter which define filter rules.
8. filefilter: Filter rules, the type filename is used to filter file name, the type filepath is used to filter file path.
Note:If the text contains special characters, please escape them according to the following rules:
" == &gt;
& == &gt;
' == &gt;
< == &gt;
> == &gt;
-->
<configuration>
<oatconfig>
<filefilterlist>
<filefilter name="defaultPolicyFilter" desc="Filters for compatibility, license header policies">
<filteritem type="filename" name="plugin_config*" desc="build and load config file, not support comments"/>
<filteritem type="filename" name="event_logger_config" desc="build and load config file, not support comments"/>
</filefilter>
<filefilter name="copyrightPolicyFilter" desc="Filters for copyright header policies">
<filteritem type="filename" name="plugin_config*" desc="build and load config file, not support comments"/>
<filteritem type="filename" name="event_logger_config" desc="build and load config file, not support comments"/>
</filefilter>
</filefilterlist>
</oatconfig>
</configuration>

View File

@ -1,36 +0,0 @@
# hiviewdfx_hiview
#### Description
Fault logging for device maintenance and test across different platforms | 系统维测信息管理工具集
#### 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/)

105
README.md
View File

@ -1,37 +1,92 @@
# hiviewdfx_hiview
# Hiview<a name="EN-US_TOPIC_0000001162254005"></a>
#### 介绍
Fault logging for device maintenance and test across different platforms | 系统维测信息管理工具集
- [Introduction](#section1289063163919)
- [Directory Structure](#section16611433113712)
- [Constraints](#section7147138193814)
- [Contribution](#section10404153013381)
- [Usage](#section1046874983819)
- [Repositories Involved](#section16647142611396)
#### 软件架构
软件架构说明
## Introduction<a name="section1289063163919"></a>
Hiview is the module of OpenHarmony that provides toolkits for device maintenance across different platforms.
#### 安装教程
Currently, Hiview opens only the plug-in management platform and system event source capabilities.
1. xxxx
2. xxxx
3. xxxx
**Figure 1** Architecture of Hiview
#### 使用说明
![](figures/en-us_image_0000001162020243.png)
1. xxxx
2. xxxx
3. xxxx
Hiview consists of the following components:
#### 参与贡献
adapter: operating system adaptation layer, which adapts APIs of the system services in use
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
hiview base: Hiview base definition, which provides the plug-in definition, detector definition, and utility class
hiview core: Hiview core module, which provides the plug-in configuration, plug-in management, and event source functions
#### 特技
hiview services: Hiview services. Currently, only the Hiview run information exporting function is provided.
plugins: Independent service modules.
Hiview works in event-driven mode. The core of Hiview is a collection of HiSysEvent stubs distributed in the system.
Formatted events are reported to Hiview through the **HiSysEvent** API for processing. Figure 2 shows the data interaction process.
**Figure 2** Data interaction between Hiview modules
![](figures/en-us_image_0000001115710726.png)
1. The application framework and system services report system events using the **HiSysEvent** API.
2. HiSysEventSource reads events and prints the events to logs.
## Directory Structure<a name="section16611433113712"></a>
The code directory structure of Hiview is as follows:
```
/base/hiviewdfx/hiview
├── adapter # Platform adaptation code
│ ├── service # Service adaptation code
│ └── system_service # System API adaptation code
├── base # Module definition and utility class
│ └── utility
├── build # Compilation scripts
├── include # Common definitions
├── core # Plug-in management
└── service # Platform services
```
## Constraints<a name="section7147138193814"></a>
Use of C++14 features requires libc of C++14 or later.
## Contribution<a name="section10404153013381"></a>
If you are interested in Hiview and want to become a contributor, refer to the _Code Contribution Guide_.
## Usage<a name="section1046874983819"></a>
Hiview automatically starts with the device and loads plug-ins based on the configuration file.
## Repositories Involved<a name="section16647142611396"></a>
[DFX subsystem](https://gitee.com/openharmony/docs/blob/master/en/readme/dfx.md)
**hiviewdfx\_hiview**
[hiviewdfx\_hilog](https://gitee.com/openharmony/hiviewdfx_hilog/blob/master/README.md)
[hiviewdfx\_hiappevent](https://gitee.com/openharmony/hiviewdfx_hiappevent/blob/master/README.md)
[hiviewdfx\_hisysevent](https://gitee.com/openharmony/hiviewdfx_hisysevent/blob/master/README.md)
[hiviewdfx\_faultloggerd](https://gitee.com/openharmony/hiviewdfx_faultloggerd/blob/master/README.md)
[hiviewdfx\_hilog\_lite](https://gitee.com/openharmony/hiviewdfx_hilog_lite/blob/master/README.md)
[hiviewdfx\_hievent\_lite](https://gitee.com/openharmony/hiviewdfx_hievent_lite/blob/master/README.md)
[hiviewdfx\_hiview\_lite](https://gitee.com/openharmony/hiviewdfx_hiview_lite/blob/master/README.md)
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/)

92
README_zh.md Normal file
View File

@ -0,0 +1,92 @@
# Hiview组件<a name="ZH-CN_TOPIC_0000001162254005"></a>
- [简介](#section1289063163919)
- [目录](#section16611433113712)
- [约束](#section7147138193814)
- [贡献](#section10404153013381)
- [使用](#section1046874983819)
- [相关仓](#section16647142611396)
## 简介<a name="section1289063163919"></a>
Hiview是一个跨平台的终端设备维测服务集。
目前开源部分仅包含插件管理平台和系统事件源。
**图1**.Hiview模块架构图
![](figures/zh-cn_image_0000001162020243.png)
Hiview由框架和插件组成分别为
操作系统适配层\(adapter\),对使用的系统服务的接口进行适配。
Hiview基础定义\(hiview base\),包括插件的定义,检测器的定义以及工具类。
Hiview的核心模块\(hiview core\),包括插件配置,插件管理以及事件源。
Hiview服务\(hiview services\)目前仅包括hiview运行信息导出功能。
Hiview插件\(plugins\),为独立功能的业务模块。
Hiview维测服务是由事件驱动的其核心为分布在系统各处的HiSysEvent桩点。
格式化的事件通过HiSysEvent API上报至hiview进行处理其基本流程如图2。
**图2**.Hiview模块数据交互图
![](figures/zh-cn_image_0000001115710726.png)
1.应用框架、系统服务使用HiSysEvent组件上报系统事件信息。
2.Hiview中HiSysEventSource读取事件并打印到流水日志中。
## 目录<a name="section16611433113712"></a>
Hiview源代码目录结构如下
```
/base/hiviewdfx/hiview.
├── adapter #平台适配
│ ├── service #服务适配
│ └── system_service #系统接口适配
├── base #模块定义,工具类
│ └── utility
├── build #编译脚本
├── include #公共定义
├── core #插件管理
└── service #平台服务
```
## 约束<a name="section7147138193814"></a>
使用C++14的特性依赖C++14及以上的libc实现。
## 贡献<a name="section10404153013381"></a>
如果您对Hiview感兴趣并想加入Hiview的开发并成为代码贡献者请参考代码贡献指南。
## 使用<a name="section1046874983819"></a>
Hiview服务随设备启动自动启动按配置文件加载插件。
## 相关仓<a name="section16647142611396"></a>
[DFX子系统](https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/DFX%E5%AD%90%E7%B3%BB%E7%BB%9F.md)
**hiviewdfx\_hiview**
[hiviewdfx\_hilog](https://gitee.com/openharmony/hiviewdfx_hilog/blob/master/README_zh.md)
[hiviewdfx\_hiappevent](https://gitee.com/openharmony/hiviewdfx_hiappevent/blob/master/README_zh.md)
[hiviewdfx\_hisysevent](https://gitee.com/openharmony/hiviewdfx_hisysevent/blob/master/README_zh.md)
[hiviewdfx\_faultloggerd](https://gitee.com/openharmony/hiviewdfx_faultloggerd/blob/master/README_zh.md)
[hiviewdfx\_hilog\_lite](https://gitee.com/openharmony/hiviewdfx_hilog_lite/blob/master/README_zh.md)
[hiviewdfx\_hievent\_lite](https://gitee.com/openharmony/hiviewdfx_hievent_lite/blob/master/README_zh.md)
[hiviewdfx\_hiview\_lite](https://gitee.com/openharmony/hiviewdfx_hiview_lite/blob/master/README_zh.md)

24
adapter/BUILD.gn Normal file
View File

@ -0,0 +1,24 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/test.gni")
group("unittest") {
testonly = true
deps = []
}
group("moduletest") {
testonly = true
deps = []
deps += []
}

12
adapter/LICENSE Normal file
View File

@ -0,0 +1,12 @@
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.

48
adapter/service/BUILD.gn Normal file
View File

@ -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.
import("//base/hiviewdfx/hiview/hiview.gni")
import("//build/ohos.gni")
config("hiview_service_adapter_config") {
visibility = [ "*:*" ]
include_dirs = [ "." ]
}
config("hiview_service_adapter_internal_config") {
visibility = [ ":*" ]
include_dirs = [ "$hiview_service" ]
}
ohos_source_set("hiview_service_adapter") {
public_configs = [ ":hiview_service_adapter_config" ]
configs = [ ":hiview_service_adapter_internal_config" ]
sources = [ "hiview_service_adapter.cpp" ]
deps = [
"$hiview_adapter/system_service:system_service",
"$hiview_base:hiviewbase",
"$hiview_core:hiview_core",
]
deps += [ "zidl:hiview_service_ability" ]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"safwk:system_ability_fwk",
"samgr_L2:samgr_proxy",
]
}

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "hiview_service_adapter.h"
#include "logger.h"
#include "hiview_service_ability.h"
#include "hiview_service.h"
namespace OHOS {
namespace HiviewDFX {
DEFINE_LOG_TAG("HiView-ServiceAdapter");
void HiviewServiceAdapter::StartService(HiviewService *service) const
{
if (service == nullptr) {
HIVIEW_LOGW("failed to start service.");
return;
}
HIVIEW_LOGD("start service.");
HiviewServiceAbility::StartService(service);
}
} // namespace HiviewDFX
} // namespace OHOS

View File

@ -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 HIVIEW_SERVICE_ADAPTER_H
#define HIVIEW_SERVICE_ADAPTER_H
namespace OHOS {
namespace HiviewDFX {
class HiviewService;
class HiviewServiceAdapter {
public:
HiviewServiceAdapter(){};
~HiviewServiceAdapter(){};
void StartService(HiviewService *service) const;
};
} // namespace HiviewDFX
} // namespace OHOS
#endif // HIVIEW_SERVICE_ADAPTER_H

View File

@ -0,0 +1,55 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//base/hiviewdfx/hiview/hiview.gni")
import("//build/ohos.gni")
config("hiview_service_ability_config") {
visibility = [ "*:*" ]
include_dirs = [
"include",
"$hiview_service",
"$hiview_base/utility/include",
]
}
ohos_source_set("hiview_service_ability") {
public_configs = [ ":hiview_service_ability_config" ]
include_dirs = [
"$hiview_base/include",
"$hiview_service",
"include",
]
sources = [
"src/hiview_service_ability.cpp",
"src/hiview_service_ability_proxy.cpp",
"src/hiview_service_ability_stub.cpp",
]
deps = [
"$hiview_base:hiviewbase",
"//utils/native/base:utils",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"safwk:system_ability_fwk",
"samgr_L2:samgr_proxy",
]
part_name = "hiview_L2"
subsystem_name = "hiviewdfx"
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HIVIEW_SERVICE_ABILITY_H
#define HIVIEW_SERVICE_ABILITY_H
#include <string>
#include <memory>
#include "logger.h"
#include "system_ability.h"
#include "hiview_service_ability_stub.h"
#include "ihiview_service_ability.h"
#include "hiview_service.h"
#include "singleton.h"
namespace OHOS {
namespace HiviewDFX {
class HiviewServiceAbility : public SystemAbility,
public HiviewServiceAbilityStub {
DECLARE_SYSTEM_ABILITY(HiviewServiceAbility);
public:
HiviewServiceAbility();
~HiviewServiceAbility();
int32_t Dump(int32_t fd, const std::vector<std::u16string> &args) override;
static void StartService(HiviewService *service);
static void StartServiceAbility(int sleepS);
static HiviewService* GetOrSetHiviewService(HiviewService *service = nullptr);
protected:
void OnDump() override;
void OnStart() override;
void OnStop() override;
};
class HiviewServiceAbilityDeathRecipient : public IRemoteObject::DeathRecipient {
public:
HiviewServiceAbilityDeathRecipient();
~HiviewServiceAbilityDeathRecipient();
void OnRemoteDied(const wptr<IRemoteObject> &object) override;
};
} // namespace HiviewDFX
} // namespace OHOS
#endif // IHIVIEW_SERVICE_H

View File

@ -0,0 +1,33 @@
/*
* 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 HIVIEW_SERVICE_ABILITY_PROXY_H
#define HIVIEW_SERVICE_ABILITY_PROXY_H
#include <string>
#include "iremote_proxy.h"
#include "nocopyable.h"
#include "ihiview_service_ability.h"
namespace OHOS {
namespace HiviewDFX {
class HiviewServiceAbilityProxy : public IRemoteProxy<IHiviewServiceAbility> {
public:
explicit HiviewServiceAbilityProxy(const sptr<IRemoteObject> &remote) : IRemoteProxy<IHiviewServiceAbility>(remote)
{}
virtual ~HiviewServiceAbilityProxy() = default;
};
} // namespace HiviewDFX
} // namespace OHOS
#endif // HIVIEW_SERVICE_ABILITY_PROXY_H

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HIVIEW_SERVICE_ABILITY_STUB_H
#define HIVIEW_SERVICE_ABILITY_STUB_H
#include <string>
#include <mutex>
#include "logger.h"
#include "iremote_stub.h"
#include "message_parcel.h"
#include "nocopyable.h"
#include "ihiview_service_ability.h"
namespace OHOS {
namespace HiviewDFX {
class HiviewServiceAbilityStub : public IRemoteStub<IHiviewServiceAbility> {
public:
HiviewServiceAbilityStub() {};
virtual ~HiviewServiceAbilityStub() {};
int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
};
} // namespace HiviewDFX
} // namespace OHOS
#endif // IHIVIEW_SERVICE_H

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IHIVIEW_SERVICE_ABILITY_H
#define IHIVIEW_SERVICE_ABILITY_H
#include <string>
#include <mutex>
#include "logger.h"
#include "iremote_broker.h"
namespace OHOS {
namespace HiviewDFX {
class IHiviewServiceAbility : public IRemoteBroker {
public:
IHiviewServiceAbility() = default;
~IHiviewServiceAbility() = default;
public:
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.HiviewDFX.IHiviewServiceAbility");
};
} // namespace HiviewDFX
} // namespace OHOS
#endif // IHIVIEW_SERVICE_H

View File

@ -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 "hiview_service_ability.h"
#include <mutex>
#include <cstdio>
#include <unistd.h>
#include "system_ability_definition.h"
#include "iservice_registry.h"
#include "ipc_skeleton.h"
#include "string_util.h"
namespace OHOS {
namespace HiviewDFX {
DEFINE_LOG_TAG("HiViewSA-HiViewServiceAbility");
namespace {
constexpr int MAXRETRYTIMEOUT = 10;
}
int HiviewServiceAbility::Dump(int32_t fd, const std::vector<std::u16string> &args)
{
auto service = GetOrSetHiviewService(nullptr);
if (service != nullptr) {
std::vector<std::string> cmds;
for (const auto &arg : args) {
cmds.push_back(StringUtil::ConvertToUTF8(arg));
}
service->DumpRequestDispatcher(fd, cmds);
}
return 0;
}
HiviewServiceAbility::HiviewServiceAbility() : SystemAbility(DFX_SYS_HIVIEW_ABILITY_ID, true)
{
HIVIEW_LOGI("begin, cmd : %d", DFX_SYS_HIVIEW_ABILITY_ID);
}
HiviewServiceAbility::~HiviewServiceAbility()
{
HIVIEW_LOGI("begin, cmd : %d", DFX_SYS_HIVIEW_ABILITY_ID);
}
void HiviewServiceAbility::StartServiceAbility(int sleepS)
{
HIVIEW_LOGI("called");
sptr<ISystemAbilityManager> serviceManager;
int retryTimeout = MAXRETRYTIMEOUT;
while (retryTimeout > 0) {
--retryTimeout;
if (sleepS > 0) {
sleep(sleepS);
}
SystemAbilityManagerClient::GetInstance().DestroySystemAbilityManagerObject();
serviceManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (serviceManager == nullptr) {
continue;
}
int result = serviceManager->AddSystemAbility(DFX_SYS_HIVIEW_ABILITY_ID, new HiviewServiceAbility());
if (result != 0) {
HIVIEW_LOGE("AddSystemAbility error %d", result);
continue;
}
break;
}
auto abilityObjext = serviceManager->AsObject();
if (abilityObjext == nullptr) {
HIVIEW_LOGE("AsObject() == nullptr");
return;
}
bool ret = abilityObjext->AddDeathRecipient(new HiviewServiceAbilityDeathRecipient());
if (ret == false) {
HIVIEW_LOGE("AddDeathRecipient == false");
}
}
void HiviewServiceAbility::StartService(HiviewService *service)
{
GetOrSetHiviewService(service);
StartServiceAbility(0);
IPCSkeleton::JoinWorkThread();
}
HiviewService *HiviewServiceAbility::GetOrSetHiviewService(HiviewService *service)
{
static HiviewService *ref = nullptr;
if (service != nullptr) {
ref = service;
}
return ref;
}
void HiviewServiceAbility::OnDump()
{
HIVIEW_LOGI("called");
}
void HiviewServiceAbility::OnStart()
{
HIVIEW_LOGI("called");
}
void HiviewServiceAbility::OnStop()
{
HIVIEW_LOGI("called");
}
HiviewServiceAbilityDeathRecipient::HiviewServiceAbilityDeathRecipient()
{
HIVIEW_LOGI("called");
}
HiviewServiceAbilityDeathRecipient::~HiviewServiceAbilityDeathRecipient()
{
HIVIEW_LOGI("called");
}
void HiviewServiceAbilityDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
{
HIVIEW_LOGI("called");
if (object == nullptr) {
return;
}
HiviewServiceAbility::StartServiceAbility(1);
}
} // namespace HiviewDFX
} // namespace OHOS

View File

@ -0,0 +1,21 @@
/*
* 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 "hiview_service_ability_proxy.h"
namespace OHOS {
namespace HiviewDFX {
} // namespace HiviewDFX
} // namespace OHOS

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "hiview_service_ability_stub.h"
#include "errors.h"
namespace OHOS {
namespace HiviewDFX {
DEFINE_LOG_TAG("HiViewSA-HiViewServiceAbilityStub");
int32_t HiviewServiceAbilityStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
MessageOption &option)
{
HIVIEW_LOGI("HiviewServiceAbilityStub::OnRemoteRequest, cmd = %d, flags= %d", code,
option.GetFlags());
std::u16string descripter = HiviewServiceAbilityStub::GetDescriptor();
std::u16string remoteDescripter = data.ReadInterfaceToken();
if (descripter != remoteDescripter) {
return -ERR_INVALID_VALUE;
}
switch (code) {
default:
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
}
} // namespace HiviewDFX
} // namespace OHOS

View File

@ -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/hiviewdfx/hiview/hiview.gni")
import("//build/test.gni")
module_output_path = "hiview_L2/hiview_L2"
group("unittest") {
testonly = true
deps = [ ":HiviewSATest" ]
}
config("unittest_config") {
include_dirs = [
"//utils/native/base/include",
"unittest/common",
"$hiview_service",
]
cflags_cc = [ "-D__UNITTEST__" ]
}
ohos_unittest("HiviewSATest") {
module_out_path = module_output_path
configs = [ ":unittest_config" ]
sources = [ "unittest/common/hiview_sa_test.cpp" ]
cflags_cc = [ "-DTEST_LOCAL_SRC" ]
deps = [
"$hiview_adapter/service/zidl:hiview_service_ability",
"$hiview_base:hiview_base",
"$hiview_service:hiview_service",
"//third_party/googletest:gtest_main",
]
external_deps = [
"ipc:ipc_core",
"safwk:system_ability_fwk",
"samgr_L2:samgr_proxy",
]
}

View File

@ -0,0 +1,96 @@
/*
* 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 "hiview_sa_test.h"
#include <string>
#include <unistd.h>
#include "hiview_service_ability_proxy.h"
#include "if_system_ability_manager.h"
#include "ipc_skeleton.h"
#include "iservice_registry.h"
#include "system_ability_definition.h"
namespace OHOS {
namespace HiviewDFX {
void HiviewSATest::SetUpTestCase() {}
void HiviewSATest::TearDownTestCase() {}
void HiviewSATest::SetUp() {}
void HiviewSATest::TearDown() {}
/* *
* @tc.name: CommonTest001
* @tc.desc: Check whether the SA is successfully obtained.
* @tc.type: FUNC
* @tc.require: AR000FJLO2
*/
HWTEST_F(HiviewSATest, CommonTest001, testing::ext::TestSize.Level3)
{
sptr<ISystemAbilityManager> serviceManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (serviceManager == nullptr) {
printf("serviceManager == nullptr");
ASSERT_NE(serviceManager, nullptr);
}
printf("ISystemAbilityManager ok \r\n");
sptr<IRemoteObject> abilityObjext = serviceManager->CheckSystemAbility(DFX_SYS_HIVIEW_ABILITY_ID);
if (abilityObjext == nullptr) {
printf("abilityObjext == nullptr");
ASSERT_NE(abilityObjext, nullptr);
}
printf("CheckSystemAbility ok \r\n");
auto hiviewSAProxy = new HiviewServiceAbilityProxy(abilityObjext);
if (hiviewSAProxy == nullptr) {
printf("hiviewSAProxy == nullptr");
ASSERT_NE(hiviewSAProxy, nullptr);
}
printf("end \r\n");
}
/* *
* @tc.name: CommonTest001
* @tc.desc: Check hidumper -s 1201.
* @tc.type: FUNC
* @tc.require: AR000FJLO2
*/
HWTEST_F(HiviewSATest, CommonTest002, testing::ext::TestSize.Level3)
{
printf("system(\"hidumper -s 1201\") \r\n");
char buffer[256];
FILE* fp = popen("hidumper -s 1201", "r");
if (fp != nullptr) {
fgets(buffer, sizeof(buffer), fp);
printf("%s", buffer);
pclose(fp);
std::string str(buffer);
if (str.find("Error") != std::string::npos) {
printf("hidumper -s 1201 fail!\r\n");
FAIL();
}
} else {
printf("popen fail!\r\n");
FAIL();
}
}
}
}

View File

@ -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.
*/
#ifndef HIVIEW_SERVICE_SA_TEST_H
#define HIVIEW_SERVICE_SA_TEST_H
#include <gtest/gtest.h>
namespace OHOS {
namespace HiviewDFX {
class HiviewSATest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp();
void TearDown();
};
} // namespace HiviewDFX
} // namespace OHOS
#endif // HIVIEW_SERVICE_SA_TEST_H

44
adapter/sql/BUILD.gn Normal file
View File

@ -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.
import("//base/hiviewdfx/hiview/hiview.gni")
import("//build/ohos.gni")
config("hiview_sqlhelper_config") {
visibility = [ "*:*" ]
include_dirs = [
"//third_party/sqlite/include",
"include",
]
}
ohos_source_set("hiview_sqlhelper") {
public_configs = [ ":hiview_sqlhelper_config" ]
sources = [
"simple_database_helper.cpp",
"sql_common.cpp",
"sql_database.cpp",
"sql_field.cpp",
"sql_operator.cpp",
"sql_record.cpp",
"sql_table.cpp",
"sql_value.cpp",
]
deps = [
"$hiview_base:hiviewbase",
"//third_party/sqlite:libsqlite",
"//utils/native/base:utils",
]
}

View File

@ -0,0 +1,43 @@
/*
* 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 SIMPLE_DATABASE_HELPER_H
#define SIMPLE_DATABASE_HELPER_H
#include <string>
#include "sql_helper.h"
namespace OHOS {
namespace HiviewDFX {
class SimpleDatabaseHelper {
public:
bool CreateTable(sql::SqlTable& sqlTable);
bool RemoveTable(sql::SqlTable& sqlTable);
bool TruncateTable(sql::SqlTable& sqlTable);
bool CreateInfoOnTable(sql::SqlTable& sqlTable, const std::string& infoSql);
size_t GetRecordCountByFullSql(sql::SqlTable& sqlTable, const std::string& infoSql);
sql::SqlValue* GetFieldValueByIndex(
sql::SqlTable& sqlTable, size_t index, size_t recordCount, const std::string& fieldName);
sql::SqlValue* GetFieldValueByRecord(sql::SqlRecord& sqlRecord, const std::string& fieldName);
sql::SqlRecord* GetRecordByKeyId(sql::SqlTable& sqlTable, int keyId);
size_t GetRecordCount(sql::SqlTable& sqlTable, const std::string& querySql);
bool AddRecord(sql::SqlTable& sqlTable, sql::SqlRecord& sqlRecord);
bool UpdateRecord(sql::SqlTable& sqlTable, sql::SqlRecord& sqlRecord);
bool DeleteRecord(sql::SqlTable& sqlTable, const std::string& deleteSql);
};
} // namespace HiviewDFX
} // namespace OHOS
#endif

View File

@ -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.
*/
#ifndef SQL_COMMON_H
#define SQL_COMMON_H
#include <string>
#include <vector>
#include <map>
#include <cstdio>
#include <ctime>
namespace sql {
using std::string;
enum FieldType {
TYPE_UNDEFINED,
TYPE_INT,
TYPE_TEXT,
TYPE_FLOAT,
};
enum FieldFlag {
FIELD_NONE = 0,
FIELD_NOT_NULL = 1,
FIELD_NULL = 2,
FIELD_PRIMARY_KEY = 3,
FIELD_NOT_PRIMARY_KEY = 4,
};
enum FieldUse {
FIELD_DEFAULT = 0,
FIELD_END = 1,
};
const int INVALID_INDEX = -1;
using Integer = long long int;
string IntToStr(int value);
string IntegerToStr(Integer value);
string QuoteStr(string value);
string& TrimLeft(string& str);
string& TrimRight(string& str);
string& Trim(string& str);
string Trim(const string& str);
struct Sqlite3Db;
char* Sqlite3Snprintf(int n, char *buf, const char *format, ...);
}; // namespace sql
#endif

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SQL_DATABASE_H
#define SQL_DATABASE_H
#include "sql_common.h"
namespace sql {
using std::string;
struct Sqlite3Db;
class SqlDatabase {
public:
SqlDatabase(void);
virtual ~SqlDatabase(void);
const Sqlite3Db& GetHandle();
bool Open(string fileName);
void Close();
bool IsOpen();
bool BeginTransaction();
bool CommitTransaction();
private:
Sqlite3Db* db;
string errMsg;
int dbStatus;
};
} // namespace sql
#endif

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SQL_FIELD_H
#define SQL_FIELD_H
#include "sql_common.h"
namespace sql {
using std::string;
class SqlField {
public:
SqlField(string name, FieldType type, FieldFlag isPrimaryKey, FieldFlag isNull);
SqlField(string name, FieldType type);
SqlField(const SqlField& value);
SqlField(FieldUse isEndingField);
virtual ~SqlField(void){};
public:
string GetName() const;
size_t GetIndex();
void setIndex(size_t index);
FieldType GetType();
string GetTypeStr();
bool IsPrimaryKey();
bool IsNull();
string GetDefinition();
bool IsEndingField();
private:
string name;
FieldType type;
bool isPrimaryKey;
bool isNull;
size_t index;
bool isEndingField;
};
} // namespace sql
#endif

View File

@ -0,0 +1,25 @@
/*
* 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 SQL_HELPER_H
#define SQL_HELPER_H
#include "sql_common.h"
#include "sql_database.h"
#include "sql_table.h"
#include "sql_field.h"
#include "sql_record.h"
#include "sql_value.h"
#endif /* SQL_HELPER_H */

View File

@ -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.
*/
#ifndef SQL_OPERATOR_H
#define SQL_OPERATOR_H
#include "sql_record.h"
namespace sql {
using std::string;
struct Sqlite3Db;
class SqlOperator {
public:
SqlOperator(const Sqlite3Db& db);
SqlOperator(const Sqlite3Db& db, std::vector<SqlField*>& fieldsVector, std::map<string, SqlField*>& fieldsMap);
virtual ~SqlOperator(void);
public:
bool IsOk();
bool Execute(string sql);
bool ExecuteNoCallback(string sql);
void Clear();
public:
size_t GetCount();
SqlRecord* GetRecord(size_t index);
SqlRecord* GetTopRecord();
SqlValue* GetTopRecordFirstValue();
private:
enum {
DATASET_ITERATION_CONTINUE = 0,
DATASET_ITERATION_ABORT = 1,
};
private:
const Sqlite3Db& db;
string errMsg;
int execResult;
std::vector<SqlField*>* fieldsVector;
std::map<string, SqlField*>* fieldsMap;
std::vector<SqlRecord> records;
private:
// this is callback function for sqlite3_exec, so must use void* param.
static int LoadRecord(void* param, int columnCount, char** values, char** columnNames);
};
}; // namespace sql
#endif

View File

@ -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 SQL_RECORD_H
#define SQL_RECORD_H
#include "sql_value.h"
#include "sql_field.h"
namespace sql {
using std::string;
class SqlRecord {
public:
SqlRecord(const std::map<string, SqlField*>& fields);
SqlRecord(const SqlRecord& record);
void InitColumnCount(size_t columns);
void InitColumnValue(size_t index, string& value, FieldType type);
virtual ~SqlRecord()
{
fields = nullptr;
}
public:
size_t GetColumnCount();
SqlValue* GetValue(size_t index);
SqlValue* GetValue(string fieldName);
SqlValue* GetValue(const SqlField& field);
SqlField* GetFieldByName(string fieldName);
string ToSql(std::vector<SqlField*>& sqlFieldVector);
public:
void SetNull(size_t index);
void SetString(size_t index, string value);
void SetInteger(size_t index, Integer value);
void SetDouble(size_t index, double value);
public:
void SetNull(string fieldName);
void SetString(string fieldName, string value);
void SetString(string fieldName, string value, int length);
void SetInteger(string fieldName, Integer value);
void SetDouble(string fieldName, double value);
public:
void SetNull(SqlField& field);
void SetString(SqlField& field, string value);
void SetInteger(SqlField& field, Integer value);
void SetDouble(SqlField& field, double value);
private:
const std::map<string, SqlField*>* fields;
std::vector<SqlValue> values;
};
}; // namespace sql
#endif

View File

@ -0,0 +1,69 @@
/*
* 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 SQL_TABLE_H
#define SQL_TABLE_H
#include "sql_operator.h"
namespace sql {
using std::string;
struct Sqlite3Db;
class SqlTable {
public:
SqlTable(const Sqlite3Db& db, string tableName, SqlField definition[], size_t length);
virtual ~SqlTable(){};
public:
string GetName();
string GetDefinition();
string GetFieldsDefinition();
void InitFields(SqlField definition[], size_t length);
const std::map<string, SqlField*>& GetFields();
string GetFieldsString();
public:
bool Create();
bool Exists();
bool Remove();
public:
bool Open();
bool Open(string whereCondition);
int GetTotalRecordCount();
public:
size_t GetRecordCount();
SqlRecord* GetRecord(size_t recordIndex);
SqlRecord* GetTopRecord();
SqlRecord* GetRecordByKeyId(Integer keyId);
public:
bool Query(string sql);
string GetAddString(SqlRecord& record);
bool AddRecord(SqlRecord& record);
string GetUpdateString(SqlRecord& record);
bool UpdateRecord(SqlRecord& record);
bool DeleteRecords(string whereCondition);
bool Truncate();
private:
string tableName;
SqlOperator sqlOperator;
std::vector<SqlField*> sqlFieldVector;
std::map<string, SqlField*> sqlFieldMap;
};
}; // namespace sql
#endif

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SQL_VALUE_H
#define SQL_VALUE_H
#include "sql_common.h"
namespace sql {
using std::string;
class SqlValue {
public:
SqlValue();
SqlValue(const string& value, FieldType type);
SqlValue(const SqlValue& value);
SqlValue& operator=(const SqlValue& value);
string ToSql(FieldType type);
virtual ~SqlValue(){};
public:
string AsString();
Integer AsInteger();
double AsDouble();
public:
void SetNull();
void SetString(string value);
void SetInteger(Integer value);
void SetDouble(double value);
public:
bool IsNull();
void SetValue(const string& value, FieldType type);
static SqlValue sql;
private:
string value;
bool isNull;
FieldType type;
};
}; // namespace sql
#endif

View File

@ -0,0 +1,99 @@
/*
* 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 "simple_database_helper.h"
namespace OHOS {
namespace HiviewDFX {
bool SimpleDatabaseHelper::CreateTable(sql::SqlTable& sqlTable)
{
return sqlTable.Create();
}
bool SimpleDatabaseHelper::RemoveTable(sql::SqlTable& sqlTable)
{
return sqlTable.Remove();
}
bool SimpleDatabaseHelper::TruncateTable(sql::SqlTable& sqlTable)
{
return sqlTable.Truncate();
}
bool SimpleDatabaseHelper::CreateInfoOnTable(sql::SqlTable& sqlTable, const std::string& infoSql)
{
return sqlTable.Query(infoSql);
}
size_t SimpleDatabaseHelper::GetRecordCountByFullSql(sql::SqlTable& sqlTable, const std::string& infoSql)
{
if (infoSql.empty()) {
return -1;
}
sqlTable.Query(infoSql);
return sqlTable.GetRecordCount();
}
sql::SqlValue* SimpleDatabaseHelper::GetFieldValueByIndex(
sql::SqlTable& sqlTable, size_t index, size_t recordCount, const std::string& fieldName)
{
if (index >= recordCount) {
return nullptr;
}
sql::SqlRecord* record = sqlTable.GetRecord(index);
if (record != nullptr) {
sql::SqlValue* value = record->GetValue(fieldName);
return value;
}
return nullptr;
}
sql::SqlValue* SimpleDatabaseHelper::GetFieldValueByRecord(sql::SqlRecord& sqlRecord, const std::string& fieldName)
{
sql::SqlValue* value = sqlRecord.GetValue(fieldName);
return value;
}
sql::SqlRecord* SimpleDatabaseHelper::GetRecordByKeyId(sql::SqlTable& sqlTable, int keyId)
{
sql::SqlRecord* record = sqlTable.GetRecordByKeyId(keyId);
return record;
}
size_t SimpleDatabaseHelper::GetRecordCount(sql::SqlTable& sqlTable, const std::string& querySql)
{
if (querySql.empty()) {
sqlTable.Open();
} else {
sqlTable.Open(querySql);
}
return sqlTable.GetRecordCount();
}
bool SimpleDatabaseHelper::AddRecord(sql::SqlTable& sqlTable, sql::SqlRecord& sqlRecord)
{
return sqlTable.AddRecord(sqlRecord);
}
bool SimpleDatabaseHelper::UpdateRecord(sql::SqlTable& sqlTable, sql::SqlRecord& sqlRecord)
{
return sqlTable.UpdateRecord(sqlRecord);
}
bool SimpleDatabaseHelper::DeleteRecord(sql::SqlTable& sqlTable, const std::string& deleteSql)
{
return sqlTable.DeleteRecords(deleteSql);
}
} // namespace HiviewDFX
} // namespace OHOS

View File

@ -0,0 +1,99 @@
/*
* 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 "sql_common.h"
#include <securec.h>
#include <sstream>
#include <string>
#include "sql_wrapper.h"
using namespace std;
namespace {
const int INT_TO_STR_BUFF = 32;
const int INTEGER_TO_STR_BUFF = 64;
} // namespace
namespace sql {
string IntToStr(int value)
{
char buffer[INT_TO_STR_BUFF];
sprintf_s(buffer, sizeof(buffer), "%d", value);
return buffer;
}
string IntegerToStr(Integer value)
{
char buffer[INTEGER_TO_STR_BUFF];
sprintf_s(buffer, sizeof(buffer), "%lld", value);
return buffer;
}
string QuoteStr(string value)
{
std::ostringstream str;
for (string::iterator iter = value.begin(); iter != value.end(); ++iter) {
if (*iter == '\'') {
str << *iter;
}
str << *iter;
}
return str.str();
}
string& TrimLeft(string& str)
{
str.erase(str.begin(), std::find_if(str.begin(), str.end(),
[](unsigned char ch) {
return !std::isspace(ch);
}));
return str;
}
string& TrimRight(string& str)
{
str.erase(std::find_if(str.rbegin(), str.rend(),
[](unsigned char ch) {
return !std::isspace(ch);
}).base(),
str.end());
return str;
}
string& Trim(string& str)
{
TrimLeft(str);
TrimRight(str);
return str;
}
string Trim(const string& str)
{
string trimStr = str;
return Trim(trimStr);
}
char* Sqlite3Snprintf(int n, char *buf, const char *format, ...)
{
char *str = nullptr;
va_list ap;
va_start(ap, format);
str = sqlite3_vsnprintf(n, buf, format, ap);
va_end(ap);
return str;
}
}; // namespace sql

View File

@ -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 "sql_database.h"
#include "logger.h"
#include "sql_operator.h"
#include "sql_wrapper.h"
using namespace std;
namespace sql {
DEFINE_LOG_TAG("HiView-SqlDatabase");
SqlDatabase::SqlDatabase(void)
{
db = new Sqlite3Db();
db->rawdb = nullptr;
dbStatus = SQLITE_ERROR;
Close();
}
SqlDatabase::~SqlDatabase(void)
{
Close();
delete db;
db = nullptr;
}
const Sqlite3Db& SqlDatabase::GetHandle()
{
return *db;
}
void SqlDatabase::Close()
{
if (db->rawdb) {
sqlite3_close(db->rawdb);
db->rawdb = nullptr;
errMsg.clear();
dbStatus = SQLITE_ERROR;
}
}
bool SqlDatabase::IsOpen()
{
return (dbStatus == SQLITE_OK);
}
bool SqlDatabase::Open(std::string fileName)
{
Close();
sqlite3_config(SQLITE_CONFIG_SMALL_MALLOC, true); // set small malloc config
sqlite3_soft_heap_limit64(100 * 1024); // set soft heap limit as 100 * 1024B = 100KB
dbStatus = sqlite3_open(fileName.c_str(), &(db->rawdb));
if (IsOpen()) {
// set cache size as 10 pages
int retCode = sqlite3_exec(db->rawdb, "PRAGMA cache_size=10;", nullptr, nullptr, nullptr);
if (retCode != SQLITE_OK) {
HIVIEW_LOGE("Failed(%d) to set cache size by %s", retCode, fileName.c_str());
}
// set normal synchronous
retCode = sqlite3_exec(db->rawdb, "PRAGMA synchronous=1;", nullptr, nullptr, nullptr);
if (retCode != SQLITE_OK) {
HIVIEW_LOGE("Failed(%d) to set synchronous by %s", retCode, fileName.c_str());
}
return true;
} else {
errMsg = sqlite3_errmsg(db->rawdb);
HIVIEW_LOGI("open db:%s failed, error msg is :%s", fileName.c_str(), errMsg.c_str());
return false;
}
}
bool SqlDatabase::BeginTransaction()
{
SqlOperator sqlOperator(*db);
return sqlOperator.ExecuteNoCallback("BEGIN TRANSACTION");
}
bool SqlDatabase::CommitTransaction()
{
SqlOperator sqlOperator(*db);
return sqlOperator.ExecuteNoCallback("COMMIT TRANSACTION");
}
}; // namespace sql

120
adapter/sql/sql_field.cpp Normal file
View File

@ -0,0 +1,120 @@
/*
* 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 "sql_field.h"
using namespace std;
namespace sql {
SqlField::SqlField(string name, FieldType type, FieldFlag isPrimaryKey, FieldFlag isNull)
{
this->name = name;
this->type = type;
this->isPrimaryKey = (isPrimaryKey == FIELD_PRIMARY_KEY);
this->isNull = (isNull != FIELD_NOT_NULL);
this->index = INVALID_INDEX;
this->isEndingField = false;
}
SqlField::SqlField(string name, FieldType type)
{
this->name = name;
this->type = type;
this->isPrimaryKey = false;
this->isNull = true;
this->index = INVALID_INDEX;
this->isEndingField = false;
}
SqlField::SqlField(const SqlField& value)
{
this->name = value.name;
this->type = value.type;
this->isPrimaryKey = value.isPrimaryKey;
this->isNull = value.isNull;
this->index = value.index;
this->isEndingField = value.isEndingField;
}
SqlField::SqlField(FieldUse isEndingField)
{
this->name = "";
this->type = TYPE_UNDEFINED;
this->isPrimaryKey = false;
this->isNull = true;
this->index = INVALID_INDEX;
this->isEndingField = (isEndingField == FIELD_END) ? true : false;
}
string SqlField::GetName() const
{
return name;
}
size_t SqlField::GetIndex()
{
return index;
}
void SqlField::setIndex(size_t index)
{
this->index = index;
}
FieldType SqlField::GetType()
{
return type;
}
string SqlField::GetTypeStr()
{
switch (type) {
case TYPE_INT:
return "INTEGER";
case TYPE_TEXT:
return "TEXT";
case TYPE_FLOAT:
return "REAL";
default:
return "";
}
}
bool SqlField::IsPrimaryKey()
{
return isPrimaryKey;
}
bool SqlField::IsNull()
{
return isNull;
}
string SqlField::GetDefinition()
{
string value = name + " " + GetTypeStr();
if (IsPrimaryKey()) {
value += " PRIMARY KEY";
}
if (!IsNull()) {
value += " NOT NULL";
}
return TrimLeft(value);
}
bool SqlField::IsEndingField()
{
return isEndingField;
}
}; // namespace sql

View File

@ -0,0 +1,177 @@
/*
* 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 "sql_operator.h"
#include "defines.h"
#include "logger.h"
#include "sql_wrapper.h"
using namespace std;
namespace sql {
DEFINE_LOG_TAG("HiView-SqlOperator");
SqlOperator::SqlOperator(const Sqlite3Db& indb): db(indb)
{
errMsg.clear();
execResult = SQLITE_ERROR;
fieldsVector = nullptr;
fieldsMap = nullptr;
records.clear();
}
SqlOperator::SqlOperator(const Sqlite3Db& indb, std::vector<SqlField*>& fieldsVector,
std::map<string, SqlField*>& fieldsMap)
: db(indb), fieldsVector(&fieldsVector), fieldsMap(&fieldsMap)
{
errMsg.clear();
execResult = SQLITE_ERROR;
records.clear();
}
size_t SqlOperator::GetCount()
{
return records.size();
}
SqlOperator::~SqlOperator(void)
{
Clear();
}
void SqlOperator::Clear()
{
errMsg.clear();
execResult = SQLITE_ERROR;
records.clear();
}
bool SqlOperator::IsOk()
{
return (execResult == SQLITE_OK);
}
int SqlOperator::LoadRecord(void* param, int columnCount, char** values, char** columnNames __UNUSED)
{
SqlOperator* oprt = reinterpret_cast<SqlOperator*>(param);
if ((oprt != nullptr) && (oprt->fieldsVector != nullptr) && values != nullptr) {
size_t count = oprt->fieldsVector->size();
SqlRecord record(*(oprt->fieldsMap));
record.InitColumnCount(columnCount);
for (size_t index = 0; (index < static_cast<size_t>(columnCount)) && (index < count); index++) {
string value = "";
if (values[index] != nullptr) {
value = values[index];
}
if (SqlField* field = oprt->fieldsVector->at(index)) {
record.InitColumnValue(index, value, field->GetType());
}
}
oprt->records.push_back(record);
}
return DATASET_ITERATION_CONTINUE;
}
bool SqlOperator::Execute(string sql)
{
Clear();
if (db.rawdb == nullptr) {
HIVIEW_LOGE("Execute db is null");
return false;
}
char* error = nullptr;
execResult = sqlite3_exec(const_cast<sqlite3*>(db.rawdb), sql.c_str(), LoadRecord, this, &error);
if (IsOk()) {
return true;
}
if (error == nullptr) {
errMsg = "";
HIVIEW_LOGE("Execute error returns null");
return false;
}
if (*error) {
errMsg = error;
sqlite3_free(error);
HIVIEW_LOGE("Execute sql failed: %s", errMsg.c_str());
}
return false;
}
bool SqlOperator::ExecuteNoCallback(string sql)
{
Clear();
if (db.rawdb == nullptr) {
HIVIEW_LOGE("ExecuteNoCallback db is null");
return false;
}
char* error = nullptr;
execResult = sqlite3_exec(const_cast<sqlite3*>(db.rawdb), sql.c_str(), NULL, NULL, &error);
if (IsOk()) {
return true;
}
if (error == nullptr) {
errMsg = "";
HIVIEW_LOGE("ExecuteNoCallback error returns null");
return false;
}
if (*error) {
errMsg = error;
sqlite3_free(error);
HIVIEW_LOGE("ExecuteNoCallback sql failed: %s", errMsg.c_str());
}
return false;
}
SqlRecord* SqlOperator::GetRecord(size_t index)
{
if (index < records.size()) {
return &records.at(index);
}
return nullptr;
}
SqlRecord* SqlOperator::GetTopRecord()
{
if (IsOk()) {
return GetRecord(0);
}
return nullptr;
}
SqlValue* SqlOperator::GetTopRecordFirstValue()
{
if (IsOk()) {
if (SqlRecord* record = GetRecord(0)) {
return record->GetValue(0);
}
}
return nullptr;
}
}; // namespace sql

204
adapter/sql/sql_record.cpp Normal file
View File

@ -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 "sql_record.h"
#include "defines.h"
using namespace std;
namespace sql {
SqlRecord::SqlRecord(const std::map<string, SqlField*>& fields) : fields(&fields)
{
InitColumnCount(fields.size());
}
SqlRecord::SqlRecord(const SqlRecord& record) : fields(record.fields)
{
if (fields != nullptr) {
InitColumnCount(fields->size());
values = record.values;
}
}
void SqlRecord::InitColumnCount(size_t columns)
{
values.resize(columns);
}
void SqlRecord::InitColumnValue(size_t index, string& value, FieldType type)
{
values[index].SetValue(value, type);
}
size_t SqlRecord::GetColumnCount()
{
return values.size();
}
SqlValue* SqlRecord::GetValue(size_t index)
{
if ((index >= 0) && (index < values.size())) {
return &values.at(index);
}
return nullptr;
}
SqlValue* SqlRecord::GetValue(string fieldName)
{
if (fields == nullptr) {
return nullptr;
}
std::map<string, SqlField*>::const_iterator iter = fields->find(fieldName);
if (iter != fields->end()) {
SqlField* field = iter->second;
if (field != nullptr) {
return GetValue(field->GetIndex());
}
}
return nullptr;
}
SqlValue* SqlRecord::GetValue(const SqlField& field)
{
return GetValue(field.GetName());
}
string SqlRecord::ToSql(std::vector<SqlField*>& sqlFieldVector)
{
if (sqlFieldVector.empty()) {
return "";
}
string str;
size_t count = sqlFieldVector.size();
SqlField* field = nullptr;
SqlValue* value = nullptr;
for (size_t index = 0; index < count; index++) {
field = sqlFieldVector[index];
if (field == nullptr) {
continue;
}
value = GetValue(field->GetName());
if (value == nullptr) {
continue;
}
str += value->ToSql(field->GetType());
if (index < (count - 1)) {
str += ", ";
}
}
return str;
}
void SqlRecord::SetNull(size_t index)
{
if (SqlValue* value = GetValue(index)) {
value->SetNull();
}
}
void SqlRecord::SetString(size_t index, string value)
{
if (SqlValue* sqlValue = GetValue(index)) {
sqlValue->SetString(value);
}
}
void SqlRecord::SetInteger(size_t index, Integer value)
{
if (SqlValue* sqlValue = GetValue(index)) {
sqlValue->SetInteger(value);
}
}
void SqlRecord::SetDouble(size_t index, double value)
{
if (SqlValue* sqlValue = GetValue(index)) {
sqlValue->SetDouble(value);
}
}
SqlField* SqlRecord::GetFieldByName(string fieldName)
{
if (fields == nullptr) {
return nullptr;
}
std::map<string, SqlField*>::const_iterator iter = fields->find(fieldName);
if (iter != fields->end()) {
SqlField* field = iter->second;
return field;
}
return nullptr;
}
void SqlRecord::SetNull(string fieldName)
{
if (SqlField* field = GetFieldByName(fieldName)) {
SetNull(field->GetIndex());
}
}
void SqlRecord::SetString(string fieldName, string value)
{
if (SqlField* field = GetFieldByName(fieldName)) {
SetString(field->GetIndex(), value);
}
}
void SqlRecord::SetString(string fieldName, string value, int length __UNUSED)
{
if (SqlField* field = GetFieldByName(fieldName)) {
SetString(field->GetIndex(), value);
}
}
void SqlRecord::SetInteger(string fieldName, Integer value)
{
if (SqlField* field = GetFieldByName(fieldName)) {
SetInteger(field->GetIndex(), value);
}
}
void SqlRecord::SetDouble(string fieldName, double value)
{
if (SqlField* field = GetFieldByName(fieldName)) {
SetDouble(field->GetIndex(), value);
}
}
void SqlRecord::SetNull(SqlField& field)
{
SetNull(field.GetName());
}
void SqlRecord::SetString(SqlField& field, string value)
{
SetString(field.GetName(), value);
}
void SqlRecord::SetInteger(SqlField& field, Integer value)
{
SetInteger(field.GetName(), value);
}
void SqlRecord::SetDouble(SqlField& field, double value)
{
SetDouble(field.GetName(), value);
}
}; // namespace sql

257
adapter/sql/sql_table.cpp Normal file
View File

@ -0,0 +1,257 @@
/*
* 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 "sql_table.h"
#include "logger.h"
#include "sql_wrapper.h"
using namespace std;
namespace sql {
SqlTable::SqlTable(const Sqlite3Db& db, string tableName, SqlField definition[], size_t length)
: tableName(tableName), sqlOperator(db, sqlFieldVector, sqlFieldMap)
{
InitFields(definition, length);
}
string SqlTable::GetName()
{
return tableName;
}
string SqlTable::GetDefinition()
{
return "CREATE TABLE " + tableName + " (" + GetFieldsDefinition() + ")";
}
void SqlTable::InitFields(SqlField definition[], size_t length)
{
if (definition) {
size_t index = 0;
while (index < length) {
SqlField& field = definition[index];
if (field.IsEndingField()) {
break;
}
field.setIndex(index);
sqlFieldVector.push_back(&field);
sqlFieldMap[field.GetName()] = &field;
index++;
}
}
}
const std::map<string, SqlField*>& SqlTable::GetFields()
{
return sqlFieldMap;
}
string SqlTable::GetFieldsDefinition()
{
string fieldsDef = "";
size_t count = sqlFieldVector.size();
for (size_t index = 0; index < count; index++) {
SqlField* field = sqlFieldVector[index];
fieldsDef += field->GetDefinition();
if (index < (count - 1)) {
fieldsDef += ", ";
}
}
return fieldsDef;
}
string SqlTable::GetFieldsString()
{
string fieldsStr = "";
size_t count = sqlFieldVector.size();
for (size_t index = 0; index < count; index++) {
SqlField* field = sqlFieldVector[index];
fieldsStr += field->GetName();
if (index < (count - 1)) {
fieldsStr += ", ";
}
}
return fieldsStr;
}
bool SqlTable::Create()
{
if (Exists()) {
return true;
}
const string sql = GetDefinition();
return sqlOperator.ExecuteNoCallback(sql);
}
bool SqlTable::Remove()
{
if (!Exists()) {
return true;
}
const string sql = "drop table " + tableName;
if (sqlOperator.ExecuteNoCallback(sql)) {
return true;
}
return false;
}
bool SqlTable::Exists()
{
const string sql = "select count(*) from sqlite_master where type = 'table' and name = '" + tableName + "'";
if (sqlOperator.Execute(sql)) {
if (SqlValue* value = sqlOperator.GetTopRecordFirstValue()) {
return (value->AsInteger() > 0);
}
}
return false;
}
bool SqlTable::Open()
{
if (!Exists()) {
return false;
}
const string sql = "select * from " + tableName;
if (sqlOperator.Execute(sql)) {
return true;
}
return false;
}
bool SqlTable::Open(string whereCondition)
{
if (!Exists()) {
return false;
}
const string sql = "select * from " + tableName + (whereCondition.empty() ? "" : (" where " + whereCondition));
return sqlOperator.Execute(sql);
}
bool SqlTable::Query(string sql)
{
return sqlOperator.Execute(sql);
}
bool SqlTable::DeleteRecords(string whereCondition)
{
if (!Exists()) {
return false;
}
const string sql = "delete from " + tableName + (whereCondition.empty() ? "" : (" where " + whereCondition));
return sqlOperator.ExecuteNoCallback(sql);
}
bool SqlTable::Truncate()
{
if (!Exists()) {
return false;
}
const string sql = "delete from " + tableName;
return sqlOperator.ExecuteNoCallback(sql);
}
size_t SqlTable::GetRecordCount()
{
return sqlOperator.GetCount();
}
int SqlTable::GetTotalRecordCount()
{
const string sql = "select count(*) from " + tableName;
if (sqlOperator.Execute(sql)) {
if (SqlValue* value = sqlOperator.GetTopRecordFirstValue()) {
return static_cast<int>(value->AsInteger());
}
}
return -1;
}
SqlRecord* SqlTable::GetRecord(size_t index)
{
return sqlOperator.GetRecord(index);
}
SqlRecord* SqlTable::GetTopRecord()
{
return GetRecord(0);
}
SqlRecord* SqlTable::GetRecordByKeyId(Integer keyId)
{
if (!Exists()) {
return nullptr;
}
const string sql = "select * from " + tableName + " where _ID = " + IntegerToStr(keyId);
if (sqlOperator.Execute(sql)) {
if (sqlOperator.GetCount() > 0) {
return sqlOperator.GetRecord(0);
}
}
return nullptr;
}
string SqlTable::GetAddString(SqlRecord& record)
{
string str = "insert into " + tableName + " ";
str += "(" + GetFieldsString() + ")";
str += " values ";
str += "(" + record.ToSql(sqlFieldVector) + ")";
return str;
}
bool SqlTable::AddRecord(SqlRecord& record)
{
const string sql = GetAddString(record);
return sqlOperator.ExecuteNoCallback(sql);
}
string SqlTable::GetUpdateString(SqlRecord& record)
{
string str = "update " + tableName + " set ";
size_t count = sqlFieldVector.size();
SqlField* field = nullptr;
SqlValue* value = nullptr;
// ignore the _ID field
for (size_t index = 1; index < count; index++) {
field = sqlFieldVector[index];
if (field == nullptr) {
continue;
}
value = record.GetValue(field->GetName());
if (value == nullptr) {
continue;
}
str += field->GetName() + "=" + value->ToSql(field->GetType());
if (index < (count - 1)) {
str += ", ";
}
}
// get _ID field
field = sqlFieldVector[0];
if (field != nullptr) {
value = record.GetValue(field->GetName());
if (value != nullptr) {
str += " where _ID = " + value->ToSql(field->GetType());
}
}
return str;
}
bool SqlTable::UpdateRecord(SqlRecord& record)
{
const string sql = GetUpdateString(record);
return sqlOperator.ExecuteNoCallback(sql);
}
}; // namespace sql

142
adapter/sql/sql_value.cpp Normal file
View File

@ -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 "sql_value.h"
#include <securec.h>
using namespace std;
namespace {
const int MAX_BUFFER_LEN = 128;
}
namespace sql {
SqlValue::SqlValue()
{
SetValue("", TYPE_UNDEFINED);
}
SqlValue::SqlValue(const string& value, FieldType type)
{
SetValue(value, type);
}
SqlValue::SqlValue(const SqlValue& value)
{
this->value = value.value;
this->isNull = value.isNull;
this->type = value.type;
}
SqlValue& SqlValue::operator=(const SqlValue& value)
{
if (&value != this) {
this->value = value.value;
this->isNull = value.isNull;
this->type = value.type;
}
return *this;
}
void SqlValue::SetValue(const string& value, FieldType type)
{
isNull = true;
this->value.clear();
this->type = type;
if (!value.empty()) {
isNull = false;
this->value = value;
this->type = type;
}
}
string SqlValue::ToSql(FieldType type)
{
if (IsNull()) {
return "null";
}
if (type == TYPE_TEXT) {
return "'" + QuoteStr(AsString()) + "'";
}
return AsString();
}
string SqlValue::AsString()
{
return value;
}
Integer SqlValue::AsInteger()
{
if (IsNull()) {
return 0;
}
long long tempValue = 0;
if (!sscanf_s(value.c_str(), "%lld", &tempValue)) {
return 0;
}
return tempValue;
}
double SqlValue::AsDouble()
{
if (IsNull()) {
return 0.0;
}
double tempValue = 0;
if (!sscanf_s(value.c_str(), "%lf", &tempValue)) {
return 0;
}
return tempValue;
}
void SqlValue::SetNull()
{
isNull = true;
value.clear();
}
void SqlValue::SetString(string tempValue)
{
isNull = false;
value = tempValue;
}
void SqlValue::SetInteger(Integer tempValue)
{
char buffer[MAX_BUFFER_LEN];
sprintf_s(buffer, sizeof(buffer), "%lld", tempValue);
isNull = false;
value = buffer;
}
void SqlValue::SetDouble(double tempValue)
{
char buffer[MAX_BUFFER_LEN];
sprintf_s(buffer, sizeof(buffer), "%0.8f", tempValue);
isNull = false;
value = buffer;
}
bool SqlValue::IsNull()
{
return isNull;
}
}; // namespace sql

27
adapter/sql/sql_wrapper.h Normal file
View File

@ -0,0 +1,27 @@
/*
* 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 ENGINE_OAL_SQLITE_WRAPPER_H
#define ENGINE_OAL_SQLITE_WRAPPER_H
#if defined(__HIVIEW_LITE__)
#include <sqlite3.h>
#else
#include <sqlite3sym.h>
#endif
namespace sql {
struct Sqlite3Db {
sqlite3* rawdb;
};
}; // namespace sql
#endif // ENGINE_OAL_SQLITE_WRAPPER_H

View File

@ -0,0 +1,36 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//base/hiviewdfx/hiview/hiview.gni")
import("//build/ohos.gni")
config("system_service_config") {
visibility = [ "*:*" ]
include_dirs = [
"//utils/native/base/include",
"include",
]
}
ohos_source_set("system_service") {
public_configs = [ ":system_service_config" ]
sources = [
"parameter.cpp",
"platform/ohos/parameter.cpp",
]
deps = [ "//utils/native/base:utils" ]
external_deps = [ "startup_l2:syspara" ]
}

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HIVIEW_OAL_SYSTEM_PROPERTY_H
#define HIVIEW_OAL_SYSTEM_PROPERTY_H
#include <cstdint>
#include <string>
namespace OHOS {
namespace HiviewDFX {
constexpr char KEY_BUILD_CHARACTER[] = "ro.build.characteristics";
constexpr char KEY_HIVIEW_USER_TYPE[] = "ro.logsystem.usertype";
namespace Parameter {
enum UserType {
COMMERCIAL = 1,
FANS,
BETA,
TEST,
OVERSEAS_BETA,
OVERSEAS_COMMERCIAL,
};
enum DeviceType {
UNKNOWN = 0,
PHONE,
WATCH,
TV,
IVI,
};
std::string GetString(const std::string& key, const std::string& defaultValue);
int64_t GetInteger(const std::string& key, const int64_t defaultValue);
uint64_t GetUnsignedInteger(const std::string& key, const uint64_t defaultValue);
bool GetBoolean(const std::string& key, const bool defaultValue);
bool SetProperty(const std::string& key, const std::string& defaultValue);
bool IsBetaVersion();
DeviceType GetDeviceType();
};
} // namespace HiviewDFX
} // namespace OHOS
#endif // HIVIEW_OAL_SYSTEM_PROPERTY_H

View File

@ -0,0 +1,43 @@
/*
* 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 "parameter.h"
#include <cstdint>
namespace OHOS {
namespace HiviewDFX {
namespace Parameter {
bool IsBetaVersion()
{
auto userType = GetInteger(KEY_HIVIEW_USER_TYPE, UserType::COMMERCIAL);
return ((userType == UserType::BETA) || (userType == UserType::OVERSEAS_BETA));
}
DeviceType GetDeviceType()
{
std::string deviceType = GetString(KEY_BUILD_CHARACTER, "unknown");
if (deviceType == "phone" || deviceType == "default") {
return DeviceType::PHONE;
} else if (deviceType == "watch") {
return DeviceType::WATCH;
} else if (deviceType == "tv") {
return DeviceType::TV;
} else if (deviceType == "car") {
return DeviceType::IVI;
} else {
return DeviceType::UNKNOWN;
}
}
} // namespace Parameter
} // namespace HiviewDFX
} // namespace OHOS

View File

@ -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.
*/
#include "parameter.h"
#include <cstdint>
#include <parameters.h>
namespace OHOS {
namespace HiviewDFX {
namespace Parameter {
std::string GetString(const std::string& key, const std::string& defaultValue)
{
return OHOS::system::GetParameter(key, defaultValue);
}
int64_t GetInteger(const std::string& key, const int64_t defaultValue)
{
return OHOS::system::GetIntParameter(key, defaultValue);
}
uint64_t GetUnsignedInteger(const std::string& key, const uint64_t defaultValue)
{
return OHOS::system::GetUintParameter(key, defaultValue);
}
bool GetBoolean(const std::string& key, const bool defaultValue)
{
return OHOS::system::GetBoolParameter(key, defaultValue);
}
bool SetProperty(const std::string& key, const std::string& defaultValue)
{
return OHOS::system::SetParameter(key, defaultValue);
}
} // namespace Parameter
} // namespace HiviewDFX
} // namespace OHOS

49
adapter/utility/BUILD.gn Normal file
View File

@ -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/hiviewdfx/hiview/hiview.gni")
import("//build/ohos.gni")
config("hiview_adapter_utils_config") {
visibility = [ "*:*" ]
include_dirs = [
".",
"include",
"$hiview_adapter/system_service/include",
"//base/hiviewdfx/hilog/adapter"
]
}
ohos_source_set("hiview_adapter_utility") {
public_configs = [ ":hiview_adapter_utils_config" ]
sources = [
"dynamic_module.cpp",
"platform/ohos/common_utils.cpp",
"platform/ohos/file_util.cpp",
"platform/ohos/socket_util.cpp",
"platform/ohos/thread_util.cpp",
"platform/ohos/time_util.cpp",
"time_util.cpp",
]
deps = [
"$hiview_adapter/system_service:system_service",
"//utils/native/base:utils",
"//base/hiviewdfx/hilog/adapter:libhilog_os_adapter"
]
part_name = "hiview_L2"
subsystem_name = "hiviewdfx"
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
}

View File

@ -0,0 +1,33 @@
/*
* 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 "dynamic_module.h"
#include <string>
#include <dlfcn.h>
namespace OHOS {
namespace HiviewDFX {
DynamicModule LoadModule(const std::string &moduleName)
{
return dlopen(moduleName.c_str(), RTLD_GLOBAL);
}
void UnloadModule(DynamicModule module)
{
dlclose(module);
}
} // namespace HiviewDFX
} // namespace OHOS

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef UTILS_H
#define UTILS_H
#include <sys/stat.h>
#include <string>
#include "errors.h"
#include "file_util.h"
namespace OHOS {
namespace HiviewDFX {
static constexpr mode_t DEFAULT_FILE_MODE = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH; // -rw-rw-r--
static constexpr mode_t FILE_PERM_755 = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
static constexpr mode_t FILE_PERM_775 = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
static constexpr mode_t FILE_PERM_770 = S_IRWXU | S_IRWXG;
static constexpr uint32_t DEFAULT_DURATION_SECONDS = 60;
static constexpr uint32_t BUF_SIZE_64 = 64;
static constexpr uint32_t BUF_SIZE_128 = 128;
static constexpr uint32_t BUF_SIZE_256 = 256;
static constexpr uint32_t BUF_SIZE_512 = 512;
static constexpr uint32_t BUF_SIZE_4096 = 4096;
static constexpr uint64_t NS_PER_SECOND = 1000000000;
static constexpr uint32_t MAX_LINE_LEN = 1024;
namespace CommonUtils {
std::string GetProcNameByPid(int32_t pid);
pid_t GetPidByName(const std::string& processName);
};
} // namespace HiviewDFX
} // namespace OHOS
#endif

View File

@ -0,0 +1,32 @@
/*
* 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 HIVIEW_BASE_DEFINES_H
#define HIVIEW_BASE_DEFINES_H
#ifndef __UNUSED
#if defined(_MSC_VER)
#define __UNUSED // Note: actually gcc seems to also supports this syntax.
#else
#if defined(__GNUC__)
#define __UNUSED __attribute__ ((__unused__))
#endif
#endif
#endif
#define DllExport
#endif // HIVIEW_BASE_DEFINES_H

View File

@ -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 HIVIEW_OAL_DYNAMIC_MODULE_LINUX_H
#define HIVIEW_OAL_DYNAMIC_MODULE_LINUX_H
#include <string>
#include "defines.h"
namespace OHOS {
namespace HiviewDFX {
using DynamicModule = void *;
#define DynamicModuleDefault nullptr
DynamicModule LoadModule(const std::string &name);
void UnloadModule(DynamicModule module);
} // namespace HiviewDFX
} // namespace OHOS
#endif // HIVIEW_OAL_DYNAMIC_MODULE_H

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef UTILITY_FILE_UTIL_H
#define UTILITY_FILE_UTIL_H
#include <string>
#include <vector>
namespace OHOS {
namespace HiviewDFX {
namespace FileUtil {
// file_ex.h
bool LoadStringFromFile(const std::string& filePath, std::string& content);
bool SaveStringToFile(const std::string& filePath, const std::string& content, bool truncated = true);
bool SaveStringToFd(int fd, const std::string& content);
bool LoadBufferFromFile(const std::string& filePath, std::vector<char>& content);
bool SaveBufferToFile(const std::string& filePath, const std::vector<char>& content, bool truncated = true);
bool FileExists(const std::string& fileName);
bool FileExistsA(const std::string& fileName);
// directory_ex.h
std::string ExtractFilePath(const std::string& fileFullName);
std::string ExtractFileName(const std::string& fileFullName);
std::string IncludeTrailingPathDelimiter(const std::string& path);
std::string ExcludeTrailingPathDelimiter(const std::string& path);
void GetDirFiles(const std::string& path, std::vector<std::string>& files);
bool ForceCreateDirectory(const std::string& path);
bool ForceCreateDirectory(const std::string& path, int mode);
void RemoveFolderBeginWith(const std::string &path, const std::string &folderName);
bool ForceRemoveDirectory(const std::string& path, bool isNeedDeleteGivenDirSelf = true);
bool RemoveFile(const std::string& fileName);
uint64_t GetFolderSize(const std::string& path);
uint64_t GetFileSize(const std::string& path);
bool ChangeMode(const std::string& fileName, const mode_t& mode);
bool ChangeModeDirectory(const std::string& path, const mode_t& mode);
bool PathToRealPath(const std::string& path, std::string& realPath);
mode_t Umask(const mode_t& mode);
int Open(const std::string& path, const int flags, const mode_t mode);
void FormatPath2UnixStyle(std::string &path);
void CreateDirWithDefaultPerm(const std::string& path, uid_t aidRoot, uid_t aid_system);
} // namespace FileUtil
} // namespace HiviewDFX
} // namespace OHOS
#endif // UTILITY_FILE_UTIL_H

View File

@ -0,0 +1,25 @@
/*
* 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 SOCKET_UTIL_H
#define SOCKET_UTIL_H
namespace OHOS {
namespace HiviewDFX {
namespace SocketUtil {
int GetHiviewExistingSocketServer(const char *name, int type);
} // namespace SocketUtil
} // namespace HiviewDFX
} // namespace OHOS
#endif /* SOCKET_UTIL_H */

View File

@ -0,0 +1,28 @@
/*
* 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 UTILITY_THREAD_UTIL_H
#define UTILITY_THREAD_UTIL_H
#include <string>
namespace OHOS {
namespace HiviewDFX {
namespace Thread {
int GetTid();
void SetThreadDescription(const std::string &name);
}
} // namespace HiviewDFX
} // namespace OHOS
#endif // UTILITY_FILE_UTIL_H

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef UTILITY_TIME_UTIL_H
#define UTILITY_TIME_UTIL_H
#include <cstdint>
#include <string>
namespace OHOS {
namespace HiviewDFX {
namespace TimeUtil {
constexpr int64_t SEC_TO_NANOSEC = 1000000000;
constexpr int64_t SEC_TO_MICROSEC = 1000000;
constexpr int64_t SEC_TO_MILLISEC = 1000;
constexpr int64_t MILLISEC_TO_NANOSEC = 1000000;
constexpr int64_t MICROSEC_TO_NANOSEC = 1000;
constexpr int SECONDS_PER_HOUR = 3600; // 60 * 60
constexpr int SECONDS_PER_DAY = 86400; // 60 * 60 * 24
uint64_t GetNanoTime();
uint64_t GetTimeOfDay();
uint64_t GenerateTimestamp();
time_t StrToTimeStamp(const std::string &tmStr, const std::string& format);
std::string GetFormatTime(time_t time);
void Sleep(unsigned int seconds);
int GetMillSecOfSec();
} // namespace TimeUtil
} // namespace HiviewDFX
} // namespace OHOS
#endif // UTILITY_TIME_UTIL_H

View File

@ -0,0 +1,86 @@
/*
* 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 "common_utils.h"
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <cerrno>
#include <ctime>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include "securec.h"
using namespace std;
namespace OHOS {
namespace HiviewDFX {
namespace CommonUtils {
std::string GetProcNameByPid(pid_t pid)
{
std::string result;
char buf[BUF_SIZE_256] = {0};
// cmdline is empty ? use comm instead
snprintf_s(buf, BUF_SIZE_256, BUF_SIZE_256 - 1, "/proc/%d/comm", pid);
FileUtil::LoadStringFromFile(std::string(buf, strlen(buf)), result);
auto pos = result.find_last_not_of(" \n\r\t");
if (pos == std::string::npos) {
return result;
}
result.erase(pos + 1);
return result;
}
pid_t GetPidByName(const std::string& processName)
{
pid_t pid = -1;
DIR* dir = opendir("/proc");
if (dir == nullptr) {
return pid;
}
struct dirent* ptr = nullptr;
while ((ptr = readdir(dir)) != nullptr) {
if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) {
continue;
}
if (DT_DIR != ptr->d_type) {
continue;
}
std::string cmdlinePath = std::string("/proc/").append(ptr->d_name).append("/cmdline");
std::string curTaskName;
FileUtil::LoadStringFromFile(cmdlinePath, curTaskName);
if (curTaskName.find(processName) != std::string::npos) {
if (sscanf_s(ptr->d_name, "%d", &pid) <= 0) {
break;
}
}
}
closedir(dir);
return pid;
}
}
} // namespace HiviewDFX
} // namespace OHOS

View File

@ -0,0 +1,186 @@
/*
* 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 "file_util.h"
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <dirent.h>
#include <fcntl.h>
#include <fstream>
#include <iostream>
#include <iterator>
#include <pthread.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/syscall.h>
#include "directory_ex.h"
#include "file_ex.h"
namespace OHOS {
namespace HiviewDFX {
namespace FileUtil {
using namespace std;
bool LoadStringFromFile(const std::string& filePath, std::string& content)
{
return OHOS::LoadStringFromFile(filePath, content);
}
bool SaveStringToFile(const std::string& filePath, const std::string& content, bool truncated)
{
return OHOS::SaveStringToFile(filePath, content, truncated);
}
bool SaveStringToFd(int fd, const std::string& content)
{
return OHOS::SaveStringToFd(fd, content);
}
bool LoadBufferFromFile(const std::string& filePath, std::vector<char>& content)
{
return OHOS::LoadBufferFromFile(filePath, content);
}
bool SaveBufferToFile(const std::string& filePath, const std::vector<char>& content, bool truncated)
{
return OHOS::SaveBufferToFile(filePath, content, truncated);
}
bool FileExists(const std::string& fileName)
{
return OHOS::FileExists(fileName);
}
std::string ExtractFilePath(const std::string& fileFullName)
{
return OHOS::ExtractFilePath(fileFullName);
}
std::string ExtractFileName(const std::string& fileFullName)
{
return OHOS::ExtractFileName(fileFullName);
}
std::string IncludeTrailingPathDelimiter(const std::string& path)
{
return OHOS::IncludeTrailingPathDelimiter(path);
}
std::string ExcludeTrailingPathDelimiter(const std::string& path)
{
return OHOS::ExcludeTrailingPathDelimiter(path);
}
void GetDirFiles(const std::string& path, std::vector<std::string>& files)
{
return OHOS::GetDirFiles(path, files);
}
bool ForceCreateDirectory(const std::string& path)
{
return OHOS::ForceCreateDirectory(path);
}
bool ForceCreateDirectory(const string& path, int mode)
{
string::size_type index = 0;
do {
index = path.find('/', index + 1);
string subPath = (index == string::npos) ? path : path.substr(0, index);
if (access(subPath.c_str(), F_OK) != 0) {
if (mkdir(subPath.c_str(), mode) != 0) {
return false;
}
}
} while (index != string::npos);
return access(path.c_str(), F_OK) == 0;
}
bool ForceRemoveDirectory(const std::string& path, bool isNeedDeleteGivenDirSelf)
{
return OHOS::ForceRemoveDirectory(path);
}
uint64_t GetFileSize(const std::string& path)
{
struct stat st;
return stat(path.c_str(), &st) ? 0 : static_cast<uint64_t>(st.st_size);
}
bool RemoveFile(const std::string& fileName)
{
return OHOS::RemoveFile(fileName);
}
uint64_t GetFolderSize(const std::string& path)
{
return OHOS::GetFolderSize(path);
}
// inner function, and param is legitimate
bool ChangeMode(const string& fileName, const mode_t& mode)
{
return (chmod(fileName.c_str(), mode) == 0);
}
bool ChangeModeFile(const string& fileName, const mode_t& mode)
{
if (access(fileName.c_str(), F_OK) != 0) {
return false;
}
return ChangeMode(fileName, mode);
}
bool ChangeModeDirectory(const std::string& path, const mode_t& mode)
{
return OHOS::ChangeModeDirectory(path, mode);
}
bool PathToRealPath(const std::string& path, std::string& realPath)
{
return OHOS::PathToRealPath(path, realPath);
}
mode_t Umask(const mode_t& mode)
{
return umask(mode);
}
int Open(const std::string& path, const int flags, const mode_t mode)
{
return open(path.c_str(), flags, mode);
}
void CreateDirWithDefaultPerm(const std::string& path, uid_t aidRoot, uid_t aidSystem)
{
FileUtil::ForceCreateDirectory(path);
chown(path.c_str(), aidRoot, aidSystem);
}
void FormatPath2UnixStyle(std::string &path)
{
// unimplemented
}
void RemoveFolderBeginWith(const std::string &path, const std::string &folderName)
{
// unimplemented
}
} // namespace FileUtil
} // namespace HiviewDFX
} // namespace OHOS

View File

@ -0,0 +1,33 @@
/*
* 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 "socket_util.h"
#include "hilog/log.h"
#include "socket_server_adapter.h"
namespace OHOS {
namespace HiviewDFX {
namespace SocketUtil {
static constexpr HiLogLabel LABEL = { LOG_CORE, 0xD002D03, "HIVIEWSOCKET" };
int GetHiviewExistingSocketServer(const char *name, int type)
{
HiLog::Error(LABEL, "get socket");
return GetExistingSocketServer(name, type);
}
} // namespace SocketUtil
} // namespace HiviewDFX
} // namespace OHOS

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "thread_util.h"
#include <pthread.h>
#include <unistd.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/syscall.h>
namespace OHOS {
namespace HiviewDFX {
namespace Thread {
pid_t GetTid()
{
return gettid();
}
void SetThreadDescription(const std::string &name)
{
prctl(PR_SET_NAME, name.c_str());
}
}
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "time_util.h"
#include <sys/time.h>
#include <unistd.h>
#include <chrono>
namespace OHOS {
namespace HiviewDFX {
namespace TimeUtil {
uint64_t GenerateTimestamp()
{
struct timeval now;
if (gettimeofday(&now, nullptr) == -1) {
return 0;
}
return (now.tv_sec * SEC_TO_MICROSEC + now.tv_usec);
}
void Sleep(unsigned int seconds)
{
sleep(seconds);
}
int GetMillSecOfSec()
{
auto now = std::chrono::system_clock::now();
auto millisecs = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
return millisecs.count() % SEC_TO_MILLISEC;
}
} // namespace TimeUtil
} // namespace HiviewDFX
} // namespace OHOS

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "time_util.h"
#include <chrono>
#include <ctime>
namespace OHOS {
namespace HiviewDFX {
namespace TimeUtil {
time_t StrToTimeStamp(const std::string &tmStr, const std::string& format)
{
std::string stTime = tmStr;
struct tm tmFormat;
strptime(stTime.c_str(), format.c_str(), &tmFormat);
tmFormat.tm_isdst = -1;
return mktime(&tmFormat);
}
uint64_t GetNanoTime()
{
auto nanoNow = std::chrono::steady_clock::now().time_since_epoch();
return nanoNow.count();
}
} // namespace TimeUtil
} // namespace HiviewDFX
} // namespace OHOS

65
base/BUILD.gn Normal file
View File

@ -0,0 +1,65 @@
# 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/hiviewdfx/hiview/hiview.gni")
import("//build/ohos.gni")
config("hiview_base_config") {
visibility = [ "*:*" ]
include_dirs = [
"//base/hiviewdfx/hilog/interfaces/native/innerkits/include",
"//utils/native/base/include",
"include",
"utility/include",
"$hiview_root/include",
"$hiview_adapter/utility/include",
"logstore/include",
]
cflags_cc = [ "-D__HIVIEW_OHOS__" ]
}
ohos_source_set("hiview_base") {
public_configs = [ ":hiview_base_config" ]
sources = [
"audit.cpp",
"audit_log_parser.cpp",
"event.cpp",
"event_dispatch_queue.cpp",
"event_loop.cpp",
"event_source.cpp",
"hiview_global.cpp",
"logger.cpp",
"pipeline.cpp",
"plugin.cpp",
"plugin_factory.cpp",
]
deps = [ "utility:hiview_utility" ]
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
}
ohos_shared_library("hiviewbase") {
public_configs = [ ":hiview_base_config" ]
deps = [
":hiview_base",
"$hiview_adapter/utility:hiview_adapter_utility",
"logstore:log_store",
]
part_name = "hiview_L2"
subsystem_name = "hiviewdfx"
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
}

204
base/audit.cpp Normal file
View File

@ -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 "audit.h"
#include <fcntl.h>
#include <iostream>
#include <sys/stat.h>
#include <sys/types.h>
#include "file_util.h"
#include "time_util.h"
namespace OHOS {
namespace HiviewDFX {
namespace {
static const char AUDIT_LOG_PATH[] = "/data/log/faultlog/hiview_audit.log.0";
static const char AUDIT_LOG_PATH_BAK[] = "/data/log/faultlog/hiview_audit.log.1";
}
Audit::~Audit()
{
enabled_ = false;
}
bool Audit::WriteAuditEvent(StatsEvent eventType, uint64_t eventId, const std::string& digest)
{
static auto& instance = Audit::GetInstance();
if (!instance.IsEnabled()) {
return false;
}
if (digest.empty() || (digest.length() >= MAX_AUDIT_LOG_SIZE)) {
return false;
}
std::string out;
out.append(std::to_string(TimeUtil::GenerateTimestamp()));
out.push_back(DOMAIN_DELIMITER);
out.append(std::to_string(eventId));
out.push_back(DOMAIN_DELIMITER);
out.append(std::to_string(eventType));
out.push_back(DOMAIN_DELIMITER);
out.append(digest);
out.append("\n");
instance.WriteEvent(out);
return true;
}
bool Audit::GetAuditLog(bool loadFromFile, std::list<std::string>& ret)
{
static auto& instance = Audit::GetInstance();
if (!instance.IsEnabled()) {
return false;
}
instance.GetAuditLogInner(loadFromFile, ret);
return true;
}
bool Audit::IsEnabled()
{
static auto& instance = Audit::GetInstance();
return instance.enabled_;
}
void Audit::GetAuditLogInner(bool loadFromFile, std::list<std::string>& ret)
{
if (!loadFromFile) {
return;
}
std::lock_guard<std::mutex> lock(mutex_);
std::string activeFile = GetLogFilePath(true);
ReadLogFromFile(activeFile, ret);
std::string inactiveFile = GetLogFilePath(false);
ReadLogFromFile(inactiveFile, ret);
}
// call once in platform initialization
void Audit::Init(bool isBeta)
{
if (init_) {
return;
}
std::call_once(initFlag_, [&]() { enabled_ = isBeta; });
std::lock_guard<std::mutex> lock(mutex_);
useBak_ = IsBackupFileActive();
std::string path = useBak_ ? AUDIT_LOG_PATH_BAK : AUDIT_LOG_PATH;
writeFd_ = UniqueFd(FileUtil::Open(path, O_CREAT | O_APPEND | O_RDWR,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH));
if (writeFd_.Get() < 0) {
enabled_ = false;
}
writeLogCount_ = 0;
init_ = true;
}
void Audit::Clear()
{
std::lock_guard<std::mutex> lock(mutex_);
std::fstream logFile(AUDIT_LOG_PATH, std::ios::out);
std::fstream bakLogFile(AUDIT_LOG_PATH_BAK, std::ios::out);
}
void Audit::WriteEvent(const std::string& content)
{
std::lock_guard<std::mutex> lock(mutex_);
SaveToFileLocked(content);
}
bool Audit::IsActiveLogFileSizeReachTheashold()
{
writeLogCount_ = 0;
const auto& path = GetLogFilePath(true);
struct stat sb;
if (stat(path.c_str(), &sb) == -1) {
return false;
}
return sb.st_size >= MAX_DISK_LOG_SIZE;
}
bool Audit::IsBackupFileActive()
{
struct stat originLogFileStat;
if (stat(AUDIT_LOG_PATH, &originLogFileStat) == -1) {
return false;
}
struct stat bakLogFileStat;
if (stat(AUDIT_LOG_PATH_BAK, &bakLogFileStat) == -1) {
return false;
}
if (originLogFileStat.st_size == 0) {
return false;
}
return bakLogFileStat.st_mtime >= originLogFileStat.st_mtime;
}
void Audit::SaveToFileLocked(const std::string& content)
{
if ((writeLogCount_ > MAX_MEMORY_LOG_COUNT) && IsActiveLogFileSizeReachTheashold()) {
SwitchActiveFile();
}
int fd = writeFd_.Get();
if (fd > 0 && content.length() < MAX_AUDIT_LOG_SIZE) {
// no need to check the result.
write(fd, content.c_str(), content.length());
}
writeLogCount_ = writeLogCount_ + 1;
}
bool Audit::ReadLogFromFile(const std::string& path, std::list<std::string>& ret)
{
std::list<std::string> fileLog;
std::ifstream logFile(path);
std::string line;
if (logFile.good()) {
while (getline(logFile, line)) {
fileLog.push_back(line);
}
} else {
logFile.close();
return false;
}
logFile.close();
ret.insert(ret.begin(), fileLog.begin(), fileLog.end());
return true;
}
const std::string Audit::GetLogFilePath(bool active)
{
if ((useBak_ && active) || (!useBak_ && !active)) {
return AUDIT_LOG_PATH_BAK;
}
return AUDIT_LOG_PATH;
}
void Audit::SwitchActiveFile()
{
useBak_ = !useBak_;
const auto& path = GetLogFilePath(true);
writeFd_ = UniqueFd(FileUtil::Open(path, O_CREAT | O_TRUNC | O_RDWR,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH));
}
} // namespace HiviewDFX
} // namespace OHOS

288
base/audit_log_parser.cpp Normal file
View File

@ -0,0 +1,288 @@
/*
* 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 "audit_log_parser.h"
#include "audit.h"
#include "string_util.h"
namespace OHOS {
namespace HiviewDFX {
namespace {
constexpr int LOG_ELEMENT_MIN_COUNT = 3;
constexpr int LOG_ELEMENT_TIMESTAMP_POS = 0;
constexpr int LOG_ELEMENT_SERIAL_ID_POS = 1;
constexpr int LOG_ELEMENT_EVENT_TYPE_POS = 2;
constexpr int LOG_ELEMENT_NORMAL_EVENT_SENDER_POS = 3;
constexpr int LOG_ELEMENT_NORMAL_EVENT_PROCESSOR_POS = 4;
constexpr int LOG_ELEMENT_NORMAL_EVENT_THREAD_POS = 5;
constexpr int LOG_ELEMENT_NORMAL_EVENT_DIGEST_POS = 6;
constexpr int LOG_ELEMENT_PIPE_EVENT_CREATOR_POS = 3;
constexpr int LOG_ELEMENT_PIPE_EVENT_DIGEST_POS = 4;
constexpr int LOG_ELEMENT_PIPE_EVENT_PROCESSOR_POS = 3;
constexpr int LOG_ELEMENT_PIPE_EVENT_THREAD_POS = 3;
constexpr int LOG_ELEMENT_PIPE_EVENT_PIPELINE_POS = 3;
constexpr int QUEUE_EVENT_IN_ELEMENT_SIZE = 7;
constexpr int QUEUE_EVENT_OUT_ELEMENT_SIZE = 3;
constexpr int PIPELINE_EVENT_CREATE_ELEMENT_SIZE = 5;
constexpr int PIPELINE_EVENT_HANDLE_IN_ELEMENT_SIZE = 4;
constexpr int PIPELINE_EVENT_HANDLE_OUT_ELEMENT_SIZE = 4;
constexpr int PIPELINE_EVENT_DONE_ELEMENT_SIZE = 4;
AuditLogParser::EventInfo CreateEventInfo(uint64_t serialId, const std::string& digest,
const std::vector<std::string>& eventElements)
{
AuditLogParser::EventInfo info;
info.isPipelineEvent = true;
info.eventSerialId = serialId;
StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_TIMESTAMP_POS], info.inTime);
info.processor = eventElements[LOG_ELEMENT_PIPE_EVENT_PROCESSOR_POS];
info.digest = digest;
return info;
}
std::vector<std::string> SplitStr(const std::string& log)
{
std::vector<std::string> elements;
std::string sep(1, Audit::DOMAIN_DELIMITER);
StringUtil::SplitStr(log, sep, elements);
return elements;
}
} // namespace
void AuditLogParser::StartParse()
{
std::list<std::string> logList;
if (!Audit::GetAuditLog(true, logList)) {
return;
}
ParseTimeScope(logList);
for (auto& log : logList) {
auto elements = SplitStr(log);
if (elements.size() < LOG_ELEMENT_MIN_COUNT) {
continue;
}
int eventType = -1;
StringUtil::ConvertStringTo<int>(elements[LOG_ELEMENT_EVENT_TYPE_POS], eventType);
if (std::to_string(eventType) != elements[LOG_ELEMENT_EVENT_TYPE_POS]) {
eventType = -1;
}
if (eventType < Audit::StatsEvent::QUEUE_EVENT_IN) {
continue;
}
if (eventType <= Audit::StatsEvent::QUEUE_EVENT_OUT) {
ParseNormalAuditEvent(eventType, elements);
} else if (eventType <= Audit::StatsEvent::PIPELINE_EVENT_DONE) {
ParsePipelineAuditEvent(eventType, elements);
}
}
}
std::list<std::string> AuditLogParser::GetThreadSummary(const std::string& name)
{
std::list<std::string> ret;
std::string pid = name;
auto pos = pid.find("@");
if (pos != std::string::npos) {
pid = pid.substr(pos + 1);
}
for (auto& event : eventList_) {
if (event.threadNameOrTid.find(pid) != std::string::npos) {
ret.push_back(event.ToString());
}
}
for (auto& pipeEvent : pipelineEventList_) {
for (auto& chainEvent : pipeEvent.processChain) {
if (chainEvent.threadNameOrTid.find(pid) != std::string::npos) {
ret.push_back(chainEvent.ToString());
}
}
}
return ret;
}
std::list<std::string> AuditLogParser::GetPluginSummary(const std::string& name)
{
std::list<std::string> ret;
for (auto& event : eventList_) {
if (event.processor.find(name) != std::string::npos) {
ret.push_back(event.ToString());
}
}
for (auto& pipeEvent : pipelineEventList_) {
for (auto& chainEvent : pipeEvent.processChain) {
if (chainEvent.processor.find(name) != std::string::npos) {
ret.push_back(chainEvent.ToString());
}
}
}
return ret;
}
std::list<std::string> AuditLogParser::GetPipelineSummary(const std::string& name)
{
std::list<std::string> ret;
for (auto& pipeEvent : pipelineEventList_) {
if (pipeEvent.pipeline.find(name) != std::string::npos) {
ret.push_back(pipeEvent.ToString());
}
}
return ret;
}
std::string AuditLogParser::GetAuditLogTimeScope()
{
return "Audit Logs From " + std::to_string(logStartTime_) + " to " + std::to_string(logEndTime_);
}
void AuditLogParser::ParseTimeScope(const std::list<std::string>& logList)
{
if (logList.empty()) {
return;
}
auto beginLog = SplitStr(*(logList.begin()));
StringUtil::ConvertStringTo<uint64_t>(beginLog[LOG_ELEMENT_TIMESTAMP_POS], logStartTime_);
auto endLog = SplitStr(*(logList.rbegin()));
StringUtil::ConvertStringTo<uint64_t>(endLog[LOG_ELEMENT_TIMESTAMP_POS], logEndTime_);
}
void AuditLogParser::ParseNormalAuditEvent(int eventType, const std::vector<std::string>& eventElements)
{
if (eventType == Audit::StatsEvent::QUEUE_EVENT_IN && eventElements.size() >= QUEUE_EVENT_IN_ELEMENT_SIZE) {
ParseNormalEnqueueEvent(eventElements);
return;
}
if (eventType == Audit::StatsEvent::QUEUE_EVENT_OUT && eventElements.size() >= QUEUE_EVENT_OUT_ELEMENT_SIZE) {
ParseNormalDequeueEvent(eventElements);
}
}
void AuditLogParser::ParseNormalEnqueueEvent(const std::vector<std::string>& eventElements)
{
EventInfo info;
StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_TIMESTAMP_POS], info.inTime);
StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_SERIAL_ID_POS], info.eventSerialId);
info.sender = eventElements[LOG_ELEMENT_NORMAL_EVENT_SENDER_POS];
info.processor = eventElements[LOG_ELEMENT_NORMAL_EVENT_PROCESSOR_POS];
info.threadNameOrTid = eventElements[LOG_ELEMENT_NORMAL_EVENT_THREAD_POS];
info.digest = eventElements[LOG_ELEMENT_NORMAL_EVENT_DIGEST_POS];
eventList_.push_back(std::move(info));
}
void AuditLogParser::ParseNormalDequeueEvent(const std::vector<std::string>& eventElements)
{
uint64_t eventSerialId = 0;
StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_SERIAL_ID_POS], eventSerialId);
for (auto rit = eventList_.rbegin(); rit != eventList_.rend(); ++rit) {
if (rit->eventSerialId == eventSerialId) {
StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_TIMESTAMP_POS], rit->outTime);
return;
}
}
}
void AuditLogParser::ParsePipelineAuditEvent(int eventType, const std::vector<std::string>& eventElements)
{
if (eventType == Audit::StatsEvent::PIPELINE_EVENT_CREATE &&
eventElements.size() >= PIPELINE_EVENT_CREATE_ELEMENT_SIZE) {
ParsePipelineCreateEvent(eventElements);
return;
}
if (eventType == Audit::StatsEvent::PIPELINE_EVENT_HANDLE_IN &&
eventElements.size() >= PIPELINE_EVENT_HANDLE_IN_ELEMENT_SIZE) {
ParsePipelineHandleInEvent(eventElements);
return;
}
if (eventType == Audit::StatsEvent::PIPELINE_EVENT_HANDLE_OUT &&
eventElements.size() >= PIPELINE_EVENT_HANDLE_OUT_ELEMENT_SIZE) {
ParsePipelineHandleOutEvent(eventElements);
return;
}
if (eventType == Audit::StatsEvent::PIPELINE_EVENT_DONE &&
eventElements.size() >= PIPELINE_EVENT_DONE_ELEMENT_SIZE) {
ParsePipelineDoneEvent(eventElements);
return;
}
}
void AuditLogParser::ParsePipelineCreateEvent(const std::vector<std::string>& eventElements)
{
PipelineEventInfo info;
StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_TIMESTAMP_POS], info.createTime);
StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_SERIAL_ID_POS], info.eventSerialId);
info.creator = eventElements[LOG_ELEMENT_PIPE_EVENT_CREATOR_POS];
info.digest = eventElements[LOG_ELEMENT_PIPE_EVENT_DIGEST_POS];
pipelineEventList_.push_back(std::move(info));
}
void AuditLogParser::ParsePipelineHandleInEvent(const std::vector<std::string>& eventElements)
{
uint64_t eventSerialId = 0;
StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_SERIAL_ID_POS], eventSerialId);
for (auto rit = pipelineEventList_.rbegin(); rit != pipelineEventList_.rend(); ++rit) {
if (rit->eventSerialId == eventSerialId) {
rit->processChain.push_back(CreateEventInfo(eventSerialId, rit->digest, eventElements));
return;
}
}
for (auto rit = eventList_.rbegin(); rit != eventList_.rend(); ++rit) {
if (rit->eventSerialId == eventSerialId) {
PipelineEventInfo info(*rit);
info.processChain.push_back(CreateEventInfo(eventSerialId, info.digest, eventElements));
pipelineEventList_.push_back(std::move(info));
return;
}
}
}
void AuditLogParser::ParsePipelineHandleOutEvent(const std::vector<std::string>& eventElements)
{
uint64_t eventSerialId = 0;
StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_SERIAL_ID_POS], eventSerialId);
for (auto rit = pipelineEventList_.rbegin(); rit != pipelineEventList_.rend(); ++rit) {
if (rit->eventSerialId == eventSerialId) {
auto& info = rit->processChain.back();
StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_TIMESTAMP_POS], info.outTime);
info.threadNameOrTid = eventElements[LOG_ELEMENT_PIPE_EVENT_THREAD_POS];
return;
}
}
}
void AuditLogParser::ParsePipelineDoneEvent(const std::vector<std::string>& eventElements)
{
uint64_t eventSerialId = 0;
StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_SERIAL_ID_POS], eventSerialId);
for (auto rit = pipelineEventList_.rbegin(); rit != pipelineEventList_.rend(); ++rit) {
if (rit->eventSerialId == eventSerialId) {
StringUtil::ConvertStringTo<uint64_t>(eventElements[LOG_ELEMENT_TIMESTAMP_POS], rit->destroyTime);
rit->pipeline = eventElements[LOG_ELEMENT_PIPE_EVENT_PIPELINE_POS];
return;
}
}
}
} // namespace HiviewDFX
} // namespace OHOS

103
base/event.cpp Normal file
View File

@ -0,0 +1,103 @@
/*
* 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 "event.h"
#include "audit.h"
#include "time_util.h"
namespace OHOS {
namespace HiviewDFX {
void Event::SetValue(const std::string &name, const std::string &value)
{
if (name.length() > 0) {
// force update original value
bundle_[name] = value;
}
}
const std::string Event::GetValue(const std::string &name) const
{
auto it = bundle_.find(name);
if (it != bundle_.end()) {
return it->second;
}
return std::string("");
}
void Event::SetValue(const std::string &name, int32_t value)
{
std::string str = std::to_string(value);
if (name.length() > 0) {
// force update original value
bundle_[name] = str;
}
}
int32_t Event::GetIntValue(const std::string &name) const
{
auto it = bundle_.find(name);
if (it != bundle_.end()) {
const int decimal = 10;
int32_t ret = static_cast<int32_t>(std::strtol(it->second.c_str(), nullptr, decimal));
return (errno == ERANGE) ? -1 : ret;
}
return -1;
}
void Event::ResetTimestamp()
{
createTime_ = TimeUtil::GenerateTimestamp();
}
void Event::SetKeyValuePairs(std::map<std::string, std::string> keyValuePairs)
{
bundle_.insert(keyValuePairs.begin(), keyValuePairs.end());
}
void EventListener::AddListenerInfo(uint32_t type, const EventIdRange& range)
{
auto it = listenerInfo_.find(type);
if (it != listenerInfo_.end()) {
it->second.insert(range);
return;
}
std::set<EventIdRange> listenerSet;
listenerSet.insert(range);
listenerInfo_[type] = std::move(listenerSet);
}
void EventListener::AddListenerInfo(uint32_t type, const std::set<EventIdRange> &listenerInfo)
{
auto it = listenerInfo_.find(type);
if (it != listenerInfo_.end()) {
it->second.insert(listenerInfo.begin(), listenerInfo.end());
return;
}
listenerInfo_[type] = listenerInfo;
}
bool EventListener::GetListenerInfo(uint32_t type, std::set<EventIdRange> &listenerInfo)
{
auto it = listenerInfo_.find(type);
if (it != listenerInfo_.end()) {
listenerInfo.clear();
listenerInfo.insert(it->second.begin(), it->second.end());
return true;
}
return false;
}
}
}

View File

@ -0,0 +1,162 @@
/*
* 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 "event_dispatch_queue.h"
#include <algorithm>
#include <memory>
#include "file_util.h"
#include "thread_util.h"
#include "logger.h"
namespace OHOS {
namespace HiviewDFX {
DEFINE_LOG_TAG("HiView-EventDispatchQueue");
EventDispatchQueue::EventDispatchQueue(const std::string& name, Event::ManageType type)
: stop_(false), isRunning_(false), threadName_(name), type_(type)
{}
EventDispatchQueue::~EventDispatchQueue()
{
Stop();
}
void EventDispatchQueue::Run()
{
const int threadNameLen = 15;
Thread::SetThreadDescription(threadName_.substr(0, threadNameLen));
isRunning_ = true;
while (true) {
std::shared_ptr<Event> event = nullptr;
{
std::unique_lock<std::mutex> lock(mutexLock_);
while (pendingEvents_.empty()) {
condition_.wait(lock);
if (stop_) {
return;
}
}
event = pendingEvents_.front();
pendingEvents_.pop_front();
}
if (event == nullptr) {
continue;
}
if (type_ == Event::ManageType::ORDERED) {
ProcessOrderedEvent(*(event.get()));
} else {
ProcessUnorderedEvent(*(event.get()));
}
if (stop_) {
break;
}
}
}
void EventDispatchQueue::RegisterListener(std::weak_ptr<EventListener> listener)
{
HIVIEW_LOGI("EventDispatchQueue RegisterListener");
listeners_.push_back(std::move(listener));
}
void EventDispatchQueue::ProcessOrderedEvent(Event& event)
{
bool skip = true;
bool stop = false;
for (const auto& listener : listeners_) {
if (std::shared_ptr<EventListener> sp = listener.lock()) {
// dispatch anonymous event from head of the listeners
if (event.sender_.empty()) {
skip = false;
}
if (skip && (sp->GetListenerName() == event.sender_)) {
skip = false;
continue;
}
if (skip) {
continue;
}
if (IsEventMatchCurrentListener(event, sp)) {
stop = sp->OnOrderedEvent(event);
}
if (stop) {
HIVIEW_LOGI("Event %d consumed by %s.", event.eventId_, sp->GetListenerName().c_str());
break;
}
}
}
}
void EventDispatchQueue::ProcessUnorderedEvent(const Event& event)
{
for (const auto& listener : listeners_) {
if (std::shared_ptr<EventListener> sp = listener.lock()) {
if (IsEventMatchCurrentListener(event, sp)) {
sp->OnUnorderedEvent(event);
}
}
}
}
bool EventDispatchQueue::IsEventMatchCurrentListener(const Event& event, std::shared_ptr<EventListener> listener)
{
std::set<EventListener::EventIdRange> listenerInfo;
if (listener->GetListenerInfo(event.messageType_, listenerInfo)) {
return std::any_of(listenerInfo.begin(), listenerInfo.end(), [&](const EventListener::EventIdRange& range) {
return ((event.eventId_ >= range.begin) && (event.eventId_ <= range.end));
});
}
return false;
}
void EventDispatchQueue::Stop()
{
stop_ = true;
condition_.notify_all();
if (thread_ != nullptr && thread_->joinable()) {
thread_->join();
}
isRunning_ = false;
}
void EventDispatchQueue::Start()
{
std::unique_lock<std::mutex> lock(mutexLock_);
if (!IsRunning()) {
thread_ = std::make_unique<std::thread>(&EventDispatchQueue::Run, this);
}
}
void EventDispatchQueue::Enqueue(std::shared_ptr<Event> event)
{
HIVIEW_LOGD("EventDispatchQueue Enqueue");
std::unique_lock<std::mutex> lock(mutexLock_);
pendingEvents_.push_back(std::move(event));
condition_.notify_one();
}
int EventDispatchQueue::GetWaitQueueSize() const
{
return pendingEvents_.size();
}
} // namespace HiviewDFX
} // namespace OHOS

89
base/event_dispatcher.cpp Normal file
View File

@ -0,0 +1,89 @@
/*
* 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 "event_dispatcher.h"
#include <algorithm>
#include "logger.h"
namespace OHOS {
namespace HiviewDFX {
void EventDispatcher::AddInterestType(int32_t type)
{
types_.insert(type);
}
void EventDispatcher::ClearInvalidListeners()
{
std::lock_guard<std::mutex> lock(lock_);
auto channelMapperIter = channelMapper_.begin();
while (channelMapperIter != channelMapper_.end()) {
auto listeners = channelMapperIter->second;
auto listenerIter = listeners.begin();
while (listenerIter != listeners.end()) {
auto listener = listenerIter->lock();
if (listener == nullptr) {
listenerIter = listeners.erase(listenerIter);
continue;
}
listenerIter++;
}
channelMapperIter++;
}
}
void EventDispatcher::DispatchEvent(Event event)
{
if (types_.find(event.messageType_) == types_.end()) {
return;
}
auto listeners = channelMapper_[event.messageType_];
for (auto listener : listeners) {
std::shared_ptr<EventListener> sp = listener.lock();
if (sp == nullptr) {
continue;
}
std::set<EventListener::EventIdRange> listenerInfo;
if (!sp->GetListenerInfo(event.messageType_, listenerInfo)) {
continue;
}
if (std::any_of(listenerInfo.begin(), listenerInfo.end(),
[&](const EventListener::EventIdRange &range) {
return ((event.eventId_ >= range.begin) && (event.eventId_ <= range.end));
})) {
sp->OnUnorderedEvent(event);
}
}
}
void EventDispatcher::RegisterListener(std::weak_ptr<EventListener> listener)
{
std::shared_ptr<EventListener> sp = listener.lock();
if (sp == nullptr) {
return;
}
for (auto type : types_) {
std::set<EventListener::EventIdRange> listenerInfo;
if (sp->GetListenerInfo(type, listenerInfo) && (!listenerInfo.empty())) {
std::lock_guard<std::mutex> lock(lock_);
channelMapper_[type].push_back(listener);
}
}
}
} // namespace HiviewDFX
} // namespace OHOS

433
base/event_loop.cpp Normal file
View File

@ -0,0 +1,433 @@
/*
* 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 "event_loop.h"
#include <climits>
#include <functional>
#include <thread>
#include <pthread.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/prctl.h>
#include "audit.h"
#include "file_util.h"
#include "logger.h"
#include "thread_util.h"
namespace OHOS {
namespace HiviewDFX {
namespace {
std::future<bool> GetFalseFuture()
{
std::promise<bool> tmpPromise;
tmpPromise.set_value(false);
return tmpPromise.get_future();
}
}
DEFINE_LOG_TAG("HiView-EventLoop");
EventLoop::EventLoop(const std::string &name) : name_(name), nextWakeupTime_(0), currentProcessingEvent_(nullptr)
{}
EventLoop::~EventLoop()
{
StopLoop();
}
bool EventLoop::InitEventQueueNotifier()
{
#if defined EPOLL_CLOEXEC
sharedPollingFd_ = UniqueFd(epoll_create1(EPOLL_CLOEXEC));
#else
sharedPollingFd_ = UniqueFd(epoll_create(1024)); // listen 1024 sockets
#endif
pendingEventQueueFd_ = UniqueFd(eventfd(0, EFD_NONBLOCK));
struct epoll_event eventItem;
eventItem.events = EPOLLIN | EPOLLET;
eventItem.data.fd = pendingEventQueueFd_.Get();
int result = epoll_ctl(sharedPollingFd_.Get(), EPOLL_CTL_ADD, pendingEventQueueFd_.Get(), &eventItem);
if (result < 0) {
HIVIEW_LOGE("Fail to Create event poll queue.");
return false;
}
return true;
}
void EventLoop::WakeUp()
{
if (pendingEventQueueFd_.Get() > 0) {
eventfd_t count = 1;
write(pendingEventQueueFd_.Get(), &count, sizeof(count));
}
}
void EventLoop::StartLoop(bool createNewThread)
{
std::lock_guard<std::mutex> lock(queueMutex_);
if (!IsRunning()) {
if (!InitEventQueueNotifier()) {
return;
}
isRunning_ = true;
if (createNewThread) {
thread_ = std::make_unique<std::thread>(&EventLoop::Run, this);
return;
}
} else {
return;
}
// handle loop in current thread cases
Run();
}
void EventLoop::StopLoop()
{
needQuit_ = true;
if (!IsRunning()) {
return;
}
{
std::lock_guard<std::mutex> lock(queueMutex_);
while (!pendingEvents_.empty()) {
pendingEvents_.pop();
}
isRunning_ = false;
}
WakeUp();
if (thread_ != nullptr && thread_->joinable()) {
thread_->join();
}
}
uint64_t EventLoop::AddEvent(std::shared_ptr<EventHandler> handler, std::shared_ptr<Event> event, const Task task)
{
if (needQuit_) {
return 0;
}
uint64_t now = NanoSecondSinceSystemStart();
if (Audit::IsEnabled() && (event != nullptr) && (handler != nullptr) && (!(event->isPipeline_))) {
auto digest = event->sender_ + Audit::DOMAIN_DELIMITER + handler->GetHandlerInfo() + Audit::DOMAIN_DELIMITER +
GetName() + Audit::DOMAIN_DELIMITER + event->GetEventInfo();
Audit::WriteAuditEvent(Audit::StatsEvent::QUEUE_EVENT_IN, event->createTime_, digest);
}
LoopEvent loopEvent = LoopEvent::CreateLoopEvent(now);
loopEvent.event = std::move(event);
loopEvent.handler = handler;
loopEvent.task = task;
std::lock_guard<std::mutex> lock(queueMutex_);
pendingEvents_.push(std::move(loopEvent));
WakeUp();
return now;
}
std::future<bool> EventLoop::AddEventForResult(std::shared_ptr<EventHandler> handler, std::shared_ptr<Event> event)
{
if (needQuit_) {
return GetFalseFuture();
}
if (handler == nullptr || event == nullptr) {
return GetFalseFuture();
}
if (Audit::IsEnabled() && (event != nullptr) && (handler != nullptr) && (!(event->isPipeline_))) {
auto digest = event->sender_ + Audit::DOMAIN_DELIMITER + handler->GetHandlerInfo() + Audit::DOMAIN_DELIMITER +
GetName() + Audit::DOMAIN_DELIMITER + event->GetEventInfo();
Audit::WriteAuditEvent(Audit::StatsEvent::QUEUE_EVENT_IN, event->createTime_, digest);
}
auto bind = std::bind(&EventHandler::OnEventProxy, handler.get(), event);
auto task = std::make_shared<std::packaged_task<bool()>>(bind);
auto result = task->get_future();
uint64_t now = NanoSecondSinceSystemStart();
LoopEvent loopEvent = LoopEvent::CreateLoopEvent(now);
loopEvent.taskType = LOOP_PACKAGED_TASK;
loopEvent.event = std::move(event);
loopEvent.handler = handler;
loopEvent.packagedTask = std::move(task);
std::lock_guard<std::mutex> lock(queueMutex_);
pendingEvents_.push(std::move(loopEvent));
WakeUp();
return result;
}
uint64_t EventLoop::AddTimerEvent(std::shared_ptr<EventHandler> handler, std::shared_ptr<Event> event, const Task &task,
uint64_t interval, bool repeat)
{
if (needQuit_) {
return 0;
}
uint64_t now = NanoSecondSinceSystemStart();
uint64_t intervalMicro = interval * SECOND_TO_NANOSECOND;
if (now + intervalMicro < now) {
HIVIEW_LOGW("Add Timer Event fail. The interval is too large. please check.");
return -1;
}
if (Audit::IsEnabled() && (event != nullptr) && (handler != nullptr) && (!(event->isPipeline_))) {
auto digest = event->sender_ + Audit::DOMAIN_DELIMITER + handler->GetHandlerInfo() + Audit::DOMAIN_DELIMITER +
GetName() + Audit::DOMAIN_DELIMITER + event->GetEventInfo();
Audit::WriteAuditEvent(Audit::StatsEvent::QUEUE_EVENT_IN, event->createTime_, digest);
}
LoopEvent loopEvent = LoopEvent::CreateLoopEvent(now);
loopEvent.isRepeat = repeat;
loopEvent.taskType = LOOP_EVENT_TASK;
loopEvent.interval = intervalMicro;
loopEvent.targetTime = now + intervalMicro;
loopEvent.event = std::move(event);
loopEvent.handler = handler;
loopEvent.task = task;
std::lock_guard<std::mutex> lock(queueMutex_);
pendingEvents_.push(std::move(loopEvent));
ResetTimerIfNeedLocked();
return now;
}
bool EventLoop::RemoveEvent(uint64_t seq)
{
std::lock_guard<std::mutex> lock(queueMutex_);
auto curEvent = currentProcessingEvent_.load(std::memory_order_relaxed);
if ((curEvent != nullptr) && (curEvent->seq == seq)) {
curEvent->seq = 0;
HIVIEW_LOGI("removing the current processing event.");
return false;
}
return pendingEvents_.remove(seq);
}
void EventLoop::ResetTimerIfNeedLocked()
{
const LoopEvent &event = pendingEvents_.top();
if (nextWakeupTime_ == event.targetTime) {
return;
}
WakeUp();
}
bool EventLoop::AddFileDescriptorEventCallback(
const std::string &name, std::shared_ptr<FileDescriptorEventCallback> source)
{
if (needQuit_) {
return false;
}
std::lock_guard<std::mutex> lock(queueMutex_);
if (eventSourceNameMap_.find(name) != eventSourceNameMap_.end()) {
HIVIEW_LOGW("Exist fd callback with same name.");
return false;
}
int fd = source->GetPollFd();
if (fd <= 0) {
HIVIEW_LOGW("Invalid poll fd.");
return false;
}
struct epoll_event eventItem;
eventItem.events = source->GetPollType();
eventItem.data.fd = fd;
int result = epoll_ctl(sharedPollingFd_.Get(), EPOLL_CTL_ADD, fd, &eventItem);
if (result < 0) {
HIVIEW_LOGW("Fail to Add Fd callback.");
return false;
}
eventSourceNameMap_[name] = fd;
eventSourceMap_[fd] = source;
return true;
}
bool EventLoop::RemoveFileDescriptorEventCallback(const std::string &name)
{
std::lock_guard<std::mutex> lock(queueMutex_);
if (eventSourceNameMap_.find(name) == eventSourceNameMap_.end()) {
HIVIEW_LOGW("fd callback name is not existed.");
return false;
}
int fd = eventSourceNameMap_[name];
eventSourceNameMap_.erase(name);
if (epoll_ctl(sharedPollingFd_.Get(), EPOLL_CTL_DEL, fd, nullptr) == -1) {
HIVIEW_LOGW("fail to remove watched fd.");
}
eventSourceMap_.erase(fd);
return true;
}
void EventLoop::Run()
{
// set thread name
const int maxLength = 16;
std::string restrictedName = name_;
if (name_.length() >= maxLength) {
HIVIEW_LOGW("%s is too long for thread, please change to a shorter one.", name_.c_str());
restrictedName = name_.substr(0, maxLength - 1);
}
Thread::SetThreadDescription(restrictedName);
name_ = name_ + "@" + std::to_string(Thread::GetTid());
while (true) {
uint64_t leftTimeNanosecond = ProcessQueuedEvent();
WaitNextEvent(leftTimeNanosecond);
if (needQuit_) {
break;
}
}
}
uint64_t EventLoop::ProcessQueuedEvent()
{
if (pendingEvents_.empty()) {
return INT_MAX;
}
uint64_t leftTimeNanosecond = 0;
while (!pendingEvents_.empty()) {
uint64_t now = NanoSecondSinceSystemStart();
LoopEvent event;
if (!FetchNextEvent(now, leftTimeNanosecond, event)) {
break;
}
ProcessEvent(event);
if (event.isRepeat && (event.interval > 0)) {
// force update time
now = NanoSecondSinceSystemStart();
ReInsertPeriodicEvent(now, event);
}
std::lock_guard<std::mutex> lock(queueMutex_);
currentProcessingEvent_.store(nullptr, std::memory_order_relaxed);
}
isWaken_ = false;
return leftTimeNanosecond;
}
bool EventLoop::FetchNextEvent(uint64_t now, uint64_t& leftTimeNanosecond, LoopEvent& out)
{
if (needQuit_) {
return false;
}
std::lock_guard<std::mutex> lock(queueMutex_);
if (pendingEvents_.empty()) {
return false;
}
const LoopEvent &event = pendingEvents_.top();
if (event.targetTime > now) {
leftTimeNanosecond = event.targetTime - now;
nextWakeupTime_ = event.targetTime;
return false;
}
out = event;
pendingEvents_.pop();
currentProcessingEvent_.store(&out, std::memory_order_relaxed);
return true;
}
void EventLoop::ProcessEvent(LoopEvent &event)
{
if (event.taskType == LOOP_EVENT_TASK) {
if (event.task != nullptr) {
event.task();
} else if ((event.handler != nullptr) && (event.event != nullptr)) {
event.handler->OnEventProxy(event.event);
} else {
HIVIEW_LOGW("Loop event task with null tasks.");
}
} else if (event.taskType == LOOP_PACKAGED_TASK) {
if (event.packagedTask != nullptr) {
event.packagedTask->operator()();
} else {
HIVIEW_LOGW("Loop packaged task with null tasks.");
}
} else {
HIVIEW_LOGW("unrecognized task type.");
}
}
void EventLoop::ReInsertPeriodicEvent(uint64_t now, LoopEvent &event)
{
std::lock_guard<std::mutex> lock(queueMutex_);
currentProcessingEvent_.store(nullptr, std::memory_order_relaxed);
if (event.seq == 0) {
return;
}
event.enqueueTime = now;
event.targetTime = now + event.interval;
if (Audit::IsEnabled() && (event.event != nullptr) && (event.handler != nullptr)) {
event.event->ResetTimestamp();
auto digest = event.event->sender_ + Audit::DOMAIN_DELIMITER + event.handler->GetHandlerInfo() +
Audit::DOMAIN_DELIMITER + GetName() + Audit::DOMAIN_DELIMITER + event.event->GetEventInfo();
Audit::WriteAuditEvent(Audit::StatsEvent::QUEUE_EVENT_IN, event.event->createTime_, digest);
}
pendingEvents_.push(std::move(event));
ResetTimerIfNeedLocked();
}
void EventLoop::WaitNextEvent(uint64_t leftTimeNanosecond)
{
struct epoll_event eventItems[MAX_EVENT_SIZE];
int eventCount = epoll_wait(sharedPollingFd_.Get(), eventItems, MAX_EVENT_SIZE,
(leftTimeNanosecond / NANOSECOND_TO_MILLSECOND));
isWaken_ = true;
if (eventCount <= 0) {
// no event read from watched fd, process queued events
return;
}
for (int i = 0; i < eventCount; i++) {
int fd = eventItems[i].data.fd;
uint32_t events = eventItems[i].events;
if (fd == pendingEventQueueFd_.Get()) {
// new queued event arrived
eventfd_t val = 0;
read(fd, &val, sizeof(val));
return;
} else {
// process data source callbacks
auto it = eventSourceMap_.find(fd);
if (it != eventSourceMap_.end()) {
it->second->OnFileDescriptorEvent(fd, events);
}
}
}
}
uint64_t EventLoop::NanoSecondSinceSystemStart()
{
auto nanoNow = std::chrono::steady_clock::now().time_since_epoch();
return nanoNow.count();
}
} // namespace HiviewDFX
} // namespace OHOS

58
base/event_source.cpp Normal file
View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "event_source.h"
#include "audit.h"
#include "logger.h"
namespace OHOS {
namespace HiviewDFX {
DEFINE_LOG_TAG("HiView-EventSource");
bool EventSource::PublishPipelineEvent(std::shared_ptr<PipelineEvent> event)
{
HIVIEW_LOGD("EventSource PublishPipelineEvent");
if (event == nullptr) {
return false;
}
if (Audit::IsEnabled()) {
auto digest = GetPluginInfo() + Audit::DOMAIN_DELIMITER + event->GetEventInfo();
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_CREATE, event->createTime_, digest);
}
for (auto& pipeline : listeners_) {
if ((pipeline != nullptr) && (pipeline->CanProcessEvent(event))) {
// one event can only be processed by on pipeline
pipeline->ProcessEvent(event);
return true;
}
}
return false;
}
void EventSource::AddPipeline(std::shared_ptr<Pipeline> pipeline)
{
if (pipeline == nullptr) {
HIVIEW_LOGW("Add nullptr pipeline to %s.", GetName().c_str());
return;
}
HIVIEW_LOGD("EventSource add pipeline %s.", pipeline->GetName().c_str());
listeners_.push_back(pipeline);
}
void EventSource::StartEventSource()
{
// default non-implement
}
} // namespace HiviewDFX
} // namespace OHOS

60
base/hiview_global.cpp Normal file
View File

@ -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.
*/
#include "hiview_global.h"
#include <mutex>
namespace OHOS {
namespace HiviewDFX {
namespace {
std::unique_ptr<HiviewGlobal>& GetOrSetGlobalReference(std::unique_ptr<HiviewGlobal> ref)
{
static std::unique_ptr<HiviewGlobal> globalRef;
if ((globalRef == nullptr) && (ref != nullptr)) {
globalRef = std::move(ref);
}
return globalRef;
}
}
void HiviewGlobal::CreateInstance(HiviewContext& context)
{
static std::once_flag flag;
std::call_once(flag, [&] {
auto globalRef = std::make_unique<HiviewGlobal>(context);
GetOrSetGlobalReference(std::move(globalRef));
});
}
// maybe null reference, check before use
std::unique_ptr<HiviewGlobal>& HiviewGlobal::GetInstance()
{
return GetOrSetGlobalReference(nullptr);
}
std::string HiviewGlobal::GetHiViewDirectory(HiviewContext::DirectoryType type) const
{
return context_.GetHiViewDirectory(type);
}
void HiviewGlobal::PostAsyncEventToTarget(const std::string &targetPlugin, std::shared_ptr<Event> event)
{
context_.PostAsyncEventToTarget(nullptr, targetPlugin, event);
}
bool HiviewGlobal::PostSyncEventToTarget(const std::string &targetPlugin, std::shared_ptr<Event> event)
{
return context_.PostSyncEventToTarget(nullptr, targetPlugin, event);
}
} // namespace HiviewDFX
} // namespace OHOS

81
base/include/audit.h Normal file
View File

@ -0,0 +1,81 @@
/*
* 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 HIVIEW_BASE_AUDIT_H
#define HIVIEW_BASE_AUDIT_H
#include <atomic>
#include <fstream>
#include <list>
#include <mutex>
#include <string>
#include "public_defines.h"
#include "singleton.h"
#include "unique_fd.h"
namespace OHOS {
namespace HiviewDFX {
class Audit : public Singleton<Audit> {
public:
Audit() : init_(false), useBak_(false), enabled_(false) {};
~Audit();
enum StatsEvent {
QUEUE_EVENT_IN = 0,
QUEUE_EVENT_OUT,
PIPELINE_EVENT_CREATE,
PIPELINE_EVENT_HANDLE_IN,
PIPELINE_EVENT_HANDLE_OUT,
PIPELINE_EVENT_DONE,
PRIVATE_AUDIT_EVENT_TYPE
};
// the format of the normal event digestion should be 1.sender 2.processor 3.thread 4.detailed event info
static bool WriteAuditEvent(StatsEvent eventType, uint64_t eventId, const std::string& digest = "");
// get a copy of the audit log
// if loadFromFile is enabled, log store in the disk will be inserted into the front of current logs
static bool GetAuditLog(bool loadFromFile, std::list<std::string>& ret);
static bool IsEnabled();
// clear all logs
void Clear();
// judge the version and do some initialization
void Init(bool isBeta);
static constexpr char DOMAIN_DELIMITER = '|';
private:
bool IsActiveLogFileSizeReachTheashold();
bool ReadLogFromFile(const std::string& path, std::list<std::string>& ret);
bool IsBackupFileActive();
const std::string GetLogFilePath(bool active);
void GetAuditLogInner(bool loadFromFile, std::list<std::string>& ret);
void SaveToFileLocked(const std::string& content);
void SwitchActiveFile();
void WriteEvent(const std::string& content);
bool init_;
bool useBak_;
bool enabled_;
UniqueFd writeFd_;
std::mutex mutex_;
std::once_flag initFlag_;
std::atomic<uint32_t> writeLogCount_;
static constexpr uint32_t MAX_MEMORY_LOG_COUNT = 1024; // 1024 lines
static constexpr uint32_t MAX_DISK_LOG_SIZE = 1024 * 512; // 512KB
static constexpr uint32_t MAX_AUDIT_LOG_SIZE = 1024; // 1024 byte
};
} // namespace HiviewDFX
} // namespace OHOS
#endif // HIVIEW_BASE_AUDIT_H

View File

@ -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.
*/
#ifndef BASE_HIVIEWDFX_HIVIEW_PLUGIN_MANAGEMENT_AUDIT_LOG_PARSER_H
#define BASE_HIVIEWDFX_HIVIEW_PLUGIN_MANAGEMENT_AUDIT_LOG_PARSER_H
#include <list>
#include <map>
#include <string>
#include <vector>
namespace OHOS {
namespace HiviewDFX {
class AuditLogParser {
public:
struct EventInfo {
uint64_t eventSerialId = 0;
bool isPipelineEvent = false;
std::string sender = "";
std::string processor = "";
std::string threadNameOrTid = "";
std::string digest = "";
uint64_t inTime = 0;
uint64_t outTime = 0;
bool operator<(const EventInfo &obj) const
{
return (this->eventSerialId < obj.eventSerialId);
};
std::string ToString()
{
return "SerialId:" + std::to_string(eventSerialId) + " Sender:" + sender + " Processor:" + processor +
" OnThread:" + threadNameOrTid + " IsPipelineEvent:" + std::to_string(isPipelineEvent) +
" TimeCost:" + std::to_string((outTime - inTime)) + " Digest:" + digest;
};
};
struct PipelineEventInfo {
uint64_t eventSerialId = 0;
uint64_t createTime = 0;
uint64_t destroyTime = 0;
std::string creator = "";
std::string pipeline = "";
std::string digest = "";
// only processor, in and out time is valid
std::list<EventInfo> processChain;
bool operator<(const PipelineEventInfo &obj) const
{
return (this->eventSerialId < obj.eventSerialId);
};
std::string ToString()
{
std::string ret = "SerialId:" + std::to_string(eventSerialId) + " Creator:" + creator +
" Pipeline:" + pipeline + " TimeCost:" + std::to_string((destroyTime - createTime)) +
" Digest:" + digest;
for (auto &processor : processChain) {
ret.append(" @plugin:");
ret.append(processor.processor);
ret.append("@begin:");
ret.append(std::to_string(processor.inTime));
ret.append("@end:");
ret.append(std::to_string(processor.outTime));
ret.append("@thread:");
ret.append(processor.threadNameOrTid);
}
return ret;
};
PipelineEventInfo() : eventSerialId(0), createTime(0), destroyTime(0), creator(""), pipeline(""), digest(""){};
explicit PipelineEventInfo(const EventInfo &info)
: eventSerialId(info.eventSerialId), createTime(info.inTime), creator(info.sender), digest(info.digest){};
};
public:
AuditLogParser() : logStartTime_(0), logEndTime_(0), parsed_(false){};
~AuditLogParser(){};
// QUEUE_EVENT_IN event format
// [timestamp] [eventSerialId] [0] [sender] [processor] [thread] [digest]
// QUEUE_EVENT_OUT event format
// [timestamp] [eventSerialId] [1]
// PIPELINE_EVENT_CREATE event format
// [timestamp] [eventSerialId] [2] [creator] [digest]
// PIPELINE_EVENT_HANDLE_IN event format
// [timestamp] [eventSerialId] [3] [processor]
// PIPELINE_EVENT_HANDLE_OUT event format
// [timestamp] [eventSerialId] [4] [thread]
// PIPELINE_EVENT_DONE event format
// [timestamp] [eventSerialId] [5] [pipeline]
void StartParse();
std::list<std::string> GetThreadSummary(const std::string &name = "");
std::list<std::string> GetPluginSummary(const std::string &name = "");
std::list<std::string> GetPipelineSummary(const std::string &name = "");
// From xxx to xxx
std::string GetAuditLogTimeScope();
private:
void ParseTimeScope(const std::list<std::string> &logList);
void ParseEvent(std::string logStr);
void ParseNormalAuditEvent(int eventType, const std::vector<std::string> &eventElements);
void ParseNormalEnqueueEvent(const std::vector<std::string> &eventElements);
void ParseNormalDequeueEvent(const std::vector<std::string> &eventElements);
void ParsePipelineAuditEvent(int eventType, const std::vector<std::string> &eventElements);
void ParsePipelineCreateEvent(const std::vector<std::string> &eventElements);
void ParsePipelineHandleInEvent(const std::vector<std::string> &eventElements);
void ParsePipelineHandleOutEvent(const std::vector<std::string> &eventElements);
void ParsePipelineDoneEvent(const std::vector<std::string> &eventElements);
uint64_t logStartTime_;
uint64_t logEndTime_;
bool parsed_;
std::map<int, std::string> threadNameMap_;
std::list<EventInfo> eventList_;
std::list<PipelineEventInfo> pipelineEventList_;
};
} // namespace HiviewDFX
} // namespace OHOS
#endif // BASE_HIVIEWDFX_HIVIEW_PLUGIN_MANAGEMENT_AUDIT_LOG_PARSER_H

31
base/include/defines.h Normal file
View File

@ -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.
*/
#ifndef HIVIEW_BASE_DEFINES_H
#define HIVIEW_BASE_DEFINES_H
#ifndef __UNUSED
#if defined(_MSC_VER)
#define __UNUSED // Note: actually gcc seems to also supports this syntax.
#else
#if defined(__GNUC__)
#define __UNUSED __attribute__ ((__unused__))
#endif
#endif
#endif
#define DllExport
#endif // HIVIEW_BASE_DEFINES_H

277
base/include/event.h Normal file
View File

@ -0,0 +1,277 @@
/*
* 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 HIVIEW_BASE_EVENT_H
#define HIVIEW_BASE_EVENT_H
#include <list>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <string>
#include <sys/types.h>
#include "defines.h"
#include "public_defines.h"
namespace OHOS {
namespace HiviewDFX {
class DllExport Event : public std::enable_shared_from_this<Event> {
public:
explicit Event(const std::string &sender)
: messageType_(MessageType::NONE),
processType_(ManageType::UNORDERED),
what_(0),
eventId_(0),
happenTime_(0),
targetDispatchTime_(0),
createTime_(0),
sender_(sender),
eventName_(""),
isPipeline_(false),
hasFinish_(false),
hasPending_(false),
traceId_(""),
spanId_(""),
parentSpanId_(""),
traceFlag_(""),
normalExtraInfo_(""),
jsonExtraInfo_("")
{
ResetTimestamp();
};
explicit Event(const std::string &sender, const std::string &name)
: messageType_(MessageType::NONE),
processType_(ManageType::UNORDERED),
what_(0),
eventId_(0),
happenTime_(0),
targetDispatchTime_(0),
createTime_(0),
sender_(sender),
eventName_(name),
isPipeline_(false),
hasFinish_(false),
hasPending_(false),
traceId_(""),
spanId_(""),
parentSpanId_(""),
traceFlag_(""),
normalExtraInfo_(""),
jsonExtraInfo_("")
{
ResetTimestamp();
};
virtual ~Event() {};
virtual bool OnContinue()
{
return true;
};
virtual bool OnFinish()
{
hasFinish_ = true;
return true;
};
virtual void OnRepack() {};
virtual void OnPending() {};
virtual uint32_t GetPendingProcessorSize()
{
return 0;
}
// call from audit module
// if you want to override this function
// you should call parent function first and append to your result
virtual std::string GetEventInfo()
{
return std::to_string(eventId_);
};
// use for broadcasting events
enum MessageType {
NONE = 0,
PLUGIN_MAINTENANCE, // Reserved
FAULT_EVENT,
STATISTICS_EVENT,
RAW_EVENT,
UE_EVENT,
EXTERNAL_EVENT,
CROSS_PLATFORM,
PRIVATE_MESSAGE_TYPE // Expand macro from public_defines.h
};
enum ManageType {
ORDERED,
UNORDERED,
PROCESS_TYPE_NUM,
};
enum EventId {
PLUGIN_LOADED,
};
MessageType messageType_;
ManageType processType_;
uint16_t what_;
uint32_t eventId_;
uint64_t happenTime_;
uint64_t targetDispatchTime_;
uint64_t createTime_;
std::string sender_;
std::string eventName_;
bool isPipeline_;
bool hasFinish_;
bool hasPending_;
// dft fault listener params
std::string traceId_;
std::string spanId_;
std::string parentSpanId_;
std::string traceFlag_;
std::string normalExtraInfo_;
std::string jsonExtraInfo_;
void SetValue(const std::string &name, const std::string &value);
void SetValue(const std::string &name, int32_t value);
void SetKeyValuePairs(std::map<std::string, std::string> keyValuePairs);
const std::string GetValue(const std::string &name) const;
int32_t GetIntValue(const std::string &name) const;
void ResetTimestamp();
void ResetPendingStatus()
{
hasPending_ = false;
};
bool IsPipelineEvent() const
{
return isPipeline_;
};
bool HasFinish() const
{
return hasFinish_;
};
bool HasPending() const
{
return hasPending_;
};
std::string GetEventName() const
{
return eventName_;
}
void SetEventName(const std::string &name)
{
eventName_ = name;
}
template <typename Derived>
static std::shared_ptr<Derived> DownCastTo(std::shared_ptr<Event> event)
{
return std::static_pointer_cast<Derived>(event);
};
// Ensure the copy constructor of Base and Derived classes are carefully arranged
template <typename Base, typename Derived>
static std::shared_ptr<Derived> Repack(std::shared_ptr<Event>& event, bool replace = true)
{
auto base = std::static_pointer_cast<Base>(event);
if (replace) {
auto derived = new Derived(*(base.get()));
event.reset(derived);
return std::static_pointer_cast<Derived>(event);
}
auto newEvent = std::make_shared<Derived>(*(base.get()));
newEvent->OnRepack();
return newEvent;
};
protected:
std::map<std::string, std::string> bundle_;
};
class DllExport EventHandler {
public:
virtual ~EventHandler(){};
virtual bool OnEvent(std::shared_ptr<Event>& event) = 0;
virtual bool OnEventProxy(std::shared_ptr<Event> event)
{
return OnEvent(event);
};
virtual bool CanProcessEvent(std::shared_ptr<Event> event __UNUSED)
{
return true;
};
virtual bool CanProcessMoreEvents()
{
return true;
};
virtual std::string GetHandlerInfo()
{
return "";
};
};
class EventListener {
public:
struct EventIdRange {
uint32_t begin;
uint32_t end;
EventIdRange(uint32_t id)
{
begin = id;
end = id;
};
EventIdRange(uint32_t begin, uint32_t end)
{
this->begin = begin;
this->end = end;
};
bool operator<(const EventIdRange &range) const
{
return (end < range.begin);
};
bool operator==(const EventIdRange &range) const
{
return ((begin == range.begin) && (end == range.end));
};
};
EventListener() {};
virtual ~EventListener(){};
virtual bool OnOrderedEvent(Event &msg) = 0;
virtual void OnUnorderedEvent(const Event &msg) = 0;
virtual std::string GetListenerName() = 0;
// Make sure that you insert non-overlayed range
void AddListenerInfo(uint32_t type, const EventIdRange &range = EventListener::EventIdRange(0));
void AddListenerInfo(uint32_t type, const std::set<EventIdRange> &listenerInfo);
bool GetListenerInfo(uint32_t type, std::set<EventIdRange> &listenerInfo);
private:
std::map<uint32_t, std::set<EventIdRange>> listenerInfo_;
};
} // namespace HiviewDFX
} // namespace OHOS
#endif // HIVIEW_BASE_EVENT_H

View File

@ -0,0 +1,59 @@
/*
* 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 HIVIEW_BASE_EVENT_DISPATCH_QUEUE_IMPL_H
#define HIVIEW_BASE_EVENT_DISPATCH_QUEUE_IMPL_H
#include <condition_variable>
#include <list>
#include <memory>
#include <mutex>
#include <string>
#include <thread>
#include "event.h"
namespace OHOS {
namespace HiviewDFX {
class EventDispatchQueue {
public:
EventDispatchQueue(const std::string& name, Event::ManageType type);
~EventDispatchQueue();
void Stop();
void Start();
void Enqueue(std::shared_ptr<Event> event);
void RegisterListener(std::weak_ptr<EventListener> listener);
int GetWaitQueueSize() const;
bool IsRunning() const
{
return isRunning_;
}
private:
void Run();
void ProcessOrderedEvent(Event &event);
void ProcessUnorderedEvent(const Event &event);
bool IsEventMatchCurrentListener(const Event& event, std::shared_ptr<EventListener> listener);
volatile bool stop_;
bool isRunning_ = false;
std::string threadName_;
Event::ManageType type_;
mutable std::mutex mutexLock_;
std::condition_variable condition_;
std::list<std::shared_ptr<Event>> pendingEvents_;
std::list<std::weak_ptr<EventListener>> listeners_;
std::unique_ptr<std::thread> thread_;
};
} // namespace HiviewDFX
} // namespace OHOS
#endif // HIVIEW_BASE_EVENT_DISPATCH_QUEUE_IMPL_H

View File

@ -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 HIVIEW_BASE_EVENT_DISPATCHER_H
#define HIVIEW_BASE_EVENT_DISPATCHER_H
#include <map>
#include <memory>
#include <mutex>
#include <string>
#include "event.h"
namespace OHOS {
namespace HiviewDFX {
class EventDispatcher {
public:
EventDispatcher(){};
~EventDispatcher() = default;
void AddInterestType(int32_t type);
void ClearInvalidListeners();
void DispatchEvent(Event event);
void RegisterListener(std::weak_ptr<EventListener> listener);
protected:
std::set<int32_t> types_;
std::map<int32_t, std::list<std::weak_ptr<EventListener>>> channelMapper_;
private:
std::mutex lock_;
};
} // namespace HiviewDFX
} // namespace OHOS
#endif // HIVIEW_BASE_EVENT_DISPATCHER_H

171
base/include/event_loop.h Normal file
View File

@ -0,0 +1,171 @@
/*
* 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 HIVIEW_BASE_EVENT_LOOP_H
#define HIVIEW_BASE_EVENT_LOOP_H
#include <algorithm>
#include <atomic>
#include <future>
#include <map>
#include <memory>
#include <queue>
#include <sys/types.h>
#include <utility>
#include "defines.h"
#include "event.h"
#include "unique_fd.h"
namespace OHOS {
namespace HiviewDFX {
constexpr int LOOP_WAKEUP_HANDLE_INDEX = 0;
constexpr int MAX_EVENT_SIZE = 16;
constexpr int MAX_HANDLE_ARRAY_SIZE = 1;
constexpr uint64_t SECOND_TO_MICROSECOND = 1000000;
constexpr uint64_t SECOND_TO_NANOSECOND = 1000000000;
constexpr uint64_t NANOSECOND_TO_MILLSECOND = 1000000;
constexpr uint64_t MICROSECOND_TO_MILLSECOND = 1000;
constexpr uint64_t MICROSECOND_TO_NANOSECOND = 1000;
using Task = std::function<void()>;
enum LoopEventType {
LOOP_EVENT_TASK,
LOOP_PACKAGED_TASK,
};
struct LoopEvent {
bool isRepeat = false;
uint8_t taskType = 0;
uint64_t seq = 0;
uint64_t interval = 0;
uint64_t enqueueTime = 0;
uint64_t targetTime = 0;
std::shared_ptr<Event> event = nullptr;
std::shared_ptr<EventHandler> handler = nullptr;
Task task = nullptr;
std::shared_ptr<std::packaged_task<bool()>> packagedTask = nullptr;
static LoopEvent CreateLoopEvent(uint64_t now)
{
LoopEvent event;
event.isRepeat = false;
event.taskType = LOOP_EVENT_TASK;
event.seq = now;
event.interval = 0;
event.enqueueTime = now;
event.targetTime = now;
event.event = nullptr;
event.handler = nullptr;
event.task = nullptr;
event.packagedTask = nullptr;
return event;
}
bool operator<(const LoopEvent &obj) const
{
// as we use std::priority_queue, the event with smaller target time will be in the top of the queue
return (this->targetTime > obj.targetTime);
}
};
class EventLoopPriorityQueue : public std::priority_queue<LoopEvent, std::vector<LoopEvent>> {
public:
bool remove(uint64_t seq)
{
auto it = std::find_if(this->c.begin(), this->c.end(), [seq](LoopEvent event) {
return event.seq == seq;
});
if (it != this->c.end()) {
this->c.erase(it);
std::make_heap(this->c.begin(), this->c.end(), this->comp);
return true;
} else {
return false;
};
};
};
class FileDescriptorEventCallback {
public:
virtual ~FileDescriptorEventCallback(){};
virtual bool OnFileDescriptorEvent(int fd, int Type) = 0;
virtual int32_t GetPollFd() = 0;
virtual int32_t GetPollType() = 0;
};
class DllExport EventLoop {
public:
explicit EventLoop(const std::string &name);
virtual ~EventLoop();
void StartLoop(bool createNewThread = true);
void StopLoop();
// poll event from file descriptor source
// the interfaces may change on windows platform
bool AddFileDescriptorEventCallback(const std::string &name, std::shared_ptr<FileDescriptorEventCallback> source);
bool RemoveFileDescriptorEventCallback(const std::string &name);
// process event immediately
uint64_t AddEvent(std::shared_ptr<EventHandler> handler, std::shared_ptr<Event> event, const Task task = nullptr);
std::future<bool> AddEventForResult(std::shared_ptr<EventHandler> handler, std::shared_ptr<Event> event);
// process delayed event
// interval in seconds
uint64_t AddTimerEvent(std::shared_ptr<EventHandler> handler, std::shared_ptr<Event> event, const Task &task,
uint64_t interval, bool repeat);
bool RemoveEvent(uint64_t seq);
const std::string &GetName() const
{
return name_;
};
bool IsRunning() const
{
return isRunning_;
};
private:
// call from audit module
std::string GetHandlerInfo(const LoopEvent &)
{
return "";
};
bool InitEventQueueNotifier();
void Run();
void WakeUp();
uint64_t ProcessQueuedEvent();
void WaitNextEvent(uint64_t leftTimeNanosecond);
bool FetchNextEvent(uint64_t now, uint64_t& leftTimeNanosecond, LoopEvent& event);
void ProcessEvent(LoopEvent &event);
void ReInsertPeriodicEvent(uint64_t now, LoopEvent &event);
void ResetTimerIfNeedLocked();
uint64_t NanoSecondSinceSystemStart();
volatile bool isWaken_ = false;
volatile bool needQuit_ = false;
volatile bool isRunning_ = false;
std::string name_;
EventLoopPriorityQueue pendingEvents_;
std::unique_ptr<std::thread> thread_;
std::mutex queueMutex_;
UniqueFd pendingEventQueueFd_;
UniqueFd sharedPollingFd_;
std::map<int32_t, std::shared_ptr<FileDescriptorEventCallback>> eventSourceMap_;
std::map<std::string, int32_t> eventSourceNameMap_;
uint64_t nextWakeupTime_;
std::atomic<LoopEvent *> currentProcessingEvent_;
};
} // namespace HiviewDFX
} // namespace OHOS
#endif // HIVIEW_BASE_EVENT_LOOP_H

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HIVIEW_BASE_EVENT_SOURCE_H
#define HIVIEW_BASE_EVENT_SOURCE_H
#include <memory>
#include "event_loop.h"
#include "plugin.h"
#include "pipeline.h"
namespace OHOS {
namespace HiviewDFX {
class EventSource : public PipelineEventProducer, public Plugin {
public:
EventSource() {};
virtual ~EventSource() {};
virtual void StartEventSource();
bool PublishPipelineEvent(std::shared_ptr<PipelineEvent> event);
void AddPipeline(std::shared_ptr<Pipeline> pipeline);
private:
std::list<std::shared_ptr<Pipeline>> listeners_;
};
} // namespace HiviewDFX
} // namespace OHOS
#endif // HIVIEW_BASE_EVENT_SOURCE_H

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HIVIEW_UTILITY_PLATFORM_GLOBAL_H
#define HIVIEW_UTILITY_PLATFORM_GLOBAL_H
#include <memory>
#include "plugin.h"
namespace OHOS {
namespace HiviewDFX {
class HiviewGlobal {
public:
explicit HiviewGlobal(HiviewContext& context) : context_(context) {}
~HiviewGlobal() {};
static void CreateInstance(HiviewContext& context);
// maybe null reference, check before use
static std::unique_ptr<HiviewGlobal>& GetInstance();
std::string GetHiViewDirectory(HiviewContext::DirectoryType type) const;
void PostAsyncEventToTarget(const std::string& targetPlugin, std::shared_ptr<Event> event);
bool PostSyncEventToTarget(const std::string& targetPlugin, std::shared_ptr<Event> event);
private:
HiviewContext& context_;
};
} // namespace HiviewDFX
} // namespace OHOS
#endif // HIVIEW_UTILITY_PLATFORM_GLOBAL_H

47
base/include/logger.h Normal file
View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HIVIEW_BASE_LOGGER_H
#define HIVIEW_BASE_LOGGER_H
#include <hilog/log.h>
// All Log domain in hiview should has the prefix of 0xD002D
// And every src file use this header should define LOG_DOMAIN and LOG_TAG
#define DEFINE_LOG_TAG(name) \
static unsigned int logLabelDomain = 0xD002D10; \
static const char *logLabelTag = name
#define DEFINE_LOG_LABEL(region, name) \
static unsigned int logLabelDomain = region; \
static const char *logLabelTag = name
int HiviewLogDebug(const char *tag, unsigned int domain, const char *format, ...);
int HiviewLogInfo(const char *tag, unsigned int domain, const char *format, ...);
int HiviewLogWarn(const char *tag, unsigned int domain, const char *format, ...);
int HiviewLogError(const char *tag, unsigned int domain, const char *format, ...);
int HiviewLogFatal(const char *tag, unsigned int domain, const char *format, ...);
#define HIVIEW_LOGD(format, ...) \
HiviewLogDebug(logLabelTag, logLabelDomain, "%s " format, __FUNCTION__, ##__VA_ARGS__)
#define HIVIEW_LOGI(format, ...) \
HiviewLogInfo(logLabelTag, logLabelDomain, "%s " format, __FUNCTION__, ##__VA_ARGS__)
#define HIVIEW_LOGW(format, ...) \
HiviewLogWarn(logLabelTag, logLabelDomain, "%s " format, __FUNCTION__, ##__VA_ARGS__)
#define HIVIEW_LOGE(format, ...) \
HiviewLogError(logLabelTag, logLabelDomain, "%s " format, __FUNCTION__, ##__VA_ARGS__)
#define HIVIEW_LOGF(format, ...) \
HiviewLogFatal(logLabelTag, logLabelDomain, "%s " format, __FUNCTION__, ##__VA_ARGS__)
#endif // HIVIEW_BASE_LOGGER_H

142
base/include/pipeline.h Normal file
View File

@ -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.
*/
#ifndef HIVIEW_BASE_PIPELINE_H
#define HIVIEW_BASE_PIPELINE_H
#include <memory>
#include "event.h"
#include "event_loop.h"
#include "plugin.h"
namespace OHOS {
namespace HiviewDFX {
class Pipeline;
class PipelineEventProducer;
class PipelineEvent : public Event {
public:
PipelineEvent(const std::string& sender, PipelineEventProducer* handler)
: Event(sender), handler_(handler), startDeliver_(false), pipelineName_("")
{
isPipeline_ = true;
};
PipelineEvent(const Event& event) : Event(event), handler_(nullptr), startDeliver_(false), pipelineName_("")
{
isPipeline_ = true;
};
PipelineEvent(const PipelineEvent& obj)
: Event(obj),
inputLogfileParamList_(std::move(obj.inputLogfileParamList_)),
deleteLogfileParamList_(std::move(obj.deleteLogfileParamList_)),
handler_(obj.handler_),
startDeliver_(obj.startDeliver_),
pipelineName_(obj.pipelineName_),
processors_(std::move(obj.processors_)){};
PipelineEvent& operator=(const PipelineEvent& obj)
{
if (&obj == this) {
return *this;
}
Event::operator=(obj);
inputLogfileParamList_ = std::move(obj.inputLogfileParamList_);
deleteLogfileParamList_ = std::move(obj.deleteLogfileParamList_);
handler_ = obj.handler_;
startDeliver_ = obj.startDeliver_;
pipelineName_ = obj.pipelineName_;
processors_ = std::move(obj.processors_);
return *this;
};
virtual ~PipelineEvent(){};
void OnRepack() override;
void OnPending() override;
bool OnContinue() override;
bool OnFinish() override;
uint32_t GetPendingProcessorSize() override;
void SetPipelineInfo(const std::string& pipelineName, std::list<std::weak_ptr<Plugin>>& processors);
std::string GetPipelineInfo();
std::list<std::string> inputLogfileParamList_;
std::list<std::string> deleteLogfileParamList_;
// transform an event into pipeline event
// fill with pipeline info of given name
// the new event share no relationship with the old one
// EventType should be the correct type of the event object
// PipelineEventType should be the type of the target repack type
// copy construct will be invoked in the repack process
template <typename EventType, typename PipelineEventType>
static std::shared_ptr<PipelineEventType> RepackPipelineEvent(std::shared_ptr<Plugin> caller,
const std::string& pipelineName,
std::shared_ptr<Event>& event,
bool deliverFromCurrent)
{
auto base = std::static_pointer_cast<EventType>(event);
auto derived = std::make_shared<PipelineEventType>(*(base.get()));
auto pipe = std::static_pointer_cast<PipelineEvent>(derived);
pipe->OnRepack();
FillPipelineInfo(caller, pipelineName, pipe, deliverFromCurrent);
return derived;
};
static void FillPipelineInfo(std::shared_ptr<Plugin> caller, const std::string& pipelineName,
std::shared_ptr<PipelineEvent> event, bool deliverFromCurrent);
private:
PipelineEventProducer* handler_;
bool startDeliver_;
std::string pipelineName_;
std::list<std::weak_ptr<Plugin>> processors_;
};
class PipelineEventProducer {
public:
virtual ~PipelineEventProducer(){};
// Notify event producer that an event has finish it's delivery
virtual void Recycle(PipelineEvent* event) = 0;
// Pause dispatch and schedule resume dispatch
virtual void PauseDispatch(std::weak_ptr<Plugin> plugin) = 0;
};
class Pipeline : public std::enable_shared_from_this<Pipeline> {
public:
Pipeline(const std::string& name, std::list<std::weak_ptr<Plugin>>& processors)
: name_(name), processors_(std::move(processors)){};
bool CanProcessEvent(std::shared_ptr<PipelineEvent> event);
void ProcessEvent(std::shared_ptr<PipelineEvent> event);
~Pipeline() {};
const std::string& GetName() const
{
return name_;
};
std::list<std::weak_ptr<Plugin>> GetProcessSequence()
{
return processors_;
};
private:
std::string name_;
std::list<std::weak_ptr<Plugin>> processors_;
};
} // namespace HiviewDFX
} // namespace OHOS
#endif // HIVIEW_BASE_PIPELINE_H

196
base/include/plugin.h Normal file
View File

@ -0,0 +1,196 @@
/*
* 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 HIVIEW_BASE_PLUGIN_H
#define HIVIEW_BASE_PLUGIN_H
#include <ctime>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
#include "defines.h"
#include "dynamic_module.h"
#include "event.h"
#include "event_loop.h"
#include "plugin_extra_info.h"
class HiEvent;
namespace OHOS {
namespace HiviewDFX {
class HiviewContext;
class DllExport Plugin : public EventHandler, public std::enable_shared_from_this<Plugin> {
public:
Plugin() : handle_(DynamicModuleDefault), context_(nullptr){};
virtual ~Plugin();
// do not store the event in the callback
// create a new one through copy constructor is preferred
virtual bool OnEvent(std::shared_ptr<Event>& event) override;
virtual bool CanProcessEvent(std::shared_ptr<Event> event) override;
virtual bool CanProcessMoreEvents() override;
bool OnEventProxy(std::shared_ptr<Event> event) override;
virtual std::string GetHandlerInfo() override;
// check whether the plugin should be loaded in current environment
// the plugin will not be load if return false
// called by plugin framework in main thread
virtual bool ReadyToLoad()
{
return true;
};
// the plugin instance will be stored in platform after calling this function
// and other loaded plugin can pass event to this plugin
// called by plugin framework in main thread
virtual void OnLoad(){};
// release resource and clear pending workloads
// after calling this function ,the reference of this plugin will be deleted
// called by plugin framework in main thread
virtual void OnUnload(){};
// dump plugin info from dump command line
virtual void Dump(int fd __UNUSED, const std::vector<std::string>& cmds __UNUSED) {};
// create an event with specific type
virtual std::shared_ptr<Event> GetEvent(Event::MessageType type)
{
auto event = std::make_shared<Event>(name_);
event->messageType_ = type;
return event;
};
// called by audit module
virtual std::string GetPluginInfo();
// reinsert the event into the workloop
// delay in seconds
void DelayProcessEvent(std::shared_ptr<Event> event, uint64_t delay);
const std::string& GetName();
const std::string& GetVersion();
void SetName(const std::string& name);
void SetVersion(const std::string& version);
void BindWorkLoop(std::shared_ptr<EventLoop> loop);
std::shared_ptr<EventLoop> GetWorkLoop();
bool IsDynamic() const
{
return (handle_ != DynamicModuleDefault);
};
HiviewContext* GetHiviewContext()
{
return context_;
};
void SetHiviewContext(HiviewContext* context)
{
std::call_once(contextSetFlag_, [&]() { context_ = context; });
};
void SetHandle(DynamicModule handle)
{
handle_ = handle;
};
protected:
std::string name_;
std::string version_;
std::shared_ptr<EventLoop> workLoop_;
private:
DynamicModule handle_;
// the reference of the plugin platform
// always available in framework callbacks
HiviewContext* context_;
std::once_flag contextSetFlag_;
};
class HiviewContext {
public:
virtual ~HiviewContext(){};
// post event to broadcast queue, the event will be terminated delivering if consumed by one plugin
virtual void PostOrderedEvent(std::shared_ptr<Plugin> plugin __UNUSED, std::shared_ptr<Event> event __UNUSED) {};
// post event to broadcast queue, the event will be delivered to all plugin that concern this event
virtual void PostUnorderedEvent(std::shared_ptr<Plugin> plugin __UNUSED, std::shared_ptr<Event> event __UNUSED) {};
// register listener to ordered broadcast queue
// for the reason that no business use this interface, mark it as deprecated
virtual void RegisterOrderedEventListener(std::weak_ptr<EventListener> listener __UNUSED) {};
// register listener to unordered broadcast queue
virtual void RegisterUnorderedEventListener(std::weak_ptr<EventListener> listener __UNUSED) {};
// send a event to a specific plugin and wait the return of the OnEvent.
virtual bool PostSyncEventToTarget(std::shared_ptr<Plugin> caller __UNUSED, const std::string& callee __UNUSED,
std::shared_ptr<Event> event __UNUSED)
{
return true;
}
// send a event to a specific plugin and return at once
virtual void PostAsyncEventToTarget(std::shared_ptr<Plugin> caller __UNUSED, const std::string& callee __UNUSED,
std::shared_ptr<Event> event __UNUSED) {};
// post event to distributed communicator plugin, to send to remote device
virtual int32_t PostEventToRemote(std::shared_ptr<Plugin> caller __UNUSED, const std::string& deviceId __UNUSED,
const std::string& targetPlugin __UNUSED, std::shared_ptr<Event> event __UNUSED)
{
return 0;
}
// request plugin platform to release plugin instance
// do not recommend unload an plugin in pipeline scheme
// platform will check the reference count if other module still holding the reference of this module
virtual void RequestUnloadPlugin(std::shared_ptr<Plugin> caller __UNUSED) {};
// publish plugin capacity and get remote capacity
virtual void PublishPluginCapacity(PluginCapacityInfo &pluginCapacityInfo __UNUSED) {};
virtual void GetRemoteByCapacity(const std::string& plugin __UNUSED, const std::string& capacity __UNUSED,
std::list<std::string> &deviceIdList __UNUSED) {};
// get the shared event loop reference
virtual std::shared_ptr<EventLoop> GetSharedWorkLoop()
{
return nullptr;
}
// get predefined pipeline list
virtual std::list<std::weak_ptr<Plugin>> GetPipelineSequenceByName(const std::string& name __UNUSED)
{
return std::list<std::weak_ptr<Plugin>>(0);
}
// check if all non-pending loaded plugins are loaded
virtual bool IsReady()
{
return false;
}
enum class DirectoryType {
CONFIG_DIRECTORY,
CLOUD_UPDATE_DIRECTORY,
WORK_DIRECTORY,
PERSIST_DIR,
};
// get hiview available directory
virtual std::string GetHiViewDirectory(DirectoryType type __UNUSED)
{
return "";
}
};
} // namespace HiviewDFX
} // namespace OHOS
#endif // HIVIEW_BASE_PLUGIN_H

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HIVIEW_BASE_PLUGIN_FACTORY_H
#define HIVIEW_BASE_PLUGIN_FACTORY_H
#include <map>
#include <memory>
#include "plugin.h"
namespace OHOS {
namespace HiviewDFX {
using PluginInstance = std::shared_ptr<Plugin> (*)();
class DllExport PluginFactory {
public:
static void RegisterPlugin(const std::string& name, PluginInstance func);
static void UnregisterPlugin(const std::string& name);
static std::shared_ptr<Plugin> GetPlugin(const std::string& name);
private:
static std::shared_ptr<std::map<std::string, PluginInstance>> GetGlobalPluginRegistryMap();
};
class PluginRegister {
public:
PluginRegister(const std::string& name, PluginInstance fp)
{
PluginFactory::RegisterPlugin(name, fp);
};
~PluginRegister(){};
};
#define REGISTER(ClassName) \
class Register##ClassName { \
public: \
static std::shared_ptr<Plugin> Instance() \
{ \
return std::make_shared<ClassName>(); \
} \
\
private: \
static const PluginRegister g_staticPluginRegister; \
}; \
const PluginRegister Register##ClassName::g_staticPluginRegister(#ClassName, Register##ClassName::Instance);
} // namespace HiviewDFX
} // namespace OHOS
#endif // HIVIEW_BASE_PLUGIN_FACTORY_H

94
base/logger.cpp Normal file
View File

@ -0,0 +1,94 @@
/*
* 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 "logger.h"
#include <cstdarg>
#include <cstdio>
#include <securec.h>
#include "hilog/log.h"
#ifdef LOG_DOMAIN
#undef LOG_DOMAIN
#define LOG_DOMAIN 0xD002D10
#endif
constexpr int LOG_BUF_LEN = 1024;
int HiviewLogDebug(const char *tag, unsigned int domain, const char *format, ...)
{
OHOS::HiviewDFX::HiLogLabel logLabel = {LOG_CORE, domain, tag};
int ret;
char buf[LOG_BUF_LEN] = {0};
va_list args;
va_start(args, format);
ret = vsnprintf_s(buf, LOG_BUF_LEN, LOG_BUF_LEN - 1, format, args);
va_end(args);
OHOS::HiviewDFX::HiLog::Debug(logLabel, "%{public}s ", buf);
return ret;
}
int HiviewLogInfo(const char *tag, unsigned int domain, const char *format, ...)
{
OHOS::HiviewDFX::HiLogLabel logLabel = {LOG_CORE, domain, tag};
int ret;
char buf[LOG_BUF_LEN] = {0};
va_list args;
va_start(args, format);
ret = vsnprintf_s(buf, LOG_BUF_LEN, LOG_BUF_LEN - 1, format, args);
va_end(args);
OHOS::HiviewDFX::HiLog::Info(logLabel, "%{public}s", buf);
return ret;
}
int HiviewLogWarn(const char *tag, unsigned int domain, const char *format, ...)
{
OHOS::HiviewDFX::HiLogLabel logLabel = {LOG_CORE, domain, tag};
int ret;
char buf[LOG_BUF_LEN] = {0};
va_list args;
va_start(args, format);
ret = vsnprintf_s(buf, LOG_BUF_LEN, LOG_BUF_LEN - 1, format, args);
va_end(args);
OHOS::HiviewDFX::HiLog::Warn(logLabel, "%{public}s", buf);
return ret;
}
int HiviewLogError(const char *tag, unsigned int domain, const char *format, ...)
{
OHOS::HiviewDFX::HiLogLabel logLabel = {LOG_CORE, domain, tag};
int ret;
char buf[LOG_BUF_LEN] = {0};
va_list args;
va_start(args, format);
ret = vsnprintf_s(buf, LOG_BUF_LEN, LOG_BUF_LEN - 1, format, args);
va_end(args);
OHOS::HiviewDFX::HiLog::Error(logLabel, "%{public}s", buf);
return ret;
}
int HiviewLogFatal(const char *tag, unsigned int domain, const char *format, ...)
{
OHOS::HiviewDFX::HiLogLabel logLabel = {LOG_CORE, domain, tag};
int ret;
char buf[LOG_BUF_LEN] = {0};
va_list args;
va_start(args, format);
ret = vsnprintf_s(buf, LOG_BUF_LEN, LOG_BUF_LEN - 1, format, args);
va_end(args);
OHOS::HiviewDFX::HiLog::Fatal(logLabel, "%{public}s", buf);
return ret;
}

38
base/logstore/BUILD.gn Normal file
View File

@ -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.
import("//base/hiviewdfx/hiview/hiview.gni")
import("//build/ohos.gni")
config("log_store_config") {
visibility = [ "*:*" ]
include_dirs = [ "include" ]
cflags_cc = [ "-D__HIVIEW_OHOS__" ]
}
ohos_source_set("log_store") {
public_configs = [ ":log_store_config" ]
sources = [
"log_file.cpp",
"log_store_ex.cpp",
]
deps = [
"$hiview_adapter/system_service:system_service",
"$hiview_base:hiview_base",
]
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LOG_STORE_LOG_FILE_H
#define LOG_STORE_LOG_FILE_H
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
namespace OHOS {
namespace HiviewDFX {
class LogFile {
public:
// base path should be end with "/", and if name contains slash which means
// the name has sub directories
explicit LogFile(const std::string& fullPath);
~LogFile() {};
bool operator < (const LogFile& other) const
{
return (mtime_ < other.mtime_);
}
// Attributes
bool isValid_ = true;
bool isDir_ = false;
off_t size_ = 0;
time_t mtime_ = 0;
std::string path_ = "";
std::string name_ = "";
};
} // namespace HiviewDFX
} // namespace OHOS
#endif // LOG_STORE_LOG_FILE_H

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LOG_STORE_LOG_STORE_EX_H
#define LOG_STORE_LOG_STORE_EX_H
#include "log_file.h"
#include <cinttypes>
#include <functional>
#include <ostream>
#include <string>
#include <vector>
#include <sys/stat.h>
#include <unistd.h>
namespace OHOS {
namespace HiviewDFX {
class LogStoreEx {
public:
using LogFileFilter = std::function<bool(const LogFile&)>;
using LogFileComparator = std::function<bool(const LogFile&, const LogFile&)>;
using FileHandle = int32_t;
// managing logs in specific path with following functions
// 1. get logs in specific order
// 2. remove old logs in specific rule
LogStoreEx(const std::string& path, bool autoDeleteFiles = false);
~LogStoreEx() {};
// create path with expected permission
bool Init();
void SetLogFileComparator(LogFileComparator comparator);
// Get all files in log store, sorted by last modify time by default
std::vector<LogFile> GetLogFiles();
std::vector<LogFile> GetLogFiles(LogFileFilter filter);
// Get the path managed by store
const std::string& GetPath() const;
// Remove all log files in managed folder
bool Clear();
// remove file according to the size and file count quota
// keep minimum number of file in store
void ClearOldestFilesIfNeeded();
// remove filtered files if the number of files exceeds maximum count
void ClearSameLogFilesIfNeeded(LogFileFilter filter, uint32_t maxCount);
// create a log file inside store path
FileHandle CreateLogFile(const std::string& name);
bool RemoveLogFile(const std::string& name);
void SetMaxSize(uint32_t size);
void SetMinKeepingFileNumber(uint32_t number);
protected:
bool autoDeleteFiles_;
uint32_t maxSize_;
uint32_t minKeepingNumberOfFiles_;
LogFileComparator comparator_;
std::string path_;
private:
void DoDeleteLogFiles(const std::vector<LogFile> &fileList, int32_t removeFileNums) const;
};
} // namespace HiviewDFX
} // namespace OHOS
#endif // LOG_STORE_LOG_STORE_EX_H

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "log_file.h"
#include <list>
#include <stack>
#include <string>
#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "file_util.h"
namespace OHOS {
namespace HiviewDFX {
LogFile::LogFile(const std::string& fullPath) : path_(fullPath)
{
struct stat sb;
if ((fullPath.length() == 0) || (stat(fullPath.c_str(), &sb) == -1)) {
isValid_ = false;
} else {
mtime_ = sb.st_mtime;
isDir_ = (S_ISDIR(sb.st_mode) != 0);
if (!isDir_) {
size_ = sb.st_size;
} else {
size_ = FileUtil::GetFolderSize(fullPath);
}
}
name_ = FileUtil::ExtractFileName(fullPath);
}
} // namespace HiviewDFX
} // namespace OHOS

View File

@ -0,0 +1,176 @@
/*
* 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 "log_store_ex.h"
#include <fstream>
#include <functional>
#include <string>
#include <vector>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "file_util.h"
#include "log_file.h"
#include "logger.h"
namespace OHOS {
namespace HiviewDFX {
DEFINE_LOG_TAG("HiView-LogStoreEx");
constexpr int32_t DEFAULT_LOGSTORE_SIZE = 1024 * 1024 * 10;
constexpr int32_t DEFAULT_LOGSTORE_MIN_KEEP_FILE_COUNT = 100;
constexpr mode_t DEFAULT_LOG_FILE_MODE = 0664;
constexpr mode_t DEFAULT_LOG_DIR_MODE = 0770;
LogStoreEx::LogStoreEx(const std::string& path, bool autoDeleteFiles)
: autoDeleteFiles_(autoDeleteFiles),
maxSize_(DEFAULT_LOGSTORE_SIZE),
minKeepingNumberOfFiles_(DEFAULT_LOGSTORE_MIN_KEEP_FILE_COUNT),
comparator_(nullptr),
path_(path)
{}
bool LogStoreEx::Init()
{
if (!FileUtil::FileExists(path_)) {
FileUtil::ForceCreateDirectory(path_);
FileUtil::ChangeModeDirectory(path_, DEFAULT_LOG_DIR_MODE);
}
return true;
}
void LogStoreEx::SetLogFileComparator(LogFileComparator comparator)
{
comparator_ = comparator;
}
void LogStoreEx::SetMaxSize(uint32_t size)
{
maxSize_ = size;
}
void LogStoreEx::SetMinKeepingFileNumber(uint32_t number)
{
minKeepingNumberOfFiles_ = number;
}
const std::string& LogStoreEx::GetPath() const
{
return path_;
}
std::vector<LogFile> LogStoreEx::GetLogFiles()
{
std::vector<std::string> fileVec;
std::vector<LogFile> logFileList;
FileUtil::GetDirFiles(path_, fileVec);
for (auto& filePath : fileVec) {
logFileList.push_back(LogFile(filePath));
}
if (comparator_ != nullptr) {
std::sort(logFileList.begin(), logFileList.end(), comparator_);
} else {
std::sort(logFileList.begin(), logFileList.end());
}
return logFileList;
}
std::vector<LogFile> LogStoreEx::GetLogFiles(LogFileFilter filter)
{
auto logFileList = GetLogFiles();
auto iter = logFileList.begin();
while (iter != logFileList.end()) {
if (!filter(*iter)) {
iter = logFileList.erase(iter);
continue;
}
iter++;
}
return logFileList;
}
bool LogStoreEx::Clear()
{
if (!FileUtil::ForceRemoveDirectory(path_)) {
return false;
}
return Init();
}
void LogStoreEx::DoDeleteLogFiles(const std::vector<LogFile> &fileList, int32_t removeFileNums) const
{
int32_t deleteCount = 0;
for (auto it = fileList.rbegin(); it != fileList.rend(); ++it) {
if (deleteCount >= removeFileNums) {
break;
}
FileUtil::RemoveFile(it->path_);
deleteCount++;
}
HIVIEW_LOGI("Remove %d Files.", deleteCount);
}
void LogStoreEx::ClearOldestFilesIfNeeded()
{
auto size = FileUtil::GetFolderSize(path_);
if (size < maxSize_) {
return;
}
auto fileList = GetLogFiles();
int32_t removeFileNumber = fileList.size() - minKeepingNumberOfFiles_;
if (removeFileNumber < 0) {
removeFileNumber = fileList.size() / 2; // 2 : remove half of the total
}
DoDeleteLogFiles(fileList, removeFileNumber);
}
void LogStoreEx::ClearSameLogFilesIfNeeded(LogFileFilter filter, uint32_t maxCount)
{
auto fileList = GetLogFiles(filter);
uint32_t removeFileNumber = 0;
if (fileList.size() > maxCount) {
removeFileNumber = fileList.size() - maxCount;
}
DoDeleteLogFiles(fileList, removeFileNumber);
}
LogStoreEx::FileHandle LogStoreEx::CreateLogFile(const std::string& name)
{
if (autoDeleteFiles_) {
ClearOldestFilesIfNeeded();
}
auto path = path_ + "/" + name;
auto fd = open(path.c_str(), O_CREAT | O_WRONLY | O_TRUNC, DEFAULT_LOG_FILE_MODE);
if (fd < 0) {
HIVIEW_LOGI("Fail to create %s.", name.c_str());
}
return fd;
}
bool LogStoreEx::RemoveLogFile(const std::string& name)
{
auto path = path_ + "/" + name;
std::string realPath;
if (!FileUtil::PathToRealPath(path, realPath)) {
return false;
}
return FileUtil::RemoveFile(path);
}
} // namespace HiviewDFX
} // namespace OHOS

153
base/pipeline.cpp Normal file
View File

@ -0,0 +1,153 @@
/*
* 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 "pipeline.h"
#include "audit.h"
#include "file_util.h"
#include "logger.h"
#include "thread_util.h"
namespace OHOS {
namespace HiviewDFX {
DEFINE_LOG_TAG("HiView-Pipeline");
void PipelineEvent::OnRepack()
{
startDeliver_ = false;
ResetTimestamp();
}
void PipelineEvent::OnPending()
{
hasPending_ = true;
}
bool PipelineEvent::OnContinue()
{
HIVIEW_LOGD("PipelineEvent OnContinue %s", std::to_string(createTime_).c_str());
if ((!hasFinish_) && processors_.empty()) {
return OnFinish();
}
// once the event start delivering
// the call OnContinue means one has done the processing of the event
// this may be called by upstream event processor or the framework
if (Audit::IsEnabled() && startDeliver_) {
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_HANDLE_OUT,
createTime_, std::to_string(Thread::GetTid()));
}
// the framework will call OnContinue when the event is assigned to a pipeline
if (!startDeliver_) {
startDeliver_ = true;
}
std::weak_ptr<Plugin> plugin = processors_.front();
processors_.pop_front();
if (auto pluginPtr = plugin.lock()) {
if (!pluginPtr->CanProcessMoreEvents()) {
handler_->PauseDispatch(plugin);
}
if (Audit::IsEnabled()) {
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_HANDLE_IN, createTime_,
pluginPtr->GetHandlerInfo());
}
if (auto workLoop = pluginPtr->GetWorkLoop()) {
workLoop->AddEvent(pluginPtr, shared_from_this());
} else {
pluginPtr->OnEventProxy(shared_from_this());
}
} else {
return OnContinue();
}
return true;
}
bool PipelineEvent::OnFinish()
{
HIVIEW_LOGD("PipelineEvent OnFinish");
if (handler_ != nullptr) {
handler_->Recycle(this);
}
hasFinish_ = true;
if (Audit::IsEnabled()) {
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_HANDLE_OUT,
createTime_, std::to_string(Thread::GetTid()));
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_DONE, createTime_, pipelineName_);
}
return true;
}
uint32_t PipelineEvent::GetPendingProcessorSize()
{
return processors_.size();
}
void PipelineEvent::SetPipelineInfo(const std::string& pipelineName, std::list<std::weak_ptr<Plugin>>& processors)
{
pipelineName_ = pipelineName;
processors_ = processors;
}
std::string PipelineEvent::GetPipelineInfo()
{
return pipelineName_;
}
void PipelineEvent::FillPipelineInfo(std::shared_ptr<Plugin> caller, const std::string& pipelineName,
std::shared_ptr<PipelineEvent> event, bool deliverFromCurrent)
{
if (caller == nullptr || event == nullptr || caller->GetHiviewContext() == nullptr) {
return;
}
auto seq = caller->GetHiviewContext()->GetPipelineSequenceByName(pipelineName);
if (deliverFromCurrent) {
while (!seq.empty()) {
auto& plugin = seq.front();
if (auto pluginPtr = plugin.lock()) {
if (pluginPtr == caller) {
break;
}
}
seq.pop_front();
}
}
event->SetPipelineInfo(pipelineName, seq);
}
bool Pipeline::CanProcessEvent(std::shared_ptr<PipelineEvent> event)
{
HIVIEW_LOGD("Pipeline CanProcessEvent");
if (processors_.empty()) {
HIVIEW_LOGI("no processor in this pipeline.");
return false;
}
std::weak_ptr<Plugin> plugin = processors_.front();
if (auto pluginPtr = plugin.lock()) {
return pluginPtr->CanProcessEvent(std::dynamic_pointer_cast<Event>(event));
}
return false;
}
void Pipeline::ProcessEvent(std::shared_ptr<PipelineEvent> event)
{
HIVIEW_LOGD("Pipeline ProcessEvent");
event->SetPipelineInfo(name_, processors_);
event->OnContinue();
}
} // namespace HiviewDFX
} // namespace OHOS

124
base/plugin.cpp Normal file
View File

@ -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.
*/
#include "plugin.h"
#include <functional>
#include "audit.h"
#include "defines.h"
#include "file_util.h"
#include "thread_util.h"
namespace OHOS {
namespace HiviewDFX {
Plugin::~Plugin()
{
if (handle_ != DynamicModuleDefault) {
UnloadModule(handle_);
handle_ = DynamicModuleDefault;
}
if (workLoop_ != nullptr) {
workLoop_->StopLoop();
}
}
bool Plugin::OnEvent(std::shared_ptr<Event>& event __UNUSED)
{
return true;
}
bool Plugin::CanProcessEvent(std::shared_ptr<Event> event __UNUSED)
{
return true;
}
bool Plugin::CanProcessMoreEvents()
{
return true;
}
bool Plugin::OnEventProxy(std::shared_ptr<Event> event)
{
if (event == nullptr) {
return false;
}
std::shared_ptr<Event> dupEvent = event;
auto processorSize = dupEvent->GetPendingProcessorSize();
dupEvent->ResetPendingStatus();
bool ret = OnEvent(dupEvent);
if (!dupEvent->IsPipelineEvent()) {
if (Audit::IsEnabled()) {
Audit::WriteAuditEvent(Audit::StatsEvent::QUEUE_EVENT_OUT, dupEvent->createTime_,
std::to_string(Thread::GetTid()));
}
} else {
if ((!dupEvent->HasFinish() && !dupEvent->HasPending()) &&
(processorSize == dupEvent->GetPendingProcessorSize())) {
dupEvent->OnContinue();
}
}
return ret;
}
void Plugin::DelayProcessEvent(std::shared_ptr<Event> event, uint64_t delay)
{
if (workLoop_ != nullptr && event != nullptr) {
event->OnPending();
auto task = std::bind(&Plugin::OnEventProxy, this, event);
workLoop_->AddTimerEvent(nullptr, nullptr, task, delay, false);
return;
}
}
std::string Plugin::GetPluginInfo()
{
return GetName();
}
std::string Plugin::GetHandlerInfo()
{
return GetName();
}
const std::string& Plugin::GetName()
{
return name_;
}
const std::string& Plugin::GetVersion()
{
return version_;
}
void Plugin::SetName(const std::string& name)
{
name_ = name;
}
void Plugin::SetVersion(const std::string& version)
{
version_ = version;
}
void Plugin::BindWorkLoop(std::shared_ptr<EventLoop> loop)
{
workLoop_ = loop;
}
std::shared_ptr<EventLoop> Plugin::GetWorkLoop()
{
return workLoop_;
}
} // namespace HiviewDFX
} // namespace OHOS

58
base/plugin_factory.cpp Normal file
View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "plugin_factory.h"
#include "logger.h"
namespace OHOS {
namespace HiviewDFX {
DEFINE_LOG_TAG("HiView-PluginFactory");
std::shared_ptr<std::map<std::string, PluginInstance>> PluginFactory::GetGlobalPluginRegistryMap()
{
static std::shared_ptr<std::map<std::string, PluginInstance>> pluginMap;
if (pluginMap == nullptr) {
pluginMap = std::make_shared<std::map<std::string, PluginInstance>>();
}
return pluginMap;
}
void PluginFactory::RegisterPlugin(const std::string& name, PluginInstance func)
{
if (func == nullptr) {
HIVIEW_LOGW("Register null plugin constructor from %s.", name.c_str());
return;
}
// force update plugin constructor
auto pluginMap = GetGlobalPluginRegistryMap();
pluginMap->insert(std::make_pair(name, func));
HIVIEW_LOGD("Register plugin constructor from %s.", name.c_str());
}
void PluginFactory::UnregisterPlugin(const std::string& name)
{
auto pluginMap = GetGlobalPluginRegistryMap();
pluginMap->erase(name);
}
std::shared_ptr<Plugin> PluginFactory::GetPlugin(const std::string& name)
{
auto pluginMap = GetGlobalPluginRegistryMap();
auto it = pluginMap->find(name);
if (it == pluginMap->end()) {
HIVIEW_LOGW("Could not find plugin with name:%s.", name.c_str());
return nullptr;
}
return it->second();
}
} // namespace HiviewDFX
} // namespace OHOS

105
base/test/BUILD.gn Normal file
View File

@ -0,0 +1,105 @@
# 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/hiviewdfx/hiview/hiview.gni")
import("//build/test.gni")
module_output_path = "hiview_L2/hiview_L2"
group("unittest") {
testonly = true
deps = [
":AuditLogParserTest",
":EventDispatchQueueTest",
":EventLoopTest",
":PluginFactoryTest",
":PluginPipelineTest",
]
}
config("unittest_config") {
include_dirs = [
"//utils/native/base/include",
"unittest/common",
]
cflags_cc = [ "-D__UNITTEST__" ]
}
ohos_unittest("EventLoopTest") {
module_out_path = module_output_path
configs = [ ":unittest_config" ]
sources = [ "unittest/common/event_loop_test.cpp" ]
deps = [
"$hiview_base:hiview_base",
"//third_party/googletest:gtest_main",
]
}
ohos_unittest("PluginFactoryTest") {
module_out_path = module_output_path
configs = [ ":unittest_config" ]
sources = [
"unittest/common/plugin_example.cpp",
"unittest/common/plugin_factory_test.cpp",
]
deps = [
"$hiview_base:hiview_base",
"//third_party/googletest:gtest_main",
]
}
ohos_unittest("EventDispatchQueueTest") {
module_out_path = module_output_path
configs = [ ":unittest_config" ]
sources = [ "unittest/common/event_dispatch_queue_test.cpp" ]
deps = [
"$hiview_base:hiview_base",
"//third_party/googletest:gtest_main",
]
}
ohos_unittest("AuditLogParserTest") {
module_out_path = module_output_path
configs = [ ":unittest_config" ]
sources = [ "unittest/common/audit_log_parser_test.cpp" ]
deps = [
"$hiview_base:hiview_base",
"//third_party/googletest:gtest_main",
]
}
ohos_unittest("PluginPipelineTest") {
module_out_path = module_output_path
configs = [ ":unittest_config" ]
sources = [
"unittest/common/pipeline_test.cpp",
"unittest/common/plugin_example.cpp",
]
deps = [
"$hiview_base:hiview_base",
"$hiview_test/plugins/examples/event_processor_example1:event_processor_example1",
"$hiview_test/plugins/examples/event_processor_example2:event_processor_example2",
"$hiview_test/plugins/examples/event_processor_example3:event_processor_example3",
"$hiview_test/plugins/examples/event_processor_example4:event_processor_example4",
"$hiview_test/plugins/examples/event_source_example:event_source_example",
"//third_party/googletest:gtest_main",
]
}

View File

@ -0,0 +1,154 @@
/*
* 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 "audit_log_parser_test.h"
#include "audit.h"
#include "audit_log_parser.h"
#include "pipeline.h"
using namespace testing::ext;
using namespace OHOS::HiviewDFX;
void AuditLogParserTest::SetUp()
{
Audit::GetInstance().Init(true);
Audit::GetInstance().Clear();
}
/**
* @tc.name: AuditLogParserTest001
* @tc.desc: write normal event log into audit log and then parse it
* @tc.type: FUNC
* @tc.require: AR000DPTT2
*/
HWTEST_F(AuditLogParserTest, AuditLogParserTest001, TestSize.Level3)
{
Audit::WriteAuditEvent(Audit::StatsEvent::QUEUE_EVENT_IN, 1585730002219098,
"EventProcessorExample4|EventProcessorExample3|example-2@7166|10000");
Audit::WriteAuditEvent(Audit::StatsEvent::QUEUE_EVENT_OUT, 1585730002219098);
Audit::WriteAuditEvent(Audit::StatsEvent::QUEUE_EVENT_IN, 1585730009919825,
"EventProcessorExample3|EventProcessorExample4|example-2@7166|10001");
Audit::WriteAuditEvent(Audit::StatsEvent::QUEUE_EVENT_OUT, 1585730009919825);
AuditLogParser parser;
parser.StartParse();
auto threadEventList = parser.GetThreadSummary();
ASSERT_EQ(threadEventList.size(), 2ul);
auto pluginEventList = parser.GetPluginSummary();
ASSERT_EQ(pluginEventList.size(), 2ul);
auto pipelineEventList = parser.GetPipelineSummary();
ASSERT_EQ(pipelineEventList.size(), 0ul);
auto scope = parser.GetAuditLogTimeScope();
ASSERT_GT(scope.length(), 10ul);
}
/**
* @tc.name: AuditLogParserTest002
* @tc.desc: write pipeline event log into audit log and then parse it
* @tc.type: FUNC
* @tc.require: AR000DPTT2
*/
HWTEST_F(AuditLogParserTest, AuditLogParserTest002, TestSize.Level3)
{
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_CREATE, 1585730002219098, "EventSourceExample|901000000");
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_HANDLE_IN, 1585730002219098, "EventProcessorExample1");
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_HANDLE_OUT, 1585730002219098, "example-2@7166");
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_HANDLE_IN, 1585730002219098, "EventProcessorExample2");
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_HANDLE_OUT, 1585730002219098, "example-2@7167");
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_HANDLE_IN, 1585730002219098, "EventProcessorExample3");
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_HANDLE_OUT, 1585730002219098, "example-2@7168");
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_DONE, 1585730002219098);
AuditLogParser parser;
parser.StartParse();
auto threadEventList = parser.GetThreadSummary();
ASSERT_EQ(threadEventList.size(), 3ul);
for (auto& log : threadEventList) {
printf("thread log:%s \n", log.c_str());
}
auto pluginEventList = parser.GetPluginSummary();
for (auto& log : pluginEventList) {
printf("plugin log:%s \n", log.c_str());
}
ASSERT_EQ(pluginEventList.size(), 3ul);
auto pipelineEventList = parser.GetPipelineSummary();
for (auto& log : pipelineEventList) {
printf("pipeline log:%s \n", log.c_str());
}
ASSERT_EQ(pipelineEventList.size(), 1ul);
auto scope = parser.GetAuditLogTimeScope();
ASSERT_GT(scope.length(), 10ul);
}
/**
* @tc.name: AuditLogParserTest003
* @tc.desc: write mixed event log into audit log and then parse it
* @tc.type: FUNC
* @tc.require: AR000DPTT2
*/
HWTEST_F(AuditLogParserTest, AuditLogParserTest003, TestSize.Level3)
{
Audit::WriteAuditEvent(Audit::StatsEvent::QUEUE_EVENT_IN, 1585730002219050,
"EventProcessorExample4|EventProcessorExample3|example-2@7166|10000");
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_CREATE, 1585730002219099, "EventSourceExample|901000000");
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_HANDLE_IN, 1585730002219099, "EventProcessorExample1");
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_HANDLE_OUT, 1585730002219099, "example-2@7166");
Audit::WriteAuditEvent(Audit::StatsEvent::QUEUE_EVENT_OUT, 1585730002219050);
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_HANDLE_IN, 1585730002219099, "EventProcessorExample2");
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_HANDLE_OUT, 1585730002219099, "example-2@7167");
Audit::WriteAuditEvent(Audit::StatsEvent::QUEUE_EVENT_IN, 1585730002219070,
"EventProcessorExample3|EventProcessorExample4|example-2@7166|10001");
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_HANDLE_IN, 1585730002219099, "EventProcessorExample3");
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_HANDLE_OUT, 1585730002219099, "example-2@7168");
Audit::WriteAuditEvent(Audit::StatsEvent::PIPELINE_EVENT_DONE, 1585730002219099);
Audit::WriteAuditEvent(Audit::StatsEvent::QUEUE_EVENT_OUT, 1585730002219070);
AuditLogParser parser;
parser.StartParse();
auto threadEventList = parser.GetThreadSummary();
ASSERT_EQ(threadEventList.size(), 5ul);
for (auto& log : threadEventList) {
printf("thread log:%s \n", log.c_str());
}
auto pluginEventList = parser.GetPluginSummary();
for (auto& log : pluginEventList) {
printf("plugin log:%s \n", log.c_str());
}
ASSERT_EQ(pluginEventList.size(), 5ul);
auto pipelineEventList = parser.GetPipelineSummary();
for (auto& log : pipelineEventList) {
printf("pipeline log:%s \n", log.c_str());
}
ASSERT_EQ(pipelineEventList.size(), 1ul);
auto scope = parser.GetAuditLogTimeScope();
ASSERT_GT(scope.length(), 10ul);
}
/**
* @tc.name: AuditLogParserTest004
* @tc.desc: construct a pipeline event with a normal event info
* @tc.type: FUNC
* @tc.require: AR000DPTT2
*/
HWTEST_F(AuditLogParserTest, AuditLogParserTest004, TestSize.Level3)
{
AuditLogParser* parser = new AuditLogParser();
ASSERT_NE(parser, nullptr);
AuditLogParser::EventInfo info;
AuditLogParser::PipelineEventInfo pipeInfo;
pipeInfo.eventSerialId = 1;
ASSERT_EQ(1ul, pipeInfo.eventSerialId);
info.eventSerialId = 1;
AuditLogParser::PipelineEventInfo pipeInfo2(info);
ASSERT_EQ(info.eventSerialId, pipeInfo2.eventSerialId);
delete parser;
}

View File

@ -0,0 +1,25 @@
/*
* 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 AUDIT_LOG_PARSER_TEST_H
#define AUDIT_LOG_PARSER_TEST_H
#include <gtest/gtest.h>
class AuditLogParserTest : public testing::Test {
public:
void SetUp();
void TearDown() {};
};
#endif // AUDIT_LOG_PARSER_TEST_H

View File

@ -0,0 +1,210 @@
/*
* 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 "event_dispatch_queue_test.h"
using namespace testing::ext;
using namespace OHOS::HiviewDFX;
void EventDispatchQueueTest::SetUp()
{
/**
* @tc.setup: create order and unordered event dispatch queue
*/
printf("SetUp.\n");
if (order_ == nullptr) {
order_ = std::make_shared<EventDispatchQueue>("disp-order", Event::ManageType::ORDERED);
order_->Start();
}
if (unorder_ == nullptr) {
unorder_ = std::make_shared<EventDispatchQueue>("disp-unorder", Event::ManageType::UNORDERED);
unorder_->Start();
}
}
void EventDispatchQueueTest::TearDown()
{
/**
* @tc.teardown: destroy the event dispatch queue we have created
*/
printf("TearDown.\n");
if (order_ != nullptr) {
order_->Stop();
order_ = nullptr;
}
if (unorder_ != nullptr) {
unorder_->Stop();
unorder_ = nullptr;
}
}
std::shared_ptr<Event> EventDispatchQueueTest::CreateEvent(const std::string& name, int32_t id,
const std::string& message, Event::MessageType type)
{
auto event = std::make_shared<Event>(name);
event->messageType_ = type;
event->eventId_ = id;
event->SetValue("message", message);
return event;
}
bool ExtendEventListener::OnOrderedEvent(Event& msg)
{
printf("cur listener:%s OnOrderedEvent eventId_:%u \n", name_.c_str(), msg.eventId_);
orderEventCount_++;
auto message = msg.GetValue("message");
processedOrderedEvents_[message] = msg.sender_;
if (msg.GetValue("Finish") == name_) {
return true;
}
return false;
}
void ExtendEventListener::OnUnorderedEvent(const Event& msg)
{
printf("cur listener:%s OnUnorderedEvent eventId_:%u \n", name_.c_str(), msg.eventId_);
unorderEventCount_++;
auto message = msg.GetValue("message");
processedUnorderedEvents_[message] = msg.sender_;
}
std::string ExtendEventListener::GetListenerName()
{
return name_;
}
/**
* @tc.name: EventDispatchQueueCreateTest001
* @tc.desc: create and init an event dispatch queue
* @tc.type: FUNC
* @tc.require: AR000DPTSU
*/
HWTEST_F(EventDispatchQueueTest, EventDispatchQueueCreateTest001, TestSize.Level3)
{
printf("EventDispatchQueueTest.\n");
auto orderQueue = std::make_shared<EventDispatchQueue>("test", Event::ManageType::ORDERED);
ASSERT_EQ(false, orderQueue->IsRunning());
ASSERT_EQ(0, orderQueue->GetWaitQueueSize());
orderQueue->Start();
sleep(1);
ASSERT_EQ(true, orderQueue->IsRunning());
orderQueue->Stop();
ASSERT_EQ(false, orderQueue->IsRunning());
auto unorderQueue = std::make_shared<EventDispatchQueue>("test1", Event::ManageType::UNORDERED);
ASSERT_EQ(false, unorderQueue->IsRunning());
unorderQueue->Start();
sleep(1);
ASSERT_EQ(true, unorderQueue->IsRunning());
unorderQueue->Stop();
ASSERT_EQ(false, unorderQueue->IsRunning());
}
/**
* @tc.name: UnorderEventDispatchTest001
* @tc.desc: create event and send it to a unorder dispatch queue
* @tc.type: FUNC
* @tc.require: AR000DPTSU
*/
HWTEST_F(EventDispatchQueueTest, UnorderEventDispatchTest001, TestSize.Level3)
{
printf("EventDispatchQueueTest.\n");
if (unorder_ == nullptr) {
FAIL();
}
auto listener1 = std::make_shared<ExtendEventListener>("listener1");
listener1->AddListenerInfo(Event::MessageType::RAW_EVENT, EventListener::EventIdRange(EVENT_ID_0, EVENT_ID_2));
unorder_->RegisterListener(listener1);
auto listener2 = std::make_shared<ExtendEventListener>("listener2");
listener2->AddListenerInfo(Event::MessageType::RAW_EVENT, EVENT_ID_2);
unorder_->RegisterListener(listener2);
auto event1 = CreateEvent("testEvent1", EVENT_ID_0, "test", Event::MessageType::RAW_EVENT);
unorder_->Enqueue(event1);
sleep(1);
ASSERT_EQ(listener1->unorderEventCount_, 1ul);
ASSERT_EQ(listener2->unorderEventCount_, 0ul);
auto event2 = CreateEvent("testEvent1", EVENT_ID_2, "test", Event::MessageType::RAW_EVENT);
unorder_->Enqueue(event2);
sleep(1);
ASSERT_EQ(listener1->unorderEventCount_, 2ul);
ASSERT_EQ(listener2->unorderEventCount_, 1ul);
auto event3 = CreateEvent("testEvent1", EVENT_ID_3, "test", Event::MessageType::RAW_EVENT);
unorder_->Enqueue(event3);
sleep(1);
ASSERT_EQ(listener1->unorderEventCount_, 2ul);
ASSERT_EQ(listener2->unorderEventCount_, 1ul);
auto event4 = CreateEvent("testEvent1", EVENT_ID_3, "test", Event::MessageType::FAULT_EVENT);
unorder_->Enqueue(event4);
sleep(1);
ASSERT_EQ(listener1->unorderEventCount_, 2ul);
ASSERT_EQ(listener2->unorderEventCount_, 1ul);
}
/**
* @tc.name: OrderEventDispatchTest001
* @tc.desc: create event and send it to a order dispatch queue
* @tc.type: FUNC
* @tc.require: AR000DPTSU
*/
HWTEST_F(EventDispatchQueueTest, OrderEventDispatchTest001, TestSize.Level3)
{
printf("EventDispatchQueueTest.\n");
if (order_ == nullptr) {
FAIL();
}
auto listener1 = std::make_shared<ExtendEventListener>("listener1");
listener1->AddListenerInfo(Event::MessageType::RAW_EVENT, EventListener::EventIdRange(EVENT_ID_0, EVENT_ID_2));
order_->RegisterListener(listener1);
auto listener2 = std::make_shared<ExtendEventListener>("listener2");
listener2->AddListenerInfo(Event::MessageType::RAW_EVENT, EVENT_ID_2);
order_->RegisterListener(listener2);
auto event1 = CreateEvent("", EVENT_ID_0, "test", Event::MessageType::RAW_EVENT);
order_->Enqueue(event1);
sleep(1);
ASSERT_EQ(listener1->orderEventCount_, 1ul);
ASSERT_EQ(listener2->orderEventCount_, 0ul);
auto listener3 = std::make_shared<ExtendEventListener>("listener3");
listener3->AddListenerInfo(Event::MessageType::RAW_EVENT, EVENT_ID_2);
order_->RegisterListener(listener3);
auto listener4 = std::make_shared<ExtendEventListener>("listener4");
listener4->AddListenerInfo(Event::MessageType::RAW_EVENT, EVENT_ID_2);
order_->RegisterListener(listener4);
auto event2 = CreateEvent("listener1", EVENT_ID_2, "test", Event::MessageType::RAW_EVENT);
order_->Enqueue(event2);
sleep(1);
ASSERT_EQ(listener1->orderEventCount_, 1ul);
ASSERT_EQ(listener2->orderEventCount_, 1ul);
ASSERT_EQ(listener3->orderEventCount_, 1ul);
ASSERT_EQ(listener4->orderEventCount_, 1ul);
auto event3 = CreateEvent("listener1", EVENT_ID_2, "test", Event::MessageType::RAW_EVENT);
event3->SetValue("Finish", "listener2");
order_->Enqueue(event3);
sleep(1);
ASSERT_EQ(listener1->orderEventCount_, 1ul);
ASSERT_EQ(listener2->orderEventCount_, 2ul);
ASSERT_EQ(listener3->orderEventCount_, 1ul);
ASSERT_EQ(listener4->orderEventCount_, 1ul);
auto event4 = CreateEvent("listener3", EVENT_ID_2, "test", Event::MessageType::RAW_EVENT);
order_->Enqueue(event4);
sleep(1);
ASSERT_EQ(listener1->orderEventCount_, 1ul);
ASSERT_EQ(listener2->orderEventCount_, 2ul);
ASSERT_EQ(listener3->orderEventCount_, 1ul);
ASSERT_EQ(listener4->orderEventCount_, 2ul);
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HIVIEW_PLATFORM_EVENT_DISPATCH_QUEUE_TEST_H
#define HIVIEW_PLATFORM_EVENT_DISPATCH_QUEUE_TEST_H
#include <map>
#include <memory>
#include <gtest/gtest.h>
#include "event.h"
#include "event_dispatch_queue.h"
class EventDispatchQueueTest : public testing::Test {
public:
void SetUp();
void TearDown();
std::shared_ptr<OHOS::HiviewDFX::Event> CreateEvent(const std::string& name, int32_t id,
const std::string& message,
OHOS::HiviewDFX::Event::MessageType type);
std::shared_ptr<OHOS::HiviewDFX::EventDispatchQueue> order_ = nullptr;
std::shared_ptr<OHOS::HiviewDFX::EventDispatchQueue> unorder_ = nullptr;
static constexpr int EVENT_ID_0 = 0;
static constexpr int EVENT_ID_1 = 1;
static constexpr int EVENT_ID_2 = 2;
static constexpr int EVENT_ID_3 = 3;
static constexpr int EVENT_ID_4 = 4;
static constexpr int EVENT_ID_5 = 5;
};
class ExtendEventListener : public OHOS::HiviewDFX::EventListener {
public:
explicit ExtendEventListener(const std::string& name) : orderEventCount_(0), unorderEventCount_(0), name_(name){};
~ExtendEventListener(){};
bool OnOrderedEvent(OHOS::HiviewDFX::Event& msg) override;
void OnUnorderedEvent(const OHOS::HiviewDFX::Event& msg) override;
std::string GetListenerName() override;
std::map<std::string, std::string> processedOrderedEvents_;
std::map<std::string, std::string> processedUnorderedEvents_;
uint32_t orderEventCount_;
uint32_t unorderEventCount_;
private:
std::string name_;
};
#endif // HIVIEW_PLATFORM_EVENT_DISPATCH_QUEUE_TEST_H

View File

@ -0,0 +1,435 @@
/*
* 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 "event_loop_test.h"
#include <cinttypes>
#include <ctime>
#include <fstream>
#include <iostream>
#include <gtest/gtest.h>
#include <sys/inotify.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "audit.h"
#include "event_loop.h"
using namespace testing::ext;
using namespace OHOS::HiviewDFX;
namespace OHOS {
namespace HiviewDFX {
void EventLoopTest::SetUp()
{
/**
* @tc.setup: create an event loop and multiple event handlers
*/
if (currentLooper_ != nullptr) {
currentLooper_->StopLoop();
currentLooper_.reset();
}
mkdir("/data/log", S_IRWXU | S_IRWXG);
const ::testing::TestInfo * const info = ::testing::UnitTest::GetInstance()->current_test_info();
printf("We are in test %s of test case %s.\n", info->name(), info->test_case_name());
currentLooper_ = std::make_shared<EventLoop>(info->test_case_name());
currentLooper_->StartLoop();
}
void EventLoopTest::TearDown()
{
/**
* @tc.teardown: destroy the event loop we have created
*/
if (currentLooper_ != nullptr) {
currentLooper_->StopLoop();
currentLooper_.reset();
}
}
bool RealEventHandler::OnEvent(std::shared_ptr<Event>& event)
{
printf("OnEvent id:%d sender:%s pid:%d time:%ld. index:%d\n", event->eventId_, event->sender_.c_str(),
gettid(), time(nullptr), event->what_);
lastProcessId_ = event->eventId_;
if ((event->what_ % 10) == 0) { // 10 : add delay in processing some event
usleep(100); // 100 : 100us
}
processedEventCount_++;
pid_ = getpid();
receivedEventNo_.push_back(event->what_);
return true;
}
void RealEventHandler::DoTask()
{
printf("RealEventHandler::DoTask pid:%d time:%ld.\n", gettid(), time(nullptr));
processedEventCount_++;
}
bool OverheadCalculateEventHandler::OnEvent(std::shared_ptr<Event>& event)
{
auto cost = clock() - event->createTime_;
totalDeliverOverHead_ += cost;
processedEventCount_++;
return true;
}
bool DataFileEventReader::OnFileDescriptorEvent(int fd, int type)
{
printf("DataFileEventReader::OnEvent id:%d inotifyFd_:%d\n", fd, inotifyFd_);
const int bufSize = 2048;
char buffer[bufSize] = {0};
char *offset = nullptr;
struct inotify_event *event = nullptr;
if (inotifyFd_ <= 0) {
printf("Invalid inotify fd:%d", inotifyFd_);
return false;
}
int len = read(inotifyFd_, buffer, bufSize);
if (len <= 0) {
printf("failed to read event");
return false;
}
offset = buffer;
event = reinterpret_cast<struct inotify_event *>(buffer);
while ((reinterpret_cast<char *>(event) - buffer) < len) {
for (const auto &it : fileMap_) {
if (it.second != event->wd) {
printf("fail to find check point: %d", event->wd);
continue;
}
std::string filePath = it.first;
printf("handle file event in %s \n", filePath.c_str());
}
int tmpLen = sizeof(struct inotify_event) + event->len;
event = reinterpret_cast<struct inotify_event *>(offset + tmpLen);
offset += tmpLen;
}
return false;
}
int32_t DataFileEventReader::GetPollFd()
{
if (inotifyFd_ > 0) {
return inotifyFd_;
}
inotifyFd_ = inotify_init();
if (inotifyFd_ == -1) {
printf("failed to init inotify: %s \n", strerror(errno));
return -1;
}
// create file
FILE *targetLogFile = fopen(EVENT_LOG_PATH.c_str(), "w+");
if (targetLogFile != nullptr) {
fclose(targetLogFile);
}
int wd = inotify_add_watch(inotifyFd_, EVENT_LOG_PATH.c_str(), IN_CLOSE_WRITE | IN_MOVED_TO);
if (wd < 0) {
printf("failed to add watch entry : %s \n", strerror(errno));
close(inotifyFd_);
inotifyFd_ = -1;
return -1;
}
fileMap_[EVENT_LOG_PATH] = wd;
return inotifyFd_;
}
int32_t DataFileEventReader::GetPollType()
{
return EPOLLIN;
}
/**
* @tc.name: EventLoopStartAndStopTest001
* @tc.desc: start the event loop and stop the event loop
* @tc.type: FUNC
* @tc.require: AR000DPTSU
*/
HWTEST_F(EventLoopTest, StartAndStopTest001, TestSize.Level3)
{
/**
* @tc.steps: step1. create event handler
*/
auto eventhandler1 = std::make_shared<RealEventHandler>();
auto event1 = std::make_shared<Event>("test1");
currentLooper_->AddEvent(eventhandler1, event1, nullptr);
/**
* @tc.expected: step1. fetch the thread id of the event loop
*/
int curPid = getpid();
EXPECT_NE(curPid, eventhandler1->pid_);
}
/**
* @tc.name: EventLoopEventProcessTest001
* @tc.desc: send multiple events to event loop
* @tc.type: FUNC
* @tc.require: AR000DPTSU
*/
HWTEST_F(EventLoopTest, EventLoopEventProcessTest001, TestSize.Level3)
{
/**
* @tc.steps: step1. create event handler and events
*/
auto eventhandler1 = std::make_shared<RealEventHandler>();
auto eventhandler2 = std::make_shared<RealEventHandler>();
auto eventhandler3 = std::make_shared<RealEventHandler>();
auto eventhandler4 = std::make_shared<RealEventHandler>();
auto event1 = std::make_shared<Event>("test1");
auto event2 = std::make_shared<Event>("test2");
auto event3 = std::make_shared<Event>("test3");
auto event4 = std::make_shared<Event>("test4");
auto event5 = std::make_shared<Event>("test5");
auto event6 = std::make_shared<Event>("test6");
auto event7 = std::make_shared<Event>("test7");
currentLooper_->AddEvent(eventhandler1, event1, nullptr);
currentLooper_->AddEvent(eventhandler2, event2, nullptr);
currentLooper_->AddEvent(eventhandler3, event3, nullptr);
currentLooper_->AddEvent(eventhandler4, event4, nullptr);
currentLooper_->AddEvent(eventhandler1, event5, nullptr);
currentLooper_->AddEvent(eventhandler4, event6, nullptr);
currentLooper_->AddEvent(eventhandler1, event7, nullptr);
sleep(2);
/**
* @tc.expected: step1. the event has been processed
*/
EXPECT_EQ(3, eventhandler1->processedEventCount_);
EXPECT_EQ(1, eventhandler2->processedEventCount_);
EXPECT_EQ(1, eventhandler3->processedEventCount_);
EXPECT_EQ(2, eventhandler4->processedEventCount_);
}
/**
* @tc.name: EventLoopEventProcessTest002
* @tc.desc: Add Fd callback and check the result from fd
* @tc.type: FUNC
* @tc.require: AR000DPTSU
*/
HWTEST_F(EventLoopTest, EventLoopEventProcessTest002, TestSize.Level3)
{
/**
* @tc.steps: step1. create a timer event and send to target
*/
auto eventReader = std::make_shared<DataFileEventReader>();
currentLooper_->AddFileDescriptorEventCallback("test1", eventReader);
auto eventhandler1 = std::make_shared<RealEventHandler>();
auto event1 = std::make_shared<Event>("test1");
auto event2 = std::make_shared<Event>("test2");
auto event3 = std::make_shared<Event>("test3");
currentLooper_->AddEvent(eventhandler1, event1, nullptr);
currentLooper_->AddEvent(eventhandler1, event2, nullptr);
currentLooper_->AddEvent(eventhandler1, event3, nullptr);
std::ofstream testFile;
testFile.open(DataFileEventReader::EVENT_LOG_PATH);
testFile << "Writing this to a file.\n";
testFile.close();
sleep(1);
testFile.open(DataFileEventReader::EVENT_LOG_PATH);
testFile << "Writing this to a file.\n";
testFile.close();
sleep(1);
testFile.open(DataFileEventReader::EVENT_LOG_PATH);
testFile << "Writing this to a file.\n";
testFile.close();
sleep(1);
/**
* @tc.expected: step1. the event has been processed
*/
EXPECT_EQ(3, eventhandler1->processedEventCount_);
}
/**
* @tc.name: EventLoopEventProcessTest003
* @tc.desc: Exec period event
* @tc.type: FUNC
* @tc.require: AR000DPTSU
*/
HWTEST_F(EventLoopTest, EventLoopEventProcessTest003, TestSize.Level3)
{
/**
* @tc.steps: step1. create a timer event and send to target
*/
auto eventhandler1 = std::make_shared<RealEventHandler>();
auto event1 = std::make_shared<Event>("test1");
currentLooper_->AddTimerEvent(eventhandler1, event1, nullptr, 2, true);
sleep(10);
/**
* @tc.expected: step1. the event has been processed
*/
EXPECT_EQ(4, eventhandler1->processedEventCount_);
}
/**
* @tc.name: EventLoopEventProcessTest004
* @tc.desc: Exec period task
* @tc.type: FUNC
* @tc.require: AR000DPTSU
*/
HWTEST_F(EventLoopTest, EventLoopEventProcessTest004, TestSize.Level3)
{
/**
* @tc.steps: step1. create a timer event and send to target
*/
auto eventhandler1 = std::make_shared<RealEventHandler>();
auto task = std::bind(&RealEventHandler::DoTask, eventhandler1.get());
currentLooper_->AddTimerEvent(nullptr, nullptr, task, 2, true);
printf("On Main Thread:%d \n", gettid());
sleep(10);
/**
* @tc.expected: step1. the event has been processed
*/
EXPECT_EQ(4, eventhandler1->processedEventCount_);
}
/**
* @tc.name: EventLoopEventProcessTest005
* @tc.desc: Exec period task and remove it
* @tc.type: FUNC
* @tc.require: AR000DPTSU
*/
HWTEST_F(EventLoopTest, EventLoopEventProcessTest005, TestSize.Level3)
{
/**
* @tc.steps: step1. create a timer event and send to target
*/
auto eventhandler1 = std::make_shared<RealEventHandler>();
auto task = std::bind(&RealEventHandler::DoTask, eventhandler1.get());
auto seqId = currentLooper_->AddTimerEvent(nullptr, nullptr, task, 2, true);
printf("On Main Thread:%d \n", gettid());
sleep(5);
currentLooper_->RemoveEvent(seqId);
sleep(5);
/**
* @tc.expected: step1. the event has been processed
*/
EXPECT_EQ(2, eventhandler1->processedEventCount_);
}
/**
* @tc.name: EventLoopEventProcessTest006
* @tc.desc: Exec timer event and remove it
* @tc.type: FUNC
* @tc.require: AR000DPTSU
*/
HWTEST_F(EventLoopTest, EventLoopEventProcessTest006, TestSize.Level3)
{
/**
* @tc.steps: step1. create a timer event and send to target
*/
auto eventhandler1 = std::make_shared<RealEventHandler>();
auto event1 = std::make_shared<Event>("test1");
currentLooper_->AddTimerEvent(eventhandler1, event1, nullptr, 2, false);
sleep(3);
EXPECT_EQ(1, eventhandler1->processedEventCount_);
auto event2 = std::make_shared<Event>("test2");
auto seq = currentLooper_->AddTimerEvent(eventhandler1, event2, nullptr, 2, false);
sleep(1);
currentLooper_->RemoveEvent(seq);
sleep(2);
EXPECT_EQ(1, eventhandler1->processedEventCount_);
}
/**
* @tc.name: EventLoopOverheadTest001
* @tc.desc: send an event and check the deliver cost
* @tc.type: FUNC
* @tc.require: AR000DPTSU
*/
HWTEST_F(EventLoopTest, EventLoopOverheadTest001, TestSize.Level3)
{
/**
* @tc.steps: step1. create a handler and event
* @tc.steps: step2. calculate event deliver overhead
*/
auto overheadCounter = std::make_shared<OverheadCalculateEventHandler>();
const int totalTestCount = 100;
for (int i = 0; i < totalTestCount; i++) {
auto event = std::make_shared<Event>("test");
event->createTime_ = clock();
currentLooper_->AddEvent(overheadCounter, event, nullptr);
}
sleep(10);
printf("TotalDeliverOverHeadCost:%" PRIu64 ".\n", overheadCounter->totalDeliverOverHead_);
printf("TotalProcessEventCount:%" PRIu64 ".\n", overheadCounter->processedEventCount_);
printf("EventTransferOverhead:%" PRIu64 ".\n",
overheadCounter->totalDeliverOverHead_/overheadCounter->processedEventCount_);
}
/**
* @tc.name: EventLoopEventOrderTest001
* @tc.desc: send 1000 events and check the receiving order
* @tc.type: FUNC
* @tc.require: AR000DPTSU
*/
HWTEST_F(EventLoopTest, EventLoopEventOrderTest001, TestSize.Level3)
{
/**
* @tc.steps: step1. create a handler and 1000 events in a loop
* @tc.steps: step2. check the received order
*/
auto eventhandler = std::make_shared<RealEventHandler>();
const uint16_t totalTestCount = 1000;
for (uint16_t i = 0; i < totalTestCount; i++) {
auto event = std::make_shared<Event>("testevent");
event->what_ = i;
currentLooper_->AddEvent(eventhandler, event, nullptr);
}
sleep(10); // 10: sleep 10 seconds
ASSERT_EQ(eventhandler->receivedEventNo_.size(), totalTestCount);
for (uint16_t i = 0; i < totalTestCount; i++) {
ASSERT_EQ(eventhandler->receivedEventNo_[i], i);
}
}
/**
* @tc.name: EventLoopWrongInputParamsTest001
* @tc.desc: pass invalid params to add event interface
* @tc.type: FUNC
* @tc.require: AR000DPTSU
*/
HWTEST_F(EventLoopTest, EventLoopWrongInputParamsTest001, TestSize.Level3)
{
/**
* @tc.steps: step1. pass invalid params to add event interface
* @tc.steps: step2. check the return future
*/
auto result0 = currentLooper_->AddEventForResult(nullptr, nullptr);
ASSERT_EQ(result0.get(), false);
auto eventhandler = std::make_shared<RealEventHandler>();
auto result1 = currentLooper_->AddEventForResult(eventhandler, nullptr);
ASSERT_EQ(result1.get(), false);
auto event = std::make_shared<Event>("testevent");
auto result2 = currentLooper_->AddEventForResult(eventhandler, event);
ASSERT_EQ(result2.get(), true);
}
}
}

View File

@ -0,0 +1,65 @@
/*
* 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 HIVIEW_EVENT_LOOP_TEST_H
#define HIVIEW_EVENT_LOOP_TEST_H
#include <memory>
#include <sys/epoll.h>
#include <gtest/gtest.h>
#include "event_loop.h"
namespace OHOS {
namespace HiviewDFX {
class EventLoopTest : public testing::Test {
public:
void SetUp();
void TearDown();
std::shared_ptr<OHOS::HiviewDFX::EventLoop> currentLooper_;
};
class RealEventHandler : public OHOS::HiviewDFX::EventHandler {
public:
~RealEventHandler() {};
bool OnEvent(std::shared_ptr<OHOS::HiviewDFX::Event>& event) override;
void DoTask();
int32_t lastProcessId_ = 0;
int32_t processedEventCount_ = 0;
int32_t pid_ = 0;
std::vector<uint16_t> receivedEventNo_;
};
class DataFileEventReader : public OHOS::HiviewDFX::FileDescriptorEventCallback {
public:
~DataFileEventReader() {};
bool OnFileDescriptorEvent(int fd, int type) override;
int32_t GetPollFd() override;
int32_t GetPollType() override;
const static inline std::string EVENT_LOG_PATH = "/data/log/DataFileEventReader";
int inotifyFd_;
std::map<std::string, int> fileMap_;
};
class OverheadCalculateEventHandler : public OHOS::HiviewDFX::EventHandler {
public:
~OverheadCalculateEventHandler() {};
bool OnEvent(std::shared_ptr<OHOS::HiviewDFX::Event>& event) override;
uint64_t totalDeliverOverHead_ = 0;
uint64_t processedEventCount_ = 0;
};
}
}
#endif // HIVIEW_EVENT_LOOP_TEST_H

View File

@ -0,0 +1,171 @@
/*
* 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 "pipeline_test.h"
#include <fstream>
#include <iostream>
#include "event_loop.h"
#include "event_source.h"
#include "event_source_example.h"
#include "pipeline.h"
#include "plugin.h"
#include "plugin_factory.h"
using namespace testing::ext;
using namespace OHOS::HiviewDFX;
void PipelineTest::BindWorkLoop(std::shared_ptr<OHOS::HiviewDFX::Plugin> plugin)
{
if (plugin != nullptr && plugin->GetWorkLoop() == nullptr) {
auto eventLoop = std::make_shared<EventLoop>(plugin->GetName());
if (eventLoop != nullptr) {
eventLoop->StartLoop();
plugin->BindWorkLoop(eventLoop);
}
}
}
void PipelineTest::DoTest(const std::string& name, bool stopBeforeEnd, bool withThread)
{
/**
* @tc.steps: step1. create plugins
*/
printf("PipelineTest. DoTest:%s.\n", name.c_str());
auto plugin1 = PluginFactory::GetPlugin("EventProcessorExample1");
auto plugin2 = PluginFactory::GetPlugin("EventProcessorExample2");
auto plugin3 = PluginFactory::GetPlugin("EventProcessorExample3");
auto plugin4 = PluginFactory::GetPlugin("EventProcessorExample4");
if (withThread) {
BindWorkLoop(plugin1);
BindWorkLoop(plugin2);
BindWorkLoop(plugin3);
BindWorkLoop(plugin4);
}
std::list<std::weak_ptr<Plugin>> pluginList;
pluginList.push_back(plugin1);
pluginList.push_back(plugin2);
pluginList.push_back(plugin3);
pluginList.push_back(plugin4);
/**
* @tc.steps: step1. create pipeline
*/
auto pipeline = std::make_shared<Pipeline>("PipelineTest", pluginList);
/**
* @tc.steps: step2. create pipeline event
*/
auto producer = std::make_shared<PipelineEventProducerTest>();
auto event = std::make_shared<PipelineEvent>(name, producer.get());
event->messageType_ = Event::MessageType::FAULT_EVENT;
event->eventId_ = EventSourceExample::PIPELINE_EVENT_ID_AAA;
if (stopBeforeEnd) {
event->SetValue("Finish", "EventProcessorExample2");
}
/**
* @tc.steps: step3. process pipeline event
*/
if (pipeline->CanProcessEvent(event)) {
pipeline->ProcessEvent(event);
}
const int sleepTime = 5;
sleep(sleepTime);
/**
* @tc.steps: step4. check whether event has been processed
*/
ASSERT_EQ(event->GetValue("EventProcessorExample1"), "Done");
ASSERT_EQ(event->GetValue("EventProcessorExample2"), "Done");
if (stopBeforeEnd) {
ASSERT_EQ(event->GetValue("EventProcessorExample3"), "");
ASSERT_EQ(event->GetValue("EventProcessorExample4"), "");
}
plugin1->OnUnload();
plugin2->OnUnload();
plugin3->OnUnload();
plugin4->OnUnload();
}
/**
* @tc.name: PluginPipelineCreateTest001
* @tc.desc: create pipeline with multiple plugins
* @tc.type: FUNC
* @tc.require: AR000DPTT3
*/
HWTEST_F(PipelineTest, PluginPipelineCreateTest001, TestSize.Level3)
{
/**
* @tc.steps: step1. create pipeline
* @tc.steps: step2. create pipeline event
* @tc.steps: step3. process pipeline event
* @tc.steps: step4. check whether event has been processed
*/
DoTest("event0", false, true);
}
/**
* @tc.name: PluginPipelineCreateTest002
* @tc.desc: create pipeline with multiple plugins
* @tc.type: FUNC
* @tc.require: AR000DPTT3
*/
HWTEST_F(PipelineTest, PluginPipelineCreateTest002, TestSize.Level3)
{
/**
* @tc.steps: step1. create pipeline
* @tc.steps: step2. create pipeline event
* @tc.steps: step3. process pipeline event
* @tc.steps: step4. check whether event has been processed
*/
DoTest("event1", true, true);
}
/**
* @tc.name: PluginPipelineCreateTest003
* @tc.desc: create pipeline with multiple plugins
* @tc.type: FUNC
* @tc.require: AR000DPTT3
*/
HWTEST_F(PipelineTest, PluginPipelineCreateTest003, TestSize.Level3)
{
/**
* @tc.steps: step1. create pipeline
* @tc.steps: step2. create pipeline event
* @tc.steps: step3. process pipeline event
* @tc.steps: step4. check whether event has been processed
*/
DoTest("event0", false, false);
}
/**
* @tc.name: PluginPipelineCreateTest004
* @tc.desc: create pipeline with multiple plugins
* @tc.type: FUNC
* @tc.require: AR000DPTT3
*/
HWTEST_F(PipelineTest, PluginPipelineCreateTest004, TestSize.Level3)
{
/**
* @tc.steps: step1. create pipeline
* @tc.steps: step2. create pipeline event
* @tc.steps: step3. process pipeline event
* @tc.steps: step4. check whether event has been processed
*/
DoTest("event1", true, false);
}

Some files were not shown because too many files have changed in this diff Show More