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, "null Apply task, result:%{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, "failed, result:%{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 quickFixInfo 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, "null apply task, result: %{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 quickFix failed, result: %{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 quickFix 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, "null apply task, result: %{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 quickFix failed, result: %{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 quickFix 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: %{public}s", processData.bundleName.c_str());
202
203 if (applyTask_ == nullptr) {
204 TAG_LOGE(AAFwkTag::QUICKFIX, "null apply task, bundle name:%{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
OnLoadPatchDone(int32_t resultCode,int32_t recordId)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 patch failed: %{public}d", resultCode);
243 applyTask_->NotifyApplyStatus(QUICK_FIX_NOTIFY_LOAD_PATCH_FAILED);
244 applyTask_->RemoveSelf();
245 return;
246 }
247
248 applyTask_->PostDeleteQuickFixTask();
249 }
250
OnUnloadPatchDone(int32_t resultCode,int32_t recordId)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 patch failed: %{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
OnReloadPageDone(int32_t resultCode,int32_t recordId)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: %{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
OnLoadPatchDone(int32_t resultCode,int32_t recordId)298 void OnLoadPatchDone(int32_t resultCode, [[maybe_unused]] int32_t recordId) override
299 {}
300
OnReloadPageDone(int32_t resultCode,int32_t recordId)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,bool isReplace)310 void QuickFixManagerApplyTask::Run(const std::vector<std::string> &quickFixFiles, bool isDebug, bool isReplace)
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, isReplace);
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, "call func:%{public}s, 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, "null quick fix service");
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,bool isReplace)388 void QuickFixManagerApplyTask::PostDeployQuickFixTask(const std::vector<std::string> &quickFixFiles, bool isDebug,
389 bool isReplace)
390 {
391 auto callback = sptr<QuickFixManagerStatusCallback>::MakeSptr(shared_from_this());
392 if (callback == nullptr) {
393 TAG_LOGE(AAFwkTag::QUICKFIX, "Create deploy callback failed");
394 NotifyApplyStatus(QUICK_FIX_DEPLOY_FAILED);
395 RemoveSelf();
396 return;
397 }
398
399 std::weak_ptr<QuickFixManagerApplyTask> thisWeakPtr(weak_from_this());
400 auto deployTask = [thisWeakPtr, quickFixFiles, callback, isDebug, isReplace]() {
401 auto applyTask = thisWeakPtr.lock();
402 if (applyTask == nullptr) {
403 TAG_LOGE(AAFwkTag::QUICKFIX, "null apply task");
404 return;
405 }
406
407 if (applyTask->bundleQfMgr_ == nullptr) {
408 TAG_LOGE(AAFwkTag::QUICKFIX, "null bundleQfMgr_");
409 applyTask->NotifyApplyStatus(QUICK_FIX_BUNDLEMGR_INVALID);
410 applyTask->RemoveSelf();
411 return;
412 }
413
414 TAG_LOGD(AAFwkTag::QUICKFIX, "isDebug is %d isReplace is %d", isDebug, isReplace);
415 auto ret = applyTask->bundleQfMgr_->DeployQuickFix(quickFixFiles, callback, isDebug, "", isReplace);
416 if (ret != 0) {
417 TAG_LOGE(AAFwkTag::QUICKFIX, "failed: %{public}d", ret);
418 applyTask->NotifyApplyStatus(QUICK_FIX_DEPLOY_FAILED);
419 applyTask->RemoveSelf();
420 return;
421 }
422 };
423 if (eventHandler_ == nullptr || !eventHandler_->PostTask(deployTask, "QuickFixManager:deployTask")) {
424 TAG_LOGE(AAFwkTag::QUICKFIX, "post deploy task failed");
425 }
426 PostTimeOutTask();
427 }
428
PostSwitchQuickFixTask()429 void QuickFixManagerApplyTask::PostSwitchQuickFixTask()
430 {
431 auto callback = sptr<QuickFixManagerStatusCallback>::MakeSptr(shared_from_this());
432 if (callback == nullptr) {
433 TAG_LOGE(AAFwkTag::QUICKFIX, "null callback");
434 NotifyApplyStatus(QUICK_FIX_SWICH_FAILED);
435 RemoveSelf();
436 return;
437 }
438
439 std::weak_ptr<QuickFixManagerApplyTask> thisWeakPtr(weak_from_this());
440 auto switchTask = [thisWeakPtr, callback]() {
441 auto applyTask = thisWeakPtr.lock();
442 if (applyTask == nullptr) {
443 TAG_LOGE(AAFwkTag::QUICKFIX, "null apply task");
444 return;
445 }
446
447 if (applyTask->bundleQfMgr_ == nullptr) {
448 TAG_LOGE(AAFwkTag::QUICKFIX, "null bundleQfMgr_");
449 applyTask->NotifyApplyStatus(QUICK_FIX_BUNDLEMGR_INVALID);
450 applyTask->RemoveSelf();
451 return;
452 }
453
454 auto ret = applyTask->bundleQfMgr_->SwitchQuickFix(applyTask->bundleName_, true, callback);
455 if (ret != 0) {
456 TAG_LOGE(AAFwkTag::QUICKFIX, "failed: %{public}d", ret);
457 applyTask->NotifyApplyStatus(QUICK_FIX_SWICH_FAILED);
458 applyTask->RemoveSelf();
459 return;
460 }
461 };
462 if (eventHandler_ == nullptr || !eventHandler_->PostTask(switchTask, "QuickFixManager:switchTask")) {
463 TAG_LOGE(AAFwkTag::QUICKFIX, "Post switch task failed");
464 }
465 PostTimeOutTask();
466 }
467
PostDeleteQuickFixTask()468 void QuickFixManagerApplyTask::PostDeleteQuickFixTask()
469 {
470 auto callback = sptr<QuickFixManagerStatusCallback>::MakeSptr(shared_from_this());
471 if (callback == nullptr) {
472 TAG_LOGE(AAFwkTag::QUICKFIX, "null callback");
473 NotifyApplyStatus(QUICK_FIX_DELETE_FAILED);
474 RemoveSelf();
475 return;
476 }
477
478 std::weak_ptr<QuickFixManagerApplyTask> thisWeakPtr(weak_from_this());
479 auto deleteTask = [thisWeakPtr, callback]() {
480 auto applyTask = thisWeakPtr.lock();
481 if (applyTask == nullptr) {
482 TAG_LOGE(AAFwkTag::QUICKFIX, "null apply task");
483 return;
484 }
485
486 if (applyTask->bundleQfMgr_ == nullptr) {
487 TAG_LOGE(AAFwkTag::QUICKFIX, "null bundleQfMgr_");
488 applyTask->NotifyApplyStatus(QUICK_FIX_BUNDLEMGR_INVALID);
489 applyTask->RemoveSelf();
490 return;
491 }
492
493 auto ret = applyTask->bundleQfMgr_->DeleteQuickFix(applyTask->bundleName_, callback);
494 if (ret != 0) {
495 TAG_LOGE(AAFwkTag::QUICKFIX, "delete quick fix failed: %{public}d", ret);
496 applyTask->NotifyApplyStatus(QUICK_FIX_DELETE_FAILED);
497 applyTask->RemoveSelf();
498 return;
499 }
500 };
501 if (eventHandler_ == nullptr || !eventHandler_->PostTask(deleteTask, "QuickFixManager:deleteTask")) {
502 TAG_LOGE(AAFwkTag::QUICKFIX, "Post delete task failed");
503 }
504 PostTimeOutTask();
505 }
506
PostTimeOutTask()507 void QuickFixManagerApplyTask::PostTimeOutTask()
508 {
509 std::weak_ptr<QuickFixManagerApplyTask> thisWeakPtr(weak_from_this());
510 auto timeoutTask = [thisWeakPtr]() {
511 auto applyTask = thisWeakPtr.lock();
512 if (applyTask == nullptr) {
513 TAG_LOGE(AAFwkTag::QUICKFIX, "null apply task");
514 return;
515 }
516
517 applyTask->NotifyApplyStatus(QUICK_FIX_PROCESS_TIMEOUT);
518 applyTask->RemoveSelf();
519 };
520 if (eventHandler_ == nullptr || !eventHandler_->PostTask(timeoutTask, TIMEOUT_TASK_NAME, TIMEOUT_TASK_DELAY_TIME)) {
521 TAG_LOGE(AAFwkTag::QUICKFIX, "Post delete task failed");
522 }
523 }
524
RemoveTimeoutTask()525 void QuickFixManagerApplyTask::RemoveTimeoutTask()
526 {
527 if (eventHandler_ == nullptr) {
528 TAG_LOGE(AAFwkTag::QUICKFIX, "null event handler");
529 return;
530 }
531 eventHandler_->RemoveTask(TIMEOUT_TASK_NAME);
532 }
533
ExtractQuickFixDataFromJson(nlohmann::json & resultJson)534 bool QuickFixManagerApplyTask::ExtractQuickFixDataFromJson(nlohmann::json& resultJson)
535 {
536 if (!resultJson.contains(QUICK_FIX_BUNDLE_NAME) || !resultJson.at(QUICK_FIX_BUNDLE_NAME).is_string()) {
537 TAG_LOGE(AAFwkTag::QUICKFIX, "Invalid bundleName");
538 return false;
539 }
540 bundleName_ = resultJson.at(QUICK_FIX_BUNDLE_NAME).get<std::string>();
541
542 if (!resultJson.contains(QUICK_FIX_BUNDLE_VERSION_CODE) ||
543 !resultJson.at(QUICK_FIX_BUNDLE_VERSION_CODE).is_number()) {
544 TAG_LOGE(AAFwkTag::QUICKFIX, "Invalid bundle version code");
545 return false;
546 }
547 bundleVersionCode_ = resultJson.at(QUICK_FIX_BUNDLE_VERSION_CODE).get<int32_t>();
548
549 if (!resultJson.contains(QUICK_FIX_PATCH_VERSION_CODE) ||
550 !resultJson.at(QUICK_FIX_PATCH_VERSION_CODE).is_number()) {
551 TAG_LOGE(AAFwkTag::QUICKFIX, "Invalid patch version code");
552 return false;
553 }
554 patchVersionCode_ = resultJson.at(QUICK_FIX_PATCH_VERSION_CODE).get<int32_t>();
555
556 if (!resultJson.contains(QUICK_FIX_IS_SO_CONTAINED) || !resultJson.at(QUICK_FIX_IS_SO_CONTAINED).is_boolean()) {
557 TAG_LOGE(AAFwkTag::QUICKFIX, "Invalid so status");
558 return false;
559 }
560 isSoContained_ = resultJson.at(QUICK_FIX_IS_SO_CONTAINED).get<bool>();
561
562 if (!resultJson.contains(QUICK_FIX_TYPE) || !resultJson.at(QUICK_FIX_TYPE).is_number()) {
563 TAG_LOGE(AAFwkTag::QUICKFIX, "Invalid quickfix type");
564 return false;
565 }
566 type_ = static_cast<AppExecFwk::QuickFixType>(resultJson.at(QUICK_FIX_TYPE).get<int32_t>());
567 return true;
568 }
569
SetQuickFixInfo(const std::shared_ptr<AppExecFwk::QuickFixResult> & result)570 bool QuickFixManagerApplyTask::SetQuickFixInfo(const std::shared_ptr<AppExecFwk::QuickFixResult> &result)
571 {
572 auto resultJson = nlohmann::json::parse(result->ToString(), nullptr, false);
573 if (resultJson.is_discarded()) {
574 TAG_LOGE(AAFwkTag::QUICKFIX, "failed to parse json sting");
575 return false;
576 }
577 if (ExtractQuickFixDataFromJson(resultJson) != true) {
578 return false;
579 }
580 if (type_ != AppExecFwk::QuickFixType::PATCH && type_ != AppExecFwk::QuickFixType::HOT_RELOAD) {
581 TAG_LOGE(AAFwkTag::QUICKFIX, "quick fix type invalid");
582 return false;
583 }
584
585 if (!resultJson.contains(QUICK_FIX_MODULE_NAME) || !resultJson.at(QUICK_FIX_MODULE_NAME).is_array()) {
586 TAG_LOGE(AAFwkTag::QUICKFIX, "Invalid moduleName");
587 return false;
588 }
589 moduleNames_.clear();
590 auto size = resultJson[QUICK_FIX_MODULE_NAME].size();
591 for (size_t i = 0; i < size; i++) {
592 if (resultJson[QUICK_FIX_MODULE_NAME][i].is_string()) {
593 moduleNames_.emplace_back(resultJson[QUICK_FIX_MODULE_NAME][i]);
594 }
595 }
596
597 TAG_LOGI(AAFwkTag::QUICKFIX, "bundleName: %{public}s, bundleVersion: %{public}d, patchVersion: %{public}d,"
598 "soContained: %{public}d, ""type: %{public}d", bundleName_.c_str(), bundleVersionCode_,
599 patchVersionCode_, isSoContained_, static_cast<int32_t>(type_));
600 return true;
601 }
602
GetRunningState()603 bool QuickFixManagerApplyTask::GetRunningState()
604 {
605 if (appMgr_ == nullptr) {
606 TAG_LOGE(AAFwkTag::QUICKFIX, "null appMgr_");
607 return false;
608 }
609
610 auto ret = appMgr_->GetAppRunningStateByBundleName(bundleName_);
611 TAG_LOGI(AAFwkTag::QUICKFIX, "process running state of [%{public}s]: %{public}d", bundleName_.c_str(), ret);
612 return ret;
613 }
614
NotifyApplyStatus(int32_t resultCode)615 void QuickFixManagerApplyTask::NotifyApplyStatus(int32_t resultCode)
616 {
617 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
618 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
619
620 Want want;
621 if (GetTaskType() == TaskType::QUICK_FIX_APPLY) {
622 want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_QUICK_FIX_APPLY_RESULT);
623 want.SetParam(APPLY_RESULT, QuickFixErrorUtil::GetErrorCode(resultCode));
624 want.SetParam(APPLY_RESULT_INFO, QuickFixErrorUtil::GetErrorMessage(resultCode));
625 want.SetParam(BUNDLE_VERSION, bundleVersionCode_);
626 want.SetParam(PATCH_VERSION, patchVersionCode_);
627
628 std::string moduleName = std::accumulate(moduleNames_.begin(), moduleNames_.end(), std::string(""),
629 [moduleName = moduleNames_](const std::string &name, const std::string &str) {
630 return (str == moduleName.front()) ? (name + str) : (name + "," + str);
631 });
632 want.SetModuleName(moduleName);
633 } else if (GetTaskType() == TaskType::QUICK_FIX_REVOKE) {
634 want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_QUICK_FIX_REVOKE_RESULT);
635 want.SetParam(REVOKE_RESULT, QuickFixErrorUtil::GetErrorCode(resultCode));
636 want.SetParam(REVOKE_RESULT_INFO, QuickFixErrorUtil::GetErrorMessage(resultCode));
637 } else {
638 TAG_LOGW(AAFwkTag::QUICKFIX, "invalid task type, not publish common event");
639 return;
640 }
641
642 want.SetParam(BUNDLE_NAME, bundleName_);
643
644 EventFwk::CommonEventData commonData {want};
645 EventFwk::CommonEventManager::PublishCommonEvent(commonData);
646 }
647
PostNotifyLoadRepairPatchTask()648 void QuickFixManagerApplyTask::PostNotifyLoadRepairPatchTask()
649 {
650 auto callback = sptr<QuickFixNotifyCallback>::MakeSptr(shared_from_this());
651 if (callback == nullptr) {
652 TAG_LOGE(AAFwkTag::QUICKFIX, "null callback");
653 NotifyApplyStatus(QUICK_FIX_NOTIFY_LOAD_PATCH_FAILED);
654 RemoveSelf();
655 return;
656 }
657
658 std::weak_ptr<QuickFixManagerApplyTask> thisWeakPtr(weak_from_this());
659 auto loadPatchTask = [thisWeakPtr, callback]() {
660 auto applyTask = thisWeakPtr.lock();
661 if (applyTask == nullptr) {
662 TAG_LOGE(AAFwkTag::QUICKFIX, "null apply task");
663 return;
664 }
665
666 if (applyTask->appMgr_ == nullptr) {
667 TAG_LOGE(AAFwkTag::QUICKFIX, "null appMgr");
668 applyTask->NotifyApplyStatus(QUICK_FIX_APPMGR_INVALID);
669 applyTask->RemoveSelf();
670 return;
671 }
672
673 auto ret = applyTask->appMgr_->NotifyLoadRepairPatch(applyTask->bundleName_, callback);
674 if (ret != 0) {
675 TAG_LOGE(AAFwkTag::QUICKFIX, "Notify app load patch failed");
676 applyTask->NotifyApplyStatus(QUICK_FIX_NOTIFY_LOAD_PATCH_FAILED);
677 applyTask->RemoveSelf();
678 }
679 };
680 if (eventHandler_ == nullptr || !eventHandler_->PostTask(loadPatchTask, "QuickFixManager:loadPatchTask")) {
681 TAG_LOGE(AAFwkTag::QUICKFIX, "post delete failed");
682 }
683 PostTimeOutTask();
684 }
685
PostNotifyUnloadRepairPatchTask()686 void QuickFixManagerApplyTask::PostNotifyUnloadRepairPatchTask()
687 {
688 auto callback = sptr<QuickFixNotifyCallback>::MakeSptr(shared_from_this());
689 if (callback == nullptr) {
690 TAG_LOGE(AAFwkTag::QUICKFIX, "null callback");
691 NotifyApplyStatus(QUICK_FIX_NOTIFY_UNLOAD_PATCH_FAILED);
692 RemoveSelf();
693 return;
694 }
695
696 std::weak_ptr<QuickFixManagerApplyTask> thisWeakPtr(weak_from_this());
697 auto unloadPatchTask = [thisWeakPtr, callback]() {
698 auto applyTask = thisWeakPtr.lock();
699 if (applyTask == nullptr) {
700 TAG_LOGE(AAFwkTag::QUICKFIX, "null apply task");
701 return;
702 }
703
704 if (applyTask->appMgr_ == nullptr) {
705 TAG_LOGE(AAFwkTag::QUICKFIX, "null appMgr");
706 applyTask->NotifyApplyStatus(QUICK_FIX_APPMGR_INVALID);
707 applyTask->RemoveSelf();
708 return;
709 }
710
711 auto ret = applyTask->appMgr_->NotifyUnLoadRepairPatch(applyTask->bundleName_, callback);
712 if (ret != 0) {
713 TAG_LOGE(AAFwkTag::QUICKFIX, "Notify app unload patch failed");
714 applyTask->NotifyApplyStatus(QUICK_FIX_NOTIFY_UNLOAD_PATCH_FAILED);
715 applyTask->RemoveSelf();
716 }
717 };
718 if (eventHandler_ == nullptr || !eventHandler_->PostTask(unloadPatchTask, "QuickFixManager:unloadPatchTask")) {
719 TAG_LOGE(AAFwkTag::QUICKFIX, "Post delete task failed");
720 }
721 PostTimeOutTask();
722 }
723
PostNotifyHotReloadPageTask()724 void QuickFixManagerApplyTask::PostNotifyHotReloadPageTask()
725 {
726 auto callback = sptr<QuickFixNotifyCallback>::MakeSptr(shared_from_this());
727 if (callback == nullptr) {
728 TAG_LOGE(AAFwkTag::QUICKFIX, "null callback");
729 NotifyApplyStatus(QUICK_FIX_NOTIFY_RELOAD_PAGE_FAILED);
730 RemoveSelf();
731 return;
732 }
733
734 std::weak_ptr<QuickFixManagerApplyTask> thisWeakPtr(weak_from_this());
735 auto reloadPageTask = [thisWeakPtr, callback]() {
736 auto applyTask = thisWeakPtr.lock();
737 if (applyTask == nullptr) {
738 TAG_LOGE(AAFwkTag::QUICKFIX, "null apply task");
739 return;
740 }
741
742 if (applyTask->appMgr_ == nullptr) {
743 TAG_LOGE(AAFwkTag::QUICKFIX, "null appMgr");
744 applyTask->NotifyApplyStatus(QUICK_FIX_APPMGR_INVALID);
745 applyTask->RemoveSelf();
746 return;
747 }
748
749 auto ret = applyTask->appMgr_->NotifyHotReloadPage(applyTask->bundleName_, callback);
750 if (ret != 0) {
751 TAG_LOGE(AAFwkTag::QUICKFIX, "Notify app reload page failed");
752 applyTask->NotifyApplyStatus(QUICK_FIX_NOTIFY_RELOAD_PAGE_FAILED);
753 applyTask->RemoveSelf();
754 }
755 };
756 if (eventHandler_ == nullptr || !eventHandler_->PostTask(reloadPageTask, "QuickFixManager:reloadPageTask")) {
757 TAG_LOGE(AAFwkTag::QUICKFIX, "Post delete task failed");
758 }
759 PostTimeOutTask();
760 }
761
RegAppStateObserver()762 void QuickFixManagerApplyTask::RegAppStateObserver()
763 {
764 TAG_LOGD(AAFwkTag::QUICKFIX, "Register application state observer");
765 if (appMgr_ == nullptr) {
766 TAG_LOGE(AAFwkTag::QUICKFIX, "null appMgr");
767 NotifyApplyStatus(QUICK_FIX_APPMGR_INVALID);
768 RemoveSelf();
769 return;
770 }
771
772 std::vector<std::string> bundleNameList;
773 bundleNameList.push_back(bundleName_);
774 auto callback = sptr<QuickFixMgrAppStateObserver>::MakeSptr(shared_from_this());
775 // The validity of callback will be checked below.
776 auto ret = appMgr_->RegisterApplicationStateObserver(callback, bundleNameList);
777 if (ret != 0) {
778 TAG_LOGE(AAFwkTag::QUICKFIX, "register app state observer failed");
779 NotifyApplyStatus(QUICK_FIX_REGISTER_OBSERVER_FAILED);
780 RemoveSelf();
781 return;
782 }
783
784 appStateCallback_ = callback;
785 TAG_LOGD(AAFwkTag::QUICKFIX, "Register application state observer succeed");
786 }
787
UnregAppStateObserver()788 void QuickFixManagerApplyTask::UnregAppStateObserver()
789 {
790 TAG_LOGD(AAFwkTag::QUICKFIX, "Unregister application state observer");
791 if (appMgr_ == nullptr || appStateCallback_ == nullptr) {
792 TAG_LOGE(AAFwkTag::QUICKFIX, "null appMgr/callback");
793 return;
794 }
795
796 auto ret = appMgr_->UnregisterApplicationStateObserver(appStateCallback_);
797 if (ret != 0) {
798 TAG_LOGE(AAFwkTag::QUICKFIX, "unregister app state observer failed");
799 return;
800 }
801
802 TAG_LOGD(AAFwkTag::QUICKFIX, "Unregister application state observer succeed");
803 }
804
RemoveSelf()805 void QuickFixManagerApplyTask::RemoveSelf()
806 {
807 auto service = quickFixMgrService_.promote();
808 if (service) {
809 service->RemoveApplyTask(shared_from_this());
810 }
811 }
812
GetBundleName()813 std::string QuickFixManagerApplyTask::GetBundleName()
814 {
815 return bundleName_;
816 }
817
GetTaskType()818 QuickFixManagerApplyTask::TaskType QuickFixManagerApplyTask::GetTaskType()
819 {
820 return taskType_;
821 }
822
PostRevokeQuickFixTask()823 void QuickFixManagerApplyTask::PostRevokeQuickFixTask()
824 {
825 std::weak_ptr<QuickFixManagerApplyTask> thisWeakPtr(weak_from_this());
826 auto revokeTask = [thisWeakPtr] () {
827 auto applyTask = thisWeakPtr.lock();
828 if (applyTask == nullptr) {
829 TAG_LOGE(AAFwkTag::QUICKFIX, "null revoke task");
830 return;
831 }
832 if (applyTask->GetRunningState()) {
833 applyTask->HandleRevokeQuickFixAppRunning();
834 return;
835 }
836 applyTask->HandleRevokeQuickFixAppStop();
837 };
838 if (eventHandler_ == nullptr || !eventHandler_->PostTask(revokeTask, "QuickFixManager:revokeTask")) {
839 TAG_LOGE(AAFwkTag::QUICKFIX, "post revoke failed");
840 }
841 PostTimeOutTask();
842 }
843
HandleRevokeQuickFixAppRunning()844 void QuickFixManagerApplyTask::HandleRevokeQuickFixAppRunning()
845 {
846 // process run
847 // so contained, reg app died
848 if (isSoContained_) {
849 RegAppStateObserver();
850 RemoveTimeoutTask();
851 return;
852 }
853
854 // so not contained, call bms to switch
855 HandleRevokeQuickFixAppStop();
856 }
857
HandleRevokePatchSwitched()858 void QuickFixManagerApplyTask::HandleRevokePatchSwitched()
859 {
860 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
861 // process is run, notify app unload patch
862 if (GetRunningState()) {
863 PostRevokeQuickFixNotifyUnloadPatchTask();
864 return;
865 }
866
867 // call bms to delete patch
868 PostRevokeQuickFixDeleteTask();
869 }
870
PostRevokeQuickFixNotifyUnloadPatchTask()871 void QuickFixManagerApplyTask::PostRevokeQuickFixNotifyUnloadPatchTask()
872 {
873 // notify app process unload patch
874 if (appMgr_ == nullptr) {
875 TAG_LOGE(AAFwkTag::QUICKFIX, "null appMgr");
876 NotifyApplyStatus(QUICK_FIX_APPMGR_INVALID);
877 RemoveSelf();
878 return;
879 }
880
881 // app process run and wait callback
882 auto callback = sptr<RevokeQuickFixNotifyCallback>::MakeSptr(shared_from_this());
883 // The validity of callback will be checked below.
884 auto ret = appMgr_->NotifyUnLoadRepairPatch(bundleName_, callback);
885 if (ret != 0) {
886 TAG_LOGE(AAFwkTag::QUICKFIX, "Notify app unload patch failed");
887 NotifyApplyStatus(QUICK_FIX_NOTIFY_UNLOAD_PATCH_FAILED);
888 RemoveSelf();
889 }
890
891 TAG_LOGD(AAFwkTag::QUICKFIX, "Function end");
892 }
893
PostRevokeQuickFixDeleteTask()894 void QuickFixManagerApplyTask::PostRevokeQuickFixDeleteTask()
895 {
896 auto callback = sptr<RevokeQuickFixTaskCallback>::MakeSptr(shared_from_this());
897 if (callback == nullptr || bundleQfMgr_ == nullptr) {
898 TAG_LOGE(AAFwkTag::QUICKFIX, "Param invalid");
899 NotifyApplyStatus(QUICK_FIX_BUNDLEMGR_INVALID);
900 RemoveSelf();
901 return;
902 }
903
904 // call delete patch to bms
905 auto ret = bundleQfMgr_->DeleteQuickFix(bundleName_, callback);
906 if (ret != ERR_OK) {
907 TAG_LOGE(AAFwkTag::QUICKFIX, "failed: %{public}d", ret);
908 NotifyApplyStatus(QUICK_FIX_DELETE_FAILED);
909 RemoveSelf();
910 return;
911 }
912 }
913
PostRevokeQuickFixProcessDiedTask()914 void QuickFixManagerApplyTask::PostRevokeQuickFixProcessDiedTask()
915 {
916 TAG_LOGD(AAFwkTag::QUICKFIX, "called");
917 // app process died
918 HandleRevokeQuickFixAppStop();
919 PostTimeOutTask();
920 }
921
HandleRevokeQuickFixAppStop()922 void QuickFixManagerApplyTask::HandleRevokeQuickFixAppStop()
923 {
924 auto callback = sptr<RevokeQuickFixTaskCallback>::MakeSptr(shared_from_this());
925 if (callback == nullptr || bundleQfMgr_ == nullptr) {
926 TAG_LOGE(AAFwkTag::QUICKFIX, "Param invalid");
927 NotifyApplyStatus(QUICK_FIX_BUNDLEMGR_INVALID);
928 RemoveSelf();
929 return;
930 }
931
932 auto ret = bundleQfMgr_->SwitchQuickFix(bundleName_, false, callback);
933 if (ret != ERR_OK) {
934 TAG_LOGE(AAFwkTag::QUICKFIX, "failed: %{public}d", ret);
935 NotifyApplyStatus(QUICK_FIX_SWICH_FAILED);
936 RemoveSelf();
937 return;
938 }
939 }
940
HandleRevokePatchDeleted()941 void QuickFixManagerApplyTask::HandleRevokePatchDeleted()
942 {
943 NotifyApplyStatus(QUICK_FIX_OK);
944 RemoveSelf();
945 }
946 } // namespace AAFwk
947 } // namespace OHOS