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