• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 #include "continuation_handler.h"
16 
17 #include "ability_manager_client.h"
18 #include "distributed_errors.h"
19 #include "element_name.h"
20 #include "hilog_wrapper.h"
21 
22 using OHOS::AAFwk::WantParams;
23 namespace OHOS {
24 namespace AppExecFwk {
25 const std::string ContinuationHandler::ORIGINAL_DEVICE_ID("deviceId");
26 const std::string VERSION_CODE_KEY = "version";
ContinuationHandler(std::weak_ptr<ContinuationManager> & continuationManager,std::weak_ptr<Ability> & ability)27 ContinuationHandler::ContinuationHandler(
28     std::weak_ptr<ContinuationManager> &continuationManager, std::weak_ptr<Ability> &ability)
29 {
30     ability_ = ability;
31     continuationManager_ = continuationManager;
32 }
33 
HandleStartContinuationWithStack(const sptr<IRemoteObject> & token,const std::string & deviceId,uint32_t versionCode)34 bool ContinuationHandler::HandleStartContinuationWithStack(const sptr<IRemoteObject> &token,
35     const std::string &deviceId, uint32_t versionCode)
36 {
37     HILOG_DEBUG("%{public}s called begin", __func__);
38     if (token == nullptr) {
39         HILOG_ERROR("HandleStartContinuationWithStack token is null.");
40         return false;
41     }
42     if (abilityInfo_ == nullptr) {
43         HILOG_ERROR("HandleStartContinuationWithStack abilityInfo is null.");
44         return false;
45     }
46 
47     abilityInfo_->deviceId = deviceId;
48 
49     std::shared_ptr<ContinuationManager> continuationManagerTmp = nullptr;
50     continuationManagerTmp = continuationManager_.lock();
51     if (continuationManagerTmp == nullptr) {
52         HILOG_ERROR("HandleStartContinuationWithStack: get continuationManagerTmp is nullptr");
53         return false;
54     }
55 
56     // decided to start continuation. Callback to ability.
57     Want want;
58     want.SetParam(VERSION_CODE_KEY, static_cast<int32_t>(versionCode));
59     want.SetParam("targetDevice", deviceId);
60     WantParams wantParams = want.GetParams();
61     int32_t status = continuationManagerTmp->OnContinue(wantParams);
62     if (status != ERR_OK) {
63         HILOG_INFO("OnContinue failed, BundleName = %{public}s, ClassName= %{public}s, status: %{public}d",
64             abilityInfo_->bundleName.c_str(),
65             abilityInfo_->name.c_str(),
66             status);
67     }
68 
69     want.SetParams(wantParams);
70     want.AddFlags(want.FLAG_ABILITY_CONTINUATION);
71     want.SetElementName(deviceId, abilityInfo_->bundleName, abilityInfo_->name, abilityInfo_->moduleName);
72 
73     int result = AAFwk::AbilityManagerClient::GetInstance()->StartContinuation(want, token, status);
74     if (result != ERR_OK) {
75         HILOG_ERROR("startContinuation failed.");
76         return false;
77     }
78     HILOG_DEBUG("%{public}s called end", __func__);
79     return true;
80 }
81 
HandleStartContinuation(const sptr<IRemoteObject> & token,const std::string & deviceId)82 bool ContinuationHandler::HandleStartContinuation(const sptr<IRemoteObject> &token, const std::string &deviceId)
83 {
84     HILOG_DEBUG("%{public}s called begin", __func__);
85     if (token == nullptr) {
86         HILOG_ERROR("ContinuationHandler::HandleStartContinuation token is null.");
87         return false;
88     }
89     if (abilityInfo_ == nullptr) {
90         HILOG_ERROR("ContinuationHandler::HandleStartContinuation abilityInfo is null.");
91         return false;
92     }
93 
94     abilityInfo_->deviceId = deviceId;
95 
96     std::shared_ptr<ContinuationManager> continuationManagerTmp = nullptr;
97     continuationManagerTmp = continuationManager_.lock();
98     if (continuationManagerTmp == nullptr) {
99         HILOG_ERROR("handleStartContinuation: get continuationManagerTmp is nullptr");
100         return false;
101     }
102 
103     // DMS decided to start continuation. Callback to ability.
104     if (!continuationManagerTmp->StartContinuation()) {
105         HILOG_DEBUG("handleStartContinuation: Ability rejected.");
106         HILOG_INFO("ID_ABILITY_SHELL_CONTINUE_ABILITY, BundleName = %{public}s, ClassName= %{public}s",
107             abilityInfo_->bundleName.c_str(),
108             abilityInfo_->name.c_str());
109         return false;
110     }
111 
112     WantParams wantParams;
113     if (!continuationManagerTmp->SaveData(wantParams)) {
114         HILOG_DEBUG("handleStartContinuation: ScheduleSaveData failed.");
115         HILOG_INFO("ID_ABILITY_SHELL_CONTINUE_ABILITY, BundleName = %{public}s, ClassName= %{public}s",
116             abilityInfo_->bundleName.c_str(),
117             abilityInfo_->name.c_str());
118         return false;
119     }
120 
121     Want want = SetWantParams(wantParams);
122     want.SetElementName(deviceId, abilityInfo_->bundleName, abilityInfo_->name, abilityInfo_->moduleName);
123 
124     int result = AAFwk::AbilityManagerClient::GetInstance()->StartContinuation(want, token, 0);
125     if (result != 0) {
126         HILOG_ERROR("distClient_.startContinuation failed.");
127         return false;
128     }
129     HILOG_DEBUG("%{public}s called end", __func__);
130     return true;
131 }
132 
HandleReceiveRemoteScheduler(const sptr<IRemoteObject> & remoteReplica)133 void ContinuationHandler::HandleReceiveRemoteScheduler(const sptr<IRemoteObject> &remoteReplica)
134 {
135     HILOG_DEBUG("%{public}s called begin", __func__);
136     if (remoteReplica == nullptr) {
137         HILOG_ERROR("scheduler is nullptr");
138         return;
139     }
140 
141     if (remoteReplicaProxy_ != nullptr && schedulerDeathRecipient_ != nullptr) {
142         auto schedulerObjectTmp = remoteReplicaProxy_->AsObject();
143         if (schedulerObjectTmp != nullptr) {
144             schedulerObjectTmp->RemoveDeathRecipient(schedulerDeathRecipient_);
145         }
146     }
147 
148     if (schedulerDeathRecipient_ == nullptr) {
149         schedulerDeathRecipient_ = new (std::nothrow) ReverseContinuationSchedulerRecipient(
150             std::bind(&ContinuationHandler::OnReplicaDied, this, std::placeholders::_1));
151     }
152 
153     remoteReplicaProxy_ = iface_cast<IReverseContinuationSchedulerReplica>(remoteReplica);
154     auto schedulerObject = remoteReplicaProxy_->AsObject();
155     if (schedulerObject != nullptr) {
156         schedulerObject->AddDeathRecipient(schedulerDeathRecipient_);
157     }
158 
159     remoteReplicaProxy_->PassPrimary(remotePrimaryStub_);
160     HILOG_DEBUG("%{public}s called end", __func__);
161 }
162 
HandleCompleteContinuation(int result)163 void ContinuationHandler::HandleCompleteContinuation(int result)
164 {
165     HILOG_DEBUG("%{public}s called begin", __func__);
166     std::shared_ptr<ContinuationManager> continuationManagerTmp = nullptr;
167     continuationManagerTmp = continuationManager_.lock();
168     if (continuationManagerTmp == nullptr) {
169         HILOG_ERROR("ContinuationHandler::HandleCompleteContinuation: get continuationManagerTmp is nullptr");
170         return;
171     }
172 
173     continuationManagerTmp->CompleteContinuation(result);
174     HILOG_DEBUG("%{public}s called end", __func__);
175 }
176 
SetReversible(bool reversible)177 void ContinuationHandler::SetReversible(bool reversible)
178 {
179     HILOG_DEBUG("%{public}s called", __func__);
180     reversible_ = reversible;
181 }
182 
SetAbilityInfo(std::shared_ptr<AbilityInfo> & abilityInfo)183 void ContinuationHandler::SetAbilityInfo(std::shared_ptr<AbilityInfo> &abilityInfo)
184 {
185     HILOG_DEBUG("%{public}s called begin", __func__);
186     abilityInfo_ = std::make_shared<AbilityInfo>(*(abilityInfo.get()));
187     ClearDeviceInfo(abilityInfo_);
188     HILOG_DEBUG("%{public}s called end", __func__);
189 }
190 
SetPrimaryStub(const sptr<IRemoteObject> & Primary)191 void ContinuationHandler::SetPrimaryStub(const sptr<IRemoteObject> &Primary)
192 {
193     HILOG_DEBUG("%{public}s called", __func__);
194     remotePrimaryStub_ = Primary;
195 }
196 
ClearDeviceInfo(std::shared_ptr<AbilityInfo> & abilityInfo)197 void ContinuationHandler::ClearDeviceInfo(std::shared_ptr<AbilityInfo> &abilityInfo)
198 {
199     HILOG_DEBUG("%{public}s called", __func__);
200     abilityInfo->deviceId = "";
201     abilityInfo->deviceTypes.clear();
202 }
203 
OnReplicaDied(const wptr<IRemoteObject> & remote)204 void ContinuationHandler::OnReplicaDied(const wptr<IRemoteObject> &remote)
205 {
206     HILOG_DEBUG("%{public}s called begin", __func__);
207     if (remoteReplicaProxy_ == nullptr) {
208         HILOG_ERROR("BUG: remote death notifies to a unready replica.");
209         return;
210     }
211 
212     auto object = remote.promote();
213     if (!object) {
214         HILOG_ERROR("replica on remoteReplica died: null object.");
215         return;
216     }
217 
218     if (object != remoteReplicaProxy_->AsObject()) {
219         HILOG_ERROR("replica on remoteReplica died: remoteReplica is not matches with remote.");
220         return;
221     }
222 
223     if (remoteReplicaProxy_ != nullptr && schedulerDeathRecipient_ != nullptr) {
224         auto schedulerObject = remoteReplicaProxy_->AsObject();
225         if (schedulerObject != nullptr) {
226             schedulerObject->RemoveDeathRecipient(schedulerDeathRecipient_);
227         }
228     }
229     remoteReplicaProxy_.clear();
230 
231     NotifyReplicaTerminated();
232     HILOG_DEBUG("%{public}s called end", __func__);
233 }
234 
NotifyReplicaTerminated()235 void ContinuationHandler::NotifyReplicaTerminated()
236 {
237     HILOG_DEBUG("%{public}s called begin", __func__);
238 
239     CleanUpAfterReverse();
240 
241     std::shared_ptr<ContinuationManager> continuationManagerTmp = nullptr;
242     continuationManagerTmp = continuationManager_.lock();
243     if (continuationManagerTmp == nullptr) {
244         HILOG_ERROR("ContinuationHandler::NotifyReplicaTerminated: get continuationManagerTmp is nullptr");
245         return;
246     }
247     HILOG_DEBUG("%{public}s called end", __func__);
248     continuationManagerTmp->NotifyRemoteTerminated();
249 }
250 
SetWantParams(const WantParams & wantParams)251 Want ContinuationHandler::SetWantParams(const WantParams &wantParams)
252 {
253     HILOG_DEBUG("%{public}s called begin", __func__);
254     Want want;
255     want.SetParams(wantParams);
256     want.AddFlags(want.FLAG_ABILITY_CONTINUATION);
257     if (abilityInfo_->launchMode != LaunchMode::STANDARD) {
258         HILOG_DEBUG("SetWantParams: Clear task.");
259     }
260     if (reversible_) {
261         HILOG_DEBUG("SetWantParams: Reversible.");
262         want.AddFlags(Want::FLAG_ABILITY_CONTINUATION_REVERSIBLE);
263     }
264     ElementName element("", abilityInfo_->bundleName, abilityInfo_->name, abilityInfo_->moduleName);
265     want.SetElement(element);
266     HILOG_DEBUG("%{public}s called end", __func__);
267     return want;
268 }
269 
CleanUpAfterReverse()270 void ContinuationHandler::CleanUpAfterReverse()
271 {
272     HILOG_DEBUG("%{public}s called", __func__);
273     remoteReplicaProxy_ = nullptr;
274 }
275 
PassPrimary(const sptr<IRemoteObject> & Primary)276 void ContinuationHandler::PassPrimary(const sptr<IRemoteObject> &Primary)
277 {
278     HILOG_DEBUG("%{public}s called", __func__);
279     remotePrimaryProxy_ = iface_cast<IReverseContinuationSchedulerPrimary>(Primary);
280 }
281 
ReverseContinuation()282 bool ContinuationHandler::ReverseContinuation()
283 {
284     HILOG_DEBUG("%{public}s called begin", __func__);
285 
286     if (remotePrimaryProxy_ == nullptr) {
287         HILOG_ERROR("ReverseContinuation:remotePrimaryProxy_ not initialized, can not reverse");
288         return false;
289     }
290 
291     if (abilityInfo_ == nullptr) {
292         HILOG_ERROR("ReverseContinuation: abilityInfo is null");
293         return false;
294     }
295 
296     std::shared_ptr<ContinuationManager> continuationManagerTmp = nullptr;
297     continuationManagerTmp = continuationManager_.lock();
298     if (continuationManagerTmp == nullptr) {
299         HILOG_ERROR("ReverseContinuation: get continuationManagerTmp is nullptr");
300         return false;
301     }
302 
303     if (!continuationManagerTmp->StartContinuation()) {
304         HILOG_ERROR("ReverseContinuation: Ability rejected.");
305         HILOG_INFO("ReverseContinuation, BundleName = %{public}s, ClassName= %{public}s",
306             abilityInfo_->bundleName.c_str(),
307             abilityInfo_->name.c_str());
308         return false;
309     }
310 
311     WantParams wantParams;
312     if (!continuationManagerTmp->SaveData(wantParams)) {
313         HILOG_ERROR("ReverseContinuation: SaveData failed.");
314         HILOG_INFO("ReverseContinuation, BundleName = %{public}s, ClassName= %{public}s",
315             abilityInfo_->bundleName.c_str(),
316             abilityInfo_->name.c_str());
317         return false;
318     }
319 
320     Want want;
321     want.SetParams(wantParams);
322     if (remotePrimaryProxy_->ContinuationBack(want)) {
323         HILOG_ERROR("reverseContinuation: ContinuationBack send failed.");
324         return false;
325     }
326     HILOG_DEBUG("%{public}s called end", __func__);
327     return true;
328 }
329 
NotifyReverseResult(int reverseResult)330 void ContinuationHandler::NotifyReverseResult(int reverseResult)
331 {
332     HILOG_DEBUG("NotifyReverseResult: Start. result = %{public}d", reverseResult);
333     if (reverseResult == 0) {
334         std::shared_ptr<Ability> ability = nullptr;
335         ability = ability_.lock();
336         if (ability == nullptr) {
337             HILOG_ERROR("ContinuationHandler::NotifyReverseResult failed. ability is nullptr");
338             return;
339         }
340         ability->TerminateAbility();
341     }
342     HILOG_DEBUG("%{public}s called end", __func__);
343 }
344 
ContinuationBack(const Want & want)345 bool ContinuationHandler::ContinuationBack(const Want &want)
346 {
347     HILOG_DEBUG("%{public}s called begin", __func__);
348     std::shared_ptr<ContinuationManager> continuationManagerTmp = nullptr;
349     continuationManagerTmp = continuationManager_.lock();
350     if (continuationManagerTmp == nullptr) {
351         HILOG_ERROR("ContinuationBack: get continuationManagerTmp is nullptr");
352         return false;
353     }
354 
355     int result = 0;
356     if (!continuationManagerTmp->RestoreFromRemote(want.GetParams())) {
357         HILOG_INFO("ContinuationBack: RestoreFromRemote failed.");
358         result = ABILITY_FAILED_RESTORE_DATA;
359     }
360 
361     remoteReplicaProxy_->NotifyReverseResult(result);
362     if (result == 0) {
363         CleanUpAfterReverse();
364     }
365     HILOG_DEBUG("%{public}s called end", __func__);
366     return true;
367 }
368 
NotifyTerminationToPrimary()369 void ContinuationHandler::NotifyTerminationToPrimary()
370 {
371     HILOG_DEBUG("%{public}s called begin", __func__);
372     if (remotePrimaryProxy_ == nullptr) {
373         HILOG_ERROR("NotifyTerminationToPrimary: remotePrimary not initialized, can not notify");
374         return;
375     }
376 
377     HILOG_DEBUG("NotifyTerminationToPrimary: Start");
378     remotePrimaryProxy_->NotifyReplicaTerminated();
379     HILOG_DEBUG("%{public}s called end", __func__);
380 }
381 
ReverseContinueAbility()382 bool ContinuationHandler::ReverseContinueAbility()
383 {
384     HILOG_DEBUG("%{public}s called begin", __func__);
385     if (remoteReplicaProxy_ == nullptr) {
386         HILOG_ERROR("ReverseContinueAbility: remoteReplica not initialized, can not reverse");
387         return false;
388     }
389 
390     HILOG_DEBUG("ReverseContinueAbility: Start");
391     bool requestSendSuccess = remoteReplicaProxy_->ReverseContinuation();
392     HILOG_DEBUG("%{public}s called end", __func__);
393     return requestSendSuccess;
394 }
395 }  // namespace AppExecFwk
396 }  // namespace OHOS
397