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