• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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