1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef UPDATE_CLIENT_H 17 #define UPDATE_CLIENT_H 18 19 #include <functional> 20 #include <iostream> 21 #include <map> 22 #include <memory> 23 #include <mutex> 24 #include <string> 25 #include <vector> 26 27 #include "napi/native_api.h" 28 #include "napi/native_node_api.h" 29 #include "node_api.h" 30 #include "node_api_types.h" 31 #include "update_helper.h" 32 #include "update_service_kits.h" 33 34 static constexpr OHOS::HiviewDFX::HiLogLabel UPDATE_CLIENT = {LOG_CORE, 0, "UPDATE_CLIENT"}; 35 #define CLIENT_LOGE(format, ...) \ 36 OHOS::HiviewDFX::HiLog::Error(UPDATE_CLIENT, "[%{public}s(%{public}d)] " format, \ 37 OHOS::update_engine::UpdateHelper::GetBriefFileName(std::string(__FILE__)).c_str(), __LINE__, ##__VA_ARGS__) 38 39 #define CLIENT_LOGI(format, ...) \ 40 OHOS::HiviewDFX::HiLog::Info(UPDATE_CLIENT, "[%{public}s(%{public}d)] " format, \ 41 OHOS::update_engine::UpdateHelper::GetBriefFileName(std::string(__FILE__)).c_str(), __LINE__, ##__VA_ARGS__) 42 43 #define CLIENT_CHECK(retCode, exper, ...) \ 44 if (!(retCode)) { \ 45 CLIENT_LOGE(__VA_ARGS__); \ 46 exper; \ 47 } 48 49 #define CLIENT_CHECK_NAPI_CALL(env, assertion, exper, message) \ 50 if (!(assertion)) { \ 51 CLIENT_LOGE(message); \ 52 exper; \ 53 } 54 55 namespace updateClient { 56 // Update status 57 enum ClientStatus { 58 CLIENT_SUCCESS = 0, 59 CLIENT_INVALID_PARAM = 1000, 60 CLIENT_INVALID_TYPE, 61 CLIENT_REPEAT_REQ, 62 CLIENT_FAIL, 63 CLIENT_CHECK_NEW_FIRST, 64 }; 65 66 enum SessionType { 67 SESSION_CHECK_VERSION = 0, 68 SESSION_DOWNLOAD, 69 SESSION_UPGRADE, 70 SESSION_SET_POLICY, 71 SESSION_GET_POLICY, 72 SESSION_GET_NEW_VERSION, 73 SESSION_GET_STATUS, 74 SESSION_SUBSCRIBE, 75 SESSION_UNSUBSCRIBE, 76 SESSION_GET_UPDATER, 77 SESSION_APPLY_NEW_VERSION, 78 SESSION_REBOOT_AND_CLEAN, 79 SESSION_VERIFY_PACKAGE, 80 SESSION_CANCEL_UPGRADE, 81 SESSION_MAX 82 }; 83 84 struct UpdateResult { 85 using BuildJSObject = std::function<int(napi_env env, napi_value &obj, const UpdateResult &result)>; 86 int32_t type; 87 union { 88 OHOS::update_engine::UpdatePolicy *updatePolicy; 89 OHOS::update_engine::Progress *progress; 90 OHOS::update_engine::VersionInfo *versionInfo; 91 int32_t status; 92 } result; 93 94 BuildJSObject buildJSObject; 95 }; 96 97 98 class UpdateSession; 99 class UpdateClient { 100 public: 101 using DoWorkFunction = std::function<int(int32_t type, void *context)>; 102 103 UpdateClient(napi_env env, napi_value thisVar); 104 ~UpdateClient(); 105 106 // Obtain the updater engine and return it through the sync API. 107 napi_value GetUpdater(napi_env env, napi_callback_info info, int32_t index); 108 napi_value GetUpdaterForOther(napi_env env, napi_callback_info info); 109 napi_value GetUpdaterFromOther(napi_env env, napi_callback_info info); 110 111 // Asynchronous API 112 napi_value CheckNewVersion(napi_env env, napi_callback_info info); 113 napi_value SetUpdatePolicy(napi_env env, napi_callback_info info); 114 napi_value GetUpdatePolicy(napi_env env, napi_callback_info info); 115 napi_value GetNewVersionInfo(napi_env env, napi_callback_info info); 116 napi_value GetUpgradeStatus(napi_env env, napi_callback_info info); 117 napi_value ApplyNewVersion(napi_env env, napi_callback_info info); 118 napi_value RebootAndClean(napi_env env, napi_callback_info info); 119 120 // Event mode, which is used to send the result to the JS. 121 napi_value CancelUpgrade(napi_env env, napi_callback_info info); 122 napi_value DownloadVersion(napi_env env, napi_callback_info info); 123 napi_value UpgradeVersion(napi_env env, napi_callback_info info); 124 napi_value VerifyUpdatePackage(napi_env env, napi_callback_info info); 125 126 // Subscription 127 napi_value SubscribeEvent(napi_env env, napi_callback_info info); 128 napi_value UnsubscribeEvent(napi_env env, napi_callback_info info); 129 130 int32_t GetUpdateResult(int type, UpdateResult &result, int32_t &fail); 131 132 UpdateSession *RemoveSession(uint32_t sessionId); 133 void AddSession(std::shared_ptr<UpdateSession> session); 134 135 void PublishToJS(const std::string &type, int32_t retcode, const UpdateResult &result); 136 void Emit(const std::string &type, int32_t retcode, const UpdateResult &result); 137 138 static int32_t GetStringValue(napi_env env, napi_value arg, std::string &strValue); 139 static int32_t BuildErrorResult(napi_env env, napi_value &obj, int32_t result); 140 141 // Notify the session. 142 void NotifyCheckVersionDone(const OHOS::update_engine::VersionInfo &info); 143 void NotifyDownloadProgress(const OHOS::update_engine::Progress &progress); 144 void NotifyUpgradeProgresss(const OHOS::update_engine::Progress &progress); 145 void NotifyVerifyProgresss(int32_t retCode, uint32_t percent); 146 147 #ifdef UPDATER_UT GetUpdateSession(uint32_t sessId)148 UpdateSession *GetUpdateSession(uint32_t sessId) 149 { 150 #ifndef UPDATER_API_TEST 151 std::lock_guard<std::mutex> guard(sessionMutex_); 152 #endif 153 auto iter = sessions_.find(sessId); 154 if (iter != sessions_.end()) { 155 return iter->second.get(); 156 } 157 return nullptr; 158 } 159 #endif 160 private: 161 napi_value StartSession(napi_env env, 162 napi_callback_info info, int32_t type, size_t startIndex, DoWorkFunction function); 163 int32_t GetNewVersion(bool isCheck); 164 bool GetNextSessionId(uint32_t &sessionId); 165 bool GetFirstSessionId(uint32_t &sessionId); 166 bool CheckUpgradeType(const std::string &type); 167 bool CheckUpgradeFile(const std::string &upgradeFile); 168 int32_t ProcessUnsubscribe(const std::string &eventType, size_t argc, napi_value arg); 169 UpdateSession *FindSessionByHandle(napi_env env, const std::string &eventType, napi_value arg); 170 171 // Verify the version and parameters. 172 std::vector<uint8_t> HexToDegist(const std::string &str) const; 173 bool VerifyDownloadPkg(); 174 std::vector<std::string> SplitString(const std::string &str, const std::string &delimiter = ".") const; 175 int32_t CompareVersion(const std::string &version1, const std::string &version2) const; 176 177 int32_t GetUpdatePolicyFromArg(napi_env env, 178 const napi_value arg, OHOS::update_engine::UpdatePolicy &updatePolicy) const; 179 180 void GetEnginContext(OHOS::update_engine::UpdateContext &context) const; 181 void GetEnginPkgInfo(OHOS::update_engine::CheckResult &info) const; 182 183 // Parse input parameters. 184 static int32_t GetInt32(napi_env env, napi_value arg, const std::string &attrName, int32_t &intValue); 185 static int32_t GetInt64(napi_env env, napi_value arg, const std::string &attrName, int64_t &intValue); 186 static int32_t GetBool(napi_env env, napi_value arg, const std::string &attrName, bool &value); 187 188 static int32_t SetString(napi_env env, napi_value arg, const std::string &attrName, const std::string &string); 189 static int32_t SetInt32(napi_env env, napi_value arg, const std::string &attrName, int32_t intValue); 190 static int32_t SetInt64(napi_env env, napi_value arg, const std::string &attrName, int64_t intValue); 191 static int32_t SetBool(napi_env env, napi_value arg, const std::string &attrName, bool value); 192 193 // Construct output parameters. 194 static int32_t BuildCheckVersionResult(napi_env env, napi_value &obj, const UpdateResult &result); 195 static int32_t BuildProgress(napi_env env, napi_value &obj, const UpdateResult &result); 196 static int32_t BuildUpdatePolicy(napi_env env, napi_value &obj, const UpdateResult &result); 197 static int32_t BuildInt32Status(napi_env env, napi_value &obj, const UpdateResult &result); 198 private: 199 napi_env env_ {}; 200 napi_ref thisReference_ {}; 201 std::map<uint32_t, std::shared_ptr<UpdateSession>> sessions_ {}; 202 #ifndef UPDATER_API_TEST 203 std::mutex sessionMutex_; 204 #endif 205 bool isInit = false; 206 int32_t result_ = 0; 207 std::string upgradeFile_; 208 std::string certsFile_; 209 OHOS::update_engine::UpdateContext context_ {}; 210 OHOS::update_engine::UpdatePolicy updatePolicy_ {}; 211 OHOS::update_engine::Progress progress_ {}; 212 OHOS::update_engine::Progress verifyProgress_ {}; 213 OHOS::update_engine::VersionInfo versionInfo_ {}; 214 OHOS::update_engine::UpgradeInfo upgradeInfo_ {}; 215 }; 216 217 // Obtain the updater engine and return it through the synchronous API. 218 napi_value GetUpdater(napi_env env, napi_callback_info info); 219 napi_value GetUpdaterForOther(napi_env env, napi_callback_info info); 220 napi_value GetUpdaterFromOther(napi_env env, napi_callback_info info); 221 222 // Asynchronous API 223 napi_value CheckNewVersion(napi_env env, napi_callback_info info); 224 napi_value SetUpdatePolicy(napi_env env, napi_callback_info info); 225 napi_value GetUpdatePolicy(napi_env env, napi_callback_info info); 226 napi_value GetNewVersionInfo(napi_env env, napi_callback_info info); 227 napi_value GetUpgradeStatus(napi_env env, napi_callback_info info); 228 napi_value ApplyNewVersion(napi_env env, napi_callback_info info); 229 napi_value RebootAndClean(napi_env env, napi_callback_info info); 230 231 // Event mode, which is used to send the result to the JS. 232 napi_value CancelUpgrade(napi_env env, napi_callback_info info); 233 napi_value DownloadVersion(napi_env env, napi_callback_info info); 234 napi_value UpgradeVersion(napi_env env, napi_callback_info info); 235 napi_value VerifyUpdatePackage(napi_env env, napi_callback_info info); 236 237 napi_value SubscribeEvent(napi_env env, napi_callback_info info); 238 napi_value UnsubscribeEvent(napi_env env, napi_callback_info info); 239 240 #ifdef UPDATER_UT 241 napi_value UpdateClientInit(napi_env env, napi_value exports); 242 #endif 243 } // namespace updateClient 244 #endif // UPDATE_CLIENT_H