mirror of
https://github.com/openharmony/update_updateservice.git
synced 2026-06-30 21:07:54 -04:00
update OpenHarmony 2.0 Canary
This commit is contained in:
@@ -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
|
||||
@@ -1,36 +0,0 @@
|
||||
# update_updateservice
|
||||
|
||||
#### Description
|
||||
Update service module | 升级服务层组件
|
||||
|
||||
#### 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/)
|
||||
@@ -1,37 +1,159 @@
|
||||
# update_updateservice
|
||||
# Update Service<a name="EN-US_TOPIC_0000001102254666"></a>
|
||||
|
||||
#### 介绍
|
||||
Update service module | 升级服务层组件
|
||||
- [Introduction](#section184mcpsimp)
|
||||
- [Directory Structure](#section193mcpsimp)
|
||||
- [Description](#section208mcpsimp)
|
||||
- [JS APIs](#section210mcpsimp)
|
||||
- [Usage](#section253mcpsimp)
|
||||
|
||||
#### 软件架构
|
||||
软件架构说明
|
||||
- [Repositories Involved](#section366mcpsimp)
|
||||
|
||||
## Introduction<a name="section184mcpsimp"></a>
|
||||
|
||||
#### 安装教程
|
||||
The update service is a system ability \(SA\) started by the init process of OHOS to implement an update.
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
The update service provides the following functions:
|
||||
|
||||
#### 使用说明
|
||||
1. Searching for available update packages
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
2. Downloading update packages
|
||||
|
||||
#### 参与贡献
|
||||
3. Setting and obtaining the update policy
|
||||
|
||||
1. Fork 本仓库
|
||||
2. 新建 Feat_xxx 分支
|
||||
3. 提交代码
|
||||
4. 新建 Pull Request
|
||||
4. Triggering an update
|
||||
|
||||
## Directory Structure<a name="section193mcpsimp"></a>
|
||||
|
||||
#### 特技
|
||||
```
|
||||
base/update/updateservice # Update service code
|
||||
├── client # NAPI-based update client
|
||||
├── engine # Update client engine
|
||||
│ ├── etc # rc configuration files for the update client engine
|
||||
│ ├── include # Header files for the update client engine
|
||||
│ ├── sa_profile # SA profiles
|
||||
│ └── src # Source code of the update client engine
|
||||
├── interfaces # Update client APIs
|
||||
│ └── innerkits # SA APIs
|
||||
├── kits # External APIs
|
||||
│ └── js # JS APIs for the update app
|
||||
└── tests # Test code
|
||||
└── unittest # Unit test code for the update client
|
||||
```
|
||||
|
||||
## Description<a name="section208mcpsimp"></a>
|
||||
|
||||
### JS APIs<a name="section210mcpsimp"></a>
|
||||
|
||||
<a name="table212mcpsimp"></a>
|
||||
<table><tbody><tr id="row217mcpsimp"><td class="cellrowborder" valign="top" width="52%"><p id="p219mcpsimp"><a name="p219mcpsimp"></a><a name="p219mcpsimp"></a><strong id="b6143153974418"><a name="b6143153974418"></a><a name="b6143153974418"></a>API</strong></p>
|
||||
</td>
|
||||
<td class="cellrowborder" valign="top" width="48%"><p id="p222mcpsimp"><a name="p222mcpsimp"></a><a name="p222mcpsimp"></a><strong id="b156019475446"><a name="b156019475446"></a><a name="b156019475446"></a>Description</strong></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="row223mcpsimp"><td class="cellrowborder" valign="top" width="52%"><p id="p16387178102716"><a name="p16387178102716"></a><a name="p16387178102716"></a>checkNewVersion</p>
|
||||
</td>
|
||||
<td class="cellrowborder" valign="top" width="48%"><p id="p227mcpsimp"><a name="p227mcpsimp"></a><a name="p227mcpsimp"></a>Checks whether a new update package is available.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="row228mcpsimp"><td class="cellrowborder" valign="top" width="52%"><p id="p1884710150275"><a name="p1884710150275"></a><a name="p1884710150275"></a>download()</p>
|
||||
</td>
|
||||
<td class="cellrowborder" valign="top" width="48%"><p id="p232mcpsimp"><a name="p232mcpsimp"></a><a name="p232mcpsimp"></a>Downloads the update package. </p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="row233mcpsimp"><td class="cellrowborder" valign="top" width="52%"><p id="p7326722162717"><a name="p7326722162717"></a><a name="p7326722162717"></a>upgrade()</p>
|
||||
</td>
|
||||
<td class="cellrowborder" valign="top" width="48%"><p id="p237mcpsimp"><a name="p237mcpsimp"></a><a name="p237mcpsimp"></a>Writes the update command to the misc partition and runs the <strong id="b1069864618574"><a name="b1069864618574"></a><a name="b1069864618574"></a>reboot</strong> command to access the updater.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="row238mcpsimp"><td class="cellrowborder" valign="top" width="52%"><p id="p4981103002720"><a name="p4981103002720"></a><a name="p4981103002720"></a>getNewVersionInfo()</p>
|
||||
</td>
|
||||
<td class="cellrowborder" valign="top" width="48%"><p id="p242mcpsimp"><a name="p242mcpsimp"></a><a name="p242mcpsimp"></a>Obtains the version information after a version update.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="row243mcpsimp"><td class="cellrowborder" valign="top" width="52%"><p id="p568117524271"><a name="p568117524271"></a><a name="p568117524271"></a>setUpdatePolicy</p>
|
||||
</td>
|
||||
<td class="cellrowborder" valign="top" width="48%"><p id="p247mcpsimp"><a name="p247mcpsimp"></a><a name="p247mcpsimp"></a>Sets the update policy.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="row248mcpsimp"><td class="cellrowborder" valign="top" width="52%"><p id="p19534844192712"><a name="p19534844192712"></a><a name="p19534844192712"></a>getUpdatePolicy</p>
|
||||
</td>
|
||||
<td class="cellrowborder" valign="top" width="48%"><p id="p252mcpsimp"><a name="p252mcpsimp"></a><a name="p252mcpsimp"></a>Obtains the update policy.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Usage<a name="section253mcpsimp"></a>
|
||||
|
||||
1. Import **libupdateclient**.
|
||||
|
||||
```
|
||||
import client from 'libupdateclient.z.so'
|
||||
```
|
||||
|
||||
2. Obtain the **Updater** object.
|
||||
|
||||
```
|
||||
let updater = client.getUpdater('OTA');
|
||||
```
|
||||
|
||||
3. Obtain the new version information.
|
||||
|
||||
```
|
||||
updater.getNewVersionInfo(info => {
|
||||
info "New version information"
|
||||
});
|
||||
```
|
||||
|
||||
4. Checks for a new version.
|
||||
|
||||
```
|
||||
updater.checkNewVersion(info => {
|
||||
info "New version information"
|
||||
});
|
||||
```
|
||||
|
||||
5. Download the new version and monitor the download process.
|
||||
|
||||
```
|
||||
updater.download();
|
||||
updater.on("downloadProgress", progress => {
|
||||
progress "Download progress information"
|
||||
});
|
||||
```
|
||||
|
||||
6. Start the update.
|
||||
|
||||
```
|
||||
updater.upgrade();
|
||||
updater.on("upgradeProgress", progress => {
|
||||
progress "Update progress information"
|
||||
});
|
||||
```
|
||||
|
||||
7. Set the update policy.
|
||||
|
||||
```
|
||||
updater.setUpdatePolicy(result => {
|
||||
result "Update policy setting result"
|
||||
});
|
||||
```
|
||||
|
||||
8. Check the update policy.
|
||||
|
||||
```
|
||||
updater.getUpdatePolicy(policy => {
|
||||
policy "Update policy"
|
||||
});
|
||||
```
|
||||
|
||||
## Repositories Involved<a name="section366mcpsimp"></a>
|
||||
|
||||
Update subsystem
|
||||
|
||||
update\_app
|
||||
|
||||
**update\_updateservice**
|
||||
|
||||
update\_updater
|
||||
|
||||
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/)
|
||||
|
||||
Executable
+159
@@ -0,0 +1,159 @@
|
||||
# 升级服务组件<a name="ZH-CN_TOPIC_0000001102254666"></a>
|
||||
|
||||
- [简介](#section184mcpsimp)
|
||||
- [目录](#section193mcpsimp)
|
||||
- [说明](#section208mcpsimp)
|
||||
- [JS接口说明](#section210mcpsimp)
|
||||
- [使用说明](#section253mcpsimp)
|
||||
|
||||
- [相关仓](#section366mcpsimp)
|
||||
|
||||
## 简介<a name="section184mcpsimp"></a>
|
||||
|
||||
升级服务组件是一个SA\(System Ability\), 由OHOS 的init 进程负责启动。
|
||||
|
||||
升级服务器引擎主要功能包括:
|
||||
|
||||
1、查找可用的升级包
|
||||
|
||||
2、下载升级包
|
||||
|
||||
3、设置/获取升级策略
|
||||
|
||||
4、触发升级
|
||||
|
||||
## 目录<a name="section193mcpsimp"></a>
|
||||
|
||||
```
|
||||
base/update/updateservice # 升级服务代码仓目录
|
||||
├── client # 升级客户端napi 接口目录
|
||||
├── engine # 升级客户端引擎服务目录
|
||||
│ ├── etc # 升级客户端引擎rc配置文件目录
|
||||
│ ├── include # 升级客户端引擎头文件目录
|
||||
│ ├── sa_profile # SA 配置文件目录
|
||||
│ └── src # 升级客户端引擎源码目录
|
||||
├── interfaces # 升级客户端接口目录
|
||||
│ └── innerkits # SA 接口定义和封装目录
|
||||
├── kits # 对外接口封装目录
|
||||
│ └── js # 提供给升级客户端应用的JS 接口目录
|
||||
└── tests # 测试代码目录
|
||||
└── unittest # 升级客户端UT代码目录
|
||||
```
|
||||
|
||||
## 说明<a name="section208mcpsimp"></a>
|
||||
|
||||
### JS接口说明<a name="section210mcpsimp"></a>
|
||||
|
||||
<a name="table212mcpsimp"></a>
|
||||
<table><tbody><tr id="row217mcpsimp"><td class="cellrowborder" valign="top" width="52%"><p id="p219mcpsimp"><a name="p219mcpsimp"></a><a name="p219mcpsimp"></a><strong id="b220mcpsimp"><a name="b220mcpsimp"></a><a name="b220mcpsimp"></a>接口</strong></p>
|
||||
</td>
|
||||
<td class="cellrowborder" valign="top" width="48%"><p id="p222mcpsimp"><a name="p222mcpsimp"></a><a name="p222mcpsimp"></a>说明</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="row223mcpsimp"><td class="cellrowborder" valign="top" width="52%"><p id="p16387178102716"><a name="p16387178102716"></a><a name="p16387178102716"></a>checkNewVersion</p>
|
||||
</td>
|
||||
<td class="cellrowborder" valign="top" width="48%"><p id="p227mcpsimp"><a name="p227mcpsimp"></a><a name="p227mcpsimp"></a>检查是否有可用的升级包版本</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="row228mcpsimp"><td class="cellrowborder" valign="top" width="52%"><p id="p1884710150275"><a name="p1884710150275"></a><a name="p1884710150275"></a>download()</p>
|
||||
</td>
|
||||
<td class="cellrowborder" valign="top" width="48%"><p id="p232mcpsimp"><a name="p232mcpsimp"></a><a name="p232mcpsimp"></a>下载升级包</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="row233mcpsimp"><td class="cellrowborder" valign="top" width="52%"><p id="p7326722162717"><a name="p7326722162717"></a><a name="p7326722162717"></a>upgrade()</p>
|
||||
</td>
|
||||
<td class="cellrowborder" valign="top" width="48%"><p id="p237mcpsimp"><a name="p237mcpsimp"></a><a name="p237mcpsimp"></a>将升级命令写入到misc分区,最终调用reboot命令,进入到updater 子系统中。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="row238mcpsimp"><td class="cellrowborder" valign="top" width="52%"><p id="p4981103002720"><a name="p4981103002720"></a><a name="p4981103002720"></a>getNewVersionInfo()</p>
|
||||
</td>
|
||||
<td class="cellrowborder" valign="top" width="48%"><p id="p242mcpsimp"><a name="p242mcpsimp"></a><a name="p242mcpsimp"></a>升级完成后,获取升级后的版本信息</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="row243mcpsimp"><td class="cellrowborder" valign="top" width="52%"><p id="p568117524271"><a name="p568117524271"></a><a name="p568117524271"></a>setUpdatePolicy</p>
|
||||
</td>
|
||||
<td class="cellrowborder" valign="top" width="48%"><p id="p247mcpsimp"><a name="p247mcpsimp"></a><a name="p247mcpsimp"></a>设置升级策略</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="row248mcpsimp"><td class="cellrowborder" valign="top" width="52%"><p id="p19534844192712"><a name="p19534844192712"></a><a name="p19534844192712"></a>getUpdatePolicy</p>
|
||||
</td>
|
||||
<td class="cellrowborder" valign="top" width="48%"><p id="p252mcpsimp"><a name="p252mcpsimp"></a><a name="p252mcpsimp"></a>获取升级策略</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### 使用说明<a name="section253mcpsimp"></a>
|
||||
|
||||
1,导入updateclient lib
|
||||
|
||||
```
|
||||
import client from 'libupdateclient.z.so'
|
||||
```
|
||||
|
||||
2,获取update对象
|
||||
|
||||
```
|
||||
let updater = client.getUpdater('OTA');
|
||||
```
|
||||
|
||||
3,获取新版本信息
|
||||
|
||||
```
|
||||
updater.getNewVersionInfo(info => {
|
||||
info "新版本信息"
|
||||
});
|
||||
```
|
||||
|
||||
4,检查新版本
|
||||
|
||||
```
|
||||
updater.checkNewVersion(info => {
|
||||
info "新版本信息"
|
||||
});
|
||||
```
|
||||
|
||||
5,下载新版本,并监听下载进程
|
||||
|
||||
```
|
||||
updater.download();
|
||||
updater.on("downloadProgress", progress => {
|
||||
progress "下载进度信息"
|
||||
});
|
||||
```
|
||||
|
||||
6,启动升级
|
||||
|
||||
```
|
||||
updater.upgrade();
|
||||
updater.on("upgradeProgress", progress => {
|
||||
progress "升级进度信息"
|
||||
});
|
||||
```
|
||||
|
||||
7,设置升级策略
|
||||
|
||||
```
|
||||
updater.setUpdatePolicy(result => {
|
||||
result "设置升级策略结果"
|
||||
});
|
||||
```
|
||||
|
||||
8,查看升级策略
|
||||
|
||||
```
|
||||
updater.getUpdatePolicy(policy => {
|
||||
policy "升级策略"
|
||||
});
|
||||
```
|
||||
|
||||
## 相关仓<a name="section366mcpsimp"></a>
|
||||
|
||||
升级子系统
|
||||
|
||||
update\_app
|
||||
|
||||
**update\_updateservice**
|
||||
|
||||
update\_updater
|
||||
|
||||
Executable
+43
@@ -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 UPDATER_CALLBACK_H
|
||||
#define UPDATER_CALLBACK_H
|
||||
|
||||
#include "if_system_ability_manager.h"
|
||||
#include "ipc_skeleton.h"
|
||||
#include "iremote_stub.h"
|
||||
#include "iupdate_callback.h"
|
||||
#include "update_callback_stub.h"
|
||||
#include "update_helper.h"
|
||||
#include "system_ability.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
class UpdateCallback : public UpdateCallbackStub {
|
||||
public:
|
||||
explicit UpdateCallback() = default;
|
||||
|
||||
~UpdateCallback() = default;
|
||||
|
||||
void OnCheckVersionDone(const VersionInfo &info) override;
|
||||
|
||||
void OnDownloadProgress(const Progress &progress) override;
|
||||
|
||||
void OnUpgradeProgress(const Progress &progress) override;
|
||||
};
|
||||
}
|
||||
} // namespace OHOS
|
||||
#endif // UPDATER_CALLBACK_H
|
||||
Executable
+41
@@ -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 UPDATER_CALLBACK_PROXY_H
|
||||
#define UPDATER_CALLBACK_PROXY_H
|
||||
|
||||
#include "iremote_proxy.h"
|
||||
#include "iupdate_service.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
class UpdateCallbackProxy : public IRemoteProxy<IUpdateCallback> {
|
||||
public:
|
||||
explicit UpdateCallbackProxy(const sptr<IRemoteObject>& impl) : IRemoteProxy<IUpdateCallback>(impl) {}
|
||||
|
||||
virtual ~UpdateCallbackProxy() = default;
|
||||
|
||||
void OnCheckVersionDone(const VersionInfo &info) override;
|
||||
|
||||
void OnDownloadProgress(const Progress &progress) override;
|
||||
|
||||
void OnUpgradeProgress(const Progress &progress) override;
|
||||
|
||||
private:
|
||||
static inline BrokerDelegator<UpdateCallbackProxy> delegator_;
|
||||
};
|
||||
}
|
||||
} // namespace OHOS
|
||||
#endif // UPDATER_CALLBACK_PROXY_H
|
||||
Executable
+33
@@ -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 UPDATE_CALLBACK_STUB_H_
|
||||
#define UPDATE_CALLBACK_STUB_H_
|
||||
|
||||
#include "iremote_stub.h"
|
||||
#include "iupdate_callback.h"
|
||||
#include "message_parcel.h"
|
||||
#include "parcel.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
class UpdateCallbackStub : public IRemoteStub<IUpdateCallback> {
|
||||
public:
|
||||
int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
|
||||
MessageOption &option) override;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif // !defined(UPDATE_CALLBACK_STUB_H_)
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "update_callback.h"
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
#include "iservice_registry.h"
|
||||
#include "parameters.h"
|
||||
#include "securec.h"
|
||||
#include "system_ability_definition.h"
|
||||
#include "update_helper.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
void UpdateCallback::OnCheckVersionDone(const VersionInfo &info)
|
||||
{
|
||||
ENGINE_LOGI("OnCheckVersionDone VersionInfo status %d", info.status);
|
||||
ENGINE_LOGI("OnCheckVersionDone VersionInfo errMsg %s", info.errMsg.c_str());
|
||||
ENGINE_LOGI("OnCheckVersionDone VersionInfo versionName : %s", info.result[0].versionName.c_str());
|
||||
ENGINE_LOGI("OnCheckVersionDone VersionInfo versionCode : %s", info.result[0].versionCode.c_str());
|
||||
ENGINE_LOGI("OnCheckVersionDone VersionInfo verifyInfo : %s", info.result[0].verifyInfo.c_str());
|
||||
ENGINE_LOGI("OnCheckVersionDone VersionInfo size : %zu", info.result[0].size);
|
||||
}
|
||||
|
||||
void UpdateCallback::OnDownloadProgress(const Progress &progress)
|
||||
{
|
||||
ENGINE_LOGI("OnDownloadProgress progress %u %d", progress.percent, progress.status);
|
||||
}
|
||||
|
||||
void UpdateCallback::OnUpgradeProgress(const Progress &progress)
|
||||
{
|
||||
ENGINE_LOGI("OnUpgradeProgress progress %u %d", progress.percent, progress.status);
|
||||
}
|
||||
}
|
||||
} // namespace OHOS
|
||||
Executable
+76
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "update_callback_proxy.h"
|
||||
#include "securec.h"
|
||||
#include "update_helper.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
void UpdateCallbackProxy::OnCheckVersionDone(const VersionInfo &info)
|
||||
{
|
||||
ENGINE_LOGI("UpdateCallbackProxy::OnCheckVersionDone");
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option { MessageOption::TF_SYNC };
|
||||
|
||||
auto remote = Remote();
|
||||
ENGINE_CHECK(remote != nullptr, return, "Can not get remote");
|
||||
|
||||
int32_t result = UpdateHelper::WriteVersionInfo(data, info);
|
||||
ENGINE_CHECK(result == 0, return, "Can not WriteVersionInfo");
|
||||
|
||||
result = remote->SendRequest(CHECK_VERSION, data, reply, option);
|
||||
ENGINE_CHECK(result == ERR_OK, return, "Can not SendRequest");
|
||||
return;
|
||||
}
|
||||
|
||||
void UpdateCallbackProxy::OnDownloadProgress(const Progress &progress)
|
||||
{
|
||||
ENGINE_LOGI("UpdateCallbackProxy::OnDownloadProgress");
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option { MessageOption::TF_SYNC };
|
||||
|
||||
auto remote = Remote();
|
||||
ENGINE_CHECK(remote != nullptr, return, "Can not get remote");
|
||||
|
||||
int32_t result = UpdateHelper::WriteUpdateProgress(data, progress);
|
||||
ENGINE_CHECK(result == 0, return, "Can not WriteUpdateProgress");
|
||||
|
||||
result = remote->SendRequest(DOWNLOAD, data, reply, option);
|
||||
ENGINE_CHECK(result == ERR_OK, return, "Can not SendRequest %d", result);
|
||||
return;
|
||||
}
|
||||
|
||||
void UpdateCallbackProxy::OnUpgradeProgress(const Progress &progress)
|
||||
{
|
||||
ENGINE_LOGI("UpdateCallbackProxy::OnUpgradeProgress");
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option { MessageOption::TF_SYNC };
|
||||
|
||||
auto remote = Remote();
|
||||
ENGINE_CHECK(remote != nullptr, return, "Can not get remote");
|
||||
|
||||
int32_t result = UpdateHelper::WriteUpdateProgress(data, progress);
|
||||
ENGINE_CHECK(result == 0, return, "Can not WriteUpdateProgress");
|
||||
|
||||
result = remote->SendRequest(UPGRADE, data, reply, option);
|
||||
ENGINE_CHECK(result == ERR_OK, return, "Can not SendRequest");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} // namespace OHOS
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
#include "update_callback_stub.h"
|
||||
#include "securec.h"
|
||||
#include "update_helper.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
int32_t UpdateCallbackStub::OnRemoteRequest(uint32_t code,
|
||||
MessageParcel &data, MessageParcel &reply, MessageOption &option)
|
||||
{
|
||||
switch (code) {
|
||||
case CHECK_VERSION: {
|
||||
VersionInfo info;
|
||||
UpdateHelper::ReadVersionInfo(data, info);
|
||||
OnCheckVersionDone(info);
|
||||
break;
|
||||
}
|
||||
case DOWNLOAD: {
|
||||
Progress info;
|
||||
UpdateHelper::ReadUpdateProgress(data, info);
|
||||
OnDownloadProgress(info);
|
||||
break;
|
||||
}
|
||||
case UPGRADE: {
|
||||
Progress info;
|
||||
UpdateHelper::ReadUpdateProgress(data, info);
|
||||
OnUpgradeProgress(info);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+65
@@ -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("//build/ohos.gni")
|
||||
|
||||
ohos_shared_library("update") {
|
||||
sources = [
|
||||
"//base/update/updateservice/client/update_client.cpp",
|
||||
"//base/update/updateservice/client/update_module.cpp",
|
||||
"//base/update/updateservice/client/update_session.cpp",
|
||||
]
|
||||
|
||||
include_dirs = [
|
||||
"//base/update/updater/interfaces/kits/include",
|
||||
"//base/update/updater/services/include",
|
||||
"//base/update/updater/utils/include",
|
||||
"//third_party/node/src",
|
||||
"//foundation/ace/napi/interfaces/kits",
|
||||
"//utils/native/base/include",
|
||||
"//utils/system/safwk/native/include",
|
||||
"//base/update/updateservice/interfaces/innerkits/include",
|
||||
"//base/update/updateservice/client",
|
||||
"//base/startup/syspara_lite/adapter/native/syspara/include",
|
||||
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include",
|
||||
"//foundation/distributedschedule/safwk/services/safwk/include",
|
||||
"//foundation/distributedschedule/safwk/interfaces/innerkits/safwk",
|
||||
"//foundation/distributedschedule/samgr/adapter/interfaces/innerkits/include",
|
||||
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//base/update/updater/interfaces/kits/misc_info:libmiscinfo",
|
||||
"//base/update/updater/interfaces/kits/packages:libpackageExt",
|
||||
"//base/update/updater/services/log:libupdaterlog",
|
||||
"//base/update/updater/utils:libutils",
|
||||
"//base/update/updateservice/interfaces/innerkits/engine:updateservicekits",
|
||||
"//foundation/ace/napi:ace_napi",
|
||||
"//third_party/bounds_checking_function:libsec_static",
|
||||
"//third_party/openssl:crypto_source",
|
||||
"//third_party/openssl:ssl_source",
|
||||
"//utils/native/base:utils",
|
||||
]
|
||||
|
||||
external_deps = [
|
||||
"hiviewdfx_hilog_native:libhilog",
|
||||
"ipc:ipc_core",
|
||||
"safwk:system_ability_fwk",
|
||||
"samgr_L2:samgr_proxy",
|
||||
"startup_l2:syspara",
|
||||
]
|
||||
|
||||
install_enable = true
|
||||
relative_install_dir = "module"
|
||||
part_name = "updater"
|
||||
}
|
||||
@@ -0,0 +1,910 @@
|
||||
/*
|
||||
* 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 "update_client.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
#include "iupdate_service.h"
|
||||
#include "misc_info/misc_info.h"
|
||||
#include "node_api.h"
|
||||
#include "node_api_types.h"
|
||||
#include "package/package.h"
|
||||
#include "securec.h"
|
||||
#include "update_helper.h"
|
||||
#include "update_service_kits.h"
|
||||
#include "update_session.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace OHOS::update_engine;
|
||||
|
||||
namespace updateClient {
|
||||
const int32_t MAX_ARGC = 3;
|
||||
const int32_t DEVICE_ID_INDEX = 1;
|
||||
const int32_t MID_ARGC = 2;
|
||||
const int32_t CLIENT_STRING_MAX_LENGTH = 200;
|
||||
constexpr int PROGRESS_DOWNLOAD_FINISH = 100;
|
||||
const std::string MISC_FILE = "/dev/block/platform/soc/10100000.himci.eMMC/by-name/misc";
|
||||
const std::string UPDATER_PKG_NAME = "/data/updater/updater.zip";
|
||||
|
||||
UpdateClient::UpdateClient(napi_env env, napi_value thisVar)
|
||||
{
|
||||
thisReference_ = nullptr;
|
||||
env_ = env;
|
||||
napi_create_reference(env, thisVar, 1, &thisReference_);
|
||||
context_.type = "OTA";
|
||||
context_.upgradeDevId = "local";
|
||||
context_.controlDevId = "local";
|
||||
context_.upgradeApp = "updateclient";
|
||||
context_.upgradeFile = UPDATER_PKG_NAME;
|
||||
}
|
||||
|
||||
UpdateClient::~UpdateClient()
|
||||
{
|
||||
sessions_.clear();
|
||||
if (thisReference_ != nullptr) {
|
||||
napi_delete_reference(env_, thisReference_);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateSession *UpdateClient::RemoveSession(uint32_t sessionId)
|
||||
{
|
||||
CLIENT_LOGI("RemoveSession sess");
|
||||
std::lock_guard<std::mutex> guard(sessionMutex_);
|
||||
UpdateSession *sess = nullptr;
|
||||
auto iter = sessions_.find(sessionId);
|
||||
if (iter != sessions_.end()) {
|
||||
sess = iter->second.get();
|
||||
sessions_.erase(iter);
|
||||
}
|
||||
return sess;
|
||||
}
|
||||
|
||||
void UpdateClient::AddSession(std::shared_ptr<UpdateSession> session)
|
||||
{
|
||||
CLIENT_CHECK(session != nullptr, return, "Invalid param");
|
||||
std::lock_guard<std::mutex> guard(sessionMutex_);
|
||||
sessions_.insert(make_pair(session->GetSessionId(), session));
|
||||
}
|
||||
|
||||
napi_value UpdateClient::GetUpdaterForOther(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = MAX_ARGC;
|
||||
napi_value args[MAX_ARGC] = {0};
|
||||
napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Error get cb info");
|
||||
CLIENT_CHECK_NAPI_CALL(env, argc >= MID_ARGC, return nullptr, "Invalid param");
|
||||
|
||||
// Get the devid.
|
||||
int ret = GetStringValue(env, args[1], context_.upgradeDevId);
|
||||
CLIENT_CHECK_NAPI_CALL(env, ret == napi_ok, return nullptr, "Error get type");
|
||||
return GetUpdater(env, info, DEVICE_ID_INDEX + 1);
|
||||
}
|
||||
|
||||
napi_value UpdateClient::GetUpdaterFromOther(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = MAX_ARGC;
|
||||
napi_value args[MAX_ARGC] = {0};
|
||||
napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Error get cb info");
|
||||
CLIENT_CHECK_NAPI_CALL(env, argc >= MID_ARGC, return nullptr, "Invalid param");
|
||||
|
||||
// Get the devid.
|
||||
int ret = GetStringValue(env, args[1], context_.controlDevId);
|
||||
CLIENT_CHECK_NAPI_CALL(env, ret == napi_ok, return nullptr, "Error get type");
|
||||
return GetUpdater(env, info, DEVICE_ID_INDEX + 1);
|
||||
}
|
||||
|
||||
bool UpdateClient::CheckUpgradeType(const std::string &type)
|
||||
{
|
||||
std::vector<std::string> upgradeTypes = {
|
||||
"ota", "patch"
|
||||
};
|
||||
std::string upgradeType = type;
|
||||
upgradeType.erase(0, upgradeType.find_first_not_of(" "));
|
||||
upgradeType.erase(upgradeType.find_last_not_of(" ") + 1);
|
||||
std::transform(upgradeType.begin(), upgradeType.end(), upgradeType.begin(), ::tolower);
|
||||
for (auto inter = upgradeTypes.cbegin(); inter != upgradeTypes.cend(); inter++) {
|
||||
if ((*inter).compare(upgradeType) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UpdateClient::CheckUpgradeFile(const std::string &upgradeFile)
|
||||
{
|
||||
if (upgradeFile.empty()) {
|
||||
return false;
|
||||
}
|
||||
std::string file = upgradeFile;
|
||||
file.erase(0, file.find_first_not_of(" "));
|
||||
file.erase(file.find_last_not_of(" ") + 1);
|
||||
int32_t pos = file.find_first_of('/');
|
||||
if (pos != 0) {
|
||||
return false;
|
||||
}
|
||||
pos = file.find_last_of('.');
|
||||
if (pos < 0) {
|
||||
return false;
|
||||
}
|
||||
std::string postfix = file.substr(pos + 1, -1);
|
||||
std::transform(postfix.begin(), postfix.end(), postfix.begin(), ::tolower);
|
||||
if (postfix.compare("bin") == 0) {
|
||||
return true;
|
||||
} else if (postfix.compare("zip") == 0) {
|
||||
return true;
|
||||
} else if (postfix.compare("lz4") == 0) {
|
||||
return true;
|
||||
} else if (postfix.compare("gz") == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
napi_value UpdateClient::GetUpdater(napi_env env, napi_callback_info info, int32_t typeIndex)
|
||||
{
|
||||
napi_value result;
|
||||
napi_create_int32(env, 0, &result);
|
||||
size_t argc = MAX_ARGC;
|
||||
napi_value args[MAX_ARGC] = {0};
|
||||
napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Error get cb info");
|
||||
CLIENT_CHECK_NAPI_CALL(env, argc >= 1, return nullptr, "Invalid param");
|
||||
CLIENT_CHECK_NAPI_CALL(env, !isInit, return nullptr, "Has beed init");
|
||||
|
||||
int ret = GetStringValue(env, args[0], context_.upgradeFile);
|
||||
CLIENT_CHECK_NAPI_CALL(env, ret == napi_ok && CheckUpgradeFile(context_.upgradeFile),
|
||||
return nullptr, "Invalid upgradeFile");
|
||||
ret = GetStringValue(env, args[typeIndex], context_.type);
|
||||
if (ret == napi_ok) {
|
||||
CLIENT_CHECK_NAPI_CALL(env, CheckUpgradeType(context_.type), return nullptr, "Error get upgradeType");
|
||||
} else {
|
||||
context_.type = "OTA";
|
||||
}
|
||||
CLIENT_LOGE("GetUpdater argc %s", context_.type.c_str());
|
||||
UpdateCallbackInfo callback {
|
||||
[&](const VersionInfo &info) {
|
||||
this->NotifyCheckVersionDone(info);
|
||||
},
|
||||
[&](const Progress &info) {
|
||||
this->NotifyDownloadProgress(info);
|
||||
},
|
||||
[&](const Progress &info) {
|
||||
this->NotifyUpgradeProgresss(info);
|
||||
},
|
||||
};
|
||||
UpdateServiceKits::GetInstance().RegisterUpdateCallback(context_, callback);
|
||||
isInit = true;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
napi_value UpdateClient::StartSession(napi_env env,
|
||||
napi_callback_info info, int32_t type, size_t callbackStartIndex, DoWorkFunction function)
|
||||
{
|
||||
size_t argc = MAX_ARGC;
|
||||
napi_value args[MAX_ARGC] = {0};
|
||||
napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Error get cb info");
|
||||
|
||||
CLIENT_LOGE("StartSession type %d argc %zu callbackStartIndex %d", type, argc, callbackStartIndex);
|
||||
std::shared_ptr<UpdateSession> sess = nullptr;
|
||||
if (argc > callbackStartIndex) {
|
||||
sess = std::make_shared<UpdateAsyncession>(this, type, argc, 1);
|
||||
} else {
|
||||
sess = std::make_shared<UpdatePromiseSession>(this, type, argc, 0);
|
||||
}
|
||||
CLIENT_CHECK_NAPI_CALL(env, sess != nullptr, return nullptr, "Failed to create update session");
|
||||
AddSession(sess);
|
||||
napi_value retValue = sess->StartWork(env, callbackStartIndex, args, function, nullptr);
|
||||
CLIENT_CHECK(retValue != nullptr, RemoveSession(sess->GetSessionId()); return nullptr, "Failed to start worker.");
|
||||
|
||||
return retValue;
|
||||
}
|
||||
|
||||
napi_value UpdateClient::CheckNewVersion(napi_env env, napi_callback_info info)
|
||||
{
|
||||
versionInfo_.status = SYSTEM_ERROR;
|
||||
napi_value ret = StartSession(env, info, SESSION_CHECK_VERSION, 0,
|
||||
[&](int32_t type, void *context) -> int {
|
||||
return UpdateServiceKits::GetInstance().CheckNewVersion();
|
||||
});
|
||||
CLIENT_CHECK(ret != nullptr, return nullptr, "Failed to start worker.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
napi_value UpdateClient::CancelUpgrade(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = MAX_ARGC;
|
||||
napi_value args[MAX_ARGC] = {0};
|
||||
napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Error get cb info");
|
||||
CLIENT_LOGE("CancelUpgrade");
|
||||
std::shared_ptr<UpdateSession> sess = nullptr;
|
||||
sess = std::make_shared<UpdateAsyncessionNoCallback>(this, SESSION_CANCEL_UPGRADE, argc, 0);
|
||||
CLIENT_CHECK_NAPI_CALL(env, sess != nullptr, return nullptr, "Failed to create update session");
|
||||
AddSession(sess);
|
||||
napi_value retValue = sess->StartWork(env, 0, args,
|
||||
[&](int32_t type, void *context) -> int {
|
||||
return UpdateServiceKits::GetInstance().Cancel(IUpdateService::DOWNLOAD);
|
||||
}, nullptr);
|
||||
CLIENT_CHECK(retValue != nullptr, RemoveSession(sess->GetSessionId()); return nullptr, "Failed to start worker.");
|
||||
return retValue;
|
||||
}
|
||||
|
||||
napi_value UpdateClient::DownloadVersion(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = MAX_ARGC;
|
||||
napi_value args[MAX_ARGC] = {0};
|
||||
napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Error get cb info");
|
||||
CLIENT_LOGE("DownloadVersion");
|
||||
std::shared_ptr<UpdateSession> sess = nullptr;
|
||||
sess = std::make_shared<UpdateAsyncessionNoCallback>(this, SESSION_DOWNLOAD, argc, 0);
|
||||
CLIENT_CHECK_NAPI_CALL(env, sess != nullptr, return nullptr, "Failed to create update session");
|
||||
AddSession(sess);
|
||||
napi_value retValue = sess->StartWork(env, 0, args,
|
||||
[&](int32_t type, void *context) -> int {
|
||||
return UpdateServiceKits::GetInstance().DownloadVersion();
|
||||
}, nullptr);
|
||||
CLIENT_CHECK(retValue != nullptr, RemoveSession(sess->GetSessionId()); return nullptr, "Failed to start worker.");
|
||||
return retValue;
|
||||
}
|
||||
|
||||
napi_value UpdateClient::UpgradeVersion(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = MAX_ARGC;
|
||||
napi_value args[MAX_ARGC] = {0};
|
||||
napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Error get cb info");
|
||||
std::shared_ptr<UpdateSession> sess = nullptr;
|
||||
sess = std::make_shared<UpdateAsyncessionNoCallback>(this, SESSION_UPGRADE, argc, 0);
|
||||
CLIENT_CHECK_NAPI_CALL(env, sess != nullptr, return nullptr, "Failed to create update session");
|
||||
AddSession(sess);
|
||||
napi_value retValue = sess->StartWork(env, 0, args,
|
||||
[&](int32_t type, void *context) -> int {
|
||||
#ifndef UPDATER_API_TEST
|
||||
return UpdateServiceKits::GetInstance().DoUpdate();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}, nullptr);
|
||||
CLIENT_CHECK(retValue != nullptr, RemoveSession(sess->GetSessionId()); return nullptr, "Failed to start worker.");
|
||||
return retValue;
|
||||
}
|
||||
|
||||
napi_value UpdateClient::SetUpdatePolicy(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = MAX_ARGC;
|
||||
napi_value args[MAX_ARGC] = {0};
|
||||
napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Error get cb info");
|
||||
|
||||
int ret = GetUpdatePolicyFromArg(env, args[0], updatePolicy_);
|
||||
CLIENT_CHECK_NAPI_CALL(env, ret == napi_ok, return nullptr, "Failed to get policy para");
|
||||
|
||||
std::shared_ptr<UpdateSession> sess = nullptr;
|
||||
if (argc >= MID_ARGC) {
|
||||
sess = std::make_shared<UpdateAsyncession>(this, SESSION_SET_POLICY, argc, 1);
|
||||
} else {
|
||||
sess = std::make_shared<UpdatePromiseSession>(this, SESSION_SET_POLICY, argc, 0);
|
||||
}
|
||||
CLIENT_CHECK_NAPI_CALL(env, sess != nullptr, return nullptr, "Failed to create update session");
|
||||
AddSession(sess);
|
||||
napi_value retValue = sess->StartWork(env, 1, args,
|
||||
[&](int32_t type, void *context) -> int {
|
||||
result_ = UpdateServiceKits::GetInstance().SetUpdatePolicy(updatePolicy_);
|
||||
return result_;
|
||||
}, nullptr);
|
||||
CLIENT_CHECK(retValue != nullptr, RemoveSession(sess->GetSessionId());
|
||||
return nullptr, "Failed to SetUpdatePolicy.");
|
||||
return retValue;
|
||||
}
|
||||
|
||||
napi_value UpdateClient::GetUpdatePolicy(napi_env env, napi_callback_info info)
|
||||
{
|
||||
napi_value retValue = StartSession(env, info, SESSION_GET_POLICY, 0,
|
||||
[&](int32_t type, void *context) -> int {
|
||||
return UpdateServiceKits::GetInstance().GetUpdatePolicy(updatePolicy_);
|
||||
});
|
||||
CLIENT_CHECK(retValue != nullptr, return nullptr, "Failed to UpgradeVersion.");
|
||||
return retValue;
|
||||
}
|
||||
|
||||
napi_value UpdateClient::GetNewVersionInfo(napi_env env, napi_callback_info info)
|
||||
{
|
||||
napi_value retValue = StartSession(env, info, SESSION_GET_NEW_VERSION, 0,
|
||||
[&](int32_t type, void *context) -> int {
|
||||
return UpdateServiceKits::GetInstance().GetNewVersion(versionInfo_);
|
||||
});
|
||||
CLIENT_CHECK(retValue != nullptr, return nullptr, "Failed to GetNewVersionInfo.");
|
||||
return retValue;
|
||||
}
|
||||
|
||||
napi_value UpdateClient::GetUpgradeStatus(napi_env env, napi_callback_info info)
|
||||
{
|
||||
napi_value retValue = StartSession(env, info, SESSION_GET_STATUS, 0,
|
||||
[&](int32_t type, void *context) -> int {
|
||||
return UpdateServiceKits::GetInstance().GetUpgradeStatus(upgradeInfo_);
|
||||
});
|
||||
CLIENT_CHECK(retValue != nullptr, return nullptr, "Failed to GetUpgradeStatus.");
|
||||
return retValue;
|
||||
}
|
||||
|
||||
napi_value UpdateClient::ApplyNewVersion(napi_env env, napi_callback_info info)
|
||||
{
|
||||
napi_value retValue = StartSession(env, info, SESSION_APPLY_NEW_VERSION, 0,
|
||||
[&](int32_t type, void *context) -> int {
|
||||
result_ = UpdateServiceKits::GetInstance().RebootAndInstall(MISC_FILE, UPDATER_PKG_NAME);
|
||||
return result_;
|
||||
});
|
||||
CLIENT_CHECK(retValue != nullptr, return nullptr, "Failed to GetNewVersionInfo.");
|
||||
return retValue;
|
||||
}
|
||||
|
||||
napi_value UpdateClient::RebootAndClean(napi_env env, napi_callback_info info)
|
||||
{
|
||||
napi_value retValue = StartSession(env, info, SESSION_REBOOT_AND_CLEAN, 0,
|
||||
[&](int32_t type, void *context) -> int {
|
||||
result_ = UpdateServiceKits::GetInstance().RebootAndClean(MISC_FILE, UPDATER_PKG_NAME);
|
||||
return result_;
|
||||
});
|
||||
CLIENT_CHECK(retValue != nullptr, return nullptr, "Failed to GetNewVersionInfo.");
|
||||
return retValue;
|
||||
}
|
||||
|
||||
napi_value UpdateClient::VerifyUpdatePackage(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = MAX_ARGC;
|
||||
napi_value args[MAX_ARGC] = {0};
|
||||
napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Error get cb info");
|
||||
CLIENT_CHECK_NAPI_CALL(env, argc >= MID_ARGC, return nullptr, "Error get cb info");
|
||||
|
||||
int ret = GetStringValue(env, args[0], upgradeFile_);
|
||||
CLIENT_CHECK_NAPI_CALL(env, ret == napi_ok, return nullptr, "Error get upgradeType");
|
||||
ret = GetStringValue(env, args[1], certsFile_);
|
||||
CLIENT_CHECK_NAPI_CALL(env, ret == napi_ok, return nullptr, "Error get certsFile");
|
||||
|
||||
CLIENT_LOGE("VerifyUpdatePackage");
|
||||
std::shared_ptr<UpdateSession> sess = nullptr;
|
||||
sess = std::make_shared<UpdateAsyncessionNoCallback>(this, SESSION_VERIFY_PACKAGE, argc, 0);
|
||||
CLIENT_CHECK_NAPI_CALL(env, sess != nullptr, return nullptr, "Fail to create update session");
|
||||
AddSession(sess);
|
||||
size_t startIndex = 2;
|
||||
napi_value retValue = sess->StartWork(env, startIndex, args,
|
||||
[&](int32_t type, void *context) -> int {
|
||||
CLIENT_LOGE("StartWork VerifyUpdatePackage");
|
||||
result_ = VerifyPackageWithCallback(upgradeFile_, certsFile_,
|
||||
[&](int32_t result, uint32_t percent) { NotifyVerifyProgresss(result, percent); });
|
||||
return result_;
|
||||
},
|
||||
nullptr);
|
||||
CLIENT_CHECK(retValue != nullptr, RemoveSession(sess->GetSessionId()); return nullptr, "Failed to start worker.");
|
||||
return retValue;
|
||||
}
|
||||
|
||||
napi_value UpdateClient::SubscribeEvent(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = MAX_ARGC;
|
||||
napi_value args[MAX_ARGC] = {0};
|
||||
napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Error get cb info");
|
||||
// Two arguments are required: type + callback.
|
||||
CLIENT_CHECK_NAPI_CALL(env, argc >= MID_ARGC, return nullptr, "Invalid param");
|
||||
|
||||
std::string eventType;
|
||||
int ret = UpdateClient::GetStringValue(env, args[0], eventType);
|
||||
CLIENT_CHECK_NAPI_CALL(env, ret == napi_ok, return nullptr, "Failed to get event type");
|
||||
CLIENT_CHECK(FindSessionByHandle(env, eventType, args[1]) == nullptr, return nullptr, "Handle has been sub");
|
||||
|
||||
std::shared_ptr<UpdateSession> sess = std::make_shared<UpdateListener>(this, SESSION_SUBSCRIBE, argc, 1, false);
|
||||
CLIENT_CHECK_NAPI_CALL(env, sess != nullptr, return nullptr, "Failed to create listener");
|
||||
AddSession(sess);
|
||||
napi_value retValue = sess->StartWork(env, 1, args,
|
||||
[&](int32_t type, void *context) -> int {
|
||||
return 0;
|
||||
}, nullptr);
|
||||
CLIENT_CHECK(retValue != nullptr, RemoveSession(sess->GetSessionId()); return nullptr, "Failed to SubscribeEvent.");
|
||||
return retValue;
|
||||
}
|
||||
|
||||
napi_value UpdateClient::UnsubscribeEvent(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = MAX_ARGC;
|
||||
napi_value args[MAX_ARGC] = {0};
|
||||
napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Error get cb info");
|
||||
|
||||
std::string eventType;
|
||||
int ret = UpdateClient::GetStringValue(env, args[0], eventType);
|
||||
CLIENT_CHECK_NAPI_CALL(env, ret == napi_ok, return nullptr, "Failed to get event type");
|
||||
|
||||
CLIENT_LOGI("UnsubscribeEvent %s argc %d", eventType.c_str(), argc);
|
||||
if (argc >= MID_ARGC) {
|
||||
napi_valuetype valuetype;
|
||||
napi_status status = napi_typeof(env, args[1], &valuetype);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Failed to napi_typeof");
|
||||
CLIENT_CHECK_NAPI_CALL(env, valuetype == napi_function, return nullptr, "Invalid callback type");
|
||||
}
|
||||
ret = ProcessUnsubscribe(eventType, argc, args[1]);
|
||||
napi_value result;
|
||||
napi_create_int32(env, ret, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t UpdateClient::ProcessUnsubscribe(const std::string &eventType, size_t argc, napi_value arg)
|
||||
{
|
||||
napi_handle_scope scope;
|
||||
napi_status status = napi_open_handle_scope(env_, &scope);
|
||||
CLIENT_CHECK(status == napi_ok, return -1, "Error open handle");
|
||||
|
||||
uint32_t nextSessId = 0;
|
||||
bool hasNext = GetFirstSessionId(nextSessId);
|
||||
while (hasNext) {
|
||||
uint32_t currSessId = nextSessId;
|
||||
auto iter = sessions_.find(currSessId);
|
||||
if (iter == sessions_.end()) {
|
||||
break;
|
||||
}
|
||||
hasNext = GetNextSessionId(nextSessId);
|
||||
|
||||
UpdateListener *listener = static_cast<UpdateListener *>(iter->second.get());
|
||||
if (listener->GetType() != SESSION_SUBSCRIBE
|
||||
|| eventType.compare(listener->GetEventType()) != 0) {
|
||||
continue;
|
||||
}
|
||||
CLIENT_LOGI("ProcessUnsubscribe remove session");
|
||||
if (argc == 1) {
|
||||
listener->RemoveHandlerRef(env_);
|
||||
RemoveSession(currSessId);
|
||||
} else if (listener->CheckEqual(env_, arg, eventType)) {
|
||||
listener->RemoveHandlerRef(env_);
|
||||
RemoveSession(currSessId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
napi_close_handle_scope(env_, scope);
|
||||
return 0;
|
||||
}
|
||||
|
||||
UpdateSession *UpdateClient::FindSessionByHandle(napi_env env, const std::string &eventType, napi_value arg)
|
||||
{
|
||||
uint32_t nextSessId = 0;
|
||||
bool hasNext = GetFirstSessionId(nextSessId);
|
||||
while (hasNext) {
|
||||
uint32_t currSessId = nextSessId;
|
||||
auto iter = sessions_.find(currSessId);
|
||||
if (iter == sessions_.end()) {
|
||||
break;
|
||||
}
|
||||
hasNext = GetNextSessionId(nextSessId);
|
||||
|
||||
UpdateListener *listener = static_cast<UpdateListener *>(iter->second.get());
|
||||
if (listener->GetType() != SESSION_SUBSCRIBE) {
|
||||
continue;
|
||||
}
|
||||
if ((eventType.compare(listener->GetEventType()) == 0) && listener->CheckEqual(env_, arg, eventType)) {
|
||||
return listener;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool UpdateClient::GetNextSessionId(uint32_t &sessionId)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(sessionMutex_);
|
||||
{
|
||||
auto iter = sessions_.find(sessionId);
|
||||
if (iter == sessions_.end()) {
|
||||
return false;
|
||||
}
|
||||
iter++;
|
||||
if (iter == sessions_.end()) {
|
||||
return false;
|
||||
}
|
||||
sessionId = iter->second->GetSessionId();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UpdateClient::GetFirstSessionId(uint32_t &sessionId)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(sessionMutex_);
|
||||
{
|
||||
if (sessions_.empty()) {
|
||||
return false;
|
||||
}
|
||||
sessionId = sessions_.begin()->second->GetSessionId();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateClient::Emit(const std::string &type, int32_t retcode, const UpdateResult &result)
|
||||
{
|
||||
napi_handle_scope scope;
|
||||
napi_status status = napi_open_handle_scope(env_, &scope);
|
||||
CLIENT_CHECK_NAPI_CALL(env_, status == napi_ok, return, "Error open_handle_scope");
|
||||
napi_value thisVar = nullptr;
|
||||
status = napi_get_reference_value(env_, thisReference_, &thisVar);
|
||||
CLIENT_CHECK_NAPI_CALL(env_, status == napi_ok, return, "Error get_reference");
|
||||
|
||||
uint32_t nextSessId = 0;
|
||||
bool hasNext = GetFirstSessionId(nextSessId);
|
||||
while (hasNext) {
|
||||
uint32_t currSessId = nextSessId;
|
||||
auto iter = sessions_.find(currSessId);
|
||||
if (iter == sessions_.end()) {
|
||||
break;
|
||||
}
|
||||
hasNext = GetNextSessionId(nextSessId);
|
||||
UpdateListener *listener = static_cast<UpdateListener *>((iter->second).get());
|
||||
if ((listener->GetType() != SESSION_SUBSCRIBE) || (type.compare(listener->GetEventType()) != 0)) {
|
||||
continue;
|
||||
}
|
||||
listener->NotifyJS(env_, thisVar, retcode, result);
|
||||
iter = sessions_.find(currSessId);
|
||||
if (iter == sessions_.end()) {
|
||||
continue;
|
||||
}
|
||||
listener = static_cast<UpdateListener *>((iter->second).get());
|
||||
if (listener->IsOnce()) {
|
||||
listener->RemoveHandlerRef(env_);
|
||||
RemoveSession(currSessId);
|
||||
}
|
||||
}
|
||||
napi_close_handle_scope(env_, scope);
|
||||
}
|
||||
|
||||
void UpdateClient::NotifyDownloadProgress(const Progress &progress)
|
||||
{
|
||||
CLIENT_LOGI("NotifyDownloadProgress status %d %d", progress.status, progress.percent);
|
||||
if (progress.percent == PROGRESS_DOWNLOAD_FINISH && progress.status == UPDATE_STATE_DOWNLOAD_ON) {
|
||||
return;
|
||||
}
|
||||
progress_.percent = progress.percent;
|
||||
progress_.status = progress.status;
|
||||
progress_.endReason = progress.endReason;
|
||||
UpdateResult result;
|
||||
result.type = SESSION_DOWNLOAD;
|
||||
result.result.progress = &progress_;
|
||||
result.buildJSObject = BuildProgress;
|
||||
int32_t fail = (progress_.status == UPDATE_STATE_DOWNLOAD_FAIL || progress_.status == UPDATE_STATE_VERIFY_FAIL) ?
|
||||
progress_.status : 0;
|
||||
Emit("downloadProgress", fail, result);
|
||||
}
|
||||
|
||||
void UpdateClient::NotifyUpgradeProgresss(const Progress &progress)
|
||||
{
|
||||
CLIENT_LOGI("NotifyUpgradeProgresss status %d %d", progress.status, progress.percent);
|
||||
progress_.percent = progress.percent;
|
||||
progress_.status = progress.status;
|
||||
|
||||
UpdateResult result;
|
||||
result.type = SESSION_UPGRADE;
|
||||
result.result.progress = &progress_;
|
||||
result.buildJSObject = BuildProgress;
|
||||
int32_t fail = (progress_.status == UPDATE_STATE_DOWNLOAD_FAIL) ? progress_.status : 0;
|
||||
Emit("upgradeProgress", fail, result);
|
||||
}
|
||||
|
||||
void UpdateClient::NotifyVerifyProgresss(int32_t retCode, uint32_t percent)
|
||||
{
|
||||
verifyProgress_.status = (retCode == 0) ? UPDATE_STATE_VERIFY_SUCCESS : UPDATE_STATE_VERIFY_FAIL;
|
||||
verifyProgress_.percent = percent;
|
||||
|
||||
UpdateResult result;
|
||||
result.type = SESSION_VERIFY_PACKAGE;
|
||||
result.result.progress = &verifyProgress_;
|
||||
result.buildJSObject = BuildProgress;
|
||||
Emit("verifyProgress", retCode, result);
|
||||
}
|
||||
|
||||
void UpdateClient::NotifyCheckVersionDone(const VersionInfo &info)
|
||||
{
|
||||
CLIENT_LOGE("NotifyCheckVersionDone status %d", info.status);
|
||||
CLIENT_LOGE("NotifyCheckVersionDone errMsg %s", info.errMsg.c_str());
|
||||
CLIENT_LOGE("NotifyCheckVersionDone versionName : %s", info.result[0].versionName.c_str());
|
||||
CLIENT_LOGE("NotifyCheckVersionDone versionCode : %s", info.result[0].versionCode.c_str());
|
||||
CLIENT_LOGE("NotifyCheckVersionDone verifyInfo : %s", info.result[0].verifyInfo.c_str());
|
||||
CLIENT_LOGE("NotifyCheckVersionDone size : %zu", info.result[0].size);
|
||||
CLIENT_LOGE("NotifyCheckVersionDone content : %s", info.descriptInfo[0].content.c_str());
|
||||
|
||||
UpdateHelper::CopyVersionInfo(info, versionInfo_);
|
||||
}
|
||||
|
||||
int32_t UpdateClient::GetInt32(napi_env env, napi_value arg, const std::string &attrName, int32_t &intValue)
|
||||
{
|
||||
bool result = false;
|
||||
napi_status status = napi_has_named_property(env, arg, attrName.c_str(), &result);
|
||||
if (result && (status == napi_ok)) {
|
||||
napi_value value;
|
||||
napi_get_named_property(env, arg, attrName.c_str(), &value);
|
||||
napi_get_value_int32(env, value, &intValue);
|
||||
}
|
||||
return CLIENT_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t UpdateClient::GetBool(napi_env env, napi_value arg, const std::string &attrName, bool &value)
|
||||
{
|
||||
bool result = false;
|
||||
napi_status status = napi_has_named_property(env, arg, attrName.c_str(), &result);
|
||||
if (result && (status == napi_ok)) {
|
||||
napi_value obj;
|
||||
napi_get_named_property(env, arg, attrName.c_str(), &obj);
|
||||
napi_get_value_bool(env, obj, &value);
|
||||
}
|
||||
return CLIENT_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t UpdateClient::GetStringValue(napi_env env, napi_value arg, std::string &strValue)
|
||||
{
|
||||
napi_valuetype valuetype;
|
||||
napi_status status = napi_typeof(env, arg, &valuetype);
|
||||
CLIENT_CHECK(status == napi_ok, return status, "Failed to napi_typeof");
|
||||
CLIENT_CHECK(valuetype == napi_string, return CLIENT_INVALID_TYPE, "Invalid type");
|
||||
std::vector<char> buff(CLIENT_STRING_MAX_LENGTH);
|
||||
size_t copied;
|
||||
status = napi_get_value_string_utf8(env, arg, (char*)buff.data(), CLIENT_STRING_MAX_LENGTH, &copied);
|
||||
CLIENT_CHECK(status == napi_ok, return CLIENT_INVALID_TYPE, "Error get string");
|
||||
strValue.assign(buff.data(), copied);
|
||||
return napi_ok;
|
||||
}
|
||||
|
||||
int32_t UpdateClient::SetString(napi_env env, napi_value arg, const std::string &attrName, const std::string &string)
|
||||
{
|
||||
napi_value value;
|
||||
napi_create_string_utf8(env, string.c_str(), string.length(), &value);
|
||||
napi_set_named_property(env, arg, attrName.c_str(), value);
|
||||
return CLIENT_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t UpdateClient::SetInt32(napi_env env, napi_value arg, const std::string &attrName, int32_t intValue)
|
||||
{
|
||||
napi_value infoStatus;
|
||||
napi_create_int32(env, intValue, &infoStatus);
|
||||
napi_set_named_property(env, arg, attrName.c_str(), infoStatus);
|
||||
return CLIENT_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t UpdateClient::SetBool(napi_env env, napi_value arg, const std::string &attrName, bool value)
|
||||
{
|
||||
napi_value infoStatus;
|
||||
napi_create_int32(env, value, &infoStatus);
|
||||
napi_set_named_property(env, arg, attrName.c_str(), infoStatus);
|
||||
return CLIENT_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t UpdateClient::SetInt64(napi_env env, napi_value arg, const std::string &attrName, int64_t intValue)
|
||||
{
|
||||
napi_value infoStatus;
|
||||
napi_create_int64(env, intValue, &infoStatus);
|
||||
napi_set_named_property(env, arg, attrName.c_str(), infoStatus);
|
||||
return CLIENT_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t UpdateClient::GetUpdatePolicyFromArg(napi_env env,
|
||||
const napi_value arg, UpdatePolicy &updatePolicy) const
|
||||
{
|
||||
napi_valuetype type = napi_undefined;
|
||||
napi_status status = napi_typeof(env, arg, &type);
|
||||
CLIENT_CHECK(status == napi_ok, return CLIENT_INVALID_TYPE, "Invlid argc %d", static_cast<int32_t>(status));
|
||||
CLIENT_CHECK(type == napi_object, return CLIENT_INVALID_TYPE, "Invlid argc %d", static_cast<int32_t>(type));
|
||||
|
||||
// updatePolicy
|
||||
int32_t tmpValue = 0;
|
||||
int32_t ret = GetBool(env, arg, "autoDownload", updatePolicy.autoDownload);
|
||||
ret |= GetBool(env, arg, "autoDownloadNet", updatePolicy.autoDownloadNet);
|
||||
ret |= GetInt32(env, arg, "mode", tmpValue);
|
||||
updatePolicy.mode = static_cast<InstallMode>(tmpValue);
|
||||
CLIENT_CHECK(ret == 0, return CLIENT_INVALID_TYPE, "Failed to get attr ");
|
||||
|
||||
// Get the array.
|
||||
bool result = false;
|
||||
status = napi_has_named_property(env, arg, "autoUpgradeInterval", &result);
|
||||
if (result && (status == napi_ok)) {
|
||||
napi_value value;
|
||||
status = napi_get_named_property(env, arg, "autoUpgradeInterval", &value);
|
||||
CLIENT_CHECK(status == napi_ok, return CLIENT_FAIL, "Failed to get attr autoUpgradeInterval");
|
||||
status = napi_is_array(env, value, &result);
|
||||
CLIENT_CHECK(status == napi_ok, return CLIENT_FAIL, "napi_is_array failed");
|
||||
uint32_t count = 0;
|
||||
status = napi_get_array_length(env, value, &count);
|
||||
CLIENT_CHECK(status == napi_ok, return CLIENT_FAIL, "napi_get_array_length failed");
|
||||
uint32_t i = 0;
|
||||
do {
|
||||
napi_value element;
|
||||
ret = napi_get_element(env, value, i, &element);
|
||||
ret = napi_get_value_uint32(env, element, &updatePolicy.autoUpgradeInterval[i]);
|
||||
CLIENT_LOGI("updatePolicy autoUpgradeInterval:%u ", updatePolicy.autoUpgradeInterval[i]);
|
||||
if (i >= sizeof(updatePolicy.autoUpgradeInterval) / sizeof(updatePolicy.autoUpgradeInterval[0])) {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
} while (i < count);
|
||||
}
|
||||
ret |= GetInt32(env, arg, "autoUpgradeCondition", tmpValue);
|
||||
CLIENT_CHECK(ret == 0, return CLIENT_INVALID_TYPE, "Failed to get attr autoUpgradeCondition");
|
||||
updatePolicy.autoUpgradeCondition = static_cast<AutoUpgradeCondition>(tmpValue);
|
||||
CLIENT_LOGI("updatePolicy autoDownload:%d autoDownloadNet:%d mode:%d autoUpgradeCondition:%d",
|
||||
static_cast<int32_t>(updatePolicy.autoDownload),
|
||||
static_cast<int32_t>(updatePolicy.autoDownloadNet),
|
||||
static_cast<int32_t>(updatePolicy.mode),
|
||||
static_cast<int32_t>(updatePolicy.autoUpgradeCondition));
|
||||
return CLIENT_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t UpdateClient::BuildCheckVersionResult(napi_env env, napi_value &obj, const UpdateResult &result)
|
||||
{
|
||||
CLIENT_CHECK(result.type == SESSION_CHECK_VERSION || result.type == SESSION_GET_NEW_VERSION,
|
||||
return CLIENT_INVALID_TYPE, "invalid type %d", result.type);
|
||||
napi_status status = napi_create_object(env, &obj);
|
||||
CLIENT_CHECK(status == napi_ok, return CLIENT_INVALID_TYPE,
|
||||
"Failed to create napi_create_object %d", static_cast<int32_t>(status));
|
||||
VersionInfo *info = result.result.versionInfo;
|
||||
|
||||
// Add the result.
|
||||
int32_t ret = SetInt32(env, obj, "status", info->status);
|
||||
if (info->status == SERVER_BUSY || info->status == SYSTEM_ERROR) {
|
||||
ret = SetString(env, obj, "errMsg", info->errMsg);
|
||||
return ret;
|
||||
}
|
||||
napi_value checkResults;
|
||||
napi_create_array_with_length(env, sizeof(info->result) / sizeof(info->result[0]), &checkResults);
|
||||
for (size_t i = 0; i < sizeof(info->result) / sizeof(info->result[0]); i++) {
|
||||
napi_value result;
|
||||
status = napi_create_object(env, &result);
|
||||
|
||||
ret |= SetString(env, result, "versionName", info->result[i].versionName);
|
||||
ret |= SetString(env, result, "versionCode", info->result[i].versionCode);
|
||||
ret |= SetString(env, result, "verifyInfo", info->result[i].verifyInfo);
|
||||
ret |= SetString(env, result, "descriptionId", info->result[i].descriptPackageId);
|
||||
ret |= SetInt64(env, result, "size", info->result[i].size);
|
||||
ret |= SetInt32(env, result, "packageType", info->result[i].packageType);
|
||||
napi_set_element(env, checkResults, i, result);
|
||||
}
|
||||
napi_set_named_property(env, obj, "checkResults", checkResults);
|
||||
|
||||
napi_value descriptInfos;
|
||||
napi_create_array_with_length(env, sizeof(info->descriptInfo) / sizeof(info->descriptInfo[0]), &descriptInfos);
|
||||
for (size_t i = 0; i < sizeof(info->descriptInfo) / sizeof(info->descriptInfo[0]); i++) {
|
||||
napi_value descriptInfo;
|
||||
status = napi_create_object(env, &descriptInfo);
|
||||
ret |= SetString(env, descriptInfo, "descriptionId", info->descriptInfo[i].descriptPackageId);
|
||||
ret |= SetString(env, descriptInfo, "content", info->descriptInfo[i].content);
|
||||
napi_set_element(env, descriptInfos, i, descriptInfo);
|
||||
}
|
||||
napi_set_named_property(env, obj, "descriptionInfo", descriptInfos);
|
||||
return CLIENT_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t UpdateClient::BuildProgress(napi_env env, napi_value &obj, const UpdateResult &result)
|
||||
{
|
||||
napi_status status = napi_create_object(env, &obj);
|
||||
CLIENT_CHECK(status == napi_ok, return CLIENT_INVALID_TYPE,
|
||||
"Failed to create napi_create_object %d", static_cast<int32_t>(status));
|
||||
int32_t ret = SetInt32(env, obj, "status", result.result.progress->status);
|
||||
ret |= SetInt32(env, obj, "percent", result.result.progress->percent);
|
||||
ret |= SetString(env, obj, "endReason", result.result.progress->endReason);
|
||||
return CLIENT_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t UpdateClient::BuildErrorResult(napi_env env, napi_value &obj, int32_t result)
|
||||
{
|
||||
napi_status status = napi_create_object(env, &obj);
|
||||
CLIENT_CHECK(status == napi_ok, return CLIENT_INVALID_TYPE,
|
||||
"Failed to create napi_create_object %d", static_cast<int32_t>(status));
|
||||
return SetInt32(env, obj, "code", result);
|
||||
}
|
||||
|
||||
int32_t UpdateClient::BuildInt32Status(napi_env env, napi_value &obj, const UpdateResult &result)
|
||||
{
|
||||
return napi_create_int32(env, result.result.status, &obj);
|
||||
}
|
||||
|
||||
int32_t UpdateClient::BuildUpdatePolicy(napi_env env, napi_value &obj, const UpdateResult &result)
|
||||
{
|
||||
CLIENT_CHECK(result.type == SESSION_GET_POLICY || result.type == SESSION_SET_POLICY,
|
||||
return CLIENT_INVALID_TYPE, "invalid type %d", result.type);
|
||||
napi_status status = napi_create_object(env, &obj);
|
||||
CLIENT_CHECK(status == napi_ok, return status, "Failed to create napi_create_object %d", status);
|
||||
UpdatePolicy &updatePolicy = *result.result.updatePolicy;
|
||||
|
||||
// Add the result.
|
||||
int32_t ret = SetBool(env, obj, "autoDownload", updatePolicy.autoDownload);
|
||||
ret |= SetBool(env, obj, "autoDownloadNet", updatePolicy.autoDownloadNet);
|
||||
ret |= SetInt32(env, obj, "mode", static_cast<int32_t>(updatePolicy.mode));
|
||||
CLIENT_CHECK(ret == napi_ok, return ret, "Failed to add value %d", ret);
|
||||
|
||||
napi_value autoUpgradeInterval;
|
||||
size_t count = sizeof(updatePolicy.autoUpgradeInterval) / sizeof(updatePolicy.autoUpgradeInterval[0]);
|
||||
status = napi_create_array_with_length(env, count, &autoUpgradeInterval);
|
||||
CLIENT_CHECK(status == napi_ok, return status, "Failed to create array for interval %d", status);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
napi_value interval;
|
||||
status = napi_create_uint32(env, updatePolicy.autoUpgradeInterval[i], &interval);
|
||||
status = napi_set_element(env, autoUpgradeInterval, i, interval);
|
||||
CLIENT_CHECK(status == napi_ok, return status, "Failed to add interval to array %d", status);
|
||||
}
|
||||
status = napi_set_named_property(env, obj, "autoUpgradeInterval", autoUpgradeInterval);
|
||||
CLIENT_CHECK(status == napi_ok, return status, "Failed to add autoUpgradeInterval %d", status);
|
||||
ret |= SetInt32(env, obj, "autoUpgradeCondition", static_cast<int32_t>(updatePolicy.autoUpgradeCondition));
|
||||
CLIENT_CHECK(ret == napi_ok, return ret, "Failed to add autoUpgradeCondition %d", ret);
|
||||
return napi_ok;
|
||||
}
|
||||
|
||||
int32_t UpdateClient::GetUpdateResult(int type, UpdateResult &result, int32_t &fail)
|
||||
{
|
||||
fail = 0;
|
||||
result.type = type;
|
||||
switch (type) {
|
||||
case SESSION_CHECK_VERSION:
|
||||
case SESSION_GET_NEW_VERSION: {
|
||||
fail = (versionInfo_.status == SYSTEM_ERROR) ? versionInfo_.status : 0;
|
||||
result.result.versionInfo = &versionInfo_;
|
||||
result.buildJSObject = BuildCheckVersionResult;
|
||||
break;
|
||||
}
|
||||
case SESSION_DOWNLOAD: {
|
||||
fail = (progress_.status == UPDATE_STATE_DOWNLOAD_FAIL || progress_.status == UPDATE_STATE_VERIFY_FAIL) ?
|
||||
progress_.status : 0;
|
||||
result.result.progress = &progress_;
|
||||
result.buildJSObject = BuildProgress;
|
||||
break;
|
||||
}
|
||||
case SESSION_UPGRADE: {
|
||||
fail = (progress_.status == UPDATE_STATE_DOWNLOAD_FAIL) ? progress_.status : 0;
|
||||
result.result.progress = &progress_;
|
||||
result.buildJSObject = BuildProgress;
|
||||
break;
|
||||
}
|
||||
case SESSION_VERIFY_PACKAGE: {
|
||||
fail = (verifyProgress_.status == UPDATE_STATE_VERIFY_FAIL) ? verifyProgress_.status : 0;
|
||||
result.result.progress = &verifyProgress_;
|
||||
result.buildJSObject = BuildProgress;
|
||||
break;
|
||||
}
|
||||
case SESSION_GET_POLICY: {
|
||||
result.result.updatePolicy = &updatePolicy_;
|
||||
result.buildJSObject = BuildUpdatePolicy;
|
||||
break;
|
||||
}
|
||||
case SESSION_GET_STATUS: {
|
||||
result.result.status = upgradeInfo_.status;
|
||||
result.buildJSObject = BuildInt32Status;
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
fail = result_;
|
||||
result.result.status = result_;
|
||||
result.buildJSObject = BuildInt32Status;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return napi_ok;
|
||||
}
|
||||
} // namespace updateClient
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* 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 UPDATE_CLIENT_H
|
||||
#define UPDATE_CLIENT_H
|
||||
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_node_api.h"
|
||||
#include "node_api.h"
|
||||
#include "node_api_types.h"
|
||||
#include "update_helper.h"
|
||||
#include "update_service_kits.h"
|
||||
|
||||
static constexpr OHOS::HiviewDFX::HiLogLabel UPDATE_CLIENT = {LOG_CORE, 0, "UPDATE_CLIENT"};
|
||||
#define CLIENT_LOGE(format, ...) \
|
||||
OHOS::update_engine::UpdateHelper::Logger(__FILE__, (__LINE__), format, ##__VA_ARGS__); \
|
||||
OHOS::HiviewDFX::HiLog::Error(UPDATE_CLIENT, "[%{public}s(%{public}d)] " format, \
|
||||
OHOS::update_engine::UpdateHelper::GetBriefFileName(std::string(__FILE__)).c_str(), __LINE__, ##__VA_ARGS__)
|
||||
|
||||
#define CLIENT_LOGI(format, ...) \
|
||||
OHOS::update_engine::UpdateHelper::Logger(__FILE__, (__LINE__), format, ##__VA_ARGS__); \
|
||||
OHOS::HiviewDFX::HiLog::Info(UPDATE_CLIENT, "[%{public}s(%{public}d)] " format, \
|
||||
OHOS::update_engine::UpdateHelper::GetBriefFileName(std::string(__FILE__)).c_str(), __LINE__, ##__VA_ARGS__)
|
||||
|
||||
#define CLIENT_CHECK(retCode, exper, ...) \
|
||||
if (!(retCode)) { \
|
||||
CLIENT_LOGE(__VA_ARGS__); \
|
||||
exper; \
|
||||
}
|
||||
|
||||
#define CLIENT_CHECK_NAPI_CALL(env, assertion, exper, message) \
|
||||
if (!(assertion)) { \
|
||||
CLIENT_LOGE(message); \
|
||||
exper; \
|
||||
}
|
||||
|
||||
namespace updateClient {
|
||||
// Update status
|
||||
enum ClientStatus {
|
||||
CLIENT_SUCCESS = 0,
|
||||
CLIENT_INVALID_PARAM = 1000,
|
||||
CLIENT_INVALID_TYPE,
|
||||
CLIENT_REPEAT_REQ,
|
||||
CLIENT_FAIL,
|
||||
CLIENT_CHECK_NEW_FIRST,
|
||||
};
|
||||
|
||||
enum SessionType {
|
||||
SESSION_CHECK_VERSION = 0,
|
||||
SESSION_DOWNLOAD,
|
||||
SESSION_UPGRADE,
|
||||
SESSION_SET_POLICY,
|
||||
SESSION_GET_POLICY,
|
||||
SESSION_GET_NEW_VERSION,
|
||||
SESSION_GET_STATUS,
|
||||
SESSION_SUBSCRIBE,
|
||||
SESSION_UNSUBSCRIBE,
|
||||
SESSION_GET_UPDATER,
|
||||
SESSION_APPLY_NEW_VERSION,
|
||||
SESSION_REBOOT_AND_CLEAN,
|
||||
SESSION_VERIFY_PACKAGE,
|
||||
SESSION_CANCEL_UPGRADE,
|
||||
SESSION_MAX
|
||||
};
|
||||
|
||||
struct UpdateResult {
|
||||
using BuildJSObject = std::function<int(napi_env env, napi_value &obj, const UpdateResult &result)>;
|
||||
int32_t type;
|
||||
union {
|
||||
OHOS::update_engine::UpdatePolicy *updatePolicy;
|
||||
OHOS::update_engine::Progress *progress;
|
||||
OHOS::update_engine::VersionInfo *versionInfo;
|
||||
int32_t status;
|
||||
} result;
|
||||
|
||||
BuildJSObject buildJSObject;
|
||||
};
|
||||
|
||||
|
||||
class UpdateSession;
|
||||
class UpdateClient {
|
||||
public:
|
||||
using DoWorkFunction = std::function<int(int32_t type, void *context)>;
|
||||
|
||||
UpdateClient(napi_env env, napi_value thisVar);
|
||||
~UpdateClient();
|
||||
|
||||
// Obtain the updater engine and return it through the sync API.
|
||||
napi_value GetUpdater(napi_env env, napi_callback_info info, int32_t index);
|
||||
napi_value GetUpdaterForOther(napi_env env, napi_callback_info info);
|
||||
napi_value GetUpdaterFromOther(napi_env env, napi_callback_info info);
|
||||
|
||||
// Asynchronous API
|
||||
napi_value CheckNewVersion(napi_env env, napi_callback_info info);
|
||||
napi_value SetUpdatePolicy(napi_env env, napi_callback_info info);
|
||||
napi_value GetUpdatePolicy(napi_env env, napi_callback_info info);
|
||||
napi_value GetNewVersionInfo(napi_env env, napi_callback_info info);
|
||||
napi_value GetUpgradeStatus(napi_env env, napi_callback_info info);
|
||||
napi_value ApplyNewVersion(napi_env env, napi_callback_info info);
|
||||
napi_value RebootAndClean(napi_env env, napi_callback_info info);
|
||||
|
||||
// Event mode, which is used to send the result to the JS.
|
||||
napi_value CancelUpgrade(napi_env env, napi_callback_info info);
|
||||
napi_value DownloadVersion(napi_env env, napi_callback_info info);
|
||||
napi_value UpgradeVersion(napi_env env, napi_callback_info info);
|
||||
napi_value VerifyUpdatePackage(napi_env env, napi_callback_info info);
|
||||
|
||||
// Subscription
|
||||
napi_value SubscribeEvent(napi_env env, napi_callback_info info);
|
||||
napi_value UnsubscribeEvent(napi_env env, napi_callback_info info);
|
||||
|
||||
int32_t GetUpdateResult(int type, UpdateResult &result, int32_t &isFail);
|
||||
|
||||
UpdateSession *RemoveSession(uint32_t sessionId);
|
||||
void AddSession(std::shared_ptr<UpdateSession> session);
|
||||
|
||||
void Emit(const std::string &type, int32_t retCode, const UpdateResult &result);
|
||||
|
||||
static int32_t GetStringValue(napi_env env, napi_value arg, std::string &strValue);
|
||||
static int32_t BuildErrorResult(napi_env env, napi_value &obj, int32_t result);
|
||||
|
||||
// Notify the session.
|
||||
void NotifyCheckVersionDone(const OHOS::update_engine::VersionInfo &info);
|
||||
void NotifyDownloadProgress(const OHOS::update_engine::Progress &progress);
|
||||
void NotifyUpgradeProgresss(const OHOS::update_engine::Progress &progress);
|
||||
void NotifyVerifyProgresss(int32_t result, uint32_t percent);
|
||||
|
||||
#ifdef UPDATER_UT
|
||||
UpdateSession *GetUpdateSession(uint32_t sessId)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(sessionMutex_);
|
||||
auto iter = sessions_.find(sessId);
|
||||
if (iter != sessions_.end()) {
|
||||
return iter->second.get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
private:
|
||||
napi_value StartSession(napi_env env,
|
||||
napi_callback_info info, int32_t type, size_t startIndex, DoWorkFunction function);
|
||||
int32_t GetNewVersion(bool isCheck);
|
||||
bool GetNextSessionId(uint32_t &sessionId);
|
||||
bool GetFirstSessionId(uint32_t &sessionId);
|
||||
bool CheckUpgradeType(const std::string &type);
|
||||
bool CheckUpgradeFile(const std::string &upgradeFile);
|
||||
int32_t ProcessUnsubscribe(const std::string &eventType, size_t argc, napi_value arg);
|
||||
UpdateSession *FindSessionByHandle(napi_env env, const std::string &eventType, napi_value arg);
|
||||
|
||||
// Verify the version and parameters.
|
||||
std::vector<uint8_t> HexToDegist(const std::string &str) const;
|
||||
bool VerifyDownloadPkg();
|
||||
std::vector<std::string> SplitString(const std::string &str, const std::string &delimiter = ".") const;
|
||||
int32_t CompareVersion(const std::string &version1, const std::string &version2) const;
|
||||
|
||||
int32_t GetUpdatePolicyFromArg(napi_env env,
|
||||
const napi_value arg, OHOS::update_engine::UpdatePolicy &updatePolicy) const;
|
||||
|
||||
void GetEnginContext(OHOS::update_engine::UpdateContext &context) const;
|
||||
void GetEnginPkgInfo(OHOS::update_engine::CheckResult &info) const;
|
||||
|
||||
// Parse input parameters.
|
||||
static int32_t GetInt32(napi_env env, napi_value arg, const std::string &attrName, int32_t &intValue);
|
||||
static int32_t GetInt64(napi_env env, napi_value arg, const std::string &attrName, int64_t &intValue);
|
||||
static int32_t GetBool(napi_env env, napi_value arg, const std::string &attrName, bool &value);
|
||||
|
||||
static int32_t SetString(napi_env env, napi_value arg, const std::string &attrName, const std::string &string);
|
||||
static int32_t SetInt32(napi_env env, napi_value arg, const std::string &attrName, int32_t intValue);
|
||||
static int32_t SetInt64(napi_env env, napi_value arg, const std::string &attrName, int64_t intValue);
|
||||
static int32_t SetBool(napi_env env, napi_value arg, const std::string &attrName, bool value);
|
||||
|
||||
// Construct output parameters.
|
||||
static int32_t BuildCheckVersionResult(napi_env env, napi_value &obj, const UpdateResult &result);
|
||||
static int32_t BuildProgress(napi_env env, napi_value &obj, const UpdateResult &result);
|
||||
static int32_t BuildUpdatePolicy(napi_env env, napi_value &obj, const UpdateResult &result);
|
||||
static int32_t BuildInt32Status(napi_env env, napi_value &obj, const UpdateResult &result);
|
||||
private:
|
||||
napi_env env_ {};
|
||||
napi_ref thisReference_ {};
|
||||
std::map<uint32_t, std::shared_ptr<UpdateSession>> sessions_ {};
|
||||
std::mutex sessionMutex_;
|
||||
bool isInit = false;
|
||||
int32_t result_ = 0;
|
||||
std::string upgradeFile_;
|
||||
std::string certsFile_;
|
||||
OHOS::update_engine::UpdateContext context_ {};
|
||||
OHOS::update_engine::UpdatePolicy updatePolicy_ {};
|
||||
OHOS::update_engine::Progress progress_ {};
|
||||
OHOS::update_engine::Progress verifyProgress_ {};
|
||||
OHOS::update_engine::VersionInfo versionInfo_ {};
|
||||
OHOS::update_engine::UpgradeInfo upgradeInfo_ {};
|
||||
};
|
||||
|
||||
// Obtain the updater engine and return it through the synchronous API.
|
||||
napi_value GetUpdater(napi_env env, napi_callback_info info);
|
||||
napi_value GetUpdaterForOther(napi_env env, napi_callback_info info);
|
||||
napi_value GetUpdaterFromOther(napi_env env, napi_callback_info info);
|
||||
|
||||
// Asynchronous API
|
||||
napi_value CheckNewVersion(napi_env env, napi_callback_info info);
|
||||
napi_value SetUpdatePolicy(napi_env env, napi_callback_info info);
|
||||
napi_value GetUpdatePolicy(napi_env env, napi_callback_info info);
|
||||
napi_value GetNewVersionInfo(napi_env env, napi_callback_info info);
|
||||
napi_value GetUpgradeStatus(napi_env env, napi_callback_info info);
|
||||
napi_value ApplyNewVersion(napi_env env, napi_callback_info info);
|
||||
napi_value RebootAndClean(napi_env env, napi_callback_info info);
|
||||
|
||||
// Event mode, which is used to send the result to the JS.
|
||||
napi_value CancelUpgrade(napi_env env, napi_callback_info info);
|
||||
napi_value DownloadVersion(napi_env env, napi_callback_info info);
|
||||
napi_value UpgradeVersion(napi_env env, napi_callback_info info);
|
||||
napi_value VerifyUpdatePackage(napi_env env, napi_callback_info info);
|
||||
|
||||
napi_value SubscribeEvent(napi_env env, napi_callback_info info);
|
||||
napi_value UnsubscribeEvent(napi_env env, napi_callback_info info);
|
||||
|
||||
#ifdef UPDATER_UT
|
||||
napi_value UpdateClientInit(napi_env env, napi_value exports);
|
||||
#endif
|
||||
} // namespace updateClient
|
||||
#endif // UPDATE_CLIENT_H
|
||||
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_node_api.h"
|
||||
#include "update_client.h"
|
||||
|
||||
namespace updateClient {
|
||||
const std::string CLASS_NAME = "UpdateClient";
|
||||
constexpr int32_t REF_COUNT = 20;
|
||||
napi_ref g_reference = nullptr;
|
||||
|
||||
napi_value UpdateClientJSConstructor(napi_env env, napi_callback_info info)
|
||||
{
|
||||
// Count of argument is 1
|
||||
size_t argc = 1;
|
||||
// Set second argument
|
||||
napi_value args[1] = {0};
|
||||
napi_value thisVar = nullptr;
|
||||
void* data = nullptr;
|
||||
napi_get_cb_info(env, info, &argc, args, &thisVar, &data);
|
||||
UpdateClient* client = new UpdateClient(env, thisVar);
|
||||
napi_wrap(env, thisVar, client,
|
||||
[](napi_env env, void* data, void* hint) {
|
||||
CLIENT_LOGI("UpdateClient Destructor");
|
||||
UpdateClient* client = (UpdateClient*)data;
|
||||
delete client;
|
||||
client = nullptr;
|
||||
},
|
||||
nullptr, nullptr);
|
||||
return thisVar;
|
||||
}
|
||||
|
||||
UpdateClient *GetAndCreateJsUpdateClient(napi_env env, napi_callback_info info, napi_value &obj)
|
||||
{
|
||||
napi_value constructor = nullptr;
|
||||
UpdateClient *client = nullptr;
|
||||
napi_status status = napi_get_reference_value(env, g_reference, &constructor);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Error get client");
|
||||
status = napi_new_instance(env, constructor, 0, nullptr, &obj);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Error get client");
|
||||
|
||||
napi_unwrap(env, obj, (void**)&client);
|
||||
return client;
|
||||
}
|
||||
|
||||
UpdateClient *GetUpdateClient(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = 1;
|
||||
napi_value argv[1] = {0};
|
||||
napi_value thisVar = nullptr;
|
||||
void* data = nullptr;
|
||||
napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
|
||||
|
||||
UpdateClient *client = nullptr;
|
||||
napi_unwrap(env, thisVar, (void**)&client);
|
||||
return client;
|
||||
}
|
||||
|
||||
napi_value GetUpdater(napi_env env, napi_callback_info info)
|
||||
{
|
||||
UpdateClient* client = GetUpdateClient(env, info);
|
||||
if (client != nullptr) {
|
||||
return client->GetUpdater(env, info, 1);
|
||||
}
|
||||
napi_value obj = nullptr;
|
||||
client = GetAndCreateJsUpdateClient(env, info, obj);
|
||||
if (client != nullptr) {
|
||||
napi_value result = client->GetUpdater(env, info, 1);
|
||||
if (result != nullptr) {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
napi_value GetUpdaterForOther(napi_env env, napi_callback_info info)
|
||||
{
|
||||
UpdateClient* client = GetUpdateClient(env, info);
|
||||
if (client != nullptr) {
|
||||
return client->GetUpdaterForOther(env, info);
|
||||
}
|
||||
napi_value obj = nullptr;
|
||||
client = GetAndCreateJsUpdateClient(env, info, obj);
|
||||
if (client != nullptr) {
|
||||
client->GetUpdaterForOther(env, info);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
napi_value GetUpdaterFromOther(napi_env env, napi_callback_info info)
|
||||
{
|
||||
UpdateClient* client = GetUpdateClient(env, info);
|
||||
if (client != nullptr) {
|
||||
return client->GetUpdaterFromOther(env, info);
|
||||
}
|
||||
napi_value obj = nullptr;
|
||||
client = GetAndCreateJsUpdateClient(env, info, obj);
|
||||
if (client != nullptr) {
|
||||
client->GetUpdaterFromOther(env, info);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
napi_value CheckNewVersion(napi_env env, napi_callback_info info)
|
||||
{
|
||||
UpdateClient* client = GetUpdateClient(env, info);
|
||||
CLIENT_CHECK_NAPI_CALL(env, client != nullptr, return nullptr, "Error get client");
|
||||
return client->CheckNewVersion(env, info);
|
||||
}
|
||||
|
||||
napi_value SetUpdatePolicy(napi_env env, napi_callback_info info)
|
||||
{
|
||||
UpdateClient* client = GetUpdateClient(env, info);
|
||||
CLIENT_CHECK_NAPI_CALL(env, client != nullptr, return nullptr, "Error get client");
|
||||
return client->SetUpdatePolicy(env, info);
|
||||
}
|
||||
|
||||
napi_value GetUpdatePolicy(napi_env env, napi_callback_info info)
|
||||
{
|
||||
UpdateClient* client = GetUpdateClient(env, info);
|
||||
CLIENT_CHECK_NAPI_CALL(env, client != nullptr, return nullptr, "Error get client");
|
||||
return client->GetUpdatePolicy(env, info);
|
||||
}
|
||||
|
||||
napi_value DownloadVersion(napi_env env, napi_callback_info info)
|
||||
{
|
||||
UpdateClient* client = GetUpdateClient(env, info);
|
||||
CLIENT_CHECK_NAPI_CALL(env, client != nullptr, return nullptr, "Error get client");
|
||||
return client->DownloadVersion(env, info);
|
||||
}
|
||||
|
||||
napi_value CancelUpgrade(napi_env env, napi_callback_info info)
|
||||
{
|
||||
UpdateClient* client = GetUpdateClient(env, info);
|
||||
CLIENT_CHECK_NAPI_CALL(env, client != nullptr, return nullptr, "Error get client");
|
||||
return client->CancelUpgrade(env, info);
|
||||
}
|
||||
|
||||
napi_value UpgradeVersion(napi_env env, napi_callback_info info)
|
||||
{
|
||||
UpdateClient* client = GetUpdateClient(env, info);
|
||||
CLIENT_CHECK_NAPI_CALL(env, client != nullptr, return nullptr, "Error get client");
|
||||
return client->UpgradeVersion(env, info);
|
||||
}
|
||||
|
||||
napi_value GetNewVersionInfo(napi_env env, napi_callback_info info)
|
||||
{
|
||||
UpdateClient* client = GetUpdateClient(env, info);
|
||||
CLIENT_CHECK_NAPI_CALL(env, client != nullptr, return nullptr, "Error get client");
|
||||
return client->GetNewVersionInfo(env, info);
|
||||
}
|
||||
|
||||
napi_value GetUpgradeStatus(napi_env env, napi_callback_info info)
|
||||
{
|
||||
UpdateClient* client = GetUpdateClient(env, info);
|
||||
CLIENT_CHECK_NAPI_CALL(env, client != nullptr, return nullptr, "Error get client");
|
||||
return client->GetUpgradeStatus(env, info);
|
||||
}
|
||||
|
||||
napi_value UnsubscribeEvent(napi_env env, napi_callback_info info)
|
||||
{
|
||||
UpdateClient* client = GetUpdateClient(env, info);
|
||||
CLIENT_CHECK_NAPI_CALL(env, client != nullptr, return nullptr, "Error get client");
|
||||
return client->UnsubscribeEvent(env, info);
|
||||
}
|
||||
|
||||
napi_value SubscribeEvent(napi_env env, napi_callback_info info)
|
||||
{
|
||||
UpdateClient* client = GetUpdateClient(env, info);
|
||||
CLIENT_CHECK_NAPI_CALL(env, client != nullptr, return nullptr, "Error get client");
|
||||
return client->SubscribeEvent(env, info);
|
||||
}
|
||||
|
||||
napi_value ApplyNewVersion(napi_env env, napi_callback_info info)
|
||||
{
|
||||
UpdateClient* client = GetUpdateClient(env, info);
|
||||
CLIENT_CHECK_NAPI_CALL(env, client != nullptr, return nullptr, "Error get client");
|
||||
return client->ApplyNewVersion(env, info);
|
||||
}
|
||||
|
||||
napi_value RebootAndClean(napi_env env, napi_callback_info info)
|
||||
{
|
||||
UpdateClient* client = GetUpdateClient(env, info);
|
||||
CLIENT_CHECK_NAPI_CALL(env, client != nullptr, return nullptr, "Error get client");
|
||||
return client->RebootAndClean(env, info);
|
||||
}
|
||||
|
||||
napi_value VerifyUpdatePackage(napi_env env, napi_callback_info info)
|
||||
{
|
||||
UpdateClient* client = GetUpdateClient(env, info);
|
||||
CLIENT_CHECK_NAPI_CALL(env, client != nullptr, return nullptr, "Error get client");
|
||||
return client->VerifyUpdatePackage(env, info);
|
||||
}
|
||||
|
||||
#ifdef UPDATER_UT
|
||||
napi_value UpdateClientInit(napi_env env, napi_value exports)
|
||||
#else
|
||||
static napi_value UpdateClientInit(napi_env env, napi_value exports)
|
||||
#endif
|
||||
{
|
||||
CLIENT_LOGI("UpdateClientInit");
|
||||
// Registration function
|
||||
napi_property_descriptor desc[] = {
|
||||
DECLARE_NAPI_FUNCTION("getUpdater", GetUpdater),
|
||||
DECLARE_NAPI_FUNCTION("getUpdaterForOther", GetUpdaterForOther),
|
||||
DECLARE_NAPI_FUNCTION("getUpdaterFromOther", GetUpdaterFromOther),
|
||||
};
|
||||
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
|
||||
|
||||
// Registration object
|
||||
napi_property_descriptor descriptors[] = {
|
||||
DECLARE_NAPI_FUNCTION("getUpdater", GetUpdater),
|
||||
DECLARE_NAPI_FUNCTION("getUpdaterForOther", GetUpdaterForOther),
|
||||
DECLARE_NAPI_FUNCTION("getUpdaterFromOther", GetUpdaterFromOther),
|
||||
|
||||
DECLARE_NAPI_FUNCTION("checkNewVersion", CheckNewVersion),
|
||||
DECLARE_NAPI_FUNCTION("getNewVersionInfo", GetNewVersionInfo),
|
||||
|
||||
DECLARE_NAPI_FUNCTION("setUpdatePolicy", SetUpdatePolicy),
|
||||
DECLARE_NAPI_FUNCTION("getUpdatePolicy", GetUpdatePolicy),
|
||||
DECLARE_NAPI_FUNCTION("getUpgradeStatus", GetUpgradeStatus),
|
||||
|
||||
DECLARE_NAPI_FUNCTION("cancelUpgrade", CancelUpgrade),
|
||||
DECLARE_NAPI_FUNCTION("download", DownloadVersion),
|
||||
DECLARE_NAPI_FUNCTION("upgrade", UpgradeVersion),
|
||||
|
||||
DECLARE_NAPI_FUNCTION("applyNewVersion", ApplyNewVersion),
|
||||
DECLARE_NAPI_FUNCTION("rebootAndCleanUserData", RebootAndClean),
|
||||
DECLARE_NAPI_FUNCTION("verifyUpdatePackage", VerifyUpdatePackage),
|
||||
|
||||
DECLARE_NAPI_FUNCTION("on", SubscribeEvent),
|
||||
DECLARE_NAPI_FUNCTION("off", UnsubscribeEvent)
|
||||
};
|
||||
|
||||
napi_value result = nullptr;
|
||||
napi_define_class(env, CLASS_NAME.c_str(), CLASS_NAME.size(), UpdateClientJSConstructor,
|
||||
nullptr, sizeof(descriptors) / sizeof(*descriptors), descriptors, &result);
|
||||
napi_set_named_property(env, exports, CLASS_NAME.c_str(), result);
|
||||
napi_status status = napi_create_reference(env, result, REF_COUNT, &g_reference);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Failed to create_reference");
|
||||
|
||||
return exports;
|
||||
}
|
||||
|
||||
/*
|
||||
* Module definition
|
||||
*/
|
||||
static napi_module g_module = {
|
||||
.nm_version = 1,
|
||||
.nm_flags = 0,
|
||||
.nm_filename = nullptr,
|
||||
.nm_register_func = UpdateClientInit,
|
||||
.nm_modname = "libupdate.z.so",
|
||||
.nm_priv = ((void*)0),
|
||||
.reserved = { 0 }
|
||||
};
|
||||
|
||||
/*
|
||||
* Module registration function
|
||||
*/
|
||||
extern "C" __attribute__((constructor)) void RegisterModule(void)
|
||||
{
|
||||
napi_module_register(&g_module);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* 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 "update_session.h"
|
||||
|
||||
#include <csignal>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
#include "node_api.h"
|
||||
#include "update_client.h"
|
||||
#include "update_helper.h"
|
||||
#include "package/package.h"
|
||||
#include "securec.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace OHOS::update_engine;
|
||||
|
||||
namespace updateClient {
|
||||
const int32_t RESULT_ARGC = 2;
|
||||
|
||||
uint32_t g_sessionId = 0;
|
||||
UpdateSession::UpdateSession(UpdateClient *client, int32_t type, size_t argc, size_t callbackNumber)
|
||||
: sessionId(++g_sessionId), client_(client), type_(type), totalArgc_(argc), callbackNumber_(callbackNumber) {}
|
||||
|
||||
int32_t UpdateSession::CreateReference(napi_env env, napi_value arg, uint32_t refcount,
|
||||
napi_ref &reference) const
|
||||
{
|
||||
napi_valuetype valuetype;
|
||||
napi_status status = napi_typeof(env, arg, &valuetype);
|
||||
CLIENT_CHECK(status == napi_ok, return status, "Failed to napi_typeof");
|
||||
CLIENT_CHECK(valuetype == napi_function, return status, "Invalid callback type");
|
||||
|
||||
status = napi_create_reference(env, arg, refcount, &reference);
|
||||
CLIENT_CHECK(status == napi_ok, return status, "Failed to create reference");
|
||||
return status;
|
||||
}
|
||||
|
||||
napi_value UpdateSession::CreateWorkerName(napi_env env) const
|
||||
{
|
||||
napi_value workName;
|
||||
std::string name = "Async Work" + std::to_string(sessionId);
|
||||
napi_status status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &workName);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Failed to worker name");
|
||||
return workName;
|
||||
}
|
||||
|
||||
napi_value UpdateSession::StartWork(napi_env env,
|
||||
size_t startIndex, const napi_value *args, UpdateClient::DoWorkFunction worker, void *context)
|
||||
{
|
||||
static std::string sessName[SESSION_MAX] = {
|
||||
"check version", "download", "upgrade", "set policy", "get policy",
|
||||
"get new version", "get upgrade status", "subscribe", "unsubscribe", "get update",
|
||||
"apply new version", "reboot and clean", "verify package", "Cancel Upgrade"
|
||||
};
|
||||
|
||||
CLIENT_LOGI("StartWork type: %s", sessName[type_].c_str());
|
||||
doWorker_ = worker;
|
||||
context_ = context;
|
||||
return StartWork(env, startIndex, args);
|
||||
}
|
||||
|
||||
void UpdateSession::ExecuteWork(napi_env env)
|
||||
{
|
||||
if (doWorker_ != nullptr) {
|
||||
#ifndef UPDATER_UT
|
||||
int32_t ret = doWorker_(type_, context_);
|
||||
CLIENT_CHECK_NAPI_CALL(env, ret == 0, return, "execute work");
|
||||
#else
|
||||
doWorker_(type_, context_);
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
napi_value UpdateAsyncession::StartWork(napi_env env, size_t startIndex, const napi_value *args)
|
||||
{
|
||||
CLIENT_LOGI("UpdateAsyncession::StartWork startIndex: %zu", startIndex);
|
||||
CLIENT_LOGI("UpdateAsyncession::totalArgc_ %zu callbackNumber_: %zu", totalArgc_, callbackNumber_);
|
||||
CLIENT_CHECK_NAPI_CALL(env, args != nullptr && totalArgc_ >= startIndex, return nullptr, "Invalid para");
|
||||
napi_value workName = CreateWorkerName(env);
|
||||
CLIENT_CHECK_NAPI_CALL(env, workName != nullptr, return nullptr, "Failed to worker name");
|
||||
|
||||
// Check whether a callback exists. Only one callback is allowed.
|
||||
for (size_t i = 0; (i < (totalArgc_ - startIndex)) && (i < callbackNumber_); i++) {
|
||||
CLIENT_LOGI("CreateReference index:%u", i + startIndex);
|
||||
int32_t ret = CreateReference(env, args[i + startIndex], 1, callbackRef_[i]);
|
||||
CLIENT_CHECK_NAPI_CALL(env, ret == napi_ok, return nullptr, "Failed to create reference");
|
||||
}
|
||||
|
||||
// Create an asynchronous call.
|
||||
napi_status status = napi_create_async_work(env, nullptr, workName, UpdateSession::ExecuteWork,
|
||||
UpdateSession::CompleteWork, this, &(worker_));
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Failed to create worker");
|
||||
|
||||
// Put the thread in the task execution queue.
|
||||
status = napi_queue_async_work(env, worker_);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Failed to queue worker");
|
||||
napi_value result;
|
||||
napi_create_int32(env, 0, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void UpdateAsyncession::CompleteWork(napi_env env, napi_status status)
|
||||
{
|
||||
CLIENT_LOGI("UpdateAsyncession::CompleteWork callbackNumber_: %d", static_cast<int32_t>(callbackNumber_));
|
||||
napi_value callback;
|
||||
napi_value undefined;
|
||||
napi_value callResult;
|
||||
napi_get_undefined(env, &undefined);
|
||||
napi_value retArgs[RESULT_ARGC] = { 0 };
|
||||
|
||||
UpdateResult result;
|
||||
int32_t fail = 0;
|
||||
client_->GetUpdateResult(type_, result, fail);
|
||||
int ret = UpdateClient::BuildErrorResult(env, retArgs[0], fail);
|
||||
ret |= result.buildJSObject(env, retArgs[1], result);
|
||||
CLIENT_CHECK_NAPI_CALL(env, ret == napi_ok, return, "Failed to build json");
|
||||
|
||||
status = napi_get_reference_value(env, callbackRef_[0], &callback);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return, "Failed to get reference");
|
||||
const int callBackNumber = 2;
|
||||
status = napi_call_function(env, undefined, callback, callBackNumber, retArgs, &callResult);
|
||||
// Release resources.
|
||||
for (size_t i = 0; i < callbackNumber_; i++) {
|
||||
napi_delete_reference(env, callbackRef_[i]);
|
||||
callbackRef_[i] = nullptr;
|
||||
}
|
||||
napi_delete_async_work(env, worker_);
|
||||
worker_ = nullptr;
|
||||
}
|
||||
|
||||
void UpdateAsyncessionNoCallback::CompleteWork(napi_env env, napi_status status)
|
||||
{
|
||||
CLIENT_LOGI("UpdateAsyncessionNoCallback::CompleteWork callbackNumber_: %d",
|
||||
static_cast<int32_t>(callbackNumber_));
|
||||
}
|
||||
|
||||
napi_value UpdatePromiseSession::StartWork(napi_env env, size_t startIndex, const napi_value *args)
|
||||
{
|
||||
CLIENT_LOGI("UpdatePromiseSession::StartWork");
|
||||
CLIENT_CHECK_NAPI_CALL(env, args != nullptr, return nullptr, "Invalid para");
|
||||
napi_value workName = CreateWorkerName(env);
|
||||
CLIENT_CHECK_NAPI_CALL(env, workName != nullptr, return nullptr, "Failed to worker name");
|
||||
|
||||
napi_value promise;
|
||||
napi_status status = napi_create_promise(env, &deferred_, &promise);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Failed to napi_create_promise");
|
||||
|
||||
// Create an asynchronous call.
|
||||
status = napi_create_async_work(env, nullptr, workName, UpdateSession::ExecuteWork,
|
||||
UpdateSession::CompleteWork, this, &(worker_));
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Failed to napi_create_async_work");
|
||||
// Put the thread in the task execution queue.
|
||||
status = napi_queue_async_work(env, worker_);
|
||||
CLIENT_CHECK_NAPI_CALL(env, status == napi_ok, return nullptr, "Failed to napi_queue_async_work");
|
||||
return promise;
|
||||
}
|
||||
|
||||
void UpdatePromiseSession::CompleteWork(napi_env env, napi_status status)
|
||||
{
|
||||
CLIENT_LOGI("UpdatePromiseSession::CompleteWork status: %d", static_cast<int32_t>(status));
|
||||
// Get the return result.
|
||||
napi_value processResult;
|
||||
UpdateResult result;
|
||||
int32_t fail = 0;
|
||||
client_->GetUpdateResult(type_, result, fail);
|
||||
if (fail == 0) {
|
||||
result.buildJSObject(env, processResult, result);
|
||||
napi_resolve_deferred(env, deferred_, processResult);
|
||||
} else {
|
||||
UpdateClient::BuildErrorResult(env, processResult, fail);
|
||||
napi_reject_deferred(env, deferred_, processResult);
|
||||
}
|
||||
napi_delete_async_work(env, worker_);
|
||||
worker_ = nullptr;
|
||||
}
|
||||
|
||||
napi_value UpdateListener::StartWork(napi_env env, size_t startIndex, const napi_value *args)
|
||||
{
|
||||
CLIENT_LOGI("UpdateListener::StartWork");
|
||||
CLIENT_CHECK_NAPI_CALL(env, args != nullptr && totalArgc_ > startIndex, return nullptr, "Invalid para");
|
||||
int ret = UpdateClient::GetStringValue(env, args[0], eventType_);
|
||||
CLIENT_CHECK_NAPI_CALL(env, ret == napi_ok, return nullptr, "Failed to get event type");
|
||||
|
||||
// reference count is 1
|
||||
ret = CreateReference(env, args[startIndex], 1, handlerRef_);
|
||||
CLIENT_CHECK_NAPI_CALL(env, ret == napi_ok, return nullptr, "Failed to create reference");
|
||||
napi_value result;
|
||||
napi_create_int32(env, 0, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void UpdateListener::NotifyJS(napi_env env, napi_value thisVar, int32_t retcode, const UpdateResult &result) const
|
||||
{
|
||||
CLIENT_LOGI("NotifyJS retcode:%d", retcode);
|
||||
napi_value jsEvent;
|
||||
result.buildJSObject(env, jsEvent, result);
|
||||
napi_value handler = nullptr;
|
||||
napi_value callResult;
|
||||
napi_get_reference_value(env, handlerRef_, &handler);
|
||||
napi_call_function(env, thisVar, handler, 1, &jsEvent, &callResult);
|
||||
}
|
||||
|
||||
bool UpdateListener::CheckEqual(napi_env env, napi_value handler, const std::string &type) const
|
||||
{
|
||||
bool isEquals = false;
|
||||
napi_value handlerTemp = nullptr;
|
||||
napi_get_reference_value(env, handlerRef_, &handlerTemp);
|
||||
napi_strict_equals(env, handler, handlerTemp, &isEquals);
|
||||
return isEquals && (type.compare(eventType_) == 0);
|
||||
}
|
||||
} // namespace updateClient
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* 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 UPDATE_SESSION_H
|
||||
#define UPDATE_SESSION_H
|
||||
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "iupdate_service.h"
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_node_api.h"
|
||||
#include "node_api.h"
|
||||
#include "node_api_types.h"
|
||||
#include "update_client.h"
|
||||
#include "update_helper.h"
|
||||
|
||||
namespace updateClient {
|
||||
class UpdateSession {
|
||||
public:
|
||||
UpdateSession() = default;
|
||||
|
||||
UpdateSession(UpdateClient *client, int32_t type, size_t argc, size_t callbackNumber);
|
||||
|
||||
virtual ~UpdateSession() {};
|
||||
|
||||
napi_value StartWork(napi_env env, size_t startIndex,
|
||||
const napi_value *args, UpdateClient::DoWorkFunction worker, void *context);
|
||||
|
||||
UpdateClient* GetUpdateClient() const
|
||||
{
|
||||
return client_;
|
||||
}
|
||||
|
||||
int32_t GetType() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
uint32_t GetSessionId() const
|
||||
{
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
virtual void CompleteWork(napi_env env, napi_status status) {}
|
||||
virtual void ExecuteWork(napi_env env);
|
||||
virtual napi_value StartWork(napi_env env, size_t startIndex, const napi_value *args) = 0;
|
||||
virtual void NotifyJS(napi_env env, napi_value thisVar, int32_t retcode, const UpdateResult &result) const
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// JS thread, which is used to notify the JS page upon completion of the operation.
|
||||
static void CompleteWork(napi_env env, napi_status status, void *data)
|
||||
{
|
||||
auto sess = reinterpret_cast<UpdateSession*>(data);
|
||||
CLIENT_CHECK(sess != nullptr && sess->GetUpdateClient() != nullptr, return, "Session is null pointer");
|
||||
sess->CompleteWork(env, status);
|
||||
// If the share ptr is used, you can directly remove the share ptr.
|
||||
UpdateClient *client = sess->GetUpdateClient();
|
||||
if (client != nullptr) {
|
||||
client->RemoveSession(sess->GetSessionId());
|
||||
}
|
||||
}
|
||||
|
||||
// The C++ thread executes the synchronization operation. After the synchronization is complete,
|
||||
// the CompleteWork is called to notify the JS page of the completion of the operation.
|
||||
static void ExecuteWork(napi_env env, void* data)
|
||||
{
|
||||
auto sess = reinterpret_cast<UpdateSession*>(data);
|
||||
CLIENT_CHECK(sess != nullptr, return, "sess is null");
|
||||
sess->ExecuteWork(env);
|
||||
}
|
||||
protected:
|
||||
napi_value CreateWorkerName(napi_env env) const;
|
||||
int32_t CreateReference(napi_env env, napi_value arg, uint32_t refcount, napi_ref &reference) const;
|
||||
|
||||
protected:
|
||||
uint32_t sessionId {0};
|
||||
UpdateClient *client_ = nullptr;
|
||||
int32_t type_ {};
|
||||
size_t totalArgc_ = 0;
|
||||
size_t callbackNumber_ = 0;
|
||||
void* context_ {};
|
||||
UpdateClient::DoWorkFunction doWorker_ {};
|
||||
};
|
||||
|
||||
class UpdateAsyncession : public UpdateSession {
|
||||
public:
|
||||
UpdateAsyncession(UpdateClient *client, int32_t type, size_t argc, size_t callbackNumber) :
|
||||
UpdateSession(client, type, argc, callbackNumber)
|
||||
{
|
||||
callbackRef_.resize(callbackNumber);
|
||||
}
|
||||
|
||||
~UpdateAsyncession() override
|
||||
{
|
||||
callbackRef_.clear();
|
||||
}
|
||||
|
||||
void CompleteWork(napi_env env, napi_status status) override;
|
||||
napi_value StartWork(napi_env env, size_t startIndex, const napi_value *args) override;
|
||||
private:
|
||||
napi_async_work worker_ = nullptr;
|
||||
std::vector<napi_ref> callbackRef_ = {0};
|
||||
};
|
||||
|
||||
class UpdateAsyncessionNoCallback : public UpdateAsyncession {
|
||||
public:
|
||||
UpdateAsyncessionNoCallback(UpdateClient *client, int32_t type, size_t argc, size_t callbackNumber) :
|
||||
UpdateAsyncession(client, type, argc, callbackNumber) {}
|
||||
|
||||
~UpdateAsyncessionNoCallback() override { }
|
||||
|
||||
void CompleteWork(napi_env env, napi_status status) override;
|
||||
};
|
||||
|
||||
class UpdatePromiseSession : public UpdateSession {
|
||||
public:
|
||||
UpdatePromiseSession(UpdateClient *client, int32_t type, size_t argc, size_t callbackNumber) :
|
||||
UpdateSession(client, type, argc, callbackNumber) {}
|
||||
|
||||
~UpdatePromiseSession() override {}
|
||||
|
||||
void CompleteWork(napi_env env, napi_status status) override;
|
||||
napi_value StartWork(napi_env env, size_t startIndex, const napi_value *args) override;
|
||||
private:
|
||||
napi_async_work worker_ = nullptr;
|
||||
napi_deferred deferred_ = nullptr;
|
||||
};
|
||||
|
||||
class UpdateListener : public UpdateSession {
|
||||
public:
|
||||
UpdateListener(UpdateClient *client, int32_t type, size_t argc, size_t callbackNumber, bool isOnce) :
|
||||
UpdateSession(client, type, argc, callbackNumber), isOnce_(isOnce) {}
|
||||
|
||||
~UpdateListener() override {}
|
||||
|
||||
napi_value StartWork(napi_env env, size_t startIndex, const napi_value *args) override;
|
||||
|
||||
void NotifyJS(napi_env env, napi_value thisVar, int32_t retcode, const UpdateResult &result) const override;
|
||||
|
||||
bool IsOnce() const
|
||||
{
|
||||
return isOnce_;
|
||||
}
|
||||
|
||||
std::string GetEventType() const
|
||||
{
|
||||
return eventType_;
|
||||
}
|
||||
|
||||
bool CheckEqual(napi_env env, napi_value handler, const std::string &type) const;
|
||||
|
||||
void RemoveHandlerRef(napi_env env)
|
||||
{
|
||||
napi_delete_reference(env, handlerRef_);
|
||||
}
|
||||
private:
|
||||
bool isOnce_ = false;
|
||||
std::string eventType_;
|
||||
napi_ref handlerRef_ = nullptr;
|
||||
};
|
||||
} // namespace updateClient
|
||||
#endif // UPDATE_SESSION_H
|
||||
Executable
+83
@@ -0,0 +1,83 @@
|
||||
# Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//build/ohos.gni")
|
||||
|
||||
ohos_prebuilt_etc("updater_sa.rc") {
|
||||
source = "etc/updater_sa.rc"
|
||||
relative_install_dir = "init"
|
||||
part_name = "updater"
|
||||
}
|
||||
|
||||
ohos_shared_library("updateservice") {
|
||||
defines = [
|
||||
"DUAL_ADAPTER",
|
||||
"UPDATE_SERVICE",
|
||||
]
|
||||
sources = [
|
||||
"//base/update/updateservice/callback/src/update_callback.cpp",
|
||||
"//base/update/updateservice/callback/src/update_callback_proxy.cpp",
|
||||
"//base/update/updateservice/callback/src/update_callback_stub.cpp",
|
||||
"//base/update/updateservice/engine/src/progress_thread.cpp",
|
||||
"//base/update/updateservice/engine/src/update_helper.cpp",
|
||||
"//base/update/updateservice/engine/src/update_service.cpp",
|
||||
"//base/update/updateservice/engine/src/update_service_stub.cpp",
|
||||
]
|
||||
|
||||
include_dirs = [
|
||||
"//base/update/updater/services/include",
|
||||
"//base/update/updater/utils/include",
|
||||
"//base/update/updater/interfaces/kits/include",
|
||||
"//utils/native/base/include",
|
||||
"//utils/system/safwk/native/include",
|
||||
"//base/update/updateservice/interfaces/innerkits/include",
|
||||
"//base/update/updateservice/engine/include",
|
||||
"//base/update/updateservice/callback/include",
|
||||
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include",
|
||||
"//foundation/distributedschedule/safwk/services/safwk/include",
|
||||
"//foundation/distributedschedule/safwk/interfaces/innerkits/safwk",
|
||||
"//foundation/distributedschedule/samgr/adapter/interfaces/innerkits/include",
|
||||
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include",
|
||||
"//third_party/cJSON",
|
||||
"//third_party/libxml2/include",
|
||||
"//third_party/curl/include",
|
||||
"//third_party/openssl/include",
|
||||
"//third_party/bounds_checking_function/include",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara",
|
||||
"//base/update/updater/interfaces/kits/misc_info:libmiscinfo",
|
||||
"//base/update/updater/interfaces/kits/packages:libpackageExt",
|
||||
"//base/update/updater/interfaces/kits/updaterkits:libupdaterkits",
|
||||
"//base/update/updater/services/log:libupdaterlog",
|
||||
"//base/update/updater/utils:libutils",
|
||||
"//third_party/bounds_checking_function:libsec_static",
|
||||
"//third_party/cJSON:cjson_static",
|
||||
"//third_party/curl:curl",
|
||||
"//third_party/libxml2:xml2",
|
||||
"//third_party/openssl:crypto_source",
|
||||
"//third_party/openssl:ssl_source",
|
||||
"//utils/native/base:utils",
|
||||
]
|
||||
|
||||
external_deps = [
|
||||
"hiviewdfx_hilog_native:libhilog",
|
||||
"ipc:ipc_core",
|
||||
"safwk:system_ability_fwk",
|
||||
"samgr_L2:samgr_proxy",
|
||||
"startup_l2:syspara",
|
||||
]
|
||||
|
||||
part_name = "updater"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?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.
|
||||
-->
|
||||
<info>
|
||||
<serverIp>127.0.0.1</serverIp>
|
||||
</info>
|
||||
Executable
+21
@@ -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.
|
||||
service updater_sa /system/bin/sa_main /system/profile/updater_sa.xml
|
||||
class z_core
|
||||
user system
|
||||
group system shell
|
||||
seclabel u:r:updater_sa:s0
|
||||
|
||||
on boot
|
||||
start updater_sa
|
||||
|
||||
Executable
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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 UPDATER_THREAD_H
|
||||
#define UPDATER_THREAD_H
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include "cJSON.h"
|
||||
#include "curl/curl.h"
|
||||
#include "curl/easy.h"
|
||||
#include "if_system_ability_manager.h"
|
||||
#include "ipc_skeleton.h"
|
||||
#include "iremote_stub.h"
|
||||
#include "iupdate_service.h"
|
||||
#include "openssl/err.h"
|
||||
#include "openssl/ssl.h"
|
||||
#include "system_ability.h"
|
||||
#include "update_service_stub.h"
|
||||
|
||||
#define ENGINE_CHECK_NO_LOG(retCode, exper) \
|
||||
if (!(retCode)) { \
|
||||
exper; \
|
||||
}
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
constexpr uint32_t DOWNLOAD_FINISH_PERCENT = 100;
|
||||
constexpr uint32_t DOWNLOAD_PERIOD_PERCENT = 5;
|
||||
constexpr int32_t TIMEOUT_FOR_DOWNLOAD = 600;
|
||||
#ifndef UPDATER_UT
|
||||
constexpr int32_t TIMEOUT_FOR_CONNECT = 10;
|
||||
#else
|
||||
constexpr int32_t TIMEOUT_FOR_CONNECT = 1;
|
||||
#endif
|
||||
|
||||
class ProgressThread {
|
||||
public:
|
||||
ProgressThread() = default;
|
||||
virtual ~ProgressThread()
|
||||
{
|
||||
StopProgress();
|
||||
}
|
||||
|
||||
protected:
|
||||
int32_t StartProgress();
|
||||
void StopProgress();
|
||||
void ExecuteThreadFunc();
|
||||
|
||||
virtual bool ProcessThreadExecute() = 0;
|
||||
virtual void ProcessThreadExit() = 0;
|
||||
|
||||
private:
|
||||
std::thread *pDealThread_ { nullptr };
|
||||
std::mutex mutex_;
|
||||
std::condition_variable condition_;
|
||||
bool isWake_ = false;
|
||||
bool isExitThread_ = false;
|
||||
};
|
||||
|
||||
class DownloadThread : public ProgressThread {
|
||||
public:
|
||||
using ProgressCallback = std::function<int (const std::string &fileName, const Progress &progress)>;
|
||||
DownloadThread(ProgressCallback callback) : ProgressThread(), callback_(callback) {}
|
||||
~DownloadThread() override {}
|
||||
|
||||
int32_t StartDownload(const std::string &fileName, const std::string &url);
|
||||
void StopDownload();
|
||||
|
||||
static size_t GetLocalFileLength(const std::string &fileName);
|
||||
static size_t WriteFunc(void *ptr, size_t size, size_t nmemb, const void *stream);
|
||||
static int32_t DownloadProgress(const void *localData,
|
||||
double dlTotal, double dlNow, double ulTotal, double ulNow);
|
||||
|
||||
double GetPackageSize()
|
||||
{
|
||||
return static_cast<double>(packageSize_);
|
||||
};
|
||||
protected:
|
||||
bool ProcessThreadExecute() override;
|
||||
void ProcessThreadExit() override;
|
||||
int32_t DownloadCallback(uint32_t percent, UpgradeStatus status, const std::string &error);
|
||||
|
||||
private:
|
||||
Progress downloadProgress_ {};
|
||||
ProgressCallback callback_;
|
||||
CURL *downloadHandle_ { nullptr };
|
||||
FILE *downloadFile_ { nullptr };
|
||||
std::string serverUrl_;
|
||||
std::atomic<bool> exitDownload_ { false };
|
||||
size_t packageSize_ { 1 };
|
||||
std::string downloadFileName_;
|
||||
};
|
||||
}
|
||||
} // namespace OHOS
|
||||
#endif // UPDATER_THREAD_H
|
||||
Executable
+101
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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 UPDATER_SERVICE_H
|
||||
#define UPDATER_SERVICE_H
|
||||
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include "cJSON.h"
|
||||
#include "if_system_ability_manager.h"
|
||||
#include "ipc_skeleton.h"
|
||||
#include "iremote_stub.h"
|
||||
#include "iupdate_service.h"
|
||||
#include "openssl/err.h"
|
||||
#include "openssl/ssl.h"
|
||||
#include "progress_thread.h"
|
||||
#include "system_ability.h"
|
||||
#include "update_service_stub.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
class UpdateService : public SystemAbility, public UpdateServiceStub {
|
||||
public:
|
||||
DECLARE_SYSTEM_ABILITY(UpdateService);
|
||||
DISALLOW_COPY_AND_MOVE(UpdateService);
|
||||
explicit UpdateService(int32_t systemAbilityId, bool runOnCreate = true);
|
||||
~UpdateService() override;
|
||||
|
||||
int32_t RegisterUpdateCallback(const UpdateContext &ctx, const sptr<IUpdateCallback> &updateCallback) override;
|
||||
|
||||
int32_t UnregisterUpdateCallback() override;
|
||||
|
||||
int32_t CheckNewVersion() override;
|
||||
|
||||
int32_t DownloadVersion() override;
|
||||
|
||||
int32_t DoUpdate() override;
|
||||
|
||||
int32_t GetNewVersion(VersionInfo &versionInfo) override;
|
||||
|
||||
int32_t GetUpgradeStatus (UpgradeInfo &info) override;
|
||||
|
||||
int32_t SetUpdatePolicy(const UpdatePolicy &policy) override;
|
||||
|
||||
int32_t GetUpdatePolicy(UpdatePolicy &policy) override;
|
||||
|
||||
int32_t Cancel(int32_t service) override;
|
||||
|
||||
int32_t RebootAndClean(const std::string &miscFile, const std::string &cmd) override;
|
||||
|
||||
int32_t RebootAndInstall(const std::string &miscFile, const std::string &packageName) override;
|
||||
static int32_t ParseJsonFile(const std::vector<char> &buffer, VersionInfo &info);
|
||||
static int32_t ReadCheckVersionResult(const cJSON* results, VersionInfo &info);
|
||||
static int32_t ReadCheckVersiondescriptInfo(const cJSON *descriptInfo, VersionInfo &info);
|
||||
static void GetServerIp(std::string &ip);
|
||||
#ifndef UPDATER_UT
|
||||
protected:
|
||||
#else
|
||||
public:
|
||||
#endif
|
||||
void OnStart() override;
|
||||
void OnStop() override;
|
||||
private:
|
||||
void SearchCallback(const std::string &msg, SearchStatus status);
|
||||
void DownloadCallback(const std::string &fileName, const Progress &progress);
|
||||
void UpgradeCallback(const Progress &progress);
|
||||
bool VerifyDownloadPkg(const std::string &pkgName, Progress &progress);
|
||||
std::string GetDownloadServerUrl() const;
|
||||
void InitVersionInfo(VersionInfo &versionInfo) const;
|
||||
#ifndef UPDATER_UT
|
||||
private:
|
||||
#else
|
||||
public:
|
||||
#endif
|
||||
void ReadDataFromSSL(int32_t engineSocket);
|
||||
private:
|
||||
std::string serverAddr_;
|
||||
UpdatePolicy policy_ = {
|
||||
1, 1, INSTALLMODE_AUTO, AUTOUPGRADECONDITION_IDLE, { 10, 20 }
|
||||
};
|
||||
UpgradeStatus upgradeStatus_ = UPDATE_STATE_INIT;
|
||||
VersionInfo versionInfo_ {};
|
||||
|
||||
sptr<IUpdateCallback> updateCallback_ { nullptr };
|
||||
DownloadThread *downloadThread_ { nullptr };
|
||||
UpdateContext updateContext_ {};
|
||||
};
|
||||
}
|
||||
} // namespace OHOS
|
||||
#endif // UPDATER_SERVICE_H
|
||||
Executable
+56
@@ -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 UPDATER_PROXY_H
|
||||
#define UPDATER_PROXY_H
|
||||
|
||||
#include "iremote_proxy.h"
|
||||
#include "iupdate_service.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
class UpdateServiceProxy : public IRemoteProxy<IUpdateService> {
|
||||
public:
|
||||
explicit UpdateServiceProxy(const sptr<IRemoteObject>& impl) : IRemoteProxy<IUpdateService>(impl) {}
|
||||
|
||||
int32_t RegisterUpdateCallback(const UpdateContext &ctx, const sptr<IUpdateCallback>& updateCallback) override;
|
||||
|
||||
int32_t UnregisterUpdateCallback() override;
|
||||
|
||||
int32_t CheckNewVersion() override;
|
||||
|
||||
int32_t DownloadVersion() override;
|
||||
|
||||
int32_t DoUpdate() override;
|
||||
|
||||
int32_t GetNewVersion(VersionInfo &versionInfo) override;
|
||||
|
||||
int32_t GetUpgradeStatus (UpgradeInfo &info) override;
|
||||
|
||||
int32_t SetUpdatePolicy(const UpdatePolicy &policy) override;
|
||||
|
||||
int32_t GetUpdatePolicy(UpdatePolicy &policy) override;
|
||||
|
||||
int32_t Cancel(int32_t service) override;
|
||||
|
||||
int32_t RebootAndClean(const std::string &miscFile, const std::string &cmd) override;
|
||||
|
||||
int32_t RebootAndInstall(const std::string &miscFile, const std::string &packageName) override;
|
||||
private:
|
||||
static inline BrokerDelegator<UpdateServiceProxy> delegator_;
|
||||
};
|
||||
}
|
||||
} // namespace OHOS
|
||||
#endif // UPDATER_PROXY_H
|
||||
Executable
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef UPDATE_SERVICE_STUB_H_
|
||||
#define UPDATE_SERVICE_STUB_H_
|
||||
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include "iremote_stub.h"
|
||||
#include "iupdate_service.h"
|
||||
#include "message_parcel.h"
|
||||
#include "parcel.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
class UpdateServiceStub : public IRemoteStub<IUpdateService> {
|
||||
public:
|
||||
int32_t OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply,
|
||||
MessageOption &option) override;
|
||||
|
||||
using UpdateServiceStubPtr = UpdateServiceStub *;
|
||||
using RequestFuncType = std::function<int(UpdateServiceStubPtr service,
|
||||
MessageParcel &data, MessageParcel &reply, MessageOption &option)>;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif // UPDATE_SERVICE_STUB_H_
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
<?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.
|
||||
-->
|
||||
<info>
|
||||
<process>updater_sa</process>
|
||||
<systemability>
|
||||
<name>3006</name>
|
||||
<libpath>libupdateservice.z.so</libpath>
|
||||
<run-on-create>true</run-on-create>
|
||||
<distributed>false</distributed>
|
||||
<dump-level>1</dump-level>
|
||||
</systemability>
|
||||
</info>
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
# Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//build/ohos/sa_profile/sa_profile.gni")
|
||||
|
||||
ohos_sa_profile("updater_sa_profile") {
|
||||
sources = [ "3006.xml" ]
|
||||
|
||||
part_name = "updater"
|
||||
}
|
||||
Executable
+208
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* 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 "progress_thread.h"
|
||||
#include <unistd.h>
|
||||
#include "curl/curl.h"
|
||||
#include "curl/easy.h"
|
||||
#include "securec.h"
|
||||
#include "update_helper.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
int32_t ProgressThread::StartProgress()
|
||||
{
|
||||
if (pDealThread_ == nullptr) {
|
||||
pDealThread_ = new (std::nothrow)std::thread(&ProgressThread::ExecuteThreadFunc, this);
|
||||
ENGINE_CHECK(pDealThread_ != nullptr, return -1, "Failed to create thread");
|
||||
}
|
||||
ENGINE_LOGI("StartProgress");
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
isWake_ = true;
|
||||
condition_.notify_one();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ProgressThread::StopProgress()
|
||||
{
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
isWake_ = true;
|
||||
isExitThread_ = true;
|
||||
condition_.notify_one();
|
||||
}
|
||||
|
||||
if (pDealThread_ != nullptr) {
|
||||
pDealThread_->join();
|
||||
delete pDealThread_;
|
||||
pDealThread_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ProgressThread::ExecuteThreadFunc()
|
||||
{
|
||||
while (1) {
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
while (!isWake_) {
|
||||
ENGINE_LOGI("ExecuteThreadFunc wait");
|
||||
condition_.wait(lock);
|
||||
}
|
||||
if (isExitThread_) {
|
||||
break;
|
||||
}
|
||||
isWake_ = false;
|
||||
}
|
||||
bool isExit = ProcessThreadExecute();
|
||||
if (isExit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// thread exit and release resource
|
||||
ProcessThreadExit();
|
||||
}
|
||||
|
||||
int32_t DownloadThread::StartDownload(const std::string &fileName, const std::string &url)
|
||||
{
|
||||
downloadFileName_ = fileName;
|
||||
serverUrl_ = url;
|
||||
exitDownload_ = false;
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
return StartProgress();
|
||||
}
|
||||
|
||||
void DownloadThread::StopDownload()
|
||||
{
|
||||
ENGINE_LOGI("StopDownload ");
|
||||
exitDownload_ = true;
|
||||
StopProgress();
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
bool DownloadThread::ProcessThreadExecute()
|
||||
{
|
||||
packageSize_ = GetLocalFileLength(downloadFileName_);
|
||||
ENGINE_LOGI("download packageSize_: %zu ", packageSize_);
|
||||
|
||||
downloadFile_ = fopen(downloadFileName_.c_str(), "ab+");
|
||||
ENGINE_CHECK(downloadFile_ != nullptr,
|
||||
DownloadCallback(0, UPDATE_STATE_DOWNLOAD_FAIL, "Failed ot open file");
|
||||
return true, "Failed to open file %s", downloadFileName_.c_str());
|
||||
|
||||
downloadHandle_ = curl_easy_init();
|
||||
ENGINE_CHECK(downloadHandle_ != nullptr,
|
||||
ProcessThreadExit();
|
||||
DownloadCallback(0, UPDATE_STATE_DOWNLOAD_FAIL, "Failed to init curl");
|
||||
return true, "Failed to init curl");
|
||||
|
||||
curl_easy_setopt(downloadHandle_, CURLOPT_TIMEOUT, TIMEOUT_FOR_DOWNLOAD);
|
||||
curl_easy_setopt(downloadHandle_, CURLOPT_CONNECTTIMEOUT, TIMEOUT_FOR_CONNECT);
|
||||
curl_easy_setopt(downloadHandle_, CURLOPT_URL, serverUrl_.c_str());
|
||||
curl_easy_setopt(downloadHandle_, CURLOPT_WRITEDATA, downloadFile_);
|
||||
curl_easy_setopt(downloadHandle_, CURLOPT_WRITEFUNCTION, WriteFunc);
|
||||
if (packageSize_ > 0) {
|
||||
curl_easy_setopt(downloadHandle_, CURLOPT_RESUME_FROM_LARGE, static_cast<curl_off_t>(packageSize_));
|
||||
}
|
||||
curl_easy_setopt(downloadHandle_, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(downloadHandle_, CURLOPT_PROGRESSDATA, this);
|
||||
curl_easy_setopt(downloadHandle_, CURLOPT_PROGRESSFUNCTION, DownloadProgress);
|
||||
CURLcode res = curl_easy_perform(downloadHandle_);
|
||||
if (res != CURLE_OK) {
|
||||
ProcessThreadExit();
|
||||
ENGINE_LOGI("Failed to download %s res %s", serverUrl_.c_str(), curl_easy_strerror(res));
|
||||
if (res != CURLE_ABORTED_BY_CALLBACK) { // cancel by user, do not callback
|
||||
DownloadCallback(0, UPDATE_STATE_DOWNLOAD_FAIL, curl_easy_strerror(res));
|
||||
}
|
||||
} else {
|
||||
ProcessThreadExit();
|
||||
ENGINE_LOGI("Success to download %s", serverUrl_.c_str());
|
||||
DownloadCallback(DOWNLOAD_FINISH_PERCENT, UPDATE_STATE_DOWNLOAD_SUCCESS, "");
|
||||
}
|
||||
// clear up
|
||||
downloadProgress_.endReason = "";
|
||||
downloadProgress_.percent = 0;
|
||||
downloadProgress_.status = UPDATE_STATE_DOWNLOAD_ON;
|
||||
return false;
|
||||
}
|
||||
|
||||
void DownloadThread::ProcessThreadExit()
|
||||
{
|
||||
ENGINE_LOGI("ProcessThreadExit");
|
||||
if (downloadHandle_ != nullptr) {
|
||||
curl_easy_cleanup(downloadHandle_);
|
||||
}
|
||||
downloadHandle_ = nullptr;
|
||||
if (downloadFile_ != nullptr) {
|
||||
fclose(downloadFile_);
|
||||
}
|
||||
downloadFile_ = nullptr;
|
||||
}
|
||||
|
||||
int32_t DownloadThread::DownloadCallback(uint32_t percent, UpgradeStatus status, const std::string &error)
|
||||
{
|
||||
if (exitDownload_) {
|
||||
ENGINE_LOGI("StopDownlDownloadCallbackoad");
|
||||
return -1;
|
||||
}
|
||||
if (status == UPDATE_STATE_DOWNLOAD_FAIL) {
|
||||
if (access(downloadFileName_.c_str(), 0) == 0) {
|
||||
unlink(downloadFileName_.c_str());
|
||||
}
|
||||
} else if (percent != DOWNLOAD_FINISH_PERCENT
|
||||
&& (percent < (downloadProgress_.percent + DOWNLOAD_PERIOD_PERCENT))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// wait until the download is complete, and then make a notification
|
||||
if (percent == DOWNLOAD_FINISH_PERCENT
|
||||
&& status == UPDATE_STATE_DOWNLOAD_ON) {
|
||||
return 0;
|
||||
}
|
||||
downloadProgress_.endReason = error;
|
||||
downloadProgress_.percent = percent;
|
||||
downloadProgress_.status = status;
|
||||
if (callback_ != nullptr) {
|
||||
callback_(downloadFileName_, downloadProgress_);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t DownloadThread::DownloadProgress(const void *localData,
|
||||
double dlTotal, double dlNow, double ulTotal, double ulNow)
|
||||
{
|
||||
ENGINE_CHECK_NO_LOG(dlTotal > 0, return 0);
|
||||
auto engine = reinterpret_cast<DownloadThread*>(const_cast<void*>(localData));
|
||||
ENGINE_CHECK(engine != nullptr, return -1, "Can not find engine");
|
||||
double curr = engine->GetPackageSize();
|
||||
unsigned int percent = (dlNow + curr) / (curr + dlTotal) * DOWNLOAD_FINISH_PERCENT;
|
||||
return engine->DownloadCallback(percent, UPDATE_STATE_DOWNLOAD_ON, "");
|
||||
}
|
||||
|
||||
size_t DownloadThread::WriteFunc(void *ptr, size_t size, size_t nmemb, const void *stream)
|
||||
{
|
||||
return fwrite(ptr, size, nmemb, reinterpret_cast<FILE*>(const_cast<void*>(stream)));
|
||||
}
|
||||
|
||||
size_t DownloadThread::GetLocalFileLength(const std::string &fileName)
|
||||
{
|
||||
FILE* fp = fopen(fileName.c_str(), "r");
|
||||
ENGINE_CHECK_NO_LOG(fp != nullptr, return 0);
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size_t length = ftell(fp);
|
||||
fclose(fp);
|
||||
return length;
|
||||
}
|
||||
}
|
||||
} // namespace OHOS
|
||||
Executable
+289
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* 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 "update_helper.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "hilog/log.h"
|
||||
#include "parcel.h"
|
||||
#include "securec.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
#ifdef UPDATE_SERVICE
|
||||
const std::string LOG_LABEL = "update_engine";
|
||||
const std::string LOG_NAME = "/data/update_service_log.txt";
|
||||
#else
|
||||
const std::string LOG_LABEL = "update_engine";
|
||||
const std::string LOG_NAME = "/data/update_client.log.txt";
|
||||
#endif
|
||||
constexpr int VECTOR_MAX_BUF_SIZE = 1024;
|
||||
constexpr int MAX_TIME_SIZE = 20;
|
||||
constexpr int HEX_DIGEST_NUM = 2;
|
||||
constexpr int HEX_DIGEST_BASE = 16;
|
||||
|
||||
UpdateLogLevel UpdateHelper::level_ = UpdateLogLevel::UPDATE_INFO;
|
||||
|
||||
int32_t UpdateHelper::WriteUpdateContext(MessageParcel &data, const UpdateContext &info)
|
||||
{
|
||||
data.WriteString16(Str8ToStr16(info.upgradeDevId));
|
||||
data.WriteString16(Str8ToStr16(info.controlDevId));
|
||||
data.WriteString16(Str8ToStr16(info.upgradeApp));
|
||||
data.WriteString16(Str8ToStr16(info.upgradeFile));
|
||||
data.WriteString16(Str8ToStr16(info.type));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateHelper::ReadUpdateContext(MessageParcel &reply, UpdateContext &info)
|
||||
{
|
||||
info.upgradeDevId = Str16ToStr8(reply.ReadString16());
|
||||
info.controlDevId = Str16ToStr8(reply.ReadString16());
|
||||
info.upgradeApp = Str16ToStr8(reply.ReadString16());
|
||||
info.upgradeFile = Str16ToStr8(reply.ReadString16());
|
||||
info.type = Str16ToStr8(reply.ReadString16());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateHelper::WriteVersionInfo(MessageParcel &data, const VersionInfo &info)
|
||||
{
|
||||
data.WriteInt32(static_cast<int32_t>(info.status));
|
||||
data.WriteString16(Str8ToStr16(info.errMsg));
|
||||
data.WriteInt32(static_cast<int32_t>(sizeof(info.result) / sizeof(info.result[0])));
|
||||
for (size_t i = 0; i < sizeof(info.result) / sizeof(info.result[0]); i++) {
|
||||
data.WriteUint64(static_cast<uint64_t>(info.result[i].size));
|
||||
data.WriteInt32(static_cast<int32_t>(info.result[i].packageType));
|
||||
|
||||
data.WriteString16(Str8ToStr16(info.result[i].versionName));
|
||||
data.WriteString16(Str8ToStr16(info.result[i].versionCode));
|
||||
data.WriteString16(Str8ToStr16(info.result[i].verifyInfo));
|
||||
data.WriteString16(Str8ToStr16(info.result[i].descriptPackageId));
|
||||
}
|
||||
data.WriteInt32(static_cast<int32_t>(sizeof(info.descriptInfo) / sizeof(info.descriptInfo[0])));
|
||||
for (size_t i = 0; i < sizeof(info.descriptInfo) / sizeof(info.descriptInfo[0]); i++) {
|
||||
data.WriteString16(Str8ToStr16(info.descriptInfo[i].descriptPackageId));
|
||||
data.WriteString16(Str8ToStr16(info.descriptInfo[i].content));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateHelper::ReadVersionInfo(MessageParcel &reply, VersionInfo &info)
|
||||
{
|
||||
info.status = static_cast<SearchStatus>(reply.ReadInt32());
|
||||
info.errMsg = Str16ToStr8(reply.ReadString16());
|
||||
|
||||
int32_t count = reply.ReadInt32();
|
||||
for (size_t i = 0; (i < static_cast<size_t>(count)) && (i < sizeof(info.result) / sizeof(info.result[0])); i++) {
|
||||
uint64_t uint64 = reply.ReadUint64();
|
||||
info.result[i].size = static_cast<size_t>(uint64);
|
||||
info.result[i].packageType = static_cast<PackageType>(reply.ReadInt32());
|
||||
|
||||
info.result[i].versionName = Str16ToStr8(reply.ReadString16());
|
||||
info.result[i].versionCode = Str16ToStr8(reply.ReadString16());
|
||||
info.result[i].verifyInfo = Str16ToStr8(reply.ReadString16());
|
||||
info.result[i].descriptPackageId = Str16ToStr8(reply.ReadString16());
|
||||
}
|
||||
count = reply.ReadInt32();
|
||||
for (size_t i = 0; (i < static_cast<size_t>(count))
|
||||
&& (i < sizeof(info.descriptInfo) / sizeof(info.descriptInfo[0])); i++) {
|
||||
info.descriptInfo[i].descriptPackageId = Str16ToStr8(reply.ReadString16());
|
||||
info.descriptInfo[i].content = Str16ToStr8(reply.ReadString16());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateHelper::WriteUpdatePolicy(MessageParcel &data, const UpdatePolicy &policy)
|
||||
{
|
||||
data.WriteBool(policy.autoDownload);
|
||||
data.WriteBool(policy.autoDownloadNet);
|
||||
data.WriteInt32(static_cast<int32_t>(policy.mode));
|
||||
data.WriteInt32(static_cast<int32_t>(policy.autoUpgradeCondition));
|
||||
data.WriteInt32(static_cast<int32_t>(sizeof(policy.autoUpgradeInterval) / sizeof(policy.autoUpgradeInterval[0])));
|
||||
for (size_t i = 0; i < sizeof(policy.autoUpgradeInterval) / sizeof(policy.autoUpgradeInterval[0]); i++) {
|
||||
data.WriteUint32(policy.autoUpgradeInterval[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateHelper::ReadUpdatePolicy(MessageParcel &data, UpdatePolicy &policy)
|
||||
{
|
||||
policy.autoDownload = static_cast<bool>(data.ReadBool());
|
||||
policy.autoDownloadNet = static_cast<bool>(data.ReadBool());
|
||||
policy.mode = static_cast<InstallMode>(data.ReadInt32());
|
||||
policy.autoUpgradeCondition = static_cast<AutoUpgradeCondition>(data.ReadInt32());
|
||||
int32_t count = data.ReadInt32();
|
||||
for (size_t i = 0; (i < static_cast<size_t>(count)) && (i <
|
||||
sizeof(policy.autoUpgradeInterval) / sizeof(policy.autoUpgradeInterval[0])); i++) {
|
||||
policy.autoUpgradeInterval[i] = data.ReadUint32();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateHelper::ReadUpgradeInfo(MessageParcel &reply, UpgradeInfo &info)
|
||||
{
|
||||
info.status = static_cast<UpgradeStatus>(reply.ReadInt32());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateHelper::WriteUpgradeInfo(MessageParcel &data, const UpgradeInfo &info)
|
||||
{
|
||||
data.WriteInt32(info.status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateHelper::ReadUpdateProgress(MessageParcel &reply, Progress &info)
|
||||
{
|
||||
info.percent = static_cast<uint32_t>(reply.ReadUint32());
|
||||
info.status = static_cast<UpgradeStatus>(reply.ReadInt32());
|
||||
info.endReason = Str16ToStr8(reply.ReadString16());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateHelper::WriteUpdateProgress(MessageParcel &data, const Progress &info)
|
||||
{
|
||||
data.WriteUint32(info.percent);
|
||||
data.WriteInt32(static_cast<int32_t>(info.status));
|
||||
data.WriteString16(Str8ToStr16(info.endReason));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateHelper::CopyVersionInfo(const VersionInfo &srcInfo, VersionInfo &dstInfo)
|
||||
{
|
||||
dstInfo.status = srcInfo.status;
|
||||
dstInfo.errMsg = srcInfo.errMsg;
|
||||
for (size_t i = 0; i < sizeof(dstInfo.result) / sizeof(dstInfo.result[0]); i++) {
|
||||
dstInfo.result[i].size = srcInfo.result[i].size;
|
||||
dstInfo.result[i].packageType = srcInfo.result[i].packageType;
|
||||
dstInfo.result[i].versionName = srcInfo.result[i].versionName;
|
||||
dstInfo.result[i].versionCode = srcInfo.result[i].versionCode;
|
||||
dstInfo.result[i].verifyInfo = srcInfo.result[i].verifyInfo;
|
||||
dstInfo.result[i].descriptPackageId = srcInfo.result[i].descriptPackageId;
|
||||
}
|
||||
for (size_t i = 0; i < sizeof(dstInfo.descriptInfo) / sizeof(dstInfo.descriptInfo[0]); i++) {
|
||||
dstInfo.descriptInfo[i].content = srcInfo.descriptInfo[i].content;
|
||||
dstInfo.descriptInfo[i].descriptPackageId = srcInfo.descriptInfo[i].descriptPackageId;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateHelper::CopyUpdatePolicy(const UpdatePolicy &srcInfo, UpdatePolicy &dstInfo)
|
||||
{
|
||||
dstInfo.autoDownload = srcInfo.autoDownload;
|
||||
dstInfo.autoDownloadNet = srcInfo.autoDownloadNet;
|
||||
dstInfo.mode = srcInfo.mode;
|
||||
dstInfo.autoUpgradeCondition = srcInfo.autoUpgradeCondition;
|
||||
for (size_t i = 0; i < sizeof(dstInfo.autoUpgradeInterval) / sizeof(dstInfo.autoUpgradeInterval[0]); i++) {
|
||||
dstInfo.autoUpgradeInterval[i] = srcInfo.autoUpgradeInterval[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UpdateHelper::Logger(const std::string &fileName, int32_t line, const char *format, ...)
|
||||
{
|
||||
std::string name = UpdateHelper::GetBriefFileName(fileName);
|
||||
std::ofstream logStream(LOG_NAME, std::ios::app | std::ios::out);
|
||||
static std::vector<char> buff(VECTOR_MAX_BUF_SIZE);
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
int size = vsnprintf_s(reinterpret_cast<char*>(buff.data()), buff.capacity(), buff.capacity(), format, list);
|
||||
ENGINE_CHECK(size != -1, return, "");
|
||||
va_end(list);
|
||||
std::string str(buff.data(), size);
|
||||
char realTime[MAX_TIME_SIZE];
|
||||
auto sysTime = std::chrono::system_clock::now();
|
||||
auto currentTime = std::chrono::system_clock::to_time_t(sysTime);
|
||||
std::strftime(realTime, sizeof(realTime), "%Y-%m-%d %H:%M:%S", std::localtime(¤tTime));
|
||||
logStream << realTime << "[" << LOG_LABEL << "]" << name << " " << line << " : " << str << std::endl;
|
||||
std::cout << realTime << "[" << LOG_LABEL << "]" << name << " " << line << " : " << str << std::endl;
|
||||
logStream.close();
|
||||
}
|
||||
|
||||
bool UpdateHelper::JudgeLevel(const UpdateLogLevel& level)
|
||||
{
|
||||
const UpdateLogLevel& curLevel = UpdateHelper::GetLogLevel();
|
||||
if (level <= curLevel) {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string UpdateHelper::GetBriefFileName(const std::string &file)
|
||||
{
|
||||
auto pos = file.find_last_of("/");
|
||||
if (pos != std::string::npos) {
|
||||
return file.substr(pos + 1);
|
||||
}
|
||||
|
||||
pos = file.find_last_of("\\");
|
||||
if (pos != std::string::npos) {
|
||||
return file.substr(pos + 1);
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
std::vector<std::string> UpdateHelper::SplitString(const std::string &str, const std::string &delimiter)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
ENGINE_CHECK(!str.empty(), return result, "string is empty");
|
||||
|
||||
size_t found = std::string::npos;
|
||||
size_t start = 0;
|
||||
while (true) {
|
||||
found = str.find_first_of(delimiter, start);
|
||||
result.push_back(str.substr(start, found - start));
|
||||
if (found == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
start = found + 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t UpdateHelper::CompareVersion(const std::string &version1, const std::string &version2)
|
||||
{
|
||||
std::vector<std::string> result1 = SplitString(version1, ".");
|
||||
std::vector<std::string> result2 = SplitString(version2, ".");
|
||||
if (result1.size() != result2.size()) {
|
||||
return ((result1.size() > result2.size()) ? -1 : 1);
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < result1.size(); i++) {
|
||||
long long ver1 = std::stoll(result1[i]);
|
||||
long long ver2 = std::stoll(result2[i]);
|
||||
if (ver1 == ver2) {
|
||||
continue;
|
||||
}
|
||||
return ((ver1 > ver2) ? 1 : -1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> UpdateHelper::HexToDegist(const std::string &str)
|
||||
{
|
||||
std::vector<uint8_t> result;
|
||||
for (size_t i = 0; i < str.length(); i += HEX_DIGEST_NUM) {
|
||||
std::string byte = str.substr(i, HEX_DIGEST_NUM);
|
||||
auto chr = static_cast<uint8_t>(static_cast<int>(strtol(byte.c_str(), nullptr, HEX_DIGEST_BASE)));
|
||||
result.push_back(chr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
} // namespace OHOS
|
||||
@@ -0,0 +1,528 @@
|
||||
/*
|
||||
* 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 "update_service.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/types.h>
|
||||
#include <vector>
|
||||
|
||||
#include "cJSON.h"
|
||||
#include "iservice_registry.h"
|
||||
#include "libxml/parser.h"
|
||||
#include "libxml/tree.h"
|
||||
#include "misc_info/misc_info.h"
|
||||
#include "openssl/err.h"
|
||||
#include "openssl/ssl.h"
|
||||
#include "package/package.h"
|
||||
#include "parameters.h"
|
||||
#include "progress_thread.h"
|
||||
#include "securec.h"
|
||||
#include "system_ability_definition.h"
|
||||
#include "update_helper.h"
|
||||
#include "updaterkits/updaterkits.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
REGISTER_SYSTEM_ABILITY_BY_ID(UpdateService, UPDATE_DISTRIBUTED_SERVICE_ID, true)
|
||||
|
||||
constexpr int32_t PORT_NUMBER = 5022;
|
||||
constexpr int32_t JSON_MAX_SIZE = 4096;
|
||||
const mode_t MKDIR_MODE = 0777;
|
||||
|
||||
const std::string MISC_FILE = "/dev/block/platform/soc/10100000.himci.eMMC/by-name/misc";
|
||||
const std::string BASE_PATH = "/data/updater";
|
||||
#ifndef UPDATER_UT
|
||||
const std::string SIGNING_CERT_NAME = "/data/update_sa/signing_cert.crt";
|
||||
#else
|
||||
const std::string SIGNING_CERT_NAME = "/data/updater/src/signing_cert.crt";
|
||||
#endif
|
||||
|
||||
UpdateService::UpdateService(int32_t systemAbilityId, bool runOnCreate)
|
||||
: SystemAbility(systemAbilityId, runOnCreate)
|
||||
{
|
||||
GetServerIp(serverAddr_);
|
||||
ENGINE_LOGI("UpdateService serverAddr: %s ", serverAddr_.c_str());
|
||||
InitVersionInfo(versionInfo_);
|
||||
}
|
||||
|
||||
UpdateService::~UpdateService()
|
||||
{
|
||||
ENGINE_LOGE("UpdateServerTest free %p", this);
|
||||
if (downloadThread_ != nullptr) {
|
||||
downloadThread_->StopDownload();
|
||||
delete downloadThread_;
|
||||
downloadThread_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t UpdateService::RegisterUpdateCallback(const UpdateContext &ctx,
|
||||
const sptr<IUpdateCallback> &updateCallback)
|
||||
{
|
||||
ENGINE_CHECK(updateCallback != nullptr, return -1, "Invalid callback");
|
||||
updateCallback_ = updateCallback;
|
||||
updateContext_.upgradeDevId = ctx.upgradeDevId;
|
||||
updateContext_.controlDevId = ctx.controlDevId;
|
||||
updateContext_.upgradeApp = ctx.upgradeApp;
|
||||
updateContext_.type = ctx.type;
|
||||
updateContext_.upgradeFile = ctx.upgradeFile;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateService::UnregisterUpdateCallback()
|
||||
{
|
||||
updateCallback_ = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateService::GetNewVersion(VersionInfo &versionInfo)
|
||||
{
|
||||
InitVersionInfo(versionInfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateService::GetUpgradeStatus(UpgradeInfo &info)
|
||||
{
|
||||
info.status = upgradeStatus_;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateService::SetUpdatePolicy(const UpdatePolicy &policy)
|
||||
{
|
||||
return UpdateHelper::CopyUpdatePolicy(policy, policy_);
|
||||
}
|
||||
|
||||
int32_t UpdateService::GetUpdatePolicy(UpdatePolicy &policy)
|
||||
{
|
||||
return UpdateHelper::CopyUpdatePolicy(policy_, policy);
|
||||
}
|
||||
|
||||
int32_t UpdateService::CheckNewVersion()
|
||||
{
|
||||
upgradeStatus_ = UPDATE_STATE_CHECK_VERSION_ON;
|
||||
int32_t engineSocket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
ENGINE_CHECK(engineSocket >= 0, SearchCallback("socket error !", SERVER_BUSY); return 1, "socket error !");
|
||||
|
||||
sockaddr_in engineSin {};
|
||||
engineSin.sin_family = AF_INET;
|
||||
engineSin.sin_port = htons(PORT_NUMBER);
|
||||
int32_t ret = inet_pton(AF_INET, serverAddr_.c_str(), &engineSin.sin_addr);
|
||||
ENGINE_CHECK(ret > 0, close(engineSocket); SearchCallback("Invalid ip!", SERVER_BUSY); return 1, "socket error");
|
||||
|
||||
struct timeval tv = {TIMEOUT_FOR_CONNECT, 0};
|
||||
setsockopt(engineSocket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(struct timeval));
|
||||
ret = connect(engineSocket, reinterpret_cast<sockaddr*>(&engineSin), sizeof(engineSin));
|
||||
ENGINE_CHECK(ret == 0,
|
||||
#ifndef UPDATER_UT
|
||||
SearchCallback("Connect error !", SERVER_BUSY);
|
||||
close(engineSocket);
|
||||
#else
|
||||
SearchCallback("update service test connect error !", HAS_NEW_VERSION);
|
||||
close(engineSocket);
|
||||
#endif
|
||||
return 1, "connect error");
|
||||
ReadDataFromSSL(engineSocket);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateService::DownloadVersion()
|
||||
{
|
||||
if (access(BASE_PATH.c_str(), 0) == -1) {
|
||||
mkdir(BASE_PATH.c_str(), MKDIR_MODE);
|
||||
}
|
||||
|
||||
Progress progress0 = {0, UPDATE_STATE_DOWNLOAD_ON, ""};
|
||||
ENGINE_CHECK(upgradeStatus_ >= UPDATE_STATE_CHECK_VERSION_SUCCESS,
|
||||
progress0.status = UPDATE_STATE_DOWNLOAD_FAIL;
|
||||
progress0.endReason = "Invalid status";
|
||||
DownloadCallback("", progress0); return -1, "Invalid status %d", upgradeStatus_);
|
||||
|
||||
ENGINE_CHECK(!versionInfo_.result[0].verifyInfo.empty(),
|
||||
progress0.status = UPDATE_STATE_DOWNLOAD_FAIL;
|
||||
progress0.endReason = "Invalid verify info";
|
||||
DownloadCallback("", progress0); return -1, "Invalid verify info");
|
||||
std::string downloadFileName = BASE_PATH + "/" + versionInfo_.result[0].verifyInfo;
|
||||
size_t localFileLength = DownloadThread::GetLocalFileLength(downloadFileName);
|
||||
ENGINE_LOGI("Download %zu %s", localFileLength, downloadFileName.c_str());
|
||||
if (localFileLength == versionInfo_.result[0].size && versionInfo_.result[0].size != 0) {
|
||||
progress0.percent = DOWNLOAD_FINISH_PERCENT;
|
||||
progress0.status = UPDATE_STATE_DOWNLOAD_SUCCESS;
|
||||
DownloadCallback(downloadFileName, progress0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
upgradeStatus_ = UPDATE_STATE_DOWNLOAD_ON;
|
||||
if (downloadThread_ == nullptr) {
|
||||
downloadThread_ = new DownloadThread([&](const std::string &fileName, const Progress &progress) -> int {
|
||||
DownloadCallback(fileName, progress);
|
||||
return 0;
|
||||
});
|
||||
ENGINE_CHECK(downloadThread_ != nullptr,
|
||||
progress0.status = UPDATE_STATE_DOWNLOAD_FAIL;
|
||||
progress0.endReason = "Failed to start thread";
|
||||
DownloadCallback(downloadFileName, progress0); return -1, "Failed to start thread");
|
||||
}
|
||||
return downloadThread_->StartDownload(downloadFileName, GetDownloadServerUrl());
|
||||
}
|
||||
|
||||
int32_t UpdateService::DoUpdate()
|
||||
{
|
||||
Progress progress;
|
||||
progress.percent = 1;
|
||||
progress.status = UPDATE_STATE_INSTALL_ON;
|
||||
ENGINE_CHECK(upgradeStatus_ >= UPDATE_STATE_DOWNLOAD_SUCCESS,
|
||||
progress.endReason = "Invalid status";
|
||||
progress.status = UPDATE_STATE_INSTALL_FAIL;
|
||||
UpgradeCallback(progress);
|
||||
return -1, "Invalid status %d", upgradeStatus_);
|
||||
|
||||
progress.status = UPDATE_STATE_INSTALL_SUCCESS;
|
||||
bool ret = RebootAndInstallUpgradePackage(MISC_FILE, updateContext_.upgradeFile);
|
||||
ENGINE_CHECK(ret, return -1, "UpdateService::DoUpdate SetParameter failed");
|
||||
progress.percent = DOWNLOAD_FINISH_PERCENT;
|
||||
UpgradeCallback(progress);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UpdateService::SearchCallback(const std::string &msg, SearchStatus status)
|
||||
{
|
||||
ENGINE_LOGI("SearchCallback %s ", msg.c_str());
|
||||
versionInfo_.status = status;
|
||||
versionInfo_.errMsg = msg;
|
||||
if (status == HAS_NEW_VERSION || status == NO_NEW_VERSION) {
|
||||
upgradeStatus_ = UPDATE_STATE_CHECK_VERSION_SUCCESS;
|
||||
|
||||
// Compare the downloaded version with the local version.
|
||||
std::string loadVersion = OHOS::system::GetParameter("ro.build.id", "");
|
||||
int32_t ret = UpdateHelper::CompareVersion(versionInfo_.result[0].versionCode, loadVersion);
|
||||
if (ret <= 0) {
|
||||
versionInfo_.status = NO_NEW_VERSION;
|
||||
}
|
||||
} else {
|
||||
upgradeStatus_ = UPDATE_STATE_CHECK_VERSION_FAIL;
|
||||
}
|
||||
if (updateCallback_ != nullptr) {
|
||||
updateCallback_->OnCheckVersionDone(versionInfo_);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateService::DownloadCallback(const std::string &fileName, const Progress &progress)
|
||||
{
|
||||
Progress downloadProgress {};
|
||||
upgradeStatus_ = UPDATE_STATE_DOWNLOAD_ON;
|
||||
if (progress.status == UPDATE_STATE_DOWNLOAD_FAIL ||
|
||||
progress.status == UPDATE_STATE_DOWNLOAD_SUCCESS) {
|
||||
upgradeStatus_ = progress.status;
|
||||
}
|
||||
downloadProgress.percent = progress.percent;
|
||||
downloadProgress.status = progress.status;
|
||||
downloadProgress.endReason = progress.endReason;
|
||||
|
||||
#ifdef UPDATER_UT
|
||||
upgradeStatus_ = UPDATE_STATE_DOWNLOAD_SUCCESS;
|
||||
#endif
|
||||
ENGINE_LOGI("DownloadCallback status %d %d", progress.status, progress.percent);
|
||||
if (progress.status == UPDATE_STATE_DOWNLOAD_SUCCESS) {
|
||||
ENGINE_LOGI("DownloadCallback fileName %s %s", fileName.c_str(), updateContext_.upgradeFile.c_str());
|
||||
if (rename(fileName.c_str(), updateContext_.upgradeFile.c_str())) {
|
||||
ENGINE_LOGE("Rename file fail %s", fileName.c_str());
|
||||
remove(updateContext_.upgradeFile.c_str());
|
||||
downloadProgress.status = UPDATE_STATE_DOWNLOAD_FAIL;
|
||||
} else if (!VerifyDownloadPkg(updateContext_.upgradeFile, downloadProgress)) {
|
||||
// If the verification fails, delete the corresponding package.
|
||||
remove(updateContext_.upgradeFile.c_str());
|
||||
downloadProgress.status = UPDATE_STATE_VERIFY_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (updateCallback_ != nullptr) {
|
||||
updateCallback_->OnDownloadProgress(downloadProgress);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateService::UpgradeCallback(const Progress &progress)
|
||||
{
|
||||
upgradeStatus_ = progress.status;
|
||||
ENGINE_LOGE("UpgradeCallback status %d %d", progress.status, progress.percent);
|
||||
if (updateCallback_ != nullptr) {
|
||||
updateCallback_->OnUpgradeProgress(progress);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateService::ReadDataFromSSL(int32_t engineSocket)
|
||||
{
|
||||
SearchStatus result = SERVER_BUSY;
|
||||
std::string errMsg = "Couldn't connect to server";
|
||||
std::vector<char> buffer(JSON_MAX_SIZE);
|
||||
|
||||
SSL_library_init();
|
||||
OpenSSL_add_all_algorithms();
|
||||
SSL_load_error_strings();
|
||||
SSL_CTX* sslCtx = SSL_CTX_new(SSLv23_client_method());
|
||||
ENGINE_CHECK(sslCtx != nullptr, return, "sslCtx is nullptr");
|
||||
SSL *ssl = SSL_new(sslCtx);
|
||||
ENGINE_CHECK(ssl != nullptr, SSL_CTX_free(sslCtx); return, "ssl is nullptr");
|
||||
SSL_set_fd(ssl, engineSocket);
|
||||
int32_t ret = SSL_connect(ssl);
|
||||
if (ret != -1) {
|
||||
int32_t len = SSL_read(ssl, buffer.data(), JSON_MAX_SIZE);
|
||||
if (len > 0 && ParseJsonFile(buffer, versionInfo_) == 0) {
|
||||
result = HAS_NEW_VERSION;
|
||||
errMsg = "";
|
||||
} else {
|
||||
result = SYSTEM_ERROR;
|
||||
errMsg = "Couldn't read data";
|
||||
}
|
||||
} else {
|
||||
result = SYSTEM_ERROR;
|
||||
errMsg = "Couldn't connect to server";
|
||||
}
|
||||
SSL_shutdown(ssl);
|
||||
SSL_free(ssl);
|
||||
close(engineSocket);
|
||||
SSL_CTX_free(sslCtx);
|
||||
|
||||
SearchCallback(errMsg, result);
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t UpdateService::ParseJsonFile(const std::vector<char> &buffer, VersionInfo &info)
|
||||
{
|
||||
ENGINE_CHECK(buffer.size() > 0, return -1, "JsonFile length must > 0");
|
||||
cJSON *root = cJSON_Parse(buffer.data());
|
||||
ENGINE_CHECK(root != nullptr, return -1, "Error get root");
|
||||
|
||||
cJSON *item = cJSON_GetObjectItem(root, "searchStatus");
|
||||
ENGINE_CHECK(item != nullptr, cJSON_Delete(root); return -1, "Error get searchStatus");
|
||||
info.status = static_cast<SearchStatus>(item->valueint);
|
||||
|
||||
item = cJSON_GetObjectItem(root, "errMsg");
|
||||
ENGINE_CHECK(item != nullptr, cJSON_Delete(root); return -1, "Error get errMsg");
|
||||
info.errMsg = item->valuestring;
|
||||
|
||||
cJSON *results = cJSON_GetObjectItem(root, "checkResults");
|
||||
ENGINE_CHECK(results != nullptr, cJSON_Delete(root); return -1, "Error get checkResults");
|
||||
int32_t ret = ReadCheckVersionResult(results, info);
|
||||
ENGINE_CHECK(ret == 0, cJSON_Delete(root); return -1, "Error get checkResults");
|
||||
|
||||
cJSON *descriptInfo = cJSON_GetObjectItem(root, "descriptInfo");
|
||||
ENGINE_CHECK(descriptInfo != nullptr, cJSON_Delete(root); return -1, "Error get descriptInfo");
|
||||
ret = ReadCheckVersiondescriptInfo(descriptInfo, info);
|
||||
ENGINE_CHECK(ret == 0, cJSON_Delete(root); return -1, "Error get descriptInfo");
|
||||
|
||||
cJSON_Delete(root);
|
||||
if (info.status == HAS_NEW_VERSION) {
|
||||
ENGINE_CHECK(!info.result[0].verifyInfo.empty() &&
|
||||
!info.result[0].versionName.empty() &&
|
||||
info.result[0].size > 0, return -1, "Error get descriptInfo");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateService::ReadCheckVersionResult(const cJSON* results, VersionInfo &info)
|
||||
{
|
||||
size_t number = cJSON_GetArraySize(results);
|
||||
for (size_t i = 0; i < number && i < sizeof(info.result) / sizeof(info.result[0]); i++) {
|
||||
cJSON *result = cJSON_GetArrayItem(results, i);
|
||||
ENGINE_CHECK(result != nullptr, return -1, "Error get result");
|
||||
|
||||
cJSON *item = cJSON_GetObjectItem(result, "versionName");
|
||||
ENGINE_CHECK(item != nullptr, return -1, "Error get versionName");
|
||||
info.result[i].versionName = item->valuestring;
|
||||
|
||||
item = cJSON_GetObjectItem(result, "versionCode");
|
||||
ENGINE_CHECK(item != nullptr, return -1, "Error get versionCode");
|
||||
info.result[i].versionCode = item->valuestring;
|
||||
|
||||
item = cJSON_GetObjectItem(result, "verifyInfo");
|
||||
ENGINE_CHECK(item != nullptr, return -1, "Error get verifyInfo");
|
||||
info.result[i].verifyInfo = item->valuestring;
|
||||
|
||||
item = cJSON_GetObjectItem(result, "size");
|
||||
ENGINE_CHECK(item != nullptr, return -1, "Error get size");
|
||||
info.result[i].size = item->valueint;
|
||||
|
||||
item = cJSON_GetObjectItem(result, "packageType");
|
||||
ENGINE_CHECK(item != nullptr, return -1, "Error get packageType");
|
||||
info.result[i].packageType = (PackageType)(item->valueint);
|
||||
|
||||
item = cJSON_GetObjectItem(result, "descriptPackageId");
|
||||
ENGINE_CHECK(item != nullptr, return -1, "Error get descriptPackageId");
|
||||
info.result[i].descriptPackageId = item->valuestring;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateService::ReadCheckVersiondescriptInfo(const cJSON *descriptInfo, VersionInfo &info)
|
||||
{
|
||||
size_t number = cJSON_GetArraySize(descriptInfo);
|
||||
for (size_t i = 0; i < number && i < sizeof(info.result) / sizeof(info.result[0]); i++) {
|
||||
cJSON* descript = cJSON_GetArrayItem(descriptInfo, i);
|
||||
ENGINE_CHECK(descript != nullptr, return -1, "Error get descriptInfo");
|
||||
|
||||
cJSON *item = cJSON_GetObjectItem(descript, "descriptPackageId");
|
||||
if (item != nullptr) {
|
||||
info.descriptInfo[i].descriptPackageId = item->valuestring;
|
||||
}
|
||||
item = cJSON_GetObjectItem(descript, "content");
|
||||
if (item != nullptr) {
|
||||
info.descriptInfo[i].content = item->valuestring;
|
||||
ENGINE_LOGI(" descriptInfo content %s", info.descriptInfo[i].content.c_str());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool UpdateService::VerifyDownloadPkg(const std::string &pkgName, Progress &progress)
|
||||
{
|
||||
// Compare the downloaded version with the local version. Only update is supported.
|
||||
std::string loadVersion = OHOS::system::GetParameter("ro.build.id", "");
|
||||
int32_t ret = UpdateHelper::CompareVersion(versionInfo_.result[0].versionCode, loadVersion);
|
||||
if (ret <= 0) {
|
||||
progress.endReason = "Update package version earlier than the local version";
|
||||
ENGINE_LOGE("Version compare Failed local '%s' server '%s'",
|
||||
loadVersion.c_str(), versionInfo_.result[0].versionCode.c_str());
|
||||
return false;
|
||||
}
|
||||
ENGINE_LOGI("versionInfo_.result[0].verifyInfo %s ", versionInfo_.result[0].verifyInfo.c_str());
|
||||
std::vector<uint8_t> digest = UpdateHelper::HexToDegist(versionInfo_.result[0].verifyInfo);
|
||||
ret = VerifyPackage(pkgName.c_str(),
|
||||
SIGNING_CERT_NAME.c_str(), versionInfo_.result[0].versionCode.c_str(), digest.data(), digest.size());
|
||||
if (ret != 0) {
|
||||
progress.endReason = "Upgrade package verify Failed";
|
||||
ENGINE_LOGE("Package %s verification Failed", pkgName.c_str());
|
||||
return false;
|
||||
}
|
||||
ENGINE_LOGE("Package verify success");
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string UpdateService::GetDownloadServerUrl() const
|
||||
{
|
||||
std::string url = "http://";
|
||||
url += serverAddr_;
|
||||
url += "/";
|
||||
url += versionInfo_.result[0].descriptPackageId;
|
||||
return url;
|
||||
}
|
||||
|
||||
void UpdateService::GetServerIp(std::string &ip)
|
||||
{
|
||||
if (access("/data/update_sa", 0) == -1) {
|
||||
mkdir("/data/update_sa", MKDIR_MODE);
|
||||
}
|
||||
|
||||
xmlDocPtr doc = xmlReadFile("/data/update_sa/update_config.xml", "UTF-8", XML_PARSE_NOBLANKS);
|
||||
ENGINE_CHECK(doc != nullptr, return, "Open config Failed");
|
||||
|
||||
xmlNodePtr rootNode = xmlDocGetRootElement(doc);
|
||||
ENGINE_CHECK(rootNode != nullptr, xmlFreeDoc(doc); return, "Get root node Failed");
|
||||
|
||||
xmlChar *nodeContent = nullptr;
|
||||
for (xmlNodePtr node = rootNode->children; node; node = node->next) {
|
||||
if ((!xmlStrcmp(node->name, (const xmlChar *)"serverIp"))) {
|
||||
nodeContent = xmlNodeGetContent(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nodeContent != nullptr) {
|
||||
ip = (char*)nodeContent;
|
||||
xmlFree(nodeContent);
|
||||
}
|
||||
xmlFreeDoc(doc);
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t UpdateService::Cancel(int32_t service)
|
||||
{
|
||||
ENGINE_LOGI("Cancel %d", service);
|
||||
if (downloadThread_ != nullptr && service == DOWNLOAD) {
|
||||
downloadThread_->StopDownload();
|
||||
ENGINE_LOGI("StopDownload");
|
||||
delete downloadThread_;
|
||||
downloadThread_ = nullptr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateService::RebootAndClean(const std::string &miscFile, const std::string &cmd)
|
||||
{
|
||||
#ifndef UPDATER_UT
|
||||
return RebootAndCleanUserData(miscFile, cmd) ? 0 : -1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t UpdateService::RebootAndInstall(const std::string &miscFile, const std::string &packageName)
|
||||
{
|
||||
#ifndef UPDATER_UT
|
||||
return RebootAndInstallUpgradePackage(miscFile, packageName) ? 0 : -1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void UpdateService::InitVersionInfo(VersionInfo &versionInfo) const
|
||||
{
|
||||
versionInfo.status = HAS_NEW_VERSION;
|
||||
std::string versionName = OHOS::system::GetParameter("ro.build.id", "");
|
||||
if (versionName.empty()) {
|
||||
versionInfo.status = SYSTEM_ERROR;
|
||||
versionInfo.errMsg = "Can not get local version";
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sizeof(versionInfo.result) / sizeof(versionInfo.result[0]); i++) {
|
||||
versionInfo.result[i].size = 0;
|
||||
versionInfo.result[i].packageType = PACKAGE_TYPE_NORMAL;
|
||||
versionInfo.result[i].versionName = versionName;
|
||||
versionInfo.result[i].versionCode = "";
|
||||
versionInfo.result[i].verifyInfo = "";
|
||||
versionInfo.result[i].descriptPackageId = "";
|
||||
}
|
||||
for (size_t i = 0; i < sizeof(versionInfo.descriptInfo) / sizeof(versionInfo.descriptInfo[0]); i++) {
|
||||
versionInfo.descriptInfo[i].content = "";
|
||||
versionInfo.descriptInfo[i].descriptPackageId = "";
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateService::OnStart()
|
||||
{
|
||||
ENGINE_LOGI("UpdaterService OnStart");
|
||||
bool res = Publish(this);
|
||||
if (res == false) {
|
||||
ENGINE_LOGI("UpdaterService OnStart failed");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void UpdateService::OnStop()
|
||||
{
|
||||
ENGINE_LOGI("UpdaterService OnStop");
|
||||
}
|
||||
}
|
||||
} // namespace OHOS
|
||||
Executable
+177
@@ -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 "update_service_stub.h"
|
||||
#include "update_helper.h"
|
||||
#include "securec.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
static int32_t GetNewVersionStub(UpdateServiceStub::UpdateServiceStubPtr service,
|
||||
MessageParcel& data, MessageParcel& reply, MessageOption &option)
|
||||
{
|
||||
ENGINE_CHECK(service != nullptr, return -1, "Invalid param");
|
||||
VersionInfo info = {};
|
||||
int32_t ret = service->GetNewVersion(info);
|
||||
ENGINE_CHECK(ret == 0, return -1, "Failed to get new version");
|
||||
UpdateHelper::WriteVersionInfo(reply, info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t GetUpgradeStatusStub(UpdateServiceStub::UpdateServiceStubPtr service,
|
||||
MessageParcel& data, MessageParcel& reply, MessageOption &option)
|
||||
{
|
||||
ENGINE_CHECK(service != nullptr, return -1, "Invalid param");
|
||||
UpgradeInfo info = {};
|
||||
int32_t ret = service->GetUpgradeStatus(info);
|
||||
ENGINE_CHECK(ret == 0, return -1, "Failed to get new upgrade status");
|
||||
UpdateHelper::WriteUpgradeInfo(reply, info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t CheckNewVersionStub(UpdateServiceStub::UpdateServiceStubPtr service,
|
||||
MessageParcel& data, MessageParcel& reply, MessageOption &option)
|
||||
{
|
||||
ENGINE_CHECK(service != nullptr, return -1, "Invalid param");
|
||||
int32_t ret = service->CheckNewVersion();
|
||||
reply.WriteInt32(ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t DownloadVersionStub(UpdateServiceStub::UpdateServiceStubPtr service,
|
||||
MessageParcel& data, MessageParcel& reply, MessageOption &option)
|
||||
{
|
||||
ENGINE_CHECK(service != nullptr, return -1, "Invalid param");
|
||||
int32_t ret = service->DownloadVersion();
|
||||
reply.WriteInt32(ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t DoUpdateStub(UpdateServiceStub::UpdateServiceStubPtr service,
|
||||
MessageParcel& data, MessageParcel& reply, MessageOption &option)
|
||||
{
|
||||
ENGINE_CHECK(service != nullptr, return -1, "Invalid param");
|
||||
int32_t ret = service->DoUpdate();
|
||||
reply.WriteInt32(ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t SetUpdatePolicyStub(UpdateServiceStub::UpdateServiceStubPtr service,
|
||||
MessageParcel& data, MessageParcel& reply, MessageOption &option)
|
||||
{
|
||||
ENGINE_CHECK(service != nullptr, return -1, "Invalid param");
|
||||
UpdatePolicy policy = {};
|
||||
UpdateHelper::ReadUpdatePolicy(data, policy);
|
||||
int32_t ret = service->SetUpdatePolicy(policy);
|
||||
reply.WriteInt32(ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t GetUpdatePolicyStub(UpdateServiceStub::UpdateServiceStubPtr service,
|
||||
MessageParcel& data, MessageParcel& reply, MessageOption &option)
|
||||
{
|
||||
ENGINE_CHECK(service != nullptr, return -1, "Invalid param");
|
||||
UpdatePolicy policy = {};
|
||||
int32_t ret = service->GetUpdatePolicy(policy);
|
||||
ENGINE_CHECK(ret == 0, return -1, "Failed to get new get policy");
|
||||
UpdateHelper::WriteUpdatePolicy(reply, policy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t RegisterUpdateCallbackStub(UpdateServiceStub::UpdateServiceStubPtr service,
|
||||
MessageParcel& data, MessageParcel& reply, MessageOption &option)
|
||||
{
|
||||
ENGINE_CHECK(service != nullptr, return -1, "Invalid param");
|
||||
int32_t ret = -1;
|
||||
UpdateContext ctx {};
|
||||
UpdateHelper::ReadUpdateContext(data, ctx);
|
||||
auto remote = data.ReadRemoteObject();
|
||||
ENGINE_CHECK(remote != nullptr, reply.WriteInt32(ret); return 0, "Failed to read remote obj");
|
||||
ret = service->RegisterUpdateCallback(ctx, iface_cast<IUpdateCallback>(remote));
|
||||
reply.WriteInt32(ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t UnregisterUpdateCallbackStub(UpdateServiceStub::UpdateServiceStubPtr service,
|
||||
MessageParcel& data, MessageParcel& reply, MessageOption &option)
|
||||
{
|
||||
ENGINE_CHECK(service != nullptr, return -1, "Invalid param");
|
||||
int32_t ret = service->UnregisterUpdateCallback();
|
||||
reply.WriteInt32(ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t CancelStub(UpdateServiceStub::UpdateServiceStubPtr service,
|
||||
MessageParcel& data, MessageParcel& reply, MessageOption &option)
|
||||
{
|
||||
ENGINE_CHECK(service != nullptr, return -1, "Invalid param");
|
||||
int32_t ret = service->Cancel(data.ReadInt32());
|
||||
reply.WriteInt32(ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t RebootAndCleanStub(UpdateServiceStub::UpdateServiceStubPtr service,
|
||||
MessageParcel& data, MessageParcel& reply, MessageOption &option)
|
||||
{
|
||||
ENGINE_CHECK(service != nullptr, return -1, "Invalid param");
|
||||
string miscFile = Str16ToStr8(data.ReadString16());
|
||||
string cmd = Str16ToStr8(data.ReadString16());
|
||||
int32_t ret = service->RebootAndClean(miscFile, cmd);
|
||||
reply.WriteInt32(ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t RebootAndInstallStub(UpdateServiceStub::UpdateServiceStubPtr service,
|
||||
MessageParcel& data, MessageParcel& reply, MessageOption &option)
|
||||
{
|
||||
ENGINE_CHECK(service != nullptr, return -1, "Invalid param");
|
||||
string miscFile = Str16ToStr8(data.ReadString16());
|
||||
string packageName = Str16ToStr8(data.ReadString16());
|
||||
int32_t ret = service->RebootAndClean(miscFile, packageName);
|
||||
reply.WriteInt32(ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateServiceStub::OnRemoteRequest(uint32_t code,
|
||||
MessageParcel& data, MessageParcel& reply, MessageOption &option)
|
||||
{
|
||||
static std::map<uint32_t, UpdateServiceStub::RequestFuncType> requestFuncMap = {
|
||||
{IUpdateService::CHECK_VERSION, CheckNewVersionStub},
|
||||
{IUpdateService::DOWNLOAD, DownloadVersionStub},
|
||||
{IUpdateService::UPGRADE, DoUpdateStub},
|
||||
{IUpdateService::SET_POLICY, SetUpdatePolicyStub},
|
||||
{IUpdateService::GET_POLICY, GetUpdatePolicyStub},
|
||||
{IUpdateService::GET_NEW_VERSION, GetNewVersionStub},
|
||||
{IUpdateService::GET_STATUS, GetUpgradeStatusStub},
|
||||
{IUpdateService::REGISTER_CALLBACK, RegisterUpdateCallbackStub},
|
||||
{IUpdateService::UNREGISTER_CALLBACK, UnregisterUpdateCallbackStub},
|
||||
{IUpdateService::CANCEL, CancelStub},
|
||||
{IUpdateService::REBOOT_CLEAN, RebootAndCleanStub},
|
||||
{IUpdateService::REBOOT_INSTALL, RebootAndInstallStub},
|
||||
};
|
||||
|
||||
ENGINE_LOGI("UpdateServiceStub OnRemoteRequest code %u", code);
|
||||
for (auto inter = requestFuncMap.begin(); inter != requestFuncMap.end(); inter++) {
|
||||
if (inter->first == code) {
|
||||
return inter->second(this, data, reply, option);
|
||||
}
|
||||
}
|
||||
ENGINE_LOGE("UpdateServiceStub OnRemoteRequest code %u not found", code);
|
||||
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
|
||||
}
|
||||
}
|
||||
} // namespace OHO
|
||||
Executable
+64
@@ -0,0 +1,64 @@
|
||||
# Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//build/ohos.gni")
|
||||
|
||||
ohos_prebuilt_etc("updater_sa.rc") {
|
||||
source = "etc/updater_sa.rc"
|
||||
relative_install_dir = "init"
|
||||
part_name = "updater"
|
||||
}
|
||||
|
||||
ohos_static_library("updateservicekits") {
|
||||
defines = [ "DUAL_ADAPTER" ]
|
||||
sources = [
|
||||
"//base/update/updateservice/callback/src/update_callback.cpp",
|
||||
"//base/update/updateservice/callback/src/update_callback_stub.cpp",
|
||||
"//base/update/updateservice/engine/src/update_helper.cpp",
|
||||
"//base/update/updateservice/interfaces/innerkits/engine/update_service_kits_impl.cpp",
|
||||
"//base/update/updateservice/interfaces/innerkits/engine/update_service_proxy.cpp",
|
||||
]
|
||||
|
||||
include_dirs = [
|
||||
"//base/update/updater/services/include",
|
||||
"//base/update/updater/utils/include",
|
||||
"//base/update/updater/interfaces/kits/include",
|
||||
"//utils/native/base/include",
|
||||
"//utils/system/safwk/native/include",
|
||||
"//base/update/updateservice/interfaces/innerkits/include",
|
||||
"//base/update/updateservice/engine/include",
|
||||
"//base/update/updateservice/callback/include",
|
||||
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include",
|
||||
"//foundation/distributedschedule/safwk/services/safwk/include",
|
||||
"//foundation/distributedschedule/safwk/interfaces/innerkits/safwk",
|
||||
"//foundation/distributedschedule/samgr/adapter/interfaces/innerkits/include",
|
||||
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include",
|
||||
"//third_party/bounds_checking_function/include",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//base/update/updater/services/log:libupdaterlog",
|
||||
"//third_party/bounds_checking_function:libsec_static",
|
||||
"//utils/native/base:utils",
|
||||
]
|
||||
|
||||
external_deps = [
|
||||
"hiviewdfx_hilog_native:libhilog",
|
||||
"ipc:ipc_core",
|
||||
"safwk:system_ability_fwk",
|
||||
"samgr_L2:samgr_proxy",
|
||||
"startup_l2:syspara",
|
||||
]
|
||||
|
||||
part_name = "updater"
|
||||
}
|
||||
+232
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* 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 "update_service_kits_impl.h"
|
||||
|
||||
#include "if_system_ability_manager.h"
|
||||
#include "iservice_registry.h"
|
||||
#include "iupdate_service.h"
|
||||
#include "iupdate_callback.h"
|
||||
#include "securec.h"
|
||||
#include "system_ability_definition.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
UpdateServiceKits& UpdateServiceKits::GetInstance()
|
||||
{
|
||||
return DelayedRefSingleton<UpdateServiceKitsImpl>::GetInstance();
|
||||
}
|
||||
|
||||
UpdateServiceKitsImpl::UpdateServiceKitsImpl() {}
|
||||
|
||||
UpdateServiceKitsImpl::~UpdateServiceKitsImpl() {}
|
||||
|
||||
void UpdateServiceKitsImpl::ResetService(const wptr<IRemoteObject>& remote)
|
||||
{
|
||||
ENGINE_LOGI("Remote is dead, reset service instance");
|
||||
|
||||
std::lock_guard<std::mutex> lock(updateServiceLock_);
|
||||
if (updateService_ != nullptr) {
|
||||
sptr<IRemoteObject> object = updateService_->AsObject();
|
||||
if ((object != nullptr) && (remote == object)) {
|
||||
object->RemoveDeathRecipient(deathRecipient_);
|
||||
updateService_ = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sptr<IUpdateService> UpdateServiceKitsImpl::GetService()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(updateServiceLock_);
|
||||
if (updateService_ != nullptr) {
|
||||
return updateService_;
|
||||
}
|
||||
|
||||
sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
|
||||
ENGINE_CHECK(samgr != nullptr, return nullptr, "Get samgr failed");
|
||||
sptr<IRemoteObject> object = samgr->GetSystemAbility(UPDATE_DISTRIBUTED_SERVICE_ID);
|
||||
ENGINE_CHECK(object != nullptr, return nullptr, "Get update object from samgr failed");
|
||||
|
||||
if (deathRecipient_ == nullptr) {
|
||||
deathRecipient_ = new DeathRecipient();
|
||||
}
|
||||
|
||||
if ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient_))) {
|
||||
ENGINE_LOGE("Failed to add death recipient");
|
||||
}
|
||||
|
||||
ENGINE_LOGI("get remote object ok");
|
||||
updateService_ = iface_cast<IUpdateService>(object);
|
||||
if (updateService_ == nullptr) {
|
||||
ENGINE_LOGE("account iface_cast failed");
|
||||
}
|
||||
return updateService_;
|
||||
}
|
||||
|
||||
void UpdateServiceKitsImpl::DeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
|
||||
{
|
||||
DelayedRefSingleton<UpdateServiceKitsImpl>::GetInstance().ResetService(remote);
|
||||
}
|
||||
|
||||
UpdateServiceKitsImpl::RemoteUpdateCallback::RemoteUpdateCallback(const UpdateCallbackInfo &cb)
|
||||
: UpdateCallback()
|
||||
{
|
||||
updateCallback_.checkNewVersionDone = cb.checkNewVersionDone;
|
||||
updateCallback_.downloadProgress = cb.downloadProgress;
|
||||
updateCallback_.upgradeProgress = cb.upgradeProgress;
|
||||
}
|
||||
|
||||
UpdateServiceKitsImpl::RemoteUpdateCallback::~RemoteUpdateCallback()
|
||||
{
|
||||
updateCallback_.checkNewVersionDone = nullptr;
|
||||
updateCallback_.downloadProgress = nullptr;
|
||||
updateCallback_.upgradeProgress = nullptr;
|
||||
}
|
||||
|
||||
void UpdateServiceKitsImpl::RemoteUpdateCallback::OnCheckVersionDone(const VersionInfo &info)
|
||||
{
|
||||
ENGINE_LOGE("OnCheckVersionDone VersionInfo status %d", info.status);
|
||||
ENGINE_LOGE("OnCheckVersionDone VersionInfo errMsg %s", info.errMsg.c_str());
|
||||
ENGINE_LOGE("OnCheckVersionDone VersionInfo versionName : %s", info.result[0].versionName.c_str());
|
||||
ENGINE_LOGE("OnCheckVersionDone VersionInfo versionCode : %s", info.result[0].versionCode.c_str());
|
||||
ENGINE_LOGE("OnCheckVersionDone VersionInfo verifyInfo : %s", info.result[0].verifyInfo.c_str());
|
||||
ENGINE_LOGE("OnCheckVersionDone VersionInfo size : %zu", info.result[0].size);
|
||||
if (updateCallback_.checkNewVersionDone != nullptr) {
|
||||
updateCallback_.checkNewVersionDone(info);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateServiceKitsImpl::RemoteUpdateCallback::OnDownloadProgress(const Progress &progress)
|
||||
{
|
||||
ENGINE_LOGE("OnDownloadProgress progress %u %d", progress.percent, progress.status);
|
||||
if (updateCallback_.downloadProgress != nullptr) {
|
||||
updateCallback_.downloadProgress(progress);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateServiceKitsImpl::RemoteUpdateCallback::OnUpgradeProgress(const Progress &progress)
|
||||
{
|
||||
ENGINE_LOGE("OnUpgradeProgress progress %u %d", progress.percent, progress.status);
|
||||
if (updateCallback_.upgradeProgress != nullptr) {
|
||||
updateCallback_.upgradeProgress(progress);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t UpdateServiceKitsImpl::RegisterUpdateCallback(const UpdateContext &ctx, const UpdateCallbackInfo &cb)
|
||||
{
|
||||
updateContext_.upgradeDevId = ctx.upgradeDevId;
|
||||
updateContext_.controlDevId = ctx.controlDevId;
|
||||
updateContext_.upgradeApp = ctx.upgradeApp;
|
||||
updateContext_.type = ctx.type;
|
||||
updateContext_.upgradeFile = ctx.upgradeFile;
|
||||
if (remoteUpdateCallback_ == nullptr) {
|
||||
remoteUpdateCallback_ = new RemoteUpdateCallback(cb);
|
||||
ENGINE_CHECK(remoteUpdateCallback_ != nullptr, return -1, "Failed to create remote callback");
|
||||
auto updateService = GetService();
|
||||
ENGINE_CHECK(updateService != nullptr, return -1, "Get updateService failed");
|
||||
updateService->RegisterUpdateCallback(ctx, remoteUpdateCallback_);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateServiceKitsImpl::UnregisterUpdateCallback()
|
||||
{
|
||||
delete remoteUpdateCallback_;
|
||||
remoteUpdateCallback_ = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t UpdateServiceKitsImpl::CheckNewVersion()
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceKitsImpl::CheckNewVersion");
|
||||
|
||||
auto updateService = GetService();
|
||||
ENGINE_CHECK(updateService != nullptr, return -1, "Get updateService failed");
|
||||
return updateService->CheckNewVersion();
|
||||
}
|
||||
|
||||
int32_t UpdateServiceKitsImpl::DownloadVersion()
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceKitsImpl::DownloadVersion");
|
||||
auto updateService = GetService();
|
||||
ENGINE_CHECK(updateService != nullptr, return -1, "Get updateService failed");
|
||||
return updateService->DownloadVersion();
|
||||
}
|
||||
|
||||
int32_t UpdateServiceKitsImpl::DoUpdate()
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceKitsImpl::DoUpdate");
|
||||
auto updateService = GetService();
|
||||
ENGINE_CHECK(updateService != nullptr, return -1, "Get updateService failed");
|
||||
return updateService->DoUpdate();
|
||||
}
|
||||
|
||||
int32_t UpdateServiceKitsImpl::GetNewVersion(VersionInfo &versionInfo)
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceKitsImpl::GetNewversion");
|
||||
auto updateService = GetService();
|
||||
ENGINE_CHECK(updateService != nullptr, return -1, "Get updateService failed");
|
||||
return updateService->GetNewVersion(versionInfo);
|
||||
}
|
||||
|
||||
int32_t UpdateServiceKitsImpl::GetUpgradeStatus(UpgradeInfo &info)
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceKitsImpl::GetUpgradeStatus");
|
||||
auto updateService = GetService();
|
||||
ENGINE_CHECK(updateService != nullptr, return -1, "Get updateService failed");
|
||||
return updateService->GetUpgradeStatus(info);
|
||||
}
|
||||
|
||||
int32_t UpdateServiceKitsImpl::SetUpdatePolicy(const UpdatePolicy &policy)
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceKitsImpl::SetUpdatePolicy");
|
||||
auto updateService = GetService();
|
||||
ENGINE_CHECK(updateService != nullptr, return -1, "Get updateService failed");
|
||||
return updateService->SetUpdatePolicy(policy);
|
||||
}
|
||||
|
||||
int32_t UpdateServiceKitsImpl::GetUpdatePolicy(UpdatePolicy &policy)
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceKitsImpl::GetUpdatePolicy");
|
||||
auto updateService = GetService();
|
||||
ENGINE_CHECK(updateService != nullptr, return -1, "Get updateService failed");
|
||||
return updateService->GetUpdatePolicy(policy);
|
||||
}
|
||||
|
||||
int32_t UpdateServiceKitsImpl::Cancel(int32_t service)
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceKitsImpl::Cancel %d", service);
|
||||
auto updateService = GetService();
|
||||
ENGINE_CHECK(updateService != nullptr, return -1, "Get updateService failed");
|
||||
return updateService->Cancel(service);
|
||||
}
|
||||
|
||||
int32_t UpdateServiceKitsImpl::RebootAndClean(const std::string &miscFile, const std::string &cmd)
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceKitsImpl::RebootAndCleanUserData");
|
||||
auto updateService = GetService();
|
||||
ENGINE_CHECK(updateService != nullptr, return -1, "Get updateService failed");
|
||||
return updateService->RebootAndClean(miscFile, cmd);
|
||||
}
|
||||
|
||||
int32_t UpdateServiceKitsImpl::RebootAndInstall(const std::string &miscFile, const std::string &packageName)
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceKitsImpl::RebootAndInstall");
|
||||
auto updateService = GetService();
|
||||
ENGINE_CHECK(updateService != nullptr, return -1, "Get updateService failed");
|
||||
return updateService->RebootAndInstall(miscFile, packageName);
|
||||
}
|
||||
}
|
||||
} // namespace OHOS
|
||||
+213
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* 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 "update_service_proxy.h"
|
||||
#include "update_helper.h"
|
||||
#include "securec.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
int32_t UpdateServiceProxy::RegisterUpdateCallback(const UpdateContext &ctx,
|
||||
const sptr<IUpdateCallback>& updateCallback)
|
||||
{
|
||||
ENGINE_CHECK(updateCallback != nullptr, return ERR_INVALID_VALUE, "Invalid param");
|
||||
ENGINE_LOGI("UpdateServiceProxy::RegisterUpdateCallback");
|
||||
|
||||
auto remote = Remote();
|
||||
ENGINE_CHECK(remote != nullptr, return ERR_FLATTEN_OBJECT, "Can not get remote");
|
||||
|
||||
MessageParcel data;
|
||||
UpdateHelper::WriteUpdateContext(data, ctx);
|
||||
bool ret = data.WriteRemoteObject(updateCallback->AsObject());
|
||||
ENGINE_CHECK(ret, return ERR_FLATTEN_OBJECT, "Can not get remote");
|
||||
MessageParcel reply;
|
||||
MessageOption option { MessageOption::TF_SYNC };
|
||||
int32_t res = remote->SendRequest(REGISTER_CALLBACK, data, reply, option);
|
||||
ENGINE_CHECK(res == ERR_OK, return ERR_FLATTEN_OBJECT, "Transact error");
|
||||
return reply.ReadInt32();
|
||||
}
|
||||
|
||||
int32_t UpdateServiceProxy::UnregisterUpdateCallback()
|
||||
{
|
||||
auto remote = Remote();
|
||||
ENGINE_CHECK(remote != nullptr, return ERR_FLATTEN_OBJECT, "Can not get remote");
|
||||
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option { MessageOption::TF_SYNC };
|
||||
int32_t res = remote->SendRequest(UNREGISTER_CALLBACK, data, reply, option);
|
||||
ENGINE_CHECK(res == ERR_OK, return ERR_FLATTEN_OBJECT, "Transact error");
|
||||
return reply.ReadInt32();
|
||||
}
|
||||
|
||||
int32_t UpdateServiceProxy::CheckNewVersion()
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceProxy::CheckNewVersion");
|
||||
auto remote = Remote();
|
||||
ENGINE_CHECK(remote != nullptr, return ERR_FLATTEN_OBJECT, "Can not get remote");
|
||||
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option(MessageOption::TF_SYNC);
|
||||
int32_t res = remote->SendRequest(CHECK_VERSION, data, reply, option);
|
||||
ENGINE_CHECK(res == ERR_OK, return ERR_FLATTEN_OBJECT, "Transact error");
|
||||
return reply.ReadInt32();
|
||||
}
|
||||
|
||||
int32_t UpdateServiceProxy::DownloadVersion()
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceProxy::DownloadVersion");
|
||||
auto remote = Remote();
|
||||
ENGINE_CHECK(remote != nullptr, return ERR_FLATTEN_OBJECT, "Can not get remote");
|
||||
|
||||
// Construct a data sending message to the stub.
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option(MessageOption::TF_ASYNC);
|
||||
int32_t ret = remote->SendRequest(DOWNLOAD, data, reply, option);
|
||||
ENGINE_CHECK(ret == ERR_OK, return ERR_FLATTEN_OBJECT, "Transact error");
|
||||
return reply.ReadInt32();
|
||||
}
|
||||
|
||||
int32_t UpdateServiceProxy::DoUpdate()
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceProxy::DoUpdate");
|
||||
auto remote = Remote();
|
||||
ENGINE_CHECK(remote != nullptr, return ERR_FLATTEN_OBJECT, "Can not get remote");
|
||||
|
||||
// Construct a data sending message to the stub.
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option(MessageOption::TF_ASYNC);
|
||||
int32_t ret = remote->SendRequest(UPGRADE, data, reply, option);
|
||||
ENGINE_CHECK(ret == ERR_OK, return ERR_FLATTEN_OBJECT, "Transact error");
|
||||
return reply.ReadInt32();
|
||||
}
|
||||
|
||||
int32_t UpdateServiceProxy::GetNewVersion(VersionInfo &versionInfo)
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceProxy::GetNewVersion");
|
||||
auto remote = Remote();
|
||||
ENGINE_CHECK(remote != nullptr, return ERR_FLATTEN_OBJECT, "Can not get remote");
|
||||
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option;
|
||||
int32_t ret = remote->SendRequest(GET_NEW_VERSION, data, reply, option);
|
||||
ENGINE_CHECK(ret == ERR_OK, return ERR_FLATTEN_OBJECT, "Transact error");
|
||||
|
||||
return UpdateHelper::ReadVersionInfo(reply, versionInfo);
|
||||
}
|
||||
|
||||
int32_t UpdateServiceProxy::GetUpgradeStatus(UpgradeInfo &info)
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceProxy::GetUpgradeStatus");
|
||||
auto remote = Remote();
|
||||
ENGINE_CHECK(remote != nullptr, return ERR_FLATTEN_OBJECT, "Can not get remote");
|
||||
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option;
|
||||
int32_t ret = remote->SendRequest(GET_STATUS, data, reply, option);
|
||||
ENGINE_CHECK(ret == ERR_OK, return ERR_FLATTEN_OBJECT, "Transact error");
|
||||
|
||||
return UpdateHelper::ReadUpgradeInfo(reply, info);
|
||||
}
|
||||
|
||||
int32_t UpdateServiceProxy::SetUpdatePolicy(const UpdatePolicy &policy)
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceProxy::SetUpdatePolicy");
|
||||
auto remote = Remote();
|
||||
ENGINE_CHECK(remote != nullptr, return ERR_FLATTEN_OBJECT, "Can not get remote");
|
||||
|
||||
MessageParcel data;
|
||||
UpdateHelper::WriteUpdatePolicy(data, policy);
|
||||
MessageParcel reply;
|
||||
MessageOption option;
|
||||
int32_t res = remote->SendRequest(SET_POLICY, data, reply, option);
|
||||
ENGINE_CHECK(res == ERR_OK, return ERR_FLATTEN_OBJECT, "Transact error");
|
||||
|
||||
int32_t result = 0;
|
||||
bool ret = reply.ReadInt32(result);
|
||||
ENGINE_CHECK(ret, return ERR_FLATTEN_OBJECT, "Failed to read length");
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t UpdateServiceProxy::GetUpdatePolicy(UpdatePolicy &policy)
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceProxy::GetUpdatePolicy");
|
||||
auto remote = Remote();
|
||||
ENGINE_CHECK(remote != nullptr, return ERR_FLATTEN_OBJECT, "Can not get remote");
|
||||
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option;
|
||||
int32_t ret = remote->SendRequest(GET_POLICY, data, reply, option);
|
||||
ENGINE_CHECK(ret == ERR_OK, return ERR_FLATTEN_OBJECT, "Transact error");
|
||||
return UpdateHelper::ReadUpdatePolicy(reply, policy);
|
||||
}
|
||||
|
||||
int32_t UpdateServiceProxy::Cancel(int32_t service)
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceProxy::Cancel");
|
||||
auto remote = Remote();
|
||||
ENGINE_CHECK(remote != nullptr, return ERR_FLATTEN_OBJECT, "Can not get remote");
|
||||
|
||||
MessageParcel data;
|
||||
data.WriteInt32(static_cast<int32_t>(service));
|
||||
MessageParcel reply;
|
||||
MessageOption option;
|
||||
int32_t res = remote->SendRequest(CANCEL, data, reply, option);
|
||||
ENGINE_CHECK(res == ERR_OK, return ERR_FLATTEN_OBJECT, "Transact error res %d", res);
|
||||
|
||||
int32_t result = -1;
|
||||
bool ret = reply.ReadInt32(result);
|
||||
ENGINE_CHECK(ret, return ERR_FLATTEN_OBJECT, "Failed to read result");
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t UpdateServiceProxy::RebootAndClean(const std::string &miscFile, const std::string &cmd)
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceProxy::RebootAndCleanUserData");
|
||||
auto remote = Remote();
|
||||
ENGINE_CHECK(remote != nullptr, return ERR_FLATTEN_OBJECT, "Can not get remote");
|
||||
|
||||
MessageParcel data;
|
||||
data.WriteString16(Str8ToStr16(miscFile));
|
||||
data.WriteString16(Str8ToStr16(cmd));
|
||||
MessageParcel reply;
|
||||
MessageOption option;
|
||||
int32_t ret = remote->SendRequest(REBOOT_CLEAN, data, reply, option);
|
||||
ENGINE_CHECK(ret == ERR_OK, return ERR_FLATTEN_OBJECT, "Transact error");
|
||||
return reply.ReadInt32();
|
||||
}
|
||||
|
||||
int32_t UpdateServiceProxy::RebootAndInstall(const std::string &miscFile, const std::string &packageName)
|
||||
{
|
||||
ENGINE_LOGI("UpdateServiceProxy::RebootAndCleanUserData");
|
||||
auto remote = Remote();
|
||||
ENGINE_CHECK(remote != nullptr, return ERR_FLATTEN_OBJECT, "Can not get remote");
|
||||
|
||||
MessageParcel data;
|
||||
data.WriteString16(Str8ToStr16(miscFile));
|
||||
data.WriteString16(Str8ToStr16(packageName));
|
||||
MessageParcel reply;
|
||||
MessageOption option;
|
||||
int32_t ret = remote->SendRequest(REBOOT_INSTALL, data, reply, option);
|
||||
ENGINE_CHECK(ret == ERR_OK, return ERR_FLATTEN_OBJECT, "Transact error");
|
||||
return reply.ReadInt32();
|
||||
}
|
||||
}
|
||||
} // namespace OHOS
|
||||
+45
@@ -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 IUPDATER_CALLBACK_H
|
||||
#define IUPDATER_CALLBACK_H
|
||||
|
||||
#include <iostream>
|
||||
#include "update_helper.h"
|
||||
#include "iremote_broker.h"
|
||||
#include "iremote_proxy.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
class IUpdateCallback : public OHOS::IRemoteBroker {
|
||||
public:
|
||||
virtual ~IUpdateCallback() = default;
|
||||
enum {
|
||||
CHECK_VERSION = 1,
|
||||
DOWNLOAD,
|
||||
UPGRADE,
|
||||
};
|
||||
|
||||
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.Update.IUpdateCallback");
|
||||
public:
|
||||
virtual void OnCheckVersionDone(const VersionInfo &info) = 0;
|
||||
|
||||
virtual void OnDownloadProgress(const Progress &progress) = 0;
|
||||
|
||||
virtual void OnUpgradeProgress(const Progress &progress) = 0;
|
||||
};
|
||||
} // namespace update_engine
|
||||
} // namespace OHOS
|
||||
#endif // IUPDATER_CALLBACK_H
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef IUPDATER_SERVICE_H
|
||||
#define IUPDATER_SERVICE_H
|
||||
|
||||
#include <iostream>
|
||||
#include "update_helper.h"
|
||||
#include "iremote_broker.h"
|
||||
#include "iremote_proxy.h"
|
||||
#include "iupdate_callback.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
class IUpdateService : public OHOS::IRemoteBroker {
|
||||
public:
|
||||
enum {
|
||||
CHECK_VERSION = 1,
|
||||
DOWNLOAD,
|
||||
UPGRADE,
|
||||
SET_POLICY,
|
||||
GET_POLICY,
|
||||
GET_NEW_VERSION,
|
||||
GET_STATUS,
|
||||
REGISTER_CALLBACK,
|
||||
UNREGISTER_CALLBACK,
|
||||
CANCEL,
|
||||
REBOOT_CLEAN,
|
||||
REBOOT_INSTALL,
|
||||
VERIFY_PACKAGE
|
||||
};
|
||||
|
||||
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.Updater.IUpdateService");
|
||||
public:
|
||||
virtual int32_t RegisterUpdateCallback(const UpdateContext &ctx, const sptr<IUpdateCallback>& updateCallback) = 0;
|
||||
|
||||
virtual int32_t UnregisterUpdateCallback() = 0;
|
||||
|
||||
virtual int32_t CheckNewVersion() = 0;
|
||||
|
||||
virtual int32_t DownloadVersion() = 0;
|
||||
|
||||
virtual int32_t DoUpdate() = 0;
|
||||
|
||||
virtual int32_t GetNewVersion(VersionInfo &versionInfo) = 0;
|
||||
|
||||
virtual int32_t GetUpgradeStatus (UpgradeInfo &info) = 0;
|
||||
|
||||
virtual int32_t SetUpdatePolicy(const UpdatePolicy &policy) = 0;
|
||||
|
||||
virtual int32_t GetUpdatePolicy(UpdatePolicy &policy) = 0;
|
||||
|
||||
virtual int32_t Cancel(int32_t service) = 0;
|
||||
|
||||
virtual int32_t RebootAndClean(const std::string &miscFile, const std::string &cmd) = 0;
|
||||
|
||||
virtual int32_t RebootAndInstall(const std::string &miscFile, const std::string &packageName) = 0;
|
||||
};
|
||||
} // namespace update_engine
|
||||
} // namespace OHOS
|
||||
#endif // IUPDATER_SERVICE_H
|
||||
Executable
+220
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* 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 UPDATER_HELPER_H
|
||||
#define UPDATER_HELPER_H
|
||||
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <ipc_types.h>
|
||||
#include <string_ex.h>
|
||||
#include "parcel.h"
|
||||
#include "message_parcel.h"
|
||||
#include "hilog/log.h"
|
||||
#include "system_ability_definition.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
// 搜索状态
|
||||
enum SearchStatus {
|
||||
SYSTEM_ERROR = -1,
|
||||
HAS_NEW_VERSION,
|
||||
NO_NEW_VERSION,
|
||||
SERVER_BUSY,
|
||||
};
|
||||
|
||||
enum UpgradeStatus {
|
||||
UPDATE_STATE_INIT = 0,
|
||||
UPDATE_STATE_CHECK_VERSION_ON = 10,
|
||||
UPDATE_STATE_CHECK_VERSION_FAIL,
|
||||
UPDATE_STATE_CHECK_VERSION_SUCCESS,
|
||||
UPDATE_STATE_DOWNLOAD_ON = 20,
|
||||
UPDATE_STATE_DOWNLOAD_PAUSE,
|
||||
UPDATE_STATE_DOWNLOAD_CANCEL,
|
||||
UPDATE_STATE_DOWNLOAD_FAIL,
|
||||
UPDATE_STATE_DOWNLOAD_SUCCESS,
|
||||
UPDATE_STATE_VERIFY_ON = 30,
|
||||
UPDATE_STATE_VERIFY_FAIL,
|
||||
UPDATE_STATE_VERIFY_SUCCESS,
|
||||
UPDATE_STATE_PACKAGE_TRANS_ON = 70,
|
||||
UPDATE_STATE_PACKAGE_TRANS_FAIL,
|
||||
UPDATE_STATE_PACKAGE_TRANS_SUCCESS,
|
||||
UPDATE_STATE_INSTALL_ON = 80,
|
||||
UPDATE_STATE_INSTALL_FAIL,
|
||||
UPDATE_STATE_INSTALL_SUCCESS,
|
||||
UPDATE_STATE_UPDATE_ON = 90,
|
||||
UPDATE_STATE_UPDATE_FAIL,
|
||||
UPDATE_STATE_UPDATE_SUCCESS
|
||||
};
|
||||
|
||||
enum PackageType {
|
||||
PACKAGE_TYPE_NORMAL = 1,
|
||||
PACKAGE_TYPE_BASE = 2,
|
||||
PACKAGE_TYPE_CUST = 3,
|
||||
PACKAGE_TYPE_PRELOAD = 4,
|
||||
PACKAGE_TYPE_COTA = 5,
|
||||
PACKAGE_TYPE_VERSION = 6,
|
||||
PACKAGE_TYPE_PATCH = 7
|
||||
};
|
||||
|
||||
struct UpdateContext {
|
||||
std::string upgradeDevId;
|
||||
std::string controlDevId;
|
||||
std::string upgradeApp;
|
||||
std::string upgradeFile;
|
||||
std::string type;
|
||||
};
|
||||
|
||||
struct DescriptInfo {
|
||||
std::string descriptPackageId;
|
||||
std::string content;
|
||||
};
|
||||
|
||||
struct CheckResult {
|
||||
size_t size;
|
||||
PackageType packageType;
|
||||
std::string versionName;
|
||||
std::string versionCode;
|
||||
std::string verifyInfo;
|
||||
std::string descriptPackageId;
|
||||
};
|
||||
|
||||
struct VersionInfo {
|
||||
SearchStatus status;
|
||||
std::string errMsg;
|
||||
CheckResult result[2];
|
||||
DescriptInfo descriptInfo[2];
|
||||
};
|
||||
|
||||
struct Progress {
|
||||
uint32_t percent;
|
||||
UpgradeStatus status;
|
||||
std::string endReason;
|
||||
};
|
||||
|
||||
struct UpgradeInfo {
|
||||
UpgradeStatus status;
|
||||
};
|
||||
|
||||
enum InstallMode {
|
||||
INSTALLMODE_NORMAL = 0,
|
||||
INSTALLMODE_NIGHT,
|
||||
INSTALLMODE_AUTO
|
||||
};
|
||||
|
||||
enum AutoUpgradeCondition {
|
||||
AUTOUPGRADECONDITION_IDLE = 0,
|
||||
};
|
||||
|
||||
struct UpdatePolicy {
|
||||
bool autoDownload;
|
||||
bool autoDownloadNet;
|
||||
InstallMode mode;
|
||||
AutoUpgradeCondition autoUpgradeCondition;
|
||||
uint32_t autoUpgradeInterval[2];
|
||||
};
|
||||
|
||||
using CheckNewVersionDone = std::function<void(const VersionInfo &info)>;
|
||||
using DownloadProgress = std::function<void(const Progress &progress)>;
|
||||
using UpgradeProgress = std::function<void(const Progress &progress)>;
|
||||
|
||||
// 回调函数
|
||||
struct UpdateCallbackInfo {
|
||||
CheckNewVersionDone checkNewVersionDone;
|
||||
DownloadProgress downloadProgress;
|
||||
UpgradeProgress upgradeProgress;
|
||||
};
|
||||
|
||||
#ifdef UPDATE_SERVICE
|
||||
static constexpr OHOS::HiviewDFX::HiLogLabel UPDATE_LABEL = {LOG_CORE, 0, "UPDATE_SA"};
|
||||
#else
|
||||
static constexpr OHOS::HiviewDFX::HiLogLabel UPDATE_LABEL = {LOG_CORE, 0, "UPDATE_KITS"};
|
||||
#endif
|
||||
|
||||
enum class UpdateLogLevel {
|
||||
UPDATE_DEBUG = 0,
|
||||
UPDATE_INFO,
|
||||
UPDATE_WARN,
|
||||
UPDATE_ERROR,
|
||||
UPDATE_FATAL
|
||||
};
|
||||
|
||||
class UpdateHelper {
|
||||
public:
|
||||
static int32_t WriteUpdateContext(MessageParcel &data, const UpdateContext &info);
|
||||
static int32_t ReadUpdateContext(MessageParcel &reply, UpdateContext &info);
|
||||
|
||||
static int32_t ReadVersionInfo(MessageParcel &reply, VersionInfo &info);
|
||||
static int32_t WriteVersionInfo(MessageParcel &data, const VersionInfo &info);
|
||||
|
||||
static int32_t WriteUpdatePolicy(MessageParcel &data, const UpdatePolicy &policy);
|
||||
static int32_t ReadUpdatePolicy(MessageParcel &reply, UpdatePolicy &policy);
|
||||
|
||||
static int32_t ReadUpgradeInfo(MessageParcel &reply, UpgradeInfo &info);
|
||||
static int32_t WriteUpgradeInfo(MessageParcel &reply, const UpgradeInfo &info);
|
||||
|
||||
static int32_t ReadUpdateProgress(MessageParcel &reply, Progress &info);
|
||||
static int32_t WriteUpdateProgress(MessageParcel &data, const Progress &info);
|
||||
|
||||
static int32_t CopyVersionInfo(const VersionInfo &srcInfo, VersionInfo &dstInfo);
|
||||
static int32_t CopyUpdatePolicy(const UpdatePolicy &srcInfo, UpdatePolicy &dstInfo);
|
||||
|
||||
static std::vector<uint8_t> HexToDegist(const std::string &str);
|
||||
static int32_t CompareVersion(const std::string &version1, const std::string &version2);
|
||||
static std::vector<std::string> SplitString(const std::string &str, const std::string &delimiter);
|
||||
|
||||
static void Logger(const std::string &fileName, int32_t line, const char *format, ...);
|
||||
|
||||
static bool JudgeLevel(const UpdateLogLevel& level);
|
||||
|
||||
static void SetLogLevel(const UpdateLogLevel& level)
|
||||
{
|
||||
level_ = level;
|
||||
}
|
||||
|
||||
static const UpdateLogLevel& GetLogLevel()
|
||||
{
|
||||
return level_;
|
||||
}
|
||||
|
||||
static std::string GetBriefFileName(const std::string &file);
|
||||
|
||||
private:
|
||||
static UpdateLogLevel level_;
|
||||
};
|
||||
|
||||
// 暂时记录两边日志
|
||||
#define PRINT_LOG(LEVEL, Level, fmt, ...) \
|
||||
UpdateHelper::Logger(__FILE__, (__LINE__), fmt, ##__VA_ARGS__); \
|
||||
if (UpdateHelper::JudgeLevel(UpdateLogLevel::LEVEL)) \
|
||||
OHOS::HiviewDFX::HiLog::Level(UPDATE_LABEL, "[%{public}s(%{public}d)] " fmt, \
|
||||
UpdateHelper::GetBriefFileName(std::string(__FILE__)).c_str(), __LINE__, ##__VA_ARGS__)
|
||||
|
||||
#define ENGINE_LOGI(fmt, ...) PRINT_LOG(UPDATE_INFO, Info, fmt, ##__VA_ARGS__)
|
||||
#define ENGINE_LOGE(fmt, ...) PRINT_LOG(UPDATE_ERROR, Error, fmt, ##__VA_ARGS__)
|
||||
|
||||
#define ENGINE_CHECK(retCode, exper, ...) \
|
||||
do { \
|
||||
if (!(retCode)) { \
|
||||
ENGINE_LOGE(__VA_ARGS__); \
|
||||
exper; \
|
||||
} \
|
||||
} while (0)
|
||||
}
|
||||
} // namespace OHOS
|
||||
#endif // UPDATER_HELPER_H
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef UPDATER_SERVICE_KITS_H
|
||||
#define UPDATER_SERVICE_KITS_H
|
||||
|
||||
#include <iostream>
|
||||
#include "iupdate_service.h"
|
||||
#include "update_helper.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
class UpdateServiceKits {
|
||||
public:
|
||||
UpdateServiceKits() = default;
|
||||
virtual ~UpdateServiceKits() = default;
|
||||
DISALLOW_COPY_AND_MOVE(UpdateServiceKits);
|
||||
|
||||
/**
|
||||
* Get instance of ohos account manager.
|
||||
*
|
||||
* @return Instance of ohos account manager.
|
||||
*/
|
||||
static UpdateServiceKits& GetInstance();
|
||||
|
||||
virtual int32_t RegisterUpdateCallback(const UpdateContext &ctx, const UpdateCallbackInfo &cb) = 0;
|
||||
|
||||
virtual int32_t UnregisterUpdateCallback() = 0;
|
||||
|
||||
virtual int32_t CheckNewVersion() = 0;
|
||||
|
||||
virtual int32_t DownloadVersion() = 0;
|
||||
|
||||
virtual int32_t DoUpdate() = 0;
|
||||
|
||||
virtual int32_t GetNewVersion(VersionInfo &versionInfo) = 0;
|
||||
|
||||
virtual int32_t GetUpgradeStatus (UpgradeInfo &info) = 0;
|
||||
|
||||
virtual int32_t SetUpdatePolicy(const UpdatePolicy &policy) = 0;
|
||||
|
||||
virtual int32_t GetUpdatePolicy(UpdatePolicy &policy) = 0;
|
||||
|
||||
virtual int32_t Cancel(int32_t service) = 0;
|
||||
|
||||
virtual int32_t RebootAndClean(const std::string &miscFile, const std::string &cmd) = 0;
|
||||
|
||||
virtual int32_t RebootAndInstall(const std::string &miscFile, const std::string &packageName) = 0;
|
||||
};
|
||||
} // namespace update_engine
|
||||
} // namespace OHOS
|
||||
#endif // UPDATER_SERVICE_KITS_H
|
||||
+96
@@ -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.
|
||||
*/
|
||||
|
||||
#ifndef UPDATER_SERVICE_KITS_IMPL_H
|
||||
#define UPDATER_SERVICE_KITS_IMPL_H
|
||||
|
||||
#include "update_service_kits.h"
|
||||
#include "update_helper.h"
|
||||
#include "singleton.h"
|
||||
#include "iupdate_callback.h"
|
||||
#include "update_callback.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace update_engine {
|
||||
class UpdateServiceKitsImpl final : public UpdateServiceKits,
|
||||
public DelayedRefSingleton<UpdateServiceKitsImpl> {
|
||||
DECLARE_DELAYED_REF_SINGLETON(UpdateServiceKitsImpl);
|
||||
public:
|
||||
DISALLOW_COPY_AND_MOVE(UpdateServiceKitsImpl);
|
||||
|
||||
int32_t RegisterUpdateCallback(const UpdateContext &ctx, const UpdateCallbackInfo &cb) final;
|
||||
|
||||
int32_t UnregisterUpdateCallback() final;
|
||||
|
||||
int32_t CheckNewVersion() final;
|
||||
|
||||
int32_t DownloadVersion() final;
|
||||
|
||||
int32_t DoUpdate() final;
|
||||
|
||||
int32_t GetNewVersion(VersionInfo &versionInfo) final;
|
||||
|
||||
int32_t GetUpgradeStatus(UpgradeInfo &info) final;
|
||||
|
||||
int32_t SetUpdatePolicy(const UpdatePolicy &policy) final;
|
||||
|
||||
int32_t GetUpdatePolicy(UpdatePolicy &policy) final;
|
||||
|
||||
int32_t Cancel(int32_t service);
|
||||
|
||||
int32_t RebootAndClean(const std::string &miscFile, const std::string &cmd) final;
|
||||
|
||||
int32_t RebootAndInstall(const std::string &miscFile, const std::string &packageName) final;
|
||||
#ifndef UPDATER_UT
|
||||
private:
|
||||
#else
|
||||
public:
|
||||
#endif
|
||||
// For call event procession
|
||||
class RemoteUpdateCallback final : public UpdateCallback {
|
||||
public:
|
||||
RemoteUpdateCallback(const UpdateCallbackInfo &cb);
|
||||
~RemoteUpdateCallback();
|
||||
|
||||
DISALLOW_COPY_AND_MOVE(RemoteUpdateCallback);
|
||||
|
||||
void OnCheckVersionDone(const VersionInfo &info) final;
|
||||
|
||||
void OnDownloadProgress(const Progress &progress) final;
|
||||
|
||||
void OnUpgradeProgress(const Progress &progress) final;
|
||||
private:
|
||||
UpdateCallbackInfo updateCallback_ {};
|
||||
};
|
||||
|
||||
// For death event procession
|
||||
class DeathRecipient final : public IRemoteObject::DeathRecipient {
|
||||
public:
|
||||
DeathRecipient() = default;
|
||||
~DeathRecipient() final = default;
|
||||
DISALLOW_COPY_AND_MOVE(DeathRecipient);
|
||||
void OnRemoteDied(const wptr<IRemoteObject>& remote) final;
|
||||
};
|
||||
void ResetService(const wptr<IRemoteObject>& remote);
|
||||
sptr<IUpdateService> GetService();
|
||||
std::mutex updateServiceLock_;
|
||||
sptr<IUpdateService> updateService_ {};
|
||||
sptr<IRemoteObject::DeathRecipient> deathRecipient_ {};
|
||||
sptr<IUpdateCallback> remoteUpdateCallback_ {};
|
||||
UpdateContext updateContext_ {};
|
||||
};
|
||||
} // namespace update_engine
|
||||
} // namespace OHOS
|
||||
#endif // UPDATER_SERVICE_KITS_IMPL_H
|
||||
+439
@@ -0,0 +1,439 @@
|
||||
/*
|
||||
* 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 { AsyncCallback, BussinessError } from "./basic";
|
||||
|
||||
/**
|
||||
* A static class to do update for device.
|
||||
*
|
||||
* @devices all
|
||||
* @since 6
|
||||
* @Syscap SystemCapability.Updater.Raw
|
||||
*/
|
||||
declare namespace update {
|
||||
/**
|
||||
* Enumerates new version package types.
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
export enum PackageTypes {
|
||||
PACKAGE_TYPE_NORMAL = 1,
|
||||
PACKAGE_TYPE_BASE = 2,
|
||||
PACKAGE_TYPE_CUST = 3,
|
||||
PACKAGE_TYPE_PRELOAD = 4,
|
||||
PACKAGE_TYPE_COTA = 5,
|
||||
PACKAGE_TYPE_VERSION = 6,
|
||||
PACKAGE_TYPE_PATCH = 7
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents new version results after update version check.
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
export interface CheckResult {
|
||||
/**
|
||||
* New version name
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
versionName: number;
|
||||
|
||||
/**
|
||||
* New version code
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
versionCode: string;
|
||||
|
||||
/**
|
||||
* New version package size
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
size: number;
|
||||
|
||||
/**
|
||||
* New version verify information
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
verifyInfo: string;
|
||||
|
||||
/**
|
||||
* New version package type
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
packageType: PackageTypes;
|
||||
|
||||
/**
|
||||
* New version description ID
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
descriptionId: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents new version description information.
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
export interface DescriptionInfo {
|
||||
/**
|
||||
* description ID
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
descriptionId: string;
|
||||
|
||||
/**
|
||||
* description content
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
content: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerates new version status.
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
export enum NewVersionStatus {
|
||||
/**
|
||||
* New version check with system error
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
VERSION_STATUS_ERR = -1,
|
||||
|
||||
/**
|
||||
* New version detected
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
VERSION_STATUS_NEW = 0,
|
||||
|
||||
/**
|
||||
* No New version
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
VERSION_STATUS_NONE = 1,
|
||||
|
||||
/**
|
||||
* Server busy
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
VERSION_STATUS_BUSY = 2
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents new version information.
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
export interface NewVersionInfo {
|
||||
/**
|
||||
* Update Check Status
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
status: NewVersionStatus;
|
||||
|
||||
/**
|
||||
* New version check error message
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
errMsg: string;
|
||||
|
||||
/**
|
||||
* New version check results
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
checkResults: Array<CheckResult>;
|
||||
|
||||
/**
|
||||
* New version check description
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
descriptionInfo: Array<DescriptionInfo>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerates update status.
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
export enum UpdateState {
|
||||
UPDATE_STATE_INIT = 0,
|
||||
UPDATE_STATE_CHECK_VERSION_ON = 10,
|
||||
UPDATE_STATE_CHECK_VERSION_FAIL,
|
||||
UPDATE_STATE_CHECK_VERSION_SUCCESS,
|
||||
UPDATE_STATE_DOWNLOAD_ON = 20,
|
||||
UPDATE_STATE_DOWNLOAD_PAUSE,
|
||||
UPDATE_STATE_DOWNLOAD_CANCEL,
|
||||
UPDATE_STATE_DOWNLOAD_FAIL,
|
||||
UPDATE_STATE_DOWNLOAD_SUCCESS,
|
||||
UPDATE_STATE_VERIFY_ON = 30,
|
||||
UPDATE_STATE_VERIFY_FAIL,
|
||||
UPDATE_STATE_VERIFY_SUCCESS,
|
||||
UPDATE_STATE_PACKAGE_TRANS_ON = 70,
|
||||
UPDATE_STATE_PACKAGE_TRANS_FAIL,
|
||||
UPDATE_STATE_PACKAGE_TRANS_SUCCESS,
|
||||
UPDATE_STATE_INSTALL_ON = 80,
|
||||
UPDATE_STATE_INSTALL_FAIL,
|
||||
UPDATE_STATE_INSTALL_SUCCESS,
|
||||
UPDATE_STATE_UPDATE_ON = 90,
|
||||
UPDATE_STATE_UPDATE_FAIL,
|
||||
UPDATE_STATE_UPDATE_SUCCESS
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents update progress information.
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
export interface Progress {
|
||||
/**
|
||||
* update progress percent
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
percent: number;
|
||||
|
||||
/**
|
||||
* update status
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
status: UpdateState;
|
||||
|
||||
/**
|
||||
* update end reason
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
endReason: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerates install mode for new version packages.
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
export enum InstallMode {
|
||||
/**
|
||||
* Normal update.
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
INSTALL_MODE_NORMAL,
|
||||
|
||||
/**
|
||||
* Update at night
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
INSTALL_MODE_NIGHT,
|
||||
|
||||
/**
|
||||
* Auto update
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
INSTALL_MODE_AUTO
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents update policy.
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
export interface UpdatePolicy {
|
||||
/**
|
||||
* Enable auto download new packages or not
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
autoDownload: boolean;
|
||||
|
||||
/**
|
||||
* New packages auto installation mode
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
installMode: INSTALL_MODE;
|
||||
|
||||
/**
|
||||
* Auto installation time interval
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
autoUpgradeInterval: Array<number>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the signal status changes. You need to implement this method in a child class.
|
||||
* Unlike {@code onSignalStatus(status: number)}, a signal source is specified in this method.
|
||||
*
|
||||
* @param status Indicates the signal status.
|
||||
* The value {@code 0} indicates that the signal is stable,
|
||||
* {@code 1} indicates that no signal is available,
|
||||
* {@code 2} indicates that the signal is not supported,
|
||||
* and {@code 3} indicates that the signal is unstable.
|
||||
* @param source Indicates the signal source. For details about available values,
|
||||
* see {@link @system.tv.SourceIndices}.
|
||||
* @since 6
|
||||
*/
|
||||
export interface UpdateProgressCallback {
|
||||
(progress: Progress): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* A static class to do update for the specified device.
|
||||
*
|
||||
* @devices all
|
||||
* @since 6
|
||||
* @Syscap SystemCapability.Updater.Raw
|
||||
*/
|
||||
export interface Updater {
|
||||
/**
|
||||
* Check new version.
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
checkNewVersion(callback: AsyncCallback<NewVersionInfo>): void;
|
||||
checkNewVersion(): Promise<NewVersionInfo>;
|
||||
|
||||
/**
|
||||
* Trigger download new version packages.
|
||||
* apps should listen to downloadProgress event
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
download(): void;
|
||||
|
||||
/**
|
||||
* Install packages for the device.
|
||||
* apps should listen to upgradeProgress event
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
upgrade(): void;
|
||||
|
||||
/**
|
||||
* Get new version information for the newly installed package.
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
getNewVersionInfo(callback: AsyncCallback<NewVersionInfo>): void;
|
||||
getNewVersionInfo(): Promise<NewVersionInfo>;
|
||||
|
||||
/**
|
||||
* Get current update policy.
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
getUpdatePolicy(callback: AsyncCallback<UpdatePolicy>): void;
|
||||
getUpdatePolicy(): Promise<UpdatePolicy>;
|
||||
|
||||
/**
|
||||
* Set update policy.
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
setUpdatePolicy(policy: UpdatePolicy, callback: AsyncCallback<number>): void;
|
||||
setUpdatePolicy(policy: UpdatePolicy): Promise<number>;
|
||||
|
||||
/**
|
||||
* Reboot to apply upgrade package.
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
applyNewVersion(callback: AsyncCallback<number>): void;
|
||||
applyNewVersion(): Promise<number>;
|
||||
|
||||
/**
|
||||
* Reboot to clean cache.
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
rebootAndCleanCache(callback: AsyncCallback<number>): void;
|
||||
rebootAndCleanCache(): Promise<number>;
|
||||
|
||||
/**
|
||||
* verify update package.
|
||||
* apps should listen to verifyProgress event
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
verifyUpdatePackage(upgradeFile: string, certsFile: string): void;
|
||||
|
||||
/**
|
||||
* Subscribe to download/upgrade/verify progress events
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
on(eventType: 'downloadProgress', callback: UpdateProgressCallback): void;
|
||||
on(eventType: 'upgradeProgress', callback: UpdateProgressCallback): void;
|
||||
on(eventType: 'verifyProgress', callback: UpdateProgressCallback): void;
|
||||
|
||||
/**
|
||||
* Unsubscribe to download/upgrade/verify progress events
|
||||
*
|
||||
* @since 6
|
||||
*/
|
||||
off(eventType: 'downloadProgress', callback?: UpdateProgressCallback): void;
|
||||
off(eventType: 'upgradeProgress', callback?: UpdateProgressCallback): void;
|
||||
off(eventType: 'verifyProgress', callback?: UpdateProgressCallback): void;
|
||||
}
|
||||
|
||||
export type UpdateTypes =
|
||||
'OTA' |
|
||||
'patch';
|
||||
|
||||
/**
|
||||
* Get Updater handler for the calling device.
|
||||
*
|
||||
* @return Updater handler to perform actual update
|
||||
* @since 6
|
||||
*/
|
||||
function getUpdater(upgradeFile: string, updateType?: UpdateTypes): Updater;
|
||||
|
||||
/**
|
||||
* Get Updater handler for the specified device.
|
||||
*
|
||||
* @return Updater handler to perform actual update
|
||||
* @since 6
|
||||
*/
|
||||
function getUpdaterForOther(upgradeFile: string, device: string, updateType?: UpdateTypes): Updater;
|
||||
|
||||
/**
|
||||
* Get Updater handler from other device to trigger update for the calling device.
|
||||
*
|
||||
* @return Updater handler to perform actual update
|
||||
* @since 6
|
||||
*/
|
||||
function getUpdaterFromOther(upgradeFile: string, device: string, updateType?: UpdateTypes): Updater;
|
||||
}
|
||||
|
||||
export default update;
|
||||
Reference in New Issue
Block a user