1 /*
2 * Copyright (c) 2020 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 "ability_start_task.h"
17
18 #include "ability_stack_manager.h"
19
20 namespace OHOS {
AbilityStartTask(AbilityMgrContext * context,const Want * want,const AbilityInfo * target,const BundleInfo * bundleInfo)21 AbilityStartTask::AbilityStartTask(AbilityMgrContext *context, const Want *want,
22 const AbilityInfo *target, const BundleInfo *bundleInfo)
23 : AbilityTask(context), want_(want), target_(target), bundleInfo_(bundleInfo)
24 {
25 }
26
~AbilityStartTask()27 AbilityStartTask::~AbilityStartTask()
28 {
29 want_ = nullptr;
30 target_ = nullptr;
31 bundleInfo_ = nullptr;
32 }
33
SetWaitConnect(bool waitConnect)34 void AbilityStartTask::SetWaitConnect(bool waitConnect)
35 {
36 waitConnect_ = waitConnect;
37 }
38
Execute()39 AbilityMsStatus AbilityStartTask::Execute()
40 {
41 PRINTD("AbilityStartTask", "start");
42 if (abilityMgrContext_ == nullptr || want_ == nullptr ||
43 target_ == nullptr || bundleInfo_ == nullptr) {
44 return AbilityMsStatus::TaskStatus("start", "invalid argument");
45 }
46 if (target_->abilityType == AbilityType::SERVICE) {
47 return StartService();
48 }
49 AbilityStackManager &stackManager = AbilityStackManager::GetInstance();
50 // Step1: Get current top ability record.
51 PageAbilityRecord *topAbility = const_cast<PageAbilityRecord *>(
52 stackManager.GetTopPageAbility(*abilityMgrContext_));
53 // Step2: Generate target ability record.
54 PageAbilityRecord *targetAbility = stackManager.GeneratePageAbility(
55 *target_, *want_, topAbility, *abilityMgrContext_);
56 if (targetAbility == nullptr || targetAbility == topAbility) {
57 return AbilityMsStatus::TaskStatus("start", "generate ability record failure");
58 }
59 targetAbility->SetBundleInfo(*bundleInfo_);
60 if (topAbility != nullptr) {
61 // step3:If topAbility is not nullptr, inactive top ability.
62 PRINTD("AbilityStartTask", "topAbility is not nullptr, first inactive");
63 AbilityMsStatus status = topAbility->InactiveAbility();
64 if (status.IsOk()) {
65 topAbility->SetNextPageAbility(targetAbility);
66 targetAbility->SetPrevPageAbility(topAbility);
67 } else {
68 stackManager.RemovePageAbility(*targetAbility, *abilityMgrContext_);
69 }
70 return status;
71 }
72 // step4: Start ability.
73 PRINTD("AbilityStartTask", "topAbility is nullptr or not active");
74 AbilityMsStatus status = targetAbility->StartAbility();
75 if (status.IsProcessError() || status.IsTransactError()) {
76 // Clean page ability record if failure
77 stackManager.RemovePageAbility(*targetAbility, *abilityMgrContext_);
78 }
79 return status;
80 }
81
StartService()82 AbilityMsStatus AbilityStartTask::StartService()
83 {
84 PRINTD("AbilityStartTask", "start service");
85 auto connectMission = const_cast<AbilityConnectMission *>(abilityMgrContext_->GetServiceConnects());
86 if (connectMission == nullptr) {
87 return AbilityMsStatus::TaskStatus("start", "invalid argument");
88 }
89 auto service = connectMission->FindServiceRecord(target_->bundleName, target_->name);
90 if (service != nullptr) {
91 return AbilityMsStatus::TaskStatus("start", "service ability exists");
92 }
93 auto targetAbility = new PageAbilityRecord(*target_, *want_);
94 targetAbility->SetBundleInfo(*bundleInfo_);
95 if (waitConnect_) {
96 targetAbility->SetStartDone(false);
97 targetAbility->SetConnectStatus(ConnectStatus::WAIT_CONNECT);
98 } else {
99 targetAbility->SetStartDone(true);
100 }
101 connectMission->PushServiceRecord(*targetAbility);
102 targetAbility->SetConnectMission(connectMission);
103 AbilityMsStatus status = targetAbility->StartService();
104 if (status.IsProcessError() || status.IsTransactError()) {
105 // Clean service ability record if failure
106 connectMission->RemoveServiceRecord(targetAbility->GetToken());
107 }
108 return status;
109 }
110 } // namespace OHOS
111