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