1 /*
2 * Copyright (c) 2023 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 #include "update_session.h"
17
18 #include "node_api.h"
19
20 #include "client_helper.h"
21 #include "napi_common_utils.h"
22 #include "update_define.h"
23 #include "update_helper.h"
24
25 using namespace std;
26
27 namespace OHOS::UpdateEngine {
CompleteWork(napi_env env,napi_status status)28 void UpdateAsyncession::CompleteWork(napi_env env, napi_status status)
29 {
30 ENGINE_LOGI("UpdateAsyncession::CompleteWork callbackNumber_: %{public}d, %{public}d",
31 static_cast<int32_t>(callbackNumber_), sessionParams_.type);
32 UpdateResult result;
33 GetUpdateResult(result);
34 NotifyJS(env, NULL, result);
35 }
36
GetFunctionName()37 std::string BaseUpdateSession::GetFunctionName()
38 {
39 return SessionFuncHelper::GetFuncName(sessionParams_.type);
40 }
41
CompleteWork(napi_env env,napi_status status)42 void UpdatePromiseSession::CompleteWork(napi_env env, napi_status status)
43 {
44 ENGINE_LOGI("UpdatePromiseSession::CompleteWork status: %d", static_cast<int32_t>(status));
45 UpdateResult result;
46 GetUpdateResult(result);
47 NotifyJS(env, NULL, result);
48 }
49
GetFunctionName()50 std::string BaseMigratePromiseSession::GetFunctionName()
51 {
52 return SessionFuncHelper::GetFuncName(sessionParams_.type);
53 }
54
StartWork(napi_env env,size_t startIndex,const napi_value * args)55 napi_value UpdateListener::StartWork(napi_env env, size_t startIndex, const napi_value *args)
56 {
57 ENGINE_LOGI("UpdateListener::StartWork");
58 PARAM_CHECK_NAPI_CALL(env, args != nullptr && totalArgc_ > startIndex, return nullptr, "Invalid para");
59
60 if (NapiCommonUtils::IsTypeOf(env, args[0], napi_string) == ClientStatus::CLIENT_SUCCESS) {
61 int ret = NapiCommonUtils::GetString(env, args[0], eventType_);
62 PARAM_CHECK_NAPI_CALL(env, ret == napi_ok, return nullptr, "Failed to get string event type");
63 } else {
64 ClientStatus ret = ClientHelper::GetEventClassifyInfoFromArg(env, args[0], eventClassifyInfo_);
65 PARAM_CHECK_NAPI_CALL(env, ret == ClientStatus::CLIENT_SUCCESS, return nullptr, "Failed to get obj event type");
66 }
67
68 PARAM_CHECK_NAPI_CALL(env,
69 NapiCommonUtils::IsTypeOf(env, args[startIndex], napi_function) == ClientStatus::CLIENT_SUCCESS, return nullptr,
70 "Invalid callback type");
71 ClientStatus ret = NapiCommonUtils::CreateReference(env, args[startIndex], 1, handlerRef_);
72 PARAM_CHECK_NAPI_CALL(env, ret == ClientStatus::CLIENT_SUCCESS, return nullptr, "Failed to create reference");
73 int32_t res = doWorker_(context_);
74 napi_value result;
75 napi_create_int32(env, res, &result);
76 return result;
77 }
78
NotifyJS(napi_env env,napi_value thisVar,const UpdateResult & result)79 void UpdateListener::NotifyJS(napi_env env, napi_value thisVar, const UpdateResult &result)
80 {
81 ENGINE_LOGI("NotifyJS");
82 napi_value jsEvent;
83 napi_value handler = nullptr;
84 napi_value callResult;
85 int32_t ret = result.buildJSObject(env, jsEvent, result);
86 PARAM_CHECK_NAPI_CALL(env, ret == napi_ok, return, "Failed to build json");
87 {
88 std::lock_guard<std::mutex> lock(mutex_);
89 PARAM_CHECK_NAPI_CALL(env, handlerRef_ != nullptr, return, "handlerRef_ has beed freed");
90 napi_status status = napi_get_reference_value(env, handlerRef_, &handler);
91 PARAM_CHECK_NAPI_CALL(env, status == napi_ok && handler != nullptr, return, "Failed to get reference");
92 }
93 PARAM_CHECK_NAPI_CALL(env, handler != nullptr, return, "handlerRef_ has beed freed");
94 napi_call_function(env, thisVar, handler, 1, &jsEvent, &callResult);
95 }
96
NotifyJS(napi_env env,napi_value thisVar,const EventInfo & eventInfo)97 void UpdateListener::NotifyJS(napi_env env, napi_value thisVar, const EventInfo &eventInfo)
98 {
99 ENGINE_LOGI("NotifyJS, eventId:0x%{public}08x", eventInfo.eventId);
100 napi_value jsEvent = nullptr;
101 ClientStatus ret = ClientHelper::BuildEventInfo(env, jsEvent, eventInfo);
102 PARAM_CHECK_NAPI_CALL(env, ret == ClientStatus::CLIENT_SUCCESS, return, "Failed to build event info");
103
104 std::lock_guard<std::mutex> lock(mutex_);
105 PARAM_CHECK_NAPI_CALL(env, handlerRef_ != nullptr, return, "handlerRef_ has beed freed");
106 napi_value handler = nullptr;
107 napi_status status = napi_get_reference_value(env, handlerRef_, &handler);
108 PARAM_CHECK_NAPI_CALL(env, status == napi_ok && handler != nullptr, return, "Failed to get reference");
109
110 napi_value callResult = nullptr;
111 status = napi_call_function(env, thisVar, handler, 1, &jsEvent, &callResult);
112 if (status != napi_ok) {
113 ENGINE_LOGE("NotifyJS error, napi_call_function fail");
114 }
115 }
116
CheckEqual(napi_env env,napi_value handler,const std::string & type)117 bool UpdateListener::CheckEqual(napi_env env, napi_value handler, const std::string &type)
118 {
119 std::lock_guard<std::mutex> lock(mutex_);
120 bool isEquals = false;
121 napi_value handlerTemp = nullptr;
122 napi_status status = napi_get_reference_value(env, handlerRef_, &handlerTemp);
123 PARAM_CHECK_NAPI_CALL(env, status == napi_ok, return false, "Failed to get reference");
124 napi_strict_equals(env, handler, handlerTemp, &isEquals);
125 return isEquals && (type.compare(eventType_) == 0);
126 }
127
IsSameListener(napi_env env,const EventClassifyInfo & eventClassifyInfo,napi_value handler)128 bool UpdateListener::IsSameListener(napi_env env, const EventClassifyInfo &eventClassifyInfo, napi_value handler)
129 {
130 if (eventClassifyInfo_.eventClassify != eventClassifyInfo.eventClassify) {
131 ENGINE_LOGI("not same listener, different event classify, 0x%{public}x, 0x%{public}x",
132 eventClassifyInfo_.eventClassify, eventClassifyInfo.eventClassify);
133 return false;
134 }
135
136 napi_value currentHandler = nullptr;
137 napi_status status = napi_get_reference_value(env, handlerRef_, ¤tHandler);
138 PARAM_CHECK_NAPI_CALL(env, status == napi_ok, return false, "Failed to get current handle");
139
140 bool isEquals = false;
141 status = napi_strict_equals(env, handler, currentHandler, &isEquals);
142 return status == napi_ok && isEquals;
143 }
144
RemoveHandlerRef(napi_env env)145 void UpdateListener::RemoveHandlerRef(napi_env env)
146 {
147 std::lock_guard<std::mutex> lock(mutex_);
148 ENGINE_LOGI("RemoveHandlerRef handlerRef sessionId:%{public}u", GetSessionId());
149 napi_delete_reference(env, handlerRef_);
150 handlerRef_ = nullptr;
151 }
152
153 std::map<uint32_t, std::string> SessionFuncHelper::sessionFuncMap_ = {
154 {SessionType::SESSION_CHECK_VERSION, "checkNewVersion"},
155 {SessionType::SESSION_DOWNLOAD, "download"},
156 {SessionType::SESSION_PAUSE_DOWNLOAD, "pauseDownload"},
157 {SessionType::SESSION_RESUME_DOWNLOAD, "resumeDownload"},
158 {SessionType::SESSION_UPGRADE, "upgrade"},
159 {SessionType::SESSION_SET_POLICY, "setUpgradePolicy"},
160 {SessionType::SESSION_GET_POLICY, "getUpgradePolicy"},
161 {SessionType::SESSION_CLEAR_ERROR, "clearError"},
162 {SessionType::SESSION_TERMINATE_UPGRADE, "terminateUpgrade"},
163 {SessionType::SESSION_GET_NEW_VERSION, "getNewVersionInfo"},
164 {SessionType::SESSION_GET_NEW_VERSION_DESCRIPTION, "getNewVersionDescription"},
165 {SessionType::SESSION_SUBSCRIBE, "subscribe"},
166 {SessionType::SESSION_UNSUBSCRIBE, "unsubscribe"},
167 {SessionType::SESSION_GET_UPDATER, "getUpdater"},
168 {SessionType::SESSION_APPLY_NEW_VERSION, "applyNewVersion"},
169 {SessionType::SESSION_FACTORY_RESET, "factoryReset"},
170 {SessionType::SESSION_VERIFY_PACKAGE, "verifyPackage"},
171 {SessionType::SESSION_CANCEL_UPGRADE, "cancel"},
172 {SessionType::SESSION_GET_CUR_VERSION, "getCurrentVersionInfo"},
173 {SessionType::SESSION_GET_CUR_VERSION_DESCRIPTION, "getCurrentVersionDescription"},
174 {SessionType::SESSION_GET_TASK_INFO, "getTaskInfo"},
175 {SessionType::SESSION_REPLY_PARAM_ERROR, "replyParamError"},
176 {SessionType::SESSION_MAX, "max"}
177 };
178
GetFuncName(uint32_t sessionType)179 std::string SessionFuncHelper::GetFuncName(uint32_t sessionType)
180 {
181 auto funcIter = sessionFuncMap_.find(sessionType);
182 if (funcIter == sessionFuncMap_.end()) {
183 ENGINE_LOGE("SessionFuncHelper::GetFuncName failed sessionType:%{public}d", sessionType);
184 return "";
185 }
186 return funcIter->second;
187 }
188 } // namespace OHOS::UpdateEngine