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