update OpenHarmony 2.0 Canary

This commit is contained in:
mamingshuai
2021-06-02 00:04:26 +08:00
parent 96153d1a53
commit 73e015c4de
39 changed files with 5805 additions and 61 deletions
View File
+177
View File
@@ -0,0 +1,177 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
-36
View File
@@ -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/)
Regular → Executable
+147 -25
View File
@@ -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
View File
@@ -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
+43
View File
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef 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
+41
View File
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef 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
+33
View File
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef 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_)
+51
View File
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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
+76
View File
@@ -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
+53
View File
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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;
}
}
}
+65
View File
@@ -0,0 +1,65 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//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"
}
+910
View File
@@ -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
+241
View File
@@ -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
+278
View File
@@ -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);
}
}
+232
View File
@@ -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
+180
View File
@@ -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
+83
View File
@@ -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"
}
+17
View File
@@ -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>
+21
View File
@@ -0,0 +1,21 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
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
+109
View File
@@ -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
+101
View File
@@ -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
+56
View File
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef 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
+40
View File
@@ -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_
+24
View File
@@ -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>
+20
View File
@@ -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"
}
+208
View File
@@ -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
+289
View File
@@ -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(&currentTime));
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
+528
View File
@@ -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
+177
View File
@@ -0,0 +1,177 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "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
+64
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef 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
View File
@@ -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
+220
View File
@@ -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
View File
@@ -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
View File
@@ -0,0 +1,96 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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
View File
@@ -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;