• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_SESSION_H
17 #define UPDATE_SESSION_H
18 
19 #include <condition_variable>
20 #include <memory>
21 #include <mutex>
22 #include <string>
23 #include <vector>
24 
25 #include "iupdater.h"
26 #include "iupdate_service.h"
27 #include "iupdate_session.h"
28 
29 namespace OHOS {
30 namespace UpdateEngine {
31 class UpdateSession : public IUpdateSession {
32 public:
33     UpdateSession(IUpdater *client, SessionParams &sessionParams, size_t argc, size_t callbackNumber);
34 
~UpdateSession()35     virtual ~UpdateSession() {}
36 
37     napi_value StartWork(napi_env env, const napi_value *args, DoWorkFunction worker, void *context) override;
38 
GetUpdateClient()39     IUpdater* GetUpdateClient() const
40     {
41         return client_;
42     }
43 
GetType()44     SessionType GetType() const override
45     {
46         return sessionParams_.type;
47     }
48 
GetSessionId()49     uint32_t GetSessionId() const override
50     {
51         return sessionId;
52     }
53 
OnAsyncComplete(const BusinessError & businessError)54     void OnAsyncComplete(const BusinessError &businessError) final
55     {
56         std::lock_guard<std::mutex> lock(conditionVariableMutex_);
57         businessError_ = businessError;
58         asyncExecuteComplete_ = true;
59         conditionVariable_.notify_all();
60     }
61 
CompleteWork(napi_env env,napi_status status)62     virtual void CompleteWork(napi_env env, napi_status status) {}
63     virtual void ExecuteWork(napi_env env);
64     virtual napi_value StartWork(napi_env env, size_t startIndex, const napi_value *args) = 0;
65 
66     static void CompleteWork(napi_env env, napi_status status, void *data);
67 
68     static void ExecuteWork(napi_env env, void *data);
69 
IsAsyncCompleteWork()70     bool IsAsyncCompleteWork() override
71     {
72         return sessionParams_.type == SessionType::SESSION_CHECK_VERSION;
73     }
74 
75 protected:
76     napi_value CreateWorkerName(napi_env env) const;
77 
GetUpdateResult(UpdateResult & result)78     void GetUpdateResult(UpdateResult &result)
79     {
80         result.businessError = businessError_;
81         client_->GetUpdateResult(sessionParams_.type, result);
82     }
83 
IsWorkExecuteSuccess()84     bool IsWorkExecuteSuccess() const
85     {
86         return workResult_ == INT_CALL_SUCCESS;
87     }
88 
GetSessionFuncParameter(std::string & funcName,std::string & permissionName)89     void GetSessionFuncParameter(std::string &funcName, std::string &permissionName)
90     {
91         struct UpdateFuncMap {
92             SessionType type;
93             std::string func;
94         } sessionFuncMap[] = {
95             { SessionType::SESSION_CHECK_VERSION,               "checkNewVersion" },
96             { SessionType::SESSION_DOWNLOAD,                    "download" },
97             { SessionType::SESSION_PAUSE_DOWNLOAD,              "pauseDownload" },
98             { SessionType::SESSION_RESUME_DOWNLOAD,             "resumeDownload" },
99             { SessionType::SESSION_UPGRADE,                     "upgrade" },
100             { SessionType::SESSION_SET_POLICY,                  "setUpgradePolicy" },
101             { SessionType::SESSION_GET_POLICY,                  "getUpgradePolicy" },
102             { SessionType::SESSION_CLEAR_ERROR,                 "clearError" },
103             { SessionType::SESSION_TERMINATE_UPGRADE,           "terminateUpgrade" },
104             { SessionType::SESSION_GET_NEW_VERSION,             "getNewVersionInfo" },
105             { SessionType::SESSION_GET_NEW_VERSION_DESCRIPTION, "getNewVersionDescription" },
106             { SessionType::SESSION_SUBSCRIBE,                   "subscribe" },
107             { SessionType::SESSION_UNSUBSCRIBE,                 "unsubscribe" },
108             { SessionType::SESSION_GET_UPDATER,                 "getUpdater" },
109             { SessionType::SESSION_APPLY_NEW_VERSION,           "applyNewVersion" },
110             { SessionType::SESSION_FACTORY_RESET,               "factoryReset" },
111             { SessionType::SESSION_VERIFY_PACKAGE,              "verifyPackage" },
112             { SessionType::SESSION_CANCEL_UPGRADE,              "cancel" },
113             { SessionType::SESSION_GET_CUR_VERSION,             "getCurrentVersionInfo" },
114             { SessionType::SESSION_GET_CUR_VERSION_DESCRIPTION, "getCurrentVersionDescription" },
115             { SessionType::SESSION_GET_TASK_INFO,               "getTaskInfo" },
116             { SessionType::SESSION_REPLY_PARAM_ERROR,           "replyParamError" },
117             { SessionType::SESSION_MAX,                         "max" }
118         };
119         for (auto &[type, func] : sessionFuncMap) {
120             if (type == sessionParams_.type) {
121                 funcName = func;
122                 break;
123             }
124         }
125         if (sessionParams_.type == SessionType::SESSION_FACTORY_RESET) {
126             permissionName = "ohos.permission.FACTORY_RESET";
127         } else {
128             permissionName = "ohos.permission.UPDATE_SYSTEM";
129         }
130     }
131 
BuildWorkBusinessErr(BusinessError & businessError)132     void BuildWorkBusinessErr(BusinessError &businessError)
133     {
134         std::string msg = "execute error";
135         std::string funcName = "";
136         std::string permissionName = "";
137         switch (workResult_) {
138             case INT_NOT_SYSTEM_APP:
139                 msg = "BusinessError " + std::to_string(workResult_) + ": Caller not system app.";
140                 break;
141             case INT_APP_NOT_GRANTED:
142                 GetSessionFuncParameter(funcName, permissionName);
143                 msg = "BusinessError " + std::to_string(workResult_) + ": Permission denied. An attempt was made to " +
144                     funcName + " forbidden by permission: " + permissionName + ".";
145                 break;
146             case INT_CALL_IPC_ERR:
147                 msg = "BusinessError " + std::to_string(COMPONENT_ERR + workResult_) + ": IPC error.";
148                 break;
149             case INT_UN_SUPPORT:
150                 GetSessionFuncParameter(funcName, permissionName);
151                 msg = "BusinessError " + std::to_string(workResult_) + ": Capability not supported. " +
152                     "function " + funcName + " can not work correctly due to limited device capabilities.";
153                 break;
154             case INT_PARAM_ERR:
155                 msg = "param error";
156                 break;
157             case INT_CALL_FAIL:
158                 msg = "BusinessError " + std::to_string(COMPONENT_ERR + workResult_) + ": Execute fail.";
159                 break;
160             case INT_FORBIDDEN:
161                 msg = "BusinessError " + std::to_string(COMPONENT_ERR + workResult_) + ": Forbidden execution.";
162                 break;
163             case INT_DEV_UPG_INFO_ERR:
164                 msg = "BusinessError " + std::to_string(COMPONENT_ERR + workResult_) + ": Device info error.";
165                 break;
166             case INT_TIME_OUT:
167                 msg = "BusinessError " + std::to_string(COMPONENT_ERR + workResult_) + ": Execute timeout.";
168                 break;
169             case INT_DB_ERROR:
170                 msg = "BusinessError " + std::to_string(COMPONENT_ERR + workResult_) + ": DB error.";
171                 break;
172             case INT_IO_ERROR:
173                 msg = "BusinessError " + std::to_string(COMPONENT_ERR + workResult_) + ": IO error.";
174                 break;
175             case INT_NET_ERROR:
176                 msg = "BusinessError " + std::to_string(COMPONENT_ERR + workResult_) + ": Network error.";
177                 break;
178             default:
179                 break;
180         }
181         businessError.Build(static_cast<CallResult>(workResult_), msg);
182     }
183 
GetBusinessError(BusinessError & businessError,const UpdateResult & result)184     void GetBusinessError(BusinessError &businessError, const UpdateResult &result)
185     {
186         if (IsWorkExecuteSuccess()) {
187             businessError = result.businessError;
188         } else {
189             BuildWorkBusinessErr(businessError);
190         }
191     }
192 
193     uint32_t sessionId {0};
194     IUpdater *client_ = nullptr;
195     BusinessError businessError_ {};
196     SessionParams sessionParams_ {};
197     int32_t workResult_ = INT_CALL_SUCCESS;
198     size_t totalArgc_ = 0;
199     size_t callbackNumber_ = 0;
200     void* context_ {};
201     DoWorkFunction doWorker_ {};
202     std::condition_variable conditionVariable_;
203     std::mutex conditionVariableMutex_;
204     bool asyncExecuteComplete_ = false;
205 };
206 
207 class UpdateAsyncession : public UpdateSession {
208 public:
209     UpdateAsyncession(IUpdater *client, SessionParams &sessionParams, size_t argc, size_t callbackNumber = 1)
UpdateSession(client,sessionParams,argc,callbackNumber)210         : UpdateSession(client, sessionParams, argc, callbackNumber)
211     {
212         callbackRef_.resize(callbackNumber);
213     }
214 
~UpdateAsyncession()215     ~UpdateAsyncession() override
216     {
217         callbackRef_.clear();
218     }
219 
220     void CompleteWork(napi_env env, napi_status status) override;
221     napi_value StartWork(napi_env env, size_t startIndex, const napi_value *args) override;
222     void NotifyJS(napi_env env, napi_value thisVar, const UpdateResult &result) override;
223 
224 private:
225     napi_async_work worker_ = nullptr;
226     std::vector<napi_ref> callbackRef_ = {0};
227 };
228 
229 class UpdateAsyncessionNoCallback : public UpdateAsyncession {
230 public:
231     UpdateAsyncessionNoCallback(
232         IUpdater *client, SessionParams &sessionParams, size_t argc, size_t callbackNumber = 0)
UpdateAsyncession(client,sessionParams,argc,callbackNumber)233         : UpdateAsyncession(client, sessionParams, argc, callbackNumber) {}
234 
~UpdateAsyncessionNoCallback()235     ~UpdateAsyncessionNoCallback() override {}
236 
237     void CompleteWork(napi_env env, napi_status status) override;
238 };
239 
240 class UpdatePromiseSession : public UpdateSession {
241 public:
242     UpdatePromiseSession(IUpdater *client, SessionParams &sessionParams, size_t argc, size_t callbackNumber = 0)
UpdateSession(client,sessionParams,argc,callbackNumber)243         : UpdateSession(client, sessionParams, argc, callbackNumber) {}
244 
~UpdatePromiseSession()245     ~UpdatePromiseSession() override {}
246 
247     void CompleteWork(napi_env env, napi_status status) override;
248     napi_value StartWork(napi_env env, size_t startIndex, const napi_value *args) override;
249     void NotifyJS(napi_env env, napi_value thisVar, const UpdateResult &result) override;
250 
251 private:
252     napi_async_work worker_ = nullptr;
253     napi_deferred deferred_ = nullptr;
254 };
255 
256 class UpdateListener : public UpdateSession {
257 public:
258     UpdateListener(
259         IUpdater *client, SessionParams &sessionParams, size_t argc, bool isOnce, size_t callbackNumber = 1)
UpdateSession(client,sessionParams,argc,callbackNumber)260         : UpdateSession(client, sessionParams, argc, callbackNumber), isOnce_(isOnce) {}
261 
~UpdateListener()262     ~UpdateListener() override {}
263 
264     napi_value StartWork(napi_env env, size_t startIndex, const napi_value *args) override;
265 
266     void NotifyJS(napi_env env, napi_value thisVar, const UpdateResult &result) override;
267 
268     void NotifyJS(napi_env env, napi_value thisVar, const EventInfo &eventInfo);
269 
IsOnce()270     bool IsOnce() const
271     {
272         return isOnce_;
273     }
274 
GetEventType()275     std::string GetEventType() const
276     {
277         return eventType_;
278     }
279 
280     bool CheckEqual(napi_env env, napi_value handler, const std::string &type);
281 
IsSubscribeEvent(const EventClassifyInfo & eventClassifyInfo)282     bool IsSubscribeEvent(const EventClassifyInfo &eventClassifyInfo) const
283     {
284         return eventClassifyInfo_.eventClassify == eventClassifyInfo.eventClassify;
285     }
286 
287     bool IsSameListener(napi_env env, const EventClassifyInfo &eventClassifyInfo, napi_value handler);
288 
289     void RemoveHandlerRef(napi_env env);
290 private:
291     bool isOnce_ = false;
292     std::string eventType_;
293     napi_ref handlerRef_ = nullptr;
294     std::mutex mutex_;
295     EventClassifyInfo eventClassifyInfo_;
296 };
297 } // namespace UpdateEngine
298 } // namespace OHOS
299 #endif // UPDATE_SESSION_H
300