1 /*
2 * Copyright (c) 2022-2024 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 "quick_fix_manager_apply_task.h"
17
18 #include "application_state_observer_stub.h"
19 #include "common_event_data.h"
20 #include "common_event_manager.h"
21 #include "common_event_support.h"
22 #include "hilog_tag_wrapper.h"
23 #include "hitrace_meter.h"
24 #include "quick_fix_callback_stub.h"
25 #include "quick_fix_error_utils.h"
26 #include "quick_fix_manager_service.h"
27 #include "quick_fix/quick_fix_status_callback_host.h"
28 #include "want.h"
29
30 namespace OHOS {
31 namespace AAFwk {
32 namespace {
33 // same with quick_fix_result_info
34 constexpr const char *QUICK_FIX_BUNDLE_NAME = "bundleName";
35 constexpr const char *QUICK_FIX_BUNDLE_VERSION_CODE = "bundleVersionCode";
36 constexpr const char *QUICK_FIX_PATCH_VERSION_CODE = "patchVersionCode";
37 constexpr const char *QUICK_FIX_IS_SO_CONTAINED = "isSoContained";
38 constexpr const char *QUICK_FIX_TYPE = "type";
39 constexpr const char *QUICK_FIX_MODULE_NAME = "moduleNames";
40
41 // common event key
42 constexpr const char *APPLY_RESULT = "applyResult";
43 constexpr const char *APPLY_RESULT_INFO = "applyResultInfo";
44 constexpr const char *REVOKE_RESULT = "revokeResult";
45 constexpr const char *REVOKE_RESULT_INFO = "revokeResultInfo";
46 constexpr const char *BUNDLE_NAME = "bundleName";
47 constexpr const char *BUNDLE_VERSION = "bundleVersion";
48 constexpr const char *PATCH_VERSION = "patchVersion";
49
50 // timeout task
51 constexpr const char *TIMEOUT_TASK_NAME = "timeoutTask";
52 constexpr int64_t TIMEOUT_TASK_DELAY_TIME = 3 * 60 * 1000;
53 } // namespace
54
55 class QuickFixManagerStatusCallback : public AppExecFwk::QuickFixStatusCallbackHost {
56 public:
QuickFixManagerStatusCallback(std::shared_ptr<QuickFixManagerApplyTask> applyTask)57 explicit QuickFixManagerStatusCallback(std::shared_ptr<QuickFixManagerApplyTask> applyTask)
58 : applyTask_(applyTask)
59 {}
60
~QuickFixManagerStatusCallback()61 virtual ~QuickFixManagerStatusCallback()
62 {
63 TAG_LOGD(AAFwkTag::QUICKFIX, "destroyed");
64 }
65
OnPatchDeployed(const std::shared_ptr<AppExecFwk::QuickFixResult> & result)66 void OnPatchDeployed(const std::shared_ptr<AppExecFwk::QuickFixResult> &result) override
67 {
68 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
69 if (applyTask_ == nullptr) {
70 TAG_LOGE(AAFwkTag::QUICKFIX, "Apply task is nullptr, result is %{public}s", result->ToString().c_str());
71 return;
72 }
73
74 int32_t ret = QUICK_FIX_OK;
75 do {
76 if (result->GetResCode() != 0) {
77 TAG_LOGE(AAFwkTag::QUICKFIX, "Deploy quick fix failed, result is %{public}s",
78 result->ToString().c_str());
79 ret = QUICK_FIX_DEPLOY_FAILED;
80 break;
81 }
82
83 if (!applyTask_->SetQuickFixInfo(result)) {
84 TAG_LOGE(AAFwkTag::QUICKFIX, "Set quick fix info failed");
85 ret = QUICK_FIX_SET_INFO_FAILED;
86 break;
87 }
88
89 applyTask_->HandlePatchDeployed();
90 } while (0);
91
92 if (ret != QUICK_FIX_OK) {
93 applyTask_->NotifyApplyStatus(ret);
94 applyTask_->RemoveSelf();
95 }
96 applyTask_->RemoveTimeoutTask();
97 }
98
OnPatchSwitched(const std::shared_ptr<AppExecFwk::QuickFixResult> & result)99 void OnPatchSwitched(const std::shared_ptr<AppExecFwk::QuickFixResult> &result) override
100 {
101 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
102 if (applyTask_ == nullptr) {
103 TAG_LOGE(AAFwkTag::QUICKFIX, "Apply task is nullptr, result is %{public}s", result->ToString().c_str());
104 return;
105 }
106
107 int32_t ret = QUICK_FIX_OK;
108 do {
109 if (result->GetResCode() != 0) {
110 TAG_LOGE(AAFwkTag::QUICKFIX, "Switch quick fix failed, result is %{public}s",
111 result->ToString().c_str());
112 ret = QUICK_FIX_SWICH_FAILED;
113 break;
114 }
115
116 if (applyTask_->GetTaskType() == QuickFixManagerApplyTask::TaskType::QUICK_FIX_APPLY) {
117 applyTask_->HandlePatchSwitched();
118 break;
119 } else if (applyTask_->GetTaskType() == QuickFixManagerApplyTask::TaskType::QUICK_FIX_REVOKE) {
120 applyTask_->HandleRevokePatchSwitched();
121 break;
122 }
123
124 ret = QUICK_FIX_SWICH_FAILED;
125 TAG_LOGE(AAFwkTag::QUICKFIX, "Switch quick fix invalid task type");
126 } while (0);
127
128 if (ret != QUICK_FIX_OK) {
129 applyTask_->NotifyApplyStatus(ret);
130 applyTask_->RemoveSelf();
131 }
132 applyTask_->RemoveTimeoutTask();
133 }
134
OnPatchDeleted(const std::shared_ptr<AppExecFwk::QuickFixResult> & result)135 void OnPatchDeleted(const std::shared_ptr<AppExecFwk::QuickFixResult> &result) override
136 {
137 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
138 if (applyTask_ == nullptr) {
139 TAG_LOGE(AAFwkTag::QUICKFIX, "Apply task is nullptr, result is %{public}s", result->ToString().c_str());
140 return;
141 }
142
143 int32_t ret = QUICK_FIX_OK;
144 do {
145 if (result->GetResCode() != 0) {
146 TAG_LOGE(AAFwkTag::QUICKFIX, "Delete quick fix failed, result is %{public}s",
147 result->ToString().c_str());
148 ret = QUICK_FIX_DELETE_FAILED;
149 break;
150 }
151
152 if (applyTask_->GetTaskType() == QuickFixManagerApplyTask::TaskType::QUICK_FIX_APPLY) {
153 applyTask_->HandlePatchDeleted();
154 break;
155 } else if (applyTask_->GetTaskType() == QuickFixManagerApplyTask::TaskType::QUICK_FIX_REVOKE) {
156 applyTask_->HandleRevokePatchDeleted();
157 break;
158 }
159
160 ret = QUICK_FIX_DELETE_FAILED;
161 TAG_LOGE(AAFwkTag::QUICKFIX, "Delete quick fix invalid task type");
162 } while (0);
163
164 if (ret != QUICK_FIX_OK) {
165 applyTask_->NotifyApplyStatus(ret);
166 applyTask_->RemoveSelf();
167 }
168 applyTask_->RemoveTimeoutTask();
169 }
170
171 private:
172 std::shared_ptr<QuickFixManagerApplyTask> applyTask_;
173 };
174
175 class RevokeQuickFixTaskCallback : public QuickFixManagerStatusCallback {
176 public:
RevokeQuickFixTaskCallback(std::shared_ptr<QuickFixManagerApplyTask> applyTask)177 explicit RevokeQuickFixTaskCallback(std::shared_ptr<QuickFixManagerApplyTask> applyTask)
178 : QuickFixManagerStatusCallback(applyTask)
179 {}
180 virtual ~RevokeQuickFixTaskCallback() = default;
181
OnPatchDeployed(const std::shared_ptr<AppExecFwk::QuickFixResult> & result)182 void OnPatchDeployed(const std::shared_ptr<AppExecFwk::QuickFixResult> &result) override
183 {
184 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
185 }
186 };
187
188 class QuickFixMgrAppStateObserver : public AppExecFwk::ApplicationStateObserverStub {
189 public:
QuickFixMgrAppStateObserver(std::shared_ptr<QuickFixManagerApplyTask> applyTask)190 explicit QuickFixMgrAppStateObserver(std::shared_ptr<QuickFixManagerApplyTask> applyTask)
191 : applyTask_(applyTask)
192 {}
193
~QuickFixMgrAppStateObserver()194 virtual ~QuickFixMgrAppStateObserver()
195 {
196 TAG_LOGD(AAFwkTag::QUICKFIX, "destroyed");
197 }
198
OnProcessDied(const AppExecFwk::ProcessData & processData)199 void OnProcessDied(const AppExecFwk::ProcessData &processData) override
200 {
201 TAG_LOGI(AAFwkTag::QUICKFIX, "process died, bundle name is %{public}s", processData.bundleName.c_str());
202
203 if (applyTask_ == nullptr) {
204 TAG_LOGE(AAFwkTag::QUICKFIX, "Apply task is nullptr, bundle name is %{public}s",
205 processData.bundleName.c_str());
206 return;
207 }
208
209 bool isRunning = applyTask_->GetRunningState();
210 if (!isRunning) {
211 if (applyTask_->GetTaskType() == QuickFixManagerApplyTask::TaskType::QUICK_FIX_APPLY) {
212 applyTask_->HandlePatchDeployed();
213 } else if (applyTask_->GetTaskType() == QuickFixManagerApplyTask::TaskType::QUICK_FIX_REVOKE) {
214 applyTask_->PostRevokeQuickFixProcessDiedTask();
215 } else {
216 TAG_LOGW(AAFwkTag::QUICKFIX, "Invalid task type");
217 }
218 }
219
220 applyTask_->UnregAppStateObserver();
221 }
222
223 private:
224 std::shared_ptr<QuickFixManagerApplyTask> applyTask_;
225 };
226
227 class QuickFixNotifyCallback : public AppExecFwk::QuickFixCallbackStub {
228 public:
QuickFixNotifyCallback(std::shared_ptr<QuickFixManagerApplyTask> applyTask)229 explicit QuickFixNotifyCallback(std::shared_ptr<QuickFixManagerApplyTask> applyTask)
230 : applyTask_(applyTask)
231 {}
232
~QuickFixNotifyCallback()233 virtual ~QuickFixNotifyCallback()
234 {
235 TAG_LOGD(AAFwkTag::QUICKFIX, "destroyed");
236 }
237
238 void OnLoadPatchDone(int32_t resultCode, [[maybe_unused]] int32_t recordId) override
239 {
240 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
241 if (resultCode != 0) {
242 TAG_LOGE(AAFwkTag::QUICKFIX, "Notify app load patch failed with %{public}d", resultCode);
243 applyTask_->NotifyApplyStatus(QUICK_FIX_NOTIFY_LOAD_PATCH_FAILED);
244 applyTask_->RemoveSelf();
245 return;
246 }
247
248 applyTask_->PostDeleteQuickFixTask();
249 }
250
251 void OnUnloadPatchDone(int32_t resultCode, [[maybe_unused]] int32_t recordId) override
252 {
253 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
254 if (resultCode != 0) {
255 TAG_LOGE(AAFwkTag::QUICKFIX, "Notify app load patch failed with %{public}d", resultCode);
256 applyTask_->NotifyApplyStatus(QUICK_FIX_NOTIFY_UNLOAD_PATCH_FAILED);
257 applyTask_->RemoveSelf();
258 return;
259 }
260
261 if (applyTask_->GetTaskType() == QuickFixManagerApplyTask::TaskType::QUICK_FIX_APPLY) {
262 applyTask_->PostSwitchQuickFixTask();
263 return;
264 } else if (applyTask_->GetTaskType() == QuickFixManagerApplyTask::TaskType::QUICK_FIX_REVOKE) {
265 applyTask_->PostRevokeQuickFixDeleteTask();
266 return;
267 }
268
269 TAG_LOGW(AAFwkTag::QUICKFIX, "Invalid task type");
270 }
271
272 void OnReloadPageDone(int32_t resultCode, [[maybe_unused]] int32_t recordId) override
273 {
274 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
275 if (resultCode != 0) {
276 TAG_LOGE(AAFwkTag::QUICKFIX, "Notify app load patch failed with %{public}d", resultCode);
277 applyTask_->NotifyApplyStatus(QUICK_FIX_NOTIFY_RELOAD_PAGE_FAILED);
278 applyTask_->RemoveSelf();
279 return;
280 }
281
282 applyTask_->NotifyApplyStatus(QUICK_FIX_OK);
283 applyTask_->RemoveSelf();
284 }
285
286 private:
287 std::shared_ptr<QuickFixManagerApplyTask> applyTask_;
288 };
289
290 class RevokeQuickFixNotifyCallback : public QuickFixNotifyCallback {
291 public:
RevokeQuickFixNotifyCallback(std::shared_ptr<QuickFixManagerApplyTask> applyTask)292 explicit RevokeQuickFixNotifyCallback(std::shared_ptr<QuickFixManagerApplyTask> applyTask)
293 : QuickFixNotifyCallback(applyTask)
294 {}
295
296 virtual ~RevokeQuickFixNotifyCallback() = default;
297
298 void OnLoadPatchDone(int32_t resultCode, [[maybe_unused]] int32_t recordId) override
299 {}
300
301 void OnReloadPageDone(int32_t resultCode, [[maybe_unused]] int32_t recordId) override
302 {}
303 };
304
~QuickFixManagerApplyTask()305 QuickFixManagerApplyTask::~QuickFixManagerApplyTask()
306 {
307 TAG_LOGD(AAFwkTag::QUICKFIX, "destroyed");
308 }
309
Run(const std::vector<std::string> & quickFixFiles,bool isDebug)310 void QuickFixManagerApplyTask::Run(const std::vector<std::string> &quickFixFiles, bool isDebug)
311 {
312 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
313 TAG_LOGI(AAFwkTag::QUICKFIX, "Run apply task");
314 taskType_ = TaskType::QUICK_FIX_APPLY;
315 PostDeployQuickFixTask(quickFixFiles, isDebug);
316 }
317
RunRevoke()318 void QuickFixManagerApplyTask::RunRevoke()
319 {
320 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
321 TAG_LOGI(AAFwkTag::QUICKFIX, "Run apply revoke task");
322 taskType_ = TaskType::QUICK_FIX_REVOKE;
323 PostRevokeQuickFixTask();
324 }
325
InitRevokeTask(const std::string & bundleName,bool isSoContained)326 void QuickFixManagerApplyTask::InitRevokeTask(const std::string &bundleName, bool isSoContained)
327 {
328 isSoContained_ = isSoContained;
329 bundleName_ = bundleName;
330 TAG_LOGI(AAFwkTag::QUICKFIX, "Function called. name:%{public}s and isSoContained:%{public}s", bundleName_.c_str(),
331 isSoContained_ ? "true" : "false");
332 }
333
HandlePatchDeployed()334 void QuickFixManagerApplyTask::HandlePatchDeployed()
335 {
336 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
337 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
338
339 isRunning_ = GetRunningState();
340 if (isRunning_ && isSoContained_) {
341 return RegAppStateObserver();
342 } else if (isRunning_ && !isSoContained_) {
343 ApplicationQuickFixInfo quickFixInfo;
344 auto service = quickFixMgrService_.promote();
345 if (service == nullptr) {
346 TAG_LOGE(AAFwkTag::QUICKFIX, "Quick fix service is nullptr");
347 NotifyApplyStatus(QUICK_FIX_INVALID_PARAM);
348 RemoveSelf();
349 return;
350 }
351
352 auto ret = service->GetApplyedQuickFixInfo(bundleName_, quickFixInfo);
353 if (ret == QUICK_FIX_OK && !quickFixInfo.appqfInfo.hqfInfos.empty()) {
354 // if there exist old version hqfInfo, need to unload.
355 TAG_LOGD(AAFwkTag::QUICKFIX, "Need unload patch firstly");
356 return PostNotifyUnloadRepairPatchTask();
357 }
358 }
359
360 PostSwitchQuickFixTask();
361 }
362
HandlePatchSwitched()363 void QuickFixManagerApplyTask::HandlePatchSwitched()
364 {
365 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
366 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
367
368 if (isRunning_ && !isSoContained_) {
369 return PostNotifyLoadRepairPatchTask();
370 }
371
372 PostDeleteQuickFixTask();
373 }
374
HandlePatchDeleted()375 void QuickFixManagerApplyTask::HandlePatchDeleted()
376 {
377 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
378 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
379
380 if (isRunning_ && !isSoContained_ && type_ == AppExecFwk::QuickFixType::HOT_RELOAD) {
381 return PostNotifyHotReloadPageTask();
382 }
383
384 NotifyApplyStatus(QUICK_FIX_OK);
385 RemoveSelf();
386 }
387
PostDeployQuickFixTask(const std::vector<std::string> & quickFixFiles,bool isDebug)388 void QuickFixManagerApplyTask::PostDeployQuickFixTask(const std::vector<std::string> &quickFixFiles, bool isDebug)
389 {
390 auto callback = sptr<QuickFixManagerStatusCallback>::MakeSptr(shared_from_this());
391 if (callback == nullptr) {
392 TAG_LOGE(AAFwkTag::QUICKFIX, "Create deploy callback failed");
393 NotifyApplyStatus(QUICK_FIX_DEPLOY_FAILED);
394 RemoveSelf();
395 return;
396 }
397
398 std::weak_ptr<QuickFixManagerApplyTask> thisWeakPtr(weak_from_this());
399 auto deployTask = [thisWeakPtr, quickFixFiles, callback, isDebug]() {
400 auto applyTask = thisWeakPtr.lock();
401 if (applyTask == nullptr) {
402 TAG_LOGE(AAFwkTag::QUICKFIX, "Apply task is nullptr");
403 return;
404 }
405
406 if (applyTask->bundleQfMgr_ == nullptr) {
407 TAG_LOGE(AAFwkTag::QUICKFIX, "Bundle quick fix manager is nullptr");
408 applyTask->NotifyApplyStatus(QUICK_FIX_BUNDLEMGR_INVALID);
409 applyTask->RemoveSelf();
410 return;
411 }
412
413 TAG_LOGD(AAFwkTag::QUICKFIX, "isDebug is %d", isDebug);
414 auto ret = applyTask->bundleQfMgr_->DeployQuickFix(quickFixFiles, callback, isDebug);
415 if (ret != 0) {
416 TAG_LOGE(AAFwkTag::QUICKFIX, "Deploy quick fix failed with %{public}d", ret);
417 applyTask->NotifyApplyStatus(QUICK_FIX_DEPLOY_FAILED);
418 applyTask->RemoveSelf();
419 return;
420 }
421 };
422 if (eventHandler_ == nullptr || !eventHandler_->PostTask(deployTask, "QuickFixManager:deployTask")) {
423 TAG_LOGE(AAFwkTag::QUICKFIX, "Post deploy task failed.");
424 }
425 PostTimeOutTask();
426 }
427
PostSwitchQuickFixTask()428 void QuickFixManagerApplyTask::PostSwitchQuickFixTask()
429 {
430 auto callback = sptr<QuickFixManagerStatusCallback>::MakeSptr(shared_from_this());
431 if (callback == nullptr) {
432 TAG_LOGE(AAFwkTag::QUICKFIX, "Create switch callback failed");
433 NotifyApplyStatus(QUICK_FIX_SWICH_FAILED);
434 RemoveSelf();
435 return;
436 }
437
438 std::weak_ptr<QuickFixManagerApplyTask> thisWeakPtr(weak_from_this());
439 auto switchTask = [thisWeakPtr, callback]() {
440 auto applyTask = thisWeakPtr.lock();
441 if (applyTask == nullptr) {
442 TAG_LOGE(AAFwkTag::QUICKFIX, "Apply task is nullptr");
443 return;
444 }
445
446 if (applyTask->bundleQfMgr_ == nullptr) {
447 TAG_LOGE(AAFwkTag::QUICKFIX, "Bundle quick fix manager is nullptr");
448 applyTask->NotifyApplyStatus(QUICK_FIX_BUNDLEMGR_INVALID);
449 applyTask->RemoveSelf();
450 return;
451 }
452
453 auto ret = applyTask->bundleQfMgr_->SwitchQuickFix(applyTask->bundleName_, true, callback);
454 if (ret != 0) {
455 TAG_LOGE(AAFwkTag::QUICKFIX, "Switch quick fix failed with %{public}d", ret);
456 applyTask->NotifyApplyStatus(QUICK_FIX_SWICH_FAILED);
457 applyTask->RemoveSelf();
458 return;
459 }
460 };
461 if (eventHandler_ == nullptr || !eventHandler_->PostTask(switchTask, "QuickFixManager:switchTask")) {
462 TAG_LOGE(AAFwkTag::QUICKFIX, "Post switch task failed");
463 }
464 PostTimeOutTask();
465 }
466
PostDeleteQuickFixTask()467 void QuickFixManagerApplyTask::PostDeleteQuickFixTask()
468 {
469 auto callback = sptr<QuickFixManagerStatusCallback>::MakeSptr(shared_from_this());
470 if (callback == nullptr) {
471 TAG_LOGE(AAFwkTag::QUICKFIX, "Create delete callback failed");
472 NotifyApplyStatus(QUICK_FIX_DELETE_FAILED);
473 RemoveSelf();
474 return;
475 }
476
477 std::weak_ptr<QuickFixManagerApplyTask> thisWeakPtr(weak_from_this());
478 auto deleteTask = [thisWeakPtr, callback]() {
479 auto applyTask = thisWeakPtr.lock();
480 if (applyTask == nullptr) {
481 TAG_LOGE(AAFwkTag::QUICKFIX, "Apply task is nullptr");
482 return;
483 }
484
485 if (applyTask->bundleQfMgr_ == nullptr) {
486 TAG_LOGE(AAFwkTag::QUICKFIX, "Bundle quick fix manager is nullptr");
487 applyTask->NotifyApplyStatus(QUICK_FIX_BUNDLEMGR_INVALID);
488 applyTask->RemoveSelf();
489 return;
490 }
491
492 auto ret = applyTask->bundleQfMgr_->DeleteQuickFix(applyTask->bundleName_, callback);
493 if (ret != 0) {
494 TAG_LOGE(AAFwkTag::QUICKFIX, "Delete quick fix failed with %{public}d", ret);
495 applyTask->NotifyApplyStatus(QUICK_FIX_DELETE_FAILED);
496 applyTask->RemoveSelf();
497 return;
498 }
499 };
500 if (eventHandler_ == nullptr || !eventHandler_->PostTask(deleteTask, "QuickFixManager:deleteTask")) {
501 TAG_LOGE(AAFwkTag::QUICKFIX, "Post delete task failed");
502 }
503 PostTimeOutTask();
504 }
505
PostTimeOutTask()506 void QuickFixManagerApplyTask::PostTimeOutTask()
507 {
508 std::weak_ptr<QuickFixManagerApplyTask> thisWeakPtr(weak_from_this());
509 auto timeoutTask = [thisWeakPtr]() {
510 auto applyTask = thisWeakPtr.lock();
511 if (applyTask == nullptr) {
512 TAG_LOGE(AAFwkTag::QUICKFIX, "Apply task is nullptr");
513 return;
514 }
515
516 applyTask->NotifyApplyStatus(QUICK_FIX_PROCESS_TIMEOUT);
517 applyTask->RemoveSelf();
518 };
519 if (eventHandler_ == nullptr || !eventHandler_->PostTask(timeoutTask, TIMEOUT_TASK_NAME, TIMEOUT_TASK_DELAY_TIME)) {
520 TAG_LOGE(AAFwkTag::QUICKFIX, "Post delete task failed");
521 }
522 }
523
RemoveTimeoutTask()524 void QuickFixManagerApplyTask::RemoveTimeoutTask()
525 {
526 if (eventHandler_ == nullptr) {
527 TAG_LOGE(AAFwkTag::QUICKFIX, "event handler is nullptr");
528 return;
529 }
530 eventHandler_->RemoveTask(TIMEOUT_TASK_NAME);
531 }
532
ExtractQuickFixDataFromJson(nlohmann::json & resultJson)533 bool QuickFixManagerApplyTask::ExtractQuickFixDataFromJson(nlohmann::json& resultJson)
534 {
535 if (!resultJson.contains(QUICK_FIX_BUNDLE_NAME) || !resultJson.at(QUICK_FIX_BUNDLE_NAME).is_string()) {
536 TAG_LOGE(AAFwkTag::QUICKFIX, "Invalid bundleName");
537 return false;
538 }
539 bundleName_ = resultJson.at(QUICK_FIX_BUNDLE_NAME).get<std::string>();
540
541 if (!resultJson.contains(QUICK_FIX_BUNDLE_VERSION_CODE) ||
542 !resultJson.at(QUICK_FIX_BUNDLE_VERSION_CODE).is_number()) {
543 TAG_LOGE(AAFwkTag::QUICKFIX, "Invalid bundle version code");
544 return false;
545 }
546 bundleVersionCode_ = resultJson.at(QUICK_FIX_BUNDLE_VERSION_CODE).get<int32_t>();
547
548 if (!resultJson.contains(QUICK_FIX_PATCH_VERSION_CODE) ||
549 !resultJson.at(QUICK_FIX_PATCH_VERSION_CODE).is_number()) {
550 TAG_LOGE(AAFwkTag::QUICKFIX, "Invalid patch version code");
551 return false;
552 }
553 patchVersionCode_ = resultJson.at(QUICK_FIX_PATCH_VERSION_CODE).get<int32_t>();
554
555 if (!resultJson.contains(QUICK_FIX_IS_SO_CONTAINED) || !resultJson.at(QUICK_FIX_IS_SO_CONTAINED).is_boolean()) {
556 TAG_LOGE(AAFwkTag::QUICKFIX, "Invalid so status");
557 return false;
558 }
559 isSoContained_ = resultJson.at(QUICK_FIX_IS_SO_CONTAINED).get<bool>();
560
561 if (!resultJson.contains(QUICK_FIX_TYPE) || !resultJson.at(QUICK_FIX_TYPE).is_number()) {
562 TAG_LOGE(AAFwkTag::QUICKFIX, "Invalid quickfix type");
563 return false;
564 }
565 type_ = static_cast<AppExecFwk::QuickFixType>(resultJson.at(QUICK_FIX_TYPE).get<int32_t>());
566 return true;
567 }
568
SetQuickFixInfo(const std::shared_ptr<AppExecFwk::QuickFixResult> & result)569 bool QuickFixManagerApplyTask::SetQuickFixInfo(const std::shared_ptr<AppExecFwk::QuickFixResult> &result)
570 {
571 auto resultJson = nlohmann::json::parse(result->ToString(), nullptr, false);
572 if (resultJson.is_discarded()) {
573 TAG_LOGE(AAFwkTag::QUICKFIX, "failed to parse json sting");
574 return false;
575 }
576 if (ExtractQuickFixDataFromJson(resultJson) != true) {
577 return false;
578 }
579 if (type_ != AppExecFwk::QuickFixType::PATCH && type_ != AppExecFwk::QuickFixType::HOT_RELOAD) {
580 TAG_LOGE(AAFwkTag::QUICKFIX, "Quick fix type is invalid");
581 return false;
582 }
583
584 if (!resultJson.contains(QUICK_FIX_MODULE_NAME) || !resultJson.at(QUICK_FIX_MODULE_NAME).is_array()) {
585 TAG_LOGE(AAFwkTag::QUICKFIX, "Invalid moduleName");
586 return false;
587 }
588 moduleNames_.clear();
589 auto size = resultJson[QUICK_FIX_MODULE_NAME].size();
590 for (size_t i = 0; i < size; i++) {
591 if (resultJson[QUICK_FIX_MODULE_NAME][i].is_string()) {
592 moduleNames_.emplace_back(resultJson[QUICK_FIX_MODULE_NAME][i]);
593 }
594 }
595
596 TAG_LOGI(AAFwkTag::QUICKFIX, "bundleName: %{public}s, bundleVersion: %{public}d, patchVersion: %{public}d,"
597 "soContained: %{public}d, ""type: %{public}d", bundleName_.c_str(), bundleVersionCode_,
598 patchVersionCode_, isSoContained_, static_cast<int32_t>(type_));
599 return true;
600 }
601
GetRunningState()602 bool QuickFixManagerApplyTask::GetRunningState()
603 {
604 if (appMgr_ == nullptr) {
605 TAG_LOGE(AAFwkTag::QUICKFIX, "App manager is nullptr");
606 return false;
607 }
608
609 auto ret = appMgr_->GetAppRunningStateByBundleName(bundleName_);
610 TAG_LOGI(AAFwkTag::QUICKFIX, "Process running state of [%{public}s] is %{public}d", bundleName_.c_str(), ret);
611 return ret;
612 }
613
NotifyApplyStatus(int32_t resultCode)614 void QuickFixManagerApplyTask::NotifyApplyStatus(int32_t resultCode)
615 {
616 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
617 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
618
619 Want want;
620 if (GetTaskType() == TaskType::QUICK_FIX_APPLY) {
621 want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_QUICK_FIX_APPLY_RESULT);
622 want.SetParam(APPLY_RESULT, QuickFixErrorUtil::GetErrorCode(resultCode));
623 want.SetParam(APPLY_RESULT_INFO, QuickFixErrorUtil::GetErrorMessage(resultCode));
624 want.SetParam(BUNDLE_VERSION, bundleVersionCode_);
625 want.SetParam(PATCH_VERSION, patchVersionCode_);
626
627 std::string moduleName = std::accumulate(moduleNames_.begin(), moduleNames_.end(), std::string(""),
628 [moduleName = moduleNames_](const std::string &name, const std::string &str) {
629 return (str == moduleName.front()) ? (name + str) : (name + "," + str);
630 });
631 want.SetModuleName(moduleName);
632 } else if (GetTaskType() == TaskType::QUICK_FIX_REVOKE) {
633 want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_QUICK_FIX_REVOKE_RESULT);
634 want.SetParam(REVOKE_RESULT, QuickFixErrorUtil::GetErrorCode(resultCode));
635 want.SetParam(REVOKE_RESULT_INFO, QuickFixErrorUtil::GetErrorMessage(resultCode));
636 } else {
637 TAG_LOGW(AAFwkTag::QUICKFIX, "Invalid task type, Can not publish common event");
638 return;
639 }
640
641 want.SetParam(BUNDLE_NAME, bundleName_);
642
643 EventFwk::CommonEventData commonData {want};
644 EventFwk::CommonEventManager::PublishCommonEvent(commonData);
645 }
646
PostNotifyLoadRepairPatchTask()647 void QuickFixManagerApplyTask::PostNotifyLoadRepairPatchTask()
648 {
649 auto callback = sptr<QuickFixNotifyCallback>::MakeSptr(shared_from_this());
650 if (callback == nullptr) {
651 TAG_LOGE(AAFwkTag::QUICKFIX, "Create load patch callback failed");
652 NotifyApplyStatus(QUICK_FIX_NOTIFY_LOAD_PATCH_FAILED);
653 RemoveSelf();
654 return;
655 }
656
657 std::weak_ptr<QuickFixManagerApplyTask> thisWeakPtr(weak_from_this());
658 auto loadPatchTask = [thisWeakPtr, callback]() {
659 auto applyTask = thisWeakPtr.lock();
660 if (applyTask == nullptr) {
661 TAG_LOGE(AAFwkTag::QUICKFIX, "Apply task is nullptr");
662 return;
663 }
664
665 if (applyTask->appMgr_ == nullptr) {
666 TAG_LOGE(AAFwkTag::QUICKFIX, "Appmgr is nullptr");
667 applyTask->NotifyApplyStatus(QUICK_FIX_APPMGR_INVALID);
668 applyTask->RemoveSelf();
669 return;
670 }
671
672 auto ret = applyTask->appMgr_->NotifyLoadRepairPatch(applyTask->bundleName_, callback);
673 if (ret != 0) {
674 TAG_LOGE(AAFwkTag::QUICKFIX, "Notify app load patch failed");
675 applyTask->NotifyApplyStatus(QUICK_FIX_NOTIFY_LOAD_PATCH_FAILED);
676 applyTask->RemoveSelf();
677 }
678 };
679 if (eventHandler_ == nullptr || !eventHandler_->PostTask(loadPatchTask, "QuickFixManager:loadPatchTask")) {
680 TAG_LOGE(AAFwkTag::QUICKFIX, "Post delete task failed");
681 }
682 PostTimeOutTask();
683 }
684
PostNotifyUnloadRepairPatchTask()685 void QuickFixManagerApplyTask::PostNotifyUnloadRepairPatchTask()
686 {
687 auto callback = sptr<QuickFixNotifyCallback>::MakeSptr(shared_from_this());
688 if (callback == nullptr) {
689 TAG_LOGE(AAFwkTag::QUICKFIX, "Create unload patch callback failed");
690 NotifyApplyStatus(QUICK_FIX_NOTIFY_UNLOAD_PATCH_FAILED);
691 RemoveSelf();
692 return;
693 }
694
695 std::weak_ptr<QuickFixManagerApplyTask> thisWeakPtr(weak_from_this());
696 auto unloadPatchTask = [thisWeakPtr, callback]() {
697 auto applyTask = thisWeakPtr.lock();
698 if (applyTask == nullptr) {
699 TAG_LOGE(AAFwkTag::QUICKFIX, "Apply task is nullptr");
700 return;
701 }
702
703 if (applyTask->appMgr_ == nullptr) {
704 TAG_LOGE(AAFwkTag::QUICKFIX, "Appmgr is nullptr");
705 applyTask->NotifyApplyStatus(QUICK_FIX_APPMGR_INVALID);
706 applyTask->RemoveSelf();
707 return;
708 }
709
710 auto ret = applyTask->appMgr_->NotifyUnLoadRepairPatch(applyTask->bundleName_, callback);
711 if (ret != 0) {
712 TAG_LOGE(AAFwkTag::QUICKFIX, "Notify app unload patch failed");
713 applyTask->NotifyApplyStatus(QUICK_FIX_NOTIFY_UNLOAD_PATCH_FAILED);
714 applyTask->RemoveSelf();
715 }
716 };
717 if (eventHandler_ == nullptr || !eventHandler_->PostTask(unloadPatchTask, "QuickFixManager:unloadPatchTask")) {
718 TAG_LOGE(AAFwkTag::QUICKFIX, "Post delete task failed");
719 }
720 PostTimeOutTask();
721 }
722
PostNotifyHotReloadPageTask()723 void QuickFixManagerApplyTask::PostNotifyHotReloadPageTask()
724 {
725 auto callback = sptr<QuickFixNotifyCallback>::MakeSptr(shared_from_this());
726 if (callback == nullptr) {
727 TAG_LOGE(AAFwkTag::QUICKFIX, "Create hotreload callback failed");
728 NotifyApplyStatus(QUICK_FIX_NOTIFY_RELOAD_PAGE_FAILED);
729 RemoveSelf();
730 return;
731 }
732
733 std::weak_ptr<QuickFixManagerApplyTask> thisWeakPtr(weak_from_this());
734 auto reloadPageTask = [thisWeakPtr, callback]() {
735 auto applyTask = thisWeakPtr.lock();
736 if (applyTask == nullptr) {
737 TAG_LOGE(AAFwkTag::QUICKFIX, "Apply task is nullptr");
738 return;
739 }
740
741 if (applyTask->appMgr_ == nullptr) {
742 TAG_LOGE(AAFwkTag::QUICKFIX, "Appmgr is nullptr");
743 applyTask->NotifyApplyStatus(QUICK_FIX_APPMGR_INVALID);
744 applyTask->RemoveSelf();
745 return;
746 }
747
748 auto ret = applyTask->appMgr_->NotifyHotReloadPage(applyTask->bundleName_, callback);
749 if (ret != 0) {
750 TAG_LOGE(AAFwkTag::QUICKFIX, "Notify app reload page failed");
751 applyTask->NotifyApplyStatus(QUICK_FIX_NOTIFY_RELOAD_PAGE_FAILED);
752 applyTask->RemoveSelf();
753 }
754 };
755 if (eventHandler_ == nullptr || !eventHandler_->PostTask(reloadPageTask, "QuickFixManager:reloadPageTask")) {
756 TAG_LOGE(AAFwkTag::QUICKFIX, "Post delete task failed");
757 }
758 PostTimeOutTask();
759 }
760
RegAppStateObserver()761 void QuickFixManagerApplyTask::RegAppStateObserver()
762 {
763 TAG_LOGD(AAFwkTag::QUICKFIX, "Register application state observer");
764 if (appMgr_ == nullptr) {
765 TAG_LOGE(AAFwkTag::QUICKFIX, "Appmgr is nullptr");
766 NotifyApplyStatus(QUICK_FIX_APPMGR_INVALID);
767 RemoveSelf();
768 return;
769 }
770
771 std::vector<std::string> bundleNameList;
772 bundleNameList.push_back(bundleName_);
773 auto callback = sptr<QuickFixMgrAppStateObserver>::MakeSptr(shared_from_this());
774 // The validity of callback will be checked below.
775 auto ret = appMgr_->RegisterApplicationStateObserver(callback, bundleNameList);
776 if (ret != 0) {
777 TAG_LOGE(AAFwkTag::QUICKFIX, "Register application state observer failed");
778 NotifyApplyStatus(QUICK_FIX_REGISTER_OBSERVER_FAILED);
779 RemoveSelf();
780 return;
781 }
782
783 appStateCallback_ = callback;
784 TAG_LOGD(AAFwkTag::QUICKFIX, "Register application state observer succeed");
785 }
786
UnregAppStateObserver()787 void QuickFixManagerApplyTask::UnregAppStateObserver()
788 {
789 TAG_LOGD(AAFwkTag::QUICKFIX, "Unregister application state observer");
790 if (appMgr_ == nullptr || appStateCallback_ == nullptr) {
791 TAG_LOGE(AAFwkTag::QUICKFIX, "Appmgr or callback is nullptr");
792 return;
793 }
794
795 auto ret = appMgr_->UnregisterApplicationStateObserver(appStateCallback_);
796 if (ret != 0) {
797 TAG_LOGE(AAFwkTag::QUICKFIX, "Unregister application state observer failed");
798 return;
799 }
800
801 TAG_LOGD(AAFwkTag::QUICKFIX, "Unregister application state observer succeed");
802 }
803
RemoveSelf()804 void QuickFixManagerApplyTask::RemoveSelf()
805 {
806 auto service = quickFixMgrService_.promote();
807 if (service) {
808 service->RemoveApplyTask(shared_from_this());
809 }
810 }
811
GetBundleName()812 std::string QuickFixManagerApplyTask::GetBundleName()
813 {
814 return bundleName_;
815 }
816
GetTaskType()817 QuickFixManagerApplyTask::TaskType QuickFixManagerApplyTask::GetTaskType()
818 {
819 return taskType_;
820 }
821
PostRevokeQuickFixTask()822 void QuickFixManagerApplyTask::PostRevokeQuickFixTask()
823 {
824 std::weak_ptr<QuickFixManagerApplyTask> thisWeakPtr(weak_from_this());
825 auto revokeTask = [thisWeakPtr] () {
826 auto applyTask = thisWeakPtr.lock();
827 if (applyTask == nullptr) {
828 TAG_LOGE(AAFwkTag::QUICKFIX, "Revoke task is nullptr");
829 return;
830 }
831 if (applyTask->GetRunningState()) {
832 applyTask->HandleRevokeQuickFixAppRunning();
833 return;
834 }
835 applyTask->HandleRevokeQuickFixAppStop();
836 };
837 if (eventHandler_ == nullptr || !eventHandler_->PostTask(revokeTask, "QuickFixManager:revokeTask")) {
838 TAG_LOGE(AAFwkTag::QUICKFIX, "Post revoke task failed");
839 }
840 PostTimeOutTask();
841 }
842
HandleRevokeQuickFixAppRunning()843 void QuickFixManagerApplyTask::HandleRevokeQuickFixAppRunning()
844 {
845 // process run
846 // so contained, reg app died
847 if (isSoContained_) {
848 RegAppStateObserver();
849 RemoveTimeoutTask();
850 return;
851 }
852
853 // so not contained, call bms to switch
854 HandleRevokeQuickFixAppStop();
855 }
856
HandleRevokePatchSwitched()857 void QuickFixManagerApplyTask::HandleRevokePatchSwitched()
858 {
859 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
860 // process is run, notify app unload patch
861 if (GetRunningState()) {
862 PostRevokeQuickFixNotifyUnloadPatchTask();
863 return;
864 }
865
866 // call bms to delete patch
867 PostRevokeQuickFixDeleteTask();
868 }
869
PostRevokeQuickFixNotifyUnloadPatchTask()870 void QuickFixManagerApplyTask::PostRevokeQuickFixNotifyUnloadPatchTask()
871 {
872 // notify app process unload patch
873 if (appMgr_ == nullptr) {
874 TAG_LOGE(AAFwkTag::QUICKFIX, "App manager is nullptr");
875 NotifyApplyStatus(QUICK_FIX_APPMGR_INVALID);
876 RemoveSelf();
877 return;
878 }
879
880 // app process run and wait callback
881 auto callback = sptr<RevokeQuickFixNotifyCallback>::MakeSptr(shared_from_this());
882 // The validity of callback will be checked below.
883 auto ret = appMgr_->NotifyUnLoadRepairPatch(bundleName_, callback);
884 if (ret != 0) {
885 TAG_LOGE(AAFwkTag::QUICKFIX, "Notify app unload patch failed");
886 NotifyApplyStatus(QUICK_FIX_NOTIFY_UNLOAD_PATCH_FAILED);
887 RemoveSelf();
888 }
889
890 TAG_LOGD(AAFwkTag::QUICKFIX, "Function end");
891 }
892
PostRevokeQuickFixDeleteTask()893 void QuickFixManagerApplyTask::PostRevokeQuickFixDeleteTask()
894 {
895 auto callback = sptr<RevokeQuickFixTaskCallback>::MakeSptr(shared_from_this());
896 if (callback == nullptr || bundleQfMgr_ == nullptr) {
897 TAG_LOGE(AAFwkTag::QUICKFIX, "Param invalid");
898 NotifyApplyStatus(QUICK_FIX_BUNDLEMGR_INVALID);
899 RemoveSelf();
900 return;
901 }
902
903 // call delete patch to bms
904 auto ret = bundleQfMgr_->DeleteQuickFix(bundleName_, callback);
905 if (ret != ERR_OK) {
906 TAG_LOGE(AAFwkTag::QUICKFIX, "Delete quick fix failed with %{public}d.", ret);
907 NotifyApplyStatus(QUICK_FIX_DELETE_FAILED);
908 RemoveSelf();
909 return;
910 }
911 }
912
PostRevokeQuickFixProcessDiedTask()913 void QuickFixManagerApplyTask::PostRevokeQuickFixProcessDiedTask()
914 {
915 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
916 // app process died
917 HandleRevokeQuickFixAppStop();
918 PostTimeOutTask();
919 }
920
HandleRevokeQuickFixAppStop()921 void QuickFixManagerApplyTask::HandleRevokeQuickFixAppStop()
922 {
923 auto callback = sptr<RevokeQuickFixTaskCallback>::MakeSptr(shared_from_this());
924 if (callback == nullptr || bundleQfMgr_ == nullptr) {
925 TAG_LOGE(AAFwkTag::QUICKFIX, "Param invalid");
926 NotifyApplyStatus(QUICK_FIX_BUNDLEMGR_INVALID);
927 RemoveSelf();
928 return;
929 }
930
931 auto ret = bundleQfMgr_->SwitchQuickFix(bundleName_, false, callback);
932 if (ret != ERR_OK) {
933 TAG_LOGE(AAFwkTag::QUICKFIX, "Switch quick fix failed with %{public}d", ret);
934 NotifyApplyStatus(QUICK_FIX_SWICH_FAILED);
935 RemoveSelf();
936 return;
937 }
938 }
939
HandleRevokePatchDeleted()940 void QuickFixManagerApplyTask::HandleRevokePatchDeleted()
941 {
942 NotifyApplyStatus(QUICK_FIX_OK);
943 RemoveSelf();
944 }
945 } // namespace AAFwk
946 } // namespace OHOS