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