• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2025 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 "dsched_continue.h"
17 
18 #include <chrono>
19 #include <sys/prctl.h>
20 #include <thread>
21 
22 #include "ability_manager_client.h"
23 #include "bool_wrapper.h"
24 #include "bundle/bundle_manager_internal.h"
25 #include "continue_scene_session_handler.h"
26 #include "datetime_ex.h"
27 #include "dfx/distributed_radar.h"
28 #include "dfx/distributed_ue.h"
29 #include "dfx/dms_continue_time_dumper.h"
30 #include "dfx/dms_hianalytics_report.h"
31 #include "distributed_sched_permission.h"
32 #include "distributed_sched_service.h"
33 #include "distributed_sched_utils.h"
34 #include "dsched_continue_event.h"
35 #include "dsched_continue_manager.h"
36 #include "dsched_data_buffer.h"
37 #include "dtbschedmgr_device_info_storage.h"
38 #include "dtbschedmgr_log.h"
39 #include "mission/distributed_bm_storage.h"
40 #include "mission/dsched_sync_e2e.h"
41 #include "multi_user_manager.h"
42 #include "ipc_skeleton.h"
43 #include "parcel_helper.h"
44 #ifdef SUPPORT_DISTRIBUTED_MISSION_MANAGER
45 #include "mission/dms_continue_condition_manager.h"
46 #endif
47 #include "scene_board_judgement.h"
48 #include "softbus_adapter/transport/dsched_transport_softbus_adapter.h"
49 #include "softbus_error_code.h"
50 
51 namespace OHOS {
52 namespace DistributedSchedule {
53 using namespace AAFwk;
54 namespace {
55 const std::string TAG = "DSchedContinue";
56 const std::string VERSION_CODE_KEY = "version";
57 const std::string DMS_SRC_NETWORK_ID = "dmsSrcNetworkId";
58 const std::string DMS_VERSION_ID = "dmsVersion";
59 const std::string SUPPORT_CONTINUE_PAGE_STACK_KEY = "ohos.extra.param.key.supportContinuePageStack";
60 const std::string SUPPORT_CONTINUE_SOURCE_EXIT_KEY = "ohos.extra.param.key.supportContinueSourceExit";
61 const std::string SUPPORT_CONTINUE_MODULE_NAME_UPDATE_KEY = "ohos.extra.param.key.supportContinueModuleNameUpdate";
62 const std::string DMSDURATION_SAVETIME = "ohos.dschedule.SaveDataTime";
63 const std::string DMS_PERSISTENT_ID = "ohos.dms.persistentId";
64 const std::string DMS_CONTINUE_SESSION_ID = "ohos.dms.continueSessionId";
65 const std::string QUICK_START_CONFIGURATION = "_ContinueQuickStart";
66 const std::string QUICK_START_SUCCESS_MESSAGE = "quickstart success.";
67 const std::string QUICK_START_FAILED_MESSAGE = "quickstart failed. error code: ";
68 const std::u16string NAPI_MISSION_CALLBACK_INTERFACE_TOKEN = u"ohos.DistributedSchedule.IMissionCallback";
69 
70 constexpr int32_t DSCHED_CONTINUE_PROTOCOL_VERSION = 1;
71 constexpr uint32_t MAX_MODULENAME_LEN = 2048;
72 constexpr int32_t DEFAULT_REQUEST_CODE = -1;
73 constexpr int32_t NOTIFY_MISSION_CALLBACK_RESULT = 4;
74 constexpr int32_t DMS_VERSION = 5;
75 constexpr int32_t START_PERMISSION = 0;
76 
77 constexpr int32_t CONTINUE_BEGIN_TIME = 0;
78 constexpr int32_t CONTINUE_END_TIME = 1;
79 constexpr int32_t CONTINUE_TOTAL_TIME = 2;
80 constexpr int32_t CONTINUE_FIRST_TRANS_TIME = 3;
81 constexpr int32_t CONTINUE_DATA_TRANS_TIME = 5;
82 constexpr int32_t CONTINUE_START_ABILITY_TIME = 6;
83 constexpr int32_t GET_ABILITY_STATE_RETRY_TIMES = 40;
84 constexpr int32_t GET_ABILITY_STATE_SLEEP_TIME = 50;
85 constexpr int32_t QUICK_START_SUCCESS = 0;
86 constexpr int32_t QUICK_START_FAILED = 1;
87 
88 }
89 
90 const std::map<int32_t, int32_t> DSchedContinue::DMS_CONVERT_TO_SDK_ERR_MAP = {
91     std::map<int32_t, int32_t>::value_type(SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_AP_STA_CHIP_CONFLICT,
92         DmsInterfaceSdkErr::ERR_BIND_REMOTE_HOTSPOT_ENABLE_STATE),
93     std::map<int32_t, int32_t>::value_type(SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_AP_P2P_CHIP_CONFLICT,
94         DmsInterfaceSdkErr::ERR_BIND_REMOTE_HOTSPOT_ENABLE_STATE),
95     std::map<int32_t, int32_t>::value_type(SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_AP_HML_CHIP_CONFLICT,
96         DmsInterfaceSdkErr::ERR_BIND_REMOTE_HOTSPOT_ENABLE_STATE),
97     std::map<int32_t, int32_t>::value_type(SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_AP_STA_HML_CHIP_CONFLICT,
98         DmsInterfaceSdkErr::ERR_BIND_REMOTE_HOTSPOT_ENABLE_STATE),
99     std::map<int32_t, int32_t>::value_type(SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_AP_STA_P2P_CHIP_CONFLICT,
100         DmsInterfaceSdkErr::ERR_BIND_REMOTE_HOTSPOT_ENABLE_STATE),
101     std::map<int32_t, int32_t>::value_type(SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_AP_P2P_HML_CHIP_CONFLICT,
102         DmsInterfaceSdkErr::ERR_BIND_REMOTE_HOTSPOT_ENABLE_STATE),
103     std::map<int32_t, int32_t>::value_type(ERROR_PEER_THREE_VAP_CONFLICT,
104         DmsInterfaceSdkErr::ERR_BIND_REMOTE_HOTSPOT_ENABLE_STATE),
105 
106     std::map<int32_t, int32_t>::value_type(SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_HML_NUM_LIMITED_CONFLICT,
107         DmsInterfaceSdkErr::ERR_BIND_REMOTE_IN_BUSY_LINK),
108     std::map<int32_t, int32_t>::value_type(SoftBusErrNo::SOFTBUS_CONN_PV1_PEER_GC_CONNECTED_TO_ANOTHER_DEVICE,
109         DmsInterfaceSdkErr::ERR_BIND_REMOTE_IN_BUSY_LINK),
110     std::map<int32_t, int32_t>::value_type(SoftBusErrNo::SOFTBUS_CONN_PV2_PEER_GC_CONNECTED_TO_ANOTHER_DEVICE,
111         DmsInterfaceSdkErr::ERR_BIND_REMOTE_IN_BUSY_LINK),
112     std::map<int32_t, int32_t>::value_type(SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_STA_P2P_HML_55_CONFLICT,
113         DmsInterfaceSdkErr::ERR_BIND_REMOTE_IN_BUSY_LINK),
114     std::map<int32_t, int32_t>::value_type(SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_STA_P2P_HML_225_CONFLICT,
115         DmsInterfaceSdkErr::ERR_BIND_REMOTE_IN_BUSY_LINK),
116     std::map<int32_t, int32_t>::value_type(SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_STA_P2P_HML_255_CONFLICT,
117         DmsInterfaceSdkErr::ERR_BIND_REMOTE_IN_BUSY_LINK),
118     std::map<int32_t, int32_t>::value_type(SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_STA_P2P_HML_525_CONFLICT,
119         DmsInterfaceSdkErr::ERR_BIND_REMOTE_IN_BUSY_LINK),
120     std::map<int32_t, int32_t>::value_type(SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_STA_P2P_HML_555_CONFLICT,
121         DmsInterfaceSdkErr::ERR_BIND_REMOTE_IN_BUSY_LINK),
122     std::map<int32_t, int32_t>::value_type(SoftBusErrNo::SOFTBUS_CONN_PASSIVE_TYPE_P2P_GO_GC_CONFLICT,
123         DmsInterfaceSdkErr::ERR_BIND_REMOTE_IN_BUSY_LINK),
124 
125     std::map<int32_t, int32_t>::value_type(CONTINUE_ALREADY_IN_PROGRESS,
126         DmsInterfaceSdkErr::ERR_CONTINUE_ALREADY_IN_PROGRESS),
127 };
128 
OnRemoteDied(const wptr<IRemoteObject> & object)129 void StateCallbackIpcDiedListener::OnRemoteDied(const wptr<IRemoteObject> &object)
130 {
131     HILOGW("State call back remote object died, clean cache! ");
132     DSchedContinueManager::GetInstance().ContinueStateCallbackUnRegister(stateCallbackInfo_);
133 }
134 
DSchedContinue(int32_t subServiceType,int32_t direction,const sptr<IRemoteObject> & callback,const DSchedContinueInfo & continueInfo,int32_t accountId)135 DSchedContinue::DSchedContinue(int32_t subServiceType, int32_t direction,  const sptr<IRemoteObject>& callback,
136     const DSchedContinueInfo& continueInfo, int32_t accountId) : subServiceType_(subServiceType), direction_(direction),
137     continueInfo_(continueInfo), callback_(callback), accountId_(accountId)
138 {
139     HILOGI("DSchedContinue create");
140     version_ = DSCHED_CONTINUE_PROTOCOL_VERSION;
141     continueByType_ = !continueInfo.continueType_.empty();
142 
143     SetEventData();
144     NotifyDSchedEventResult(ERR_OK);
145 }
146 
DSchedContinue(std::shared_ptr<DSchedContinueStartCmd> startCmd,int32_t sessionId,int32_t accountId)147 DSchedContinue::DSchedContinue(std::shared_ptr<DSchedContinueStartCmd> startCmd, int32_t sessionId, int32_t accountId)
148 {
149     HILOGI("DSchedContinue create by start command");
150     if (startCmd == nullptr) {
151         HILOGE("startCmd is null");
152         return;
153     }
154     version_ = DSCHED_CONTINUE_PROTOCOL_VERSION;
155     subServiceType_ = startCmd->subServiceType_;
156     continueByType_ = startCmd->continueByType_;
157     direction_ = (startCmd->direction_ == CONTINUE_SOURCE) ? CONTINUE_SINK : CONTINUE_SOURCE;
158     continueInfo_.sourceDeviceId_ = startCmd->srcDeviceId_;
159     continueInfo_.sourceBundleName_ = startCmd->srcBundleName_;
160     continueInfo_.sinkDeviceId_ = startCmd->dstDeviceId_;
161     continueInfo_.sinkBundleName_ = startCmd->dstBundleName_;
162     continueInfo_.continueType_ = startCmd->continueType_;
163     continueInfo_.missionId_ = startCmd->sourceMissionId_;
164     softbusSessionId_ = sessionId;
165     SetEventData();
166     NotifyDSchedEventResult(ERR_OK);
167     if (continueInfo_.sourceBundleName_.empty() && continueInfo_.sinkBundleName_.empty()
168         && continueInfo_.missionId_ != 0) {
169         MissionInfo missionInfo;
170         if (AbilityManagerClient::GetInstance()->GetMissionInfo("", continueInfo_.missionId_, missionInfo) != ERR_OK) {
171             HILOGE("get missionInfo failed");
172             return;
173         }
174         continueInfo_.sourceBundleName_ = missionInfo.want.GetBundle();
175         continueInfo_.sinkBundleName_ = missionInfo.want.GetBundle();
176     }
177     accountId_ = accountId;
178 }
179 
~DSchedContinue()180 DSchedContinue::~DSchedContinue()
181 {
182     HILOGI("DSchedContinue delete enter");
183     if ((eventHandler_ != nullptr) && (eventHandler_->GetEventRunner() != nullptr)) {
184         eventHandler_->GetEventRunner()->Stop();
185     }
186     if (eventThread_.joinable()) {
187         eventThread_.join();
188     }
189     eventHandler_ = nullptr;
190     HILOGI("DSchedContinue delete end");
191 }
192 
SetEventData()193 void DSchedContinue::SetEventData()
194 {
195     HILOGI("called");
196     ContinueEventInfo srcContinueInfo;
197     DmsBmStorage::GetInstance()->GetContinueEventInfo(continueInfo_.sourceDeviceId_, continueInfo_.sourceBundleName_,
198         continueInfo_.continueType_, srcContinueInfo);
199     ContinueEventInfo dstContinueInfo;
200     DmsBmStorage::GetInstance()->GetContinueEventInfo(continueInfo_.sinkDeviceId_, continueInfo_.sinkBundleName_,
201         continueInfo_.continueType_, dstContinueInfo);
202     eventData_.eventResult_ = 0;
203     eventData_.srcNetworkId_ = srcContinueInfo.networkId;
204     eventData_.srcBundleName_ = srcContinueInfo.bundleName;
205     eventData_.srcModuleName_ = srcContinueInfo.moduleName;
206     eventData_.srcAbilityName_ = srcContinueInfo.abilityName;
207     eventData_.dstNetworkId_ = dstContinueInfo.networkId;
208     eventData_.destBundleName_ = dstContinueInfo.bundleName;
209     eventData_.destModuleName_ = dstContinueInfo.moduleName;
210     eventData_.destAbilityName_ = dstContinueInfo.abilityName;
211     eventData_.developerId_ = srcContinueInfo.developerId;
212     eventData_.dSchedEventType_ = DMS_CONTINUE;
213     eventData_.state_ = DMS_DSCHED_EVENT_START;
214 }
215 
Init()216 int32_t DSchedContinue::Init()
217 {
218     HILOGI("DSchedContinue init start");
219     if (eventHandler_ != nullptr) {
220         HILOGI("Already inited, end.");
221         return ERR_OK;
222     }
223     auto dContinue = std::shared_ptr<DSchedContinue>(shared_from_this());
224     stateMachine_ = std::make_shared<DSchedContinueStateMachine>(dContinue);
225     if (direction_ == CONTINUE_SOURCE) {
226         UpdateState(DSCHED_CONTINUE_SOURCE_START_STATE);
227     } else {
228         UpdateState(DSCHED_CONTINUE_SINK_START_STATE);
229     }
230 
231     eventThread_ = std::thread(&DSchedContinue::StartEventHandler, this);
232     std::unique_lock<std::mutex> lock(eventMutex_);
233     eventCon_.wait(lock, [this] {
234         return eventHandler_ != nullptr;
235     });
236     HILOGI("DSchedContinue init end");
237     return ERR_OK;
238 }
239 
StartEventHandler()240 void DSchedContinue::StartEventHandler()
241 {
242     HILOGI("called");
243     std::string eventThreadName = "DSchedContinue_EventHandler";
244     prctl(PR_SET_NAME, eventThreadName.c_str());
245     auto runner = AppExecFwk::EventRunner::Create(false);
246     if (runner == nullptr) {
247         HILOGE("continue start eventHandler failed.");
248         return;
249     }
250     {
251         std::lock_guard<std::mutex> lock(eventMutex_);
252         eventHandler_ = std::make_shared<DSchedContinueEventHandler>(runner, shared_from_this());
253     }
254     eventCon_.notify_one();
255     runner->Run();
256 }
257 
OnContinueMission(const OHOS::AAFwk::WantParams & wantParams)258 int32_t DSchedContinue::OnContinueMission(const OHOS::AAFwk::WantParams& wantParams)
259 {
260     HILOGI("called");
261     return PostStartTask(wantParams);
262 }
263 
PostStartTask(const OHOS::AAFwk::WantParams & wantParams)264 int32_t DSchedContinue::PostStartTask(const OHOS::AAFwk::WantParams& wantParams)
265 {
266     DSchedContinueEventType eventType = (subServiceType_ == CONTINUE_PULL) ?
267         DSCHED_CONTINUE_REQ_PULL_EVENT : DSHCED_CONTINUE_REQ_PUSH_EVENT;
268     HILOGI("PostStartTask %{public}d, continueInfo: %{public}s", eventType, continueInfo_.ToString().c_str());
269     if (eventHandler_ == nullptr) {
270         HILOGE("PostStartTask eventHandler is nullptr");
271         return INVALID_PARAMETERS_ERR;
272     }
273 
274     auto wantParamsPtr = std::make_shared<OHOS::AAFwk::WantParams>(wantParams);
275     auto msgEvent = AppExecFwk::InnerEvent::Get(eventType, wantParamsPtr, 0);
276     if (!eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
277         HILOGE("PostStartTask eventHandler send event type %{public}d fail", eventType);
278         return CONTINUE_SEND_EVENT_FAILED;
279     }
280     return ERR_OK;
281 }
282 
OnStartCmd(int32_t appVersion)283 int32_t DSchedContinue::OnStartCmd(int32_t appVersion)
284 {
285     HILOGI("called");
286     return PostCotinueAbilityTask(appVersion);
287 }
288 
PostCotinueAbilityTask(int32_t appVersion)289 int32_t DSchedContinue::PostCotinueAbilityTask(int32_t appVersion)
290 {
291     DSchedContinueEventType eventType = DSHCED_CONTINUE_ABILITY_EVENT;
292     HILOGI("PostCotinueAbilityTask %{public}d, continueInfo %{public}s", eventType,
293         continueInfo_.ToString().c_str());
294     if (eventHandler_ == nullptr) {
295         HILOGE("PostCotinueAbilityTask eventHandler is nullptr");
296         return INVALID_PARAMETERS_ERR;
297     }
298     auto data = std::make_shared<int32_t>(appVersion);
299     auto msgEvent = AppExecFwk::InnerEvent::Get(eventType, data, 0);
300     if (!eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
301         HILOGE("PostCotinueAbilityTask eventHandler send event type %{public}d fail", eventType);
302         return CONTINUE_SEND_EVENT_FAILED;
303     }
304     return ERR_OK;
305 }
306 
OnReplyCmd(std::shared_ptr<DSchedContinueReplyCmd> cmd)307 int32_t DSchedContinue::OnReplyCmd(std::shared_ptr<DSchedContinueReplyCmd> cmd)
308 {
309     HILOGI("called");
310     return PostReplyTask(cmd);
311 }
312 
PostReplyTask(std::shared_ptr<DSchedContinueReplyCmd> cmd)313 int32_t DSchedContinue::PostReplyTask(std::shared_ptr<DSchedContinueReplyCmd> cmd)
314 {
315     if (cmd == nullptr) {
316         HILOGE("cmd is null");
317         return INVALID_PARAMETERS_ERR;
318     }
319     HILOGI("PostReplyTask called, replyCmd: %{public}d, result: %{public}d, reason: %{public}s", cmd->replyCmd_,
320         cmd->result_, cmd->reason_.c_str());
321 
322     DSchedContinueEventType eventType = DSCHED_CONTINUE_INVALID_EVENT;
323     int32_t input = 0;
324     switch (cmd->replyCmd_) {
325         case DSCHED_CONTINUE_CMD_START: {
326             eventType = DSHCED_CONTINUE_ABILITY_EVENT;
327             input = cmd->appVersion_;
328             break;
329         }
330         case DSCHED_CONTINUE_CMD_END: {
331             eventType = DSCHED_CONTINUE_END_EVENT;
332             input = cmd->result_;
333             break;
334         }
335         default:
336             HILOGW("PostReplyTask %{public}d, receive irrelevant reply to cmd %{public}d", eventType,
337                 cmd->replyCmd_);
338             return ERR_OK;
339     }
340 
341     HILOGI("PostReplyTask %{public}d, continueInfo %{public}s", eventType, continueInfo_.ToString().c_str());
342     if (eventHandler_ == nullptr) {
343         HILOGE("PostReplyTask eventHandler is nullptr");
344         return INVALID_PARAMETERS_ERR;
345     }
346 
347     auto result = std::make_shared<int32_t>(input);
348     auto msgEvent = AppExecFwk::InnerEvent::Get(eventType, result, 0);
349     if (!eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
350         HILOGE("PostReplyTask eventHandler send event type %{public}d fail", eventType);
351         return CONTINUE_SEND_EVENT_FAILED;
352     }
353     return ERR_OK;
354 }
355 
OnStartContinuation(const OHOS::AAFwk::Want & want,int32_t callerUid,int32_t status,uint32_t accessToken)356 int32_t DSchedContinue::OnStartContinuation(const OHOS::AAFwk::Want& want, int32_t callerUid,
357     int32_t status, uint32_t accessToken)
358 {
359     HILOGI("called");
360     return PostContinueSendTask(want, callerUid, status, accessToken);
361 }
362 
PostContinueSendTask(const OHOS::AAFwk::Want & want,int32_t callerUid,int32_t status,uint32_t accessToken)363 int32_t DSchedContinue::PostContinueSendTask(const OHOS::AAFwk::Want& want, int32_t callerUid, int32_t status,
364     uint32_t accessToken)
365 {
366     HILOGI("PostContinueSendTask called");
367     if (eventHandler_ == nullptr) {
368         HILOGE("eventHandler_ is nullptr");
369         return INVALID_PARAMETERS_ERR;
370     }
371     DSchedContinueEventType eventType = DSHCED_CONTINUE_SEND_DATA_EVENT;
372     if (status != ERR_OK) {
373         HILOGE("continuation has been rejected, status: %{public}d", status);
374         eventType = DSCHED_CONTINUE_END_EVENT;
375         auto result = std::make_shared<int32_t>(status);
376         auto msgEvent = AppExecFwk::InnerEvent::Get(eventType, result, 0);
377         if (!eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
378             HILOGE("PostContinueSendTask eventHandler send event type %{public}d fail", eventType);
379             return CONTINUE_SEND_EVENT_FAILED;
380         }
381         return ERR_OK;
382     }
383 
384     HILOGI("PostContinueSendTask %{public}d, continueInfo %{public}s", eventType, continueInfo_.ToString().c_str());
385     if (eventHandler_ == nullptr) {
386         HILOGE("PostContinueSendTask eventHandler is nullptr");
387         return INVALID_PARAMETERS_ERR;
388     }
389     auto data = std::make_shared<ContinueAbilityData>();
390     data->want = want;
391     data->callerUid  = callerUid;
392     data->accessToken = accessToken;
393 
394     auto msgEvent = AppExecFwk::InnerEvent::Get(eventType, data, 0);
395     if (!eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
396         HILOGE("PostContinueSendTask eventHandler send event type %{public}d fail", eventType);
397         return CONTINUE_SEND_EVENT_FAILED;
398     }
399     return ERR_OK;
400 }
401 
OnContinueDataCmd(std::shared_ptr<DSchedContinueDataCmd> cmd)402 int32_t DSchedContinue::OnContinueDataCmd(std::shared_ptr<DSchedContinueDataCmd> cmd)
403 {
404     HILOGI("called");
405     return PostContinueDataTask(cmd);
406 }
407 
PostContinueDataTask(std::shared_ptr<DSchedContinueDataCmd> cmd)408 int32_t DSchedContinue::PostContinueDataTask(std::shared_ptr<DSchedContinueDataCmd> cmd)
409 {
410     DSchedContinueEventType eventType = DSCHED_CONTINUE_DATA_EVENT;
411     HILOGI("PostContinueDataTask %{public}d, continueInfo %{public}s", eventType, continueInfo_.ToString().c_str());
412     if (eventHandler_ == nullptr) {
413         HILOGE("PostContinueDataTask eventHandler is nullptr");
414         return INVALID_PARAMETERS_ERR;
415     }
416 
417     auto msgEvent = AppExecFwk::InnerEvent::Get(eventType, cmd, 0);
418     if (!eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
419         HILOGE("PostContinueDataTask eventHandler send event type %{public}d fail", eventType);
420         return CONTINUE_SEND_EVENT_FAILED;
421     }
422     return ERR_OK;
423 }
424 
OnNotifyComplete(int32_t missionId,bool isSuccess)425 int32_t DSchedContinue::OnNotifyComplete(int32_t missionId, bool isSuccess)
426 {
427     HILOGI("called");
428     if (!isSuccess) {
429         HILOGE("start ability not success");
430         PostNotifyCompleteTask(CONTINUE_CALL_START_ABILITY_FAILED);
431         return ERR_OK;
432     }
433     if (missionId <= 0) {
434         HILOGE("start ability returns invalid missionId");
435         PostNotifyCompleteTask(INVALID_PARAMETERS_ERR);
436         return ERR_OK;
437     }
438     PostNotifyCompleteTask(ERR_OK);
439     return ERR_OK;
440 }
441 
OnContinueEndCmd(std::shared_ptr<DSchedContinueEndCmd> cmd)442 int32_t DSchedContinue::OnContinueEndCmd(std::shared_ptr<DSchedContinueEndCmd> cmd)
443 {
444     HILOGI("called");
445     if (cmd == nullptr) {
446         HILOGE("cmd is null");
447         return INVALID_PARAMETERS_ERR;
448     }
449     return PostNotifyCompleteTask(cmd->result_);
450 }
451 
PostNotifyCompleteTask(int32_t result)452 int32_t DSchedContinue::PostNotifyCompleteTask(int32_t result)
453 {
454     DSchedContinueEventType eventType = DSCHED_CONTINUE_COMPLETE_EVENT;
455     HILOGI("PostNotifyCompleteTask %{public}d, continueInfo %{public}s", eventType,
456         continueInfo_.ToString().c_str());
457 
458     if (eventHandler_ == nullptr) {
459         HILOGE("PostNotifyCompleteTask eventHandler is nullptr");
460         return INVALID_PARAMETERS_ERR;
461     }
462 
463     auto data = std::make_shared<int32_t>(result);
464     auto msgEvent = AppExecFwk::InnerEvent::Get(eventType, data, 0);
465     if (!eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
466         HILOGE("PostNotifyCompleteTask eventHandler send event type %{public}d fail", eventType);
467         return CONTINUE_SEND_EVENT_FAILED;
468     }
469     return ERR_OK;
470 }
471 
OnContinueEnd(int32_t result)472 int32_t DSchedContinue::OnContinueEnd(int32_t result)
473 {
474     HILOGI("called");
475     if (result == CONTINUE_SINK_ABILITY_TERMINATED &&
476         stateMachine_->GetStateType() >= DSCHED_CONTINUE_SINK_WAIT_END_STATE) {
477         HILOGI("OnContinueEnd result %{public}d, continueStateType %{public}d",
478             result, stateMachine_->GetStateType());
479         return ERR_OK;
480     }
481     return PostContinueEndTask(result);
482 }
483 
PostContinueEndTask(int32_t result)484 int32_t DSchedContinue::PostContinueEndTask(int32_t result)
485 {
486     DSchedContinueEventType eventType = DSCHED_CONTINUE_END_EVENT;
487     HILOGI("PostContinueEndTask %{public}d, continueInfo %{public}s", eventType, continueInfo_.ToString().c_str());
488     if (eventHandler_ == nullptr) {
489         HILOGE("PostContinueEndTask eventHandler is nullptr");
490         return INVALID_PARAMETERS_ERR;
491     }
492 
493     auto data = std::make_shared<int32_t>(result);
494     auto msgEvent = AppExecFwk::InnerEvent::Get(eventType, data, 0);
495     if (!eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
496         HILOGE("PostContinueEndTask eventHandler send event type %{public}d fail", eventType);
497         return CONTINUE_SEND_EVENT_FAILED;
498     }
499     return ERR_OK;
500 }
501 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)502 void DSchedContinue::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
503 {
504     if (event == nullptr || stateMachine_ == nullptr) {
505         HILOGE("event or state machine is null");
506         return;
507     }
508     auto eventId = event->GetInnerEventId();
509     HILOGI("process event %{public}d with state %{public}d", eventId, stateMachine_->GetStateType());
510     int32_t ret = stateMachine_->Execute(event);
511     if (ret != ERR_OK) {
512         HILOGE("event %{public}d execute failed, ret %{public}d", eventId, ret);
513         OnContinueEnd(ret);
514     }
515     return;
516 }
517 
ExecuteContinueReq(std::shared_ptr<DistributedWantParams> wantParams)518 int32_t DSchedContinue::ExecuteContinueReq(std::shared_ptr<DistributedWantParams> wantParams)
519 {
520     HILOGI("ExecuteContinueReq start, continueInfo: %{public}s", continueInfo_.ToString().c_str());
521     DurationDumperStart();
522 
523     std::string peerDeviceId = (direction_ == CONTINUE_SOURCE) ?
524         continueInfo_.sinkDeviceId_ : continueInfo_.sourceDeviceId_;
525 
526     DmsRadar::GetInstance().ClickIconDmsContinue("ContinueMission", ERR_OK, peerDeviceId,
527         continueInfo_.sourceBundleName_, continueInfo_.sinkBundleName_);
528 
529     DmsUE::GetInstance().TriggerDmsContinue(continueInfo_.sinkBundleName_, continueInfo_.sinkAbilityName_,
530         continueInfo_.sourceDeviceId_, ERR_OK);
531 
532     if (CheckQuickStartConfiguration()) {
533         QuickStartAbility();
534     }
535 
536     int32_t ret = DSchedTransportSoftbusAdapter::GetInstance().ConnectDevice(peerDeviceId, softbusSessionId_);
537     if (ret != ERR_OK) {
538         HILOGE("ExecuteContinueReq connect peer device %{public}s failed, ret %{public}d",
539             GetAnonymStr(peerDeviceId).c_str(), ret);
540         return ret;
541     }
542     HILOGI("ExecuteContinueReq peer %{public}s connected, sessionId %{public}d",
543         GetAnonymStr(peerDeviceId).c_str(), softbusSessionId_);
544 
545     auto startCmd = std::make_shared<DSchedContinueStartCmd>();
546     ret = PackStartCmd(startCmd, wantParams);
547     if (ret != ERR_OK) {
548         HILOGE("ExecuteContinueReq pack start cmd failed, ret %{public}d", ret);
549         return ret;
550     }
551     ret = SendCommand(startCmd);
552     if (ret != ERR_OK) {
553         HILOGE("ExecuteContinueReq send start cmd failed, ret %{public}d", ret);
554         return ret;
555     }
556     if (direction_ == CONTINUE_SINK) {
557         UpdateState(DSCHED_CONTINUE_DATA_STATE);
558         DmsContinueTime::GetInstance().SetDurationEnd(CONTINUE_FIRST_TRANS_TIME, GetTickCount());
559     }
560     HILOGI("ExecuteContinueReq end");
561     return ERR_OK;
562 }
563 
CheckQuickStartConfiguration()564 bool DSchedContinue::CheckQuickStartConfiguration()
565 {
566     std::string continueType = continueInfo_.continueType_;
567     std::string suffix = QUICK_START_CONFIGURATION;
568 
569     if (suffix.length() > continueType.length()) {
570         return false;
571     }
572     return (continueType.rfind(suffix) == (continueType.length() - suffix.length()));
573 }
574 
QuickStartAbility()575 int32_t DSchedContinue::QuickStartAbility()
576 {
577     HILOGI("called");
578     if (!Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
579         HILOGE("sceneBoard not available.");
580         return INVALID_PARAMETERS_ERR;
581     }
582 
583     std::string abilityName = QuerySinkAbilityName();
584     if (abilityName.empty()) {
585         HILOGE("QuickStartAbility failed.");
586         return INVALID_PARAMETERS_ERR;
587     }
588     ContinueSceneSessionHandler::GetInstance().UpdateContinueSessionId(continueInfo_.sinkBundleName_, abilityName);
589     std::string continueSessionId = ContinueSceneSessionHandler::GetInstance().GetContinueSessionId();
590     continueInfo_.continueSessionId_ = continueSessionId;
591     HILOGI("continueSessionId is %{public}s", continueSessionId.c_str());
592 
593     AAFwk::Want want;
594     want.SetElementName(continueInfo_.sinkBundleName_, abilityName);
595     want.SetParam(DMS_CONTINUE_SESSION_ID, continueSessionId);
596     want.SetFlags(AAFwk::Want::FLAG_ABILITY_PREPARE_CONTINUATION);
597 
598     return StartAbility(want, DEFAULT_REQUEST_CODE);
599 }
600 
QuerySinkAbilityName()601 std::string DSchedContinue::QuerySinkAbilityName()
602 {
603     std::string abilityName = GetAbilityNameByContinueType();
604     if (!abilityName.empty()) {
605         return abilityName;
606     }
607 
608     AppExecFwk::BundleInfo localBundleInfo;
609     if (BundleManagerInternal::GetLocalBundleInfo(continueInfo_.sinkBundleName_, localBundleInfo) != ERR_OK) {
610         HILOGE("get local bundle info failed.");
611         return abilityName;
612     }
613     if (localBundleInfo.abilityInfos.empty() || localBundleInfo.abilityInfos.size() > 1) {
614         HILOGE("quick start is not supported, abilityInfos size: %{public}d",
615                static_cast<int32_t>(localBundleInfo.abilityInfos.size()));
616         return abilityName;
617     }
618 
619     return localBundleInfo.abilityInfos.front().name;
620 }
621 
GetAbilityNameByContinueType()622 std::string DSchedContinue::GetAbilityNameByContinueType()
623 {
624     std::string continueType = continueInfo_.continueType_;
625     if (CheckQuickStartConfiguration()) {
626         continueType = continueType.substr(0, continueType.rfind(QUICK_START_CONFIGURATION));
627     }
628     std::string abilityName = BundleManagerInternal::GetAbilityName(continueInfo_.sinkDeviceId_,
629         continueInfo_.sinkBundleName_, continueType);
630     if (!abilityName.empty()) {
631         return abilityName;
632     }
633 
634     continueType += QUICK_START_CONFIGURATION;
635     abilityName = BundleManagerInternal::GetAbilityName(continueInfo_.sinkDeviceId_,
636         continueInfo_.sinkBundleName_, continueType);
637     return abilityName;
638 }
639 
DurationDumperStart()640 void DSchedContinue::DurationDumperStart()
641 {
642     DmsContinueTime::GetInstance().Init();
643     DmsContinueTime::GetInstance().SetNetWorkId(continueInfo_.sourceDeviceId_, continueInfo_.sinkDeviceId_);
644     DmsContinueTime::GetInstance().SetPull(subServiceType_ == CONTINUE_PULL);
645 
646     std::string strBeginTime = DmsContinueTime::GetInstance().GetCurrentTime();
647     DmsContinueTime::GetInstance().SetDurationStrTime(CONTINUE_BEGIN_TIME, strBeginTime);
648     int64_t tick = GetTickCount();
649     DmsContinueTime::GetInstance().SetDurationBegin(CONTINUE_TOTAL_TIME, tick);
650     DmsContinueTime::GetInstance().SetDurationBegin(CONTINUE_FIRST_TRANS_TIME, tick);
651 }
652 
PackStartCmd(std::shared_ptr<DSchedContinueStartCmd> & cmd,std::shared_ptr<DistributedWantParams> wantParams)653 int32_t DSchedContinue::PackStartCmd(std::shared_ptr<DSchedContinueStartCmd>& cmd,
654     std::shared_ptr<DistributedWantParams> wantParams)
655 {
656     if (cmd == nullptr || wantParams == nullptr) {
657         HILOGE("cmd or wantParams is null");
658         return INVALID_PARAMETERS_ERR;
659     }
660     cmd->version_ = version_;
661     cmd->serviceType_ = SERVICE_TYPE_CONTINUE;
662     cmd->subServiceType_ = subServiceType_;
663     cmd->command_ = DSCHED_CONTINUE_CMD_START;
664     cmd->srcDeviceId_ = continueInfo_.sourceDeviceId_;
665     cmd->srcBundleName_ = continueInfo_.sourceBundleName_;
666     cmd->dstDeviceId_ = continueInfo_.sinkDeviceId_;
667     cmd->dstBundleName_ = continueInfo_.sinkBundleName_;
668     cmd->continueType_ = continueInfo_.continueType_;
669     cmd->sourceMissionId_ = continueInfo_.missionId_;
670     cmd->continueByType_ = continueByType_;
671     cmd->dmsVersion_ = DMS_VERSION;
672 
673     cmd->direction_ = direction_;
674     if (subServiceType_ == CONTINUE_PULL && continueInfo_.missionId_ == 0) {
675         AppExecFwk::BundleInfo localBundleInfo;
676         int32_t ret = BundleManagerInternal::GetLocalBundleInfoV9(continueInfo_.sinkBundleName_, localBundleInfo);
677         if (ret != ERR_OK) {
678             HILOGE("pack start cmd failed, the bundle is not installed on local device.");
679             return ret;
680         }
681         cmd->appVersion_ = static_cast<int32_t>(localBundleInfo.versionCode);
682     }
683     cmd->wantParams_ = *wantParams;
684     return ERR_OK;
685 }
686 
ExecuteContinueAbility(int32_t appVersion)687 int32_t DSchedContinue::ExecuteContinueAbility(int32_t appVersion)
688 {
689     HILOGI("ExecuteContinueAbility start, appVersion: %{public}d", appVersion);
690     DmsRadar::GetInstance().SaveDataDmsContinue("ContinueAbility", ERR_OK);
691 
692     int32_t result = GetMissionIdByBundleName();
693     if (result != ERR_OK) {
694         HILOGE("ExecuteContinueAbility GetMissionIdByBundleName failed");
695         return result;
696     }
697 
698     result = CheckContinueAbilityPermission();
699     if (result != ERR_OK) {
700         HILOGE("ExecuteContinueAbility CheckContinueAbilityPermission failed");
701         return result;
702     }
703 
704     auto tick = GetTickCount();
705     DmsContinueTime::GetInstance().SetDurationEnd(CONTINUE_FIRST_TRANS_TIME, tick);
706     DmsContinueTime::GetInstance().SetSaveDataDurationBegin(tick);
707 
708     HILOGI("ExecuteContinueAbility call continueAbility begin, continueInfo: %{public}s",
709         continueInfo_.ToString().c_str());
710     result = AbilityManagerClient::GetInstance()->ContinueAbility(continueInfo_.sinkDeviceId_,
711         continueInfo_.missionId_, appVersion);
712     HILOGI("ExecuteContinueAbility call continueAbility end, result: %{public}d.", result);
713 
714     if (result != ERR_OK) {
715         return CONTINUE_CALL_CONTINUE_ABILITY_FAILED;
716     }
717     UpdateState(DSCHED_CONTINUE_ABILITY_STATE);
718     HILOGI("ExecuteContinueAbility end");
719     return result;
720 }
721 
GetMissionIdByBundleName()722 int32_t DSchedContinue::GetMissionIdByBundleName()
723 {
724 #ifdef SUPPORT_DISTRIBUTED_MISSION_MANAGER
725     if (continueInfo_.missionId_ == 0) {
726         return DmsContinueConditionMgr::GetInstance().GetMissionIdByBundleName(
727             accountId_, continueInfo_.sourceBundleName_, continueInfo_.missionId_);
728     }
729 #endif
730     return ERR_OK;
731 }
732 
CheckContinueAbilityPermission()733 int32_t DSchedContinue::CheckContinueAbilityPermission()
734 {
735     if (!DmsKvSyncE2E::GetInstance()->CheckBundleContinueConfig(continueInfo_.sourceBundleName_)) {
736         HILOGI("App does not allow continue in config file, bundle name %{public}s",
737             continueInfo_.sourceBundleName_.c_str());
738         return REMOTE_DEVICE_BIND_ABILITY_ERR;
739     }
740 
741     MissionInfo missionInfo;
742     int32_t result = AbilityManagerClient::GetInstance()->GetMissionInfo("", continueInfo_.missionId_, missionInfo);
743     if (result != ERR_OK) {
744         HILOGE("get missionInfo failed");
745         return NO_MISSION_INFO_FOR_MISSION_ID;
746     }
747 
748     if (missionInfo.continueState != AAFwk::ContinueState::CONTINUESTATE_ACTIVE) {
749         HILOGE("Mission continue state set to INACTIVE. Can't continue. Mission id: %{public}d",
750             continueInfo_.missionId_);
751         return MISSION_NOT_CONTINUE_ACTIVE;
752     }
753     return ERR_OK;
754 }
755 
ExecuteContinueReply()756 int32_t DSchedContinue::ExecuteContinueReply()
757 {
758     HILOGI("ExecuteContinueReply start, continueInfo: %{public}s", continueInfo_.ToString().c_str());
759 
760     AppExecFwk::BundleInfo bundleInfo;
761     if (BundleManagerInternal::GetLocalBundleInfoV9(continueInfo_.sinkBundleName_, bundleInfo) != ERR_OK) {
762         HILOGE("ExecuteContinueReply get local bundleInfo failed, the bundle is not installed on local device.");
763         return INVALID_PARAMETERS_ERR;
764     }
765     auto cmd = std::make_shared<DSchedContinueReplyCmd>();
766     int32_t ret = PackReplyCmd(cmd, DSCHED_CONTINUE_CMD_START, bundleInfo.versionCode, ERR_OK, "ExecuteContinueReply");
767     if (ret != ERR_OK) {
768         HILOGE("ExecuteContinueReply pack reply cmd failed, ret %{public}d", ret);
769         return ret;
770     }
771     ret = SendCommand(cmd);
772     if (ret != ERR_OK) {
773         HILOGE("ExecuteContinueReply send reply cmd failed, ret %{public}d", ret);
774         return ret;
775     }
776 
777     UpdateState(DSCHED_CONTINUE_DATA_STATE);
778     HILOGI("ExecuteContinueReply end");
779     return ERR_OK;
780 }
781 
ExecuteContinueSend(std::shared_ptr<ContinueAbilityData> data)782 int32_t DSchedContinue::ExecuteContinueSend(std::shared_ptr<ContinueAbilityData> data)
783 {
784     HILOGI("ExecuteContinueSend start, continueInfo: %{public}s", continueInfo_.ToString().c_str());
785     if (data == nullptr) {
786         return INVALID_PARAMETERS_ERR;
787     }
788     DurationDumperBeforeStartRemoteAbility();
789 
790     SetCleanMissionFlag(data->want);
791 
792     AAFwk::Want newWant = data->want;
793     if ((newWant.GetFlags() & AAFwk::Want::FLAG_ABILITY_CONTINUATION) == 0) {
794         HILOGE("StartContinuation want continuation flags invalid!");
795         return INVALID_REMOTE_PARAMETERS_ERR;
796     }
797 
798     if (SetWantForContinuation(newWant) != ERR_OK) {
799         HILOGE("set new want failed");
800         return INVALID_PARAMETERS_ERR;
801     }
802 
803     AppExecFwk::AbilityInfo abilityInfo;
804     CallerInfo callerInfo;
805     callerInfo.sourceDeviceId = continueInfo_.sourceDeviceId_;
806     callerInfo.uid = data->callerUid;
807     callerInfo.accessToken = data->accessToken;
808     if (!BundleManagerInternal::GetCallerAppIdFromBms(callerInfo.uid, callerInfo.callerAppId)) {
809         HILOGE("GetCallerAppIdFromBms failed");
810         return INVALID_PARAMETERS_ERR;
811     }
812     if (!BundleManagerInternal::GetBundleNameListFromBms(callerInfo.uid, callerInfo.bundleNames)) {
813         HILOGE("GetBundleNameListFromBms failed");
814         return INVALID_PARAMETERS_ERR;
815     }
816     callerInfo.extraInfoJson[DMS_VERSION_ID] = DMS_VERSION;
817     AccountInfo accountInfo;
818     int32_t ret = DistributedSchedPermission::GetInstance().GetAccountInfo(continueInfo_.sinkDeviceId_, callerInfo,
819         accountInfo);
820     if (ret != ERR_OK) {
821         HILOGE("GetAccountInfo failed");
822         return ret;
823     }
824 
825     auto cmd = std::make_shared<DSchedContinueDataCmd>();
826     PackDataCmd(cmd, newWant, abilityInfo, callerInfo, accountInfo);
827     ret = SendCommand(cmd);
828     DmsRadar::GetInstance().SaveDataDmsRemoteWant("SendContinueData", ret);
829     if (ret != ERR_OK) {
830         HILOGE("ExecuteContinueSend send data cmd failed, ret %{public}d", ret);
831         return ret;
832     }
833 
834     DmsContinueTime::GetInstance().SetDurationEnd(CONTINUE_DATA_TRANS_TIME, GetTickCount());
835     UpdateState(DSCHED_CONTINUE_SOURCE_WAIT_END_STATE);
836     HILOGI("ExecuteContinueSend end");
837     return ERR_OK;
838 }
839 
DurationDumperBeforeStartRemoteAbility()840 void DSchedContinue::DurationDumperBeforeStartRemoteAbility()
841 {
842     auto tick = GetTickCount();
843     DmsContinueTime::GetInstance().SetSaveDataDurationEnd(tick);
844     DmsContinueTime::GetInstance().SetDurationBegin(CONTINUE_DATA_TRANS_TIME, tick);
845     DmsContinueTime::GetInstance().SetDurationBegin(CONTINUE_START_ABILITY_TIME, tick);
846 }
847 
SetCleanMissionFlag(const OHOS::AAFwk::Want & want)848 void DSchedContinue::SetCleanMissionFlag(const OHOS::AAFwk::Want& want)
849 {
850     auto value =  want.GetParams().GetParam(SUPPORT_CONTINUE_SOURCE_EXIT_KEY);
851     IBoolean *ao = IBoolean::Query(value);
852     if (ao != nullptr) {
853         isSourceExit_ = AAFwk::Boolean::Unbox(ao);
854     }
855 }
856 
SetWantForContinuation(AAFwk::Want & newWant)857 int32_t DSchedContinue::SetWantForContinuation(AAFwk::Want& newWant)
858 {
859     newWant.SetParam("sessionId", continueInfo_.missionId_);
860     newWant.SetParam("deviceId", continueInfo_.sourceDeviceId_);
861 
862     AppExecFwk::BundleInfo localBundleInfo;
863     if (BundleManagerInternal::GetLocalBundleInfo(newWant.GetBundle(), localBundleInfo) != ERR_OK) {
864         HILOGE("get local bundle info failed");
865         return INVALID_PARAMETERS_ERR;
866     }
867     newWant.SetParam(VERSION_CODE_KEY, static_cast<int32_t>(localBundleInfo.versionCode));
868     HILOGD("local version = %{public}u!", localBundleInfo.versionCode);
869 
870     bool isPageStackContinue = newWant.GetBoolParam(SUPPORT_CONTINUE_PAGE_STACK_KEY, true);
871     std::string moduleName = newWant.GetStringParam(SUPPORT_CONTINUE_MODULE_NAME_UPDATE_KEY);
872     if (!isPageStackContinue && !moduleName.empty() && moduleName.length() <= MAX_MODULENAME_LEN) {
873         HILOGD("set application moduleName = %{public}s!", moduleName.c_str());
874         auto element = newWant.GetElement();
875         newWant.SetElementName(element.GetDeviceID(), element.GetBundleName(), element.GetAbilityName(), moduleName);
876     }
877 
878     std::string saveDataTime =
879         DmsContinueTime::GetInstance().WriteDurationInfo(DmsContinueTime::GetInstance().GetSaveDataDuration());
880     newWant.SetParam(DMSDURATION_SAVETIME, saveDataTime);
881     if (subServiceType_ == CONTINUE_PUSH) {
882         DmsContinueTime::GetInstance().SetSrcBundleName(continueInfo_.sourceBundleName_);
883         DmsContinueTime::GetInstance().SetSrcAbilityName(newWant.GetElement().GetAbilityName());
884         DmsContinueTime::GetInstance().SetDstBundleName(continueInfo_.sinkBundleName_);
885         DmsContinueTime::GetInstance().SetDstAbilityName(newWant.GetElement().GetAbilityName());
886     }
887     return ERR_OK;
888 }
889 
PackDataCmd(std::shared_ptr<DSchedContinueDataCmd> & cmd,const OHOS::AAFwk::Want & want,const AppExecFwk::AbilityInfo & abilityInfo,const CallerInfo & callerInfo,const AccountInfo & accountInfo)890 int32_t DSchedContinue::PackDataCmd(std::shared_ptr<DSchedContinueDataCmd>& cmd,
891     const OHOS::AAFwk::Want& want, const AppExecFwk::AbilityInfo& abilityInfo, const CallerInfo& callerInfo,
892     const AccountInfo& accountInfo)
893 {
894     if (cmd == nullptr) {
895         HILOGE("cmd is null");
896         return INVALID_PARAMETERS_ERR;
897     }
898     cmd->version_ = version_;
899     cmd->serviceType_ = SERVICE_TYPE_CONTINUE;
900     cmd->subServiceType_ = subServiceType_;
901     cmd->command_ = DSCHED_CONTINUE_CMD_DATA;
902     cmd->srcDeviceId_ = continueInfo_.sourceDeviceId_;
903     cmd->srcBundleName_ = continueInfo_.sourceBundleName_;
904     cmd->dstDeviceId_ = continueInfo_.sinkDeviceId_;
905     cmd->dstBundleName_ = continueInfo_.sinkBundleName_;
906     cmd->continueType_ = continueInfo_.continueType_;
907     cmd->sourceMissionId_ = continueInfo_.missionId_;
908     cmd->continueByType_ = continueByType_;
909     cmd->dmsVersion_ = DMS_VERSION;
910 
911     cmd->want_ = want;
912     AppExecFwk::CompatibleAbilityInfo compatibleAbilityInfo;
913     abilityInfo.ConvertToCompatiableAbilityInfo(compatibleAbilityInfo);
914     cmd->abilityInfo_ = compatibleAbilityInfo;
915     cmd->callerInfo_ = callerInfo;
916     cmd->accountInfo_ = accountInfo;
917     cmd->requestCode_ = DEFAULT_REQUEST_CODE;
918 
919     AppExecFwk::AppProvisionInfo appProvisionInfo;
920     BundleManagerInternal::GetAppProvisionInfo4CurrentUser(cmd->srcBundleName_, appProvisionInfo);
921     cmd->srcDeveloperId_ = appProvisionInfo.developerId;
922     return ERR_OK;
923 }
924 
CheckStartPermission(std::shared_ptr<DSchedContinueDataCmd> cmd)925 int32_t DSchedContinue::CheckStartPermission(std::shared_ptr<DSchedContinueDataCmd> cmd)
926 {
927     if (cmd->srcBundleName_ == cmd->dstBundleName_) {
928         return DistributedSchedService::GetInstance().CheckTargetPermission(cmd->want_, cmd->callerInfo_,
929             cmd->accountInfo_, START_PERMISSION, true);
930     } else {
931         if (!BundleManagerInternal::IsSameDeveloperId(cmd->dstBundleName_, cmd->srcDeveloperId_)) {
932             return INVALID_PARAMETERS_ERR;
933         }
934         return DistributedSchedService::GetInstance().CheckTargetPermission4DiffBundle(cmd->want_, cmd->callerInfo_,
935             cmd->accountInfo_, START_PERMISSION, true);
936     }
937 }
938 
ExecuteContinueData(std::shared_ptr<DSchedContinueDataCmd> cmd)939 int32_t DSchedContinue::ExecuteContinueData(std::shared_ptr<DSchedContinueDataCmd> cmd)
940 {
941     HILOGI("ExecuteContinueData start, continueInfo: %{public}s", continueInfo_.ToString().c_str());
942     if (cmd == nullptr) {
943         HILOGE("cmd is null");
944         return INVALID_PARAMETERS_ERR;
945     }
946 
947     if (UpdateElementInfo(cmd) != ERR_OK) {
948         HILOGE("ExecuteContinueData UpdateElementInfo failed.");
949     }
950     DurationDumperBeforeStartAbility(cmd);
951 
952     std::string localDeviceId;
953     std::string deviceId = cmd->want_.GetElement().GetDeviceID();
954     if (!GetLocalDeviceId(localDeviceId) ||
955         !CheckDeviceIdFromRemote(localDeviceId, deviceId, cmd->callerInfo_.sourceDeviceId)) {
956         HILOGE("check deviceId failed");
957         return INVALID_REMOTE_PARAMETERS_ERR;
958     }
959     int32_t ret = CheckStartPermission(cmd);
960     if (ret != ERR_OK) {
961         HILOGE("ExecuteContinueData CheckTargetPermission failed!");
962         return ret;
963     }
964 
965     OHOS::AAFwk::Want want = cmd->want_;
966     UpdateWantForContinueType(want);
967     if (subServiceType_ == CONTINUE_PULL &&
968         !ContinueSceneSessionHandler::GetInstance().GetContinueSessionId().empty()) {
969         int32_t persistentId;
970         if (ContinueSceneSessionHandler::GetInstance().GetPersistentId(persistentId) != ERR_OK) {
971             HILOGE("get persistentId failed, stop start ability");
972             return OnContinueEnd(DMS_GET_WINDOW_FAILED_FROM_SCB);
973         }
974         HILOGI("get persistentId success, persistentId: %{public}d", persistentId);
975         WaitAbilityStateInitial(persistentId);
976         want.SetParam(DMS_PERSISTENT_ID, persistentId);
977 
978         if (ContinueSceneSessionHandler::GetInstance().GetPersistentId(persistentId) != ERR_OK) {
979             HILOGE("Second get persistentId failed, stop start ability");
980             return OnContinueEnd(DMS_GET_WINDOW_FAILED_FROM_SCB);
981         }
982         continueInfo_.sinkMissionId_ = persistentId;
983     }
984 
985     ret = StartAbility(want, cmd->requestCode_);
986     if (ret == ERR_OK) {
987         UpdateState(DSCHED_CONTINUE_SINK_WAIT_END_STATE);
988         HILOGI("ExecuteContinueData end");
989     }
990     return ret;
991 }
992 
UpdateElementInfo(std::shared_ptr<DSchedContinueDataCmd> cmd)993 int32_t DSchedContinue::UpdateElementInfo(std::shared_ptr<DSchedContinueDataCmd> cmd)
994 {
995     std::string srcModuleName = cmd->want_.GetModuleName();
996     if (srcModuleName.empty()) {
997         HILOGD("UpdateElementInfo srcModuleName from element is empty");
998         srcModuleName = cmd->want_.GetStringParam(OHOS::AAFwk::Want::PARAM_MODULE_NAME);
999     }
1000     std::string srcContinueType = cmd->continueType_;
1001     ContinueTypeFormat(srcContinueType);
1002     HILOGD("UpdateElementInfo srcModuleName: %{public}s; srcContinueType:%{public}s", srcModuleName.c_str(),
1003            srcContinueType.c_str());
1004     DmsBundleInfo distributedBundleInfo;
1005     std::string localDeviceId;
1006     if (!GetLocalDeviceId(localDeviceId) || !DmsBmStorage::GetInstance()->GetDistributedBundleInfo(
1007         localDeviceId, cmd->dstBundleName_, distributedBundleInfo)) {
1008         HILOGE("UpdateElementInfo can not found bundle info for bundle name: %{public}s",
1009                cmd->dstBundleName_.c_str());
1010         return CAN_NOT_FOUND_MODULE_ERR;
1011     }
1012 
1013     std::vector<DmsAbilityInfo> dmsAbilityInfos = distributedBundleInfo.dmsAbilityInfos;
1014     std::vector<DmsAbilityInfo> result;
1015     FindSinkContinueAbilityInfo(srcModuleName, srcContinueType, dmsAbilityInfos, result);
1016     if (result.empty()) {
1017         HILOGE("UpdateElementInfo can not found bundle info for bundle name: %{public}s",
1018                cmd->dstBundleName_.c_str());
1019         return CAN_NOT_FOUND_MODULE_ERR;
1020     }
1021     auto element = cmd->want_.GetElement();
1022     DmsAbilityInfo finalAbility = result[0];
1023     HILOGD("UpdateElementInfo final sink ability detail info: "
1024            "bundleName: %{public}s; abilityName: %{public}s; moduleName: %{public}s",
1025            cmd->dstBundleName_.c_str(), finalAbility.abilityName.c_str(), finalAbility.moduleName.c_str());
1026     cmd->want_.SetElementName(element.GetDeviceID(), cmd->dstBundleName_, finalAbility.abilityName,
1027                               finalAbility.moduleName);
1028     return ERR_OK;
1029 }
1030 
FindSinkContinueAbilityInfo(const std::string & srcModuleName,const std::string & srcContinueType,std::vector<DmsAbilityInfo> & dmsAbilityInfos,std::vector<DmsAbilityInfo> & result)1031 void DSchedContinue::FindSinkContinueAbilityInfo(const std::string &srcModuleName, const std::string &srcContinueType,
1032     std::vector<DmsAbilityInfo> &dmsAbilityInfos, std::vector<DmsAbilityInfo> &result)
1033 {
1034     bool sameModuleGot = false;
1035     for (const auto &abilityInfoElement: dmsAbilityInfos) {
1036         std::vector<std::string> continueTypes = abilityInfoElement.continueType;
1037         for (std::string &continueTypeElement: continueTypes) {
1038             ContinueTypeFormat(continueTypeElement);
1039             HILOGD("UpdateElementInfo check sink continue ability, current: "
1040                    "continueType: %{public}s; abilityName: %{public}s; moduleName: %{public}s",
1041                    continueTypeElement.c_str(), abilityInfoElement.abilityName.c_str(),
1042                    abilityInfoElement.moduleName.c_str());
1043             if (continueTypeElement != srcContinueType) {
1044                 continue;
1045             }
1046             if (srcModuleName == abilityInfoElement.moduleName) {
1047                 sameModuleGot = true;
1048                 result.clear();
1049                 result.push_back(abilityInfoElement);
1050                 break;
1051             } else {
1052                 result.push_back(abilityInfoElement);
1053                 break;
1054             }
1055         }
1056         if (sameModuleGot) {
1057             break;
1058         }
1059     }
1060 }
1061 
ContinueTypeFormat(std::string & continueType)1062 void DSchedContinue::ContinueTypeFormat(std::string &continueType)
1063 {
1064     std::string suffix = QUICK_START_CONFIGURATION;
1065     if (suffix.length() <= continueType.length() &&
1066         continueType.rfind(suffix) == (continueType.length() - suffix.length())) {
1067         continueType = continueType.substr(0, continueType.rfind(QUICK_START_CONFIGURATION));
1068     }
1069 }
1070 
UpdateWantForContinueType(OHOS::AAFwk::Want & want)1071 int32_t DSchedContinue::UpdateWantForContinueType(OHOS::AAFwk::Want& want)
1072 {
1073     std::string srcAbilityName = want.GetElement().GetAbilityName();
1074     std::string sinkAbilityName = GetAbilityNameByContinueType();
1075     if (!sinkAbilityName.empty() && sinkAbilityName != srcAbilityName) {
1076         OHOS::AppExecFwk::ElementName element = want.GetElement();
1077         want.SetElementName(element.GetDeviceID(), element.GetBundleName(), sinkAbilityName);
1078         want.RemoveParam(SUPPORT_CONTINUE_PAGE_STACK_KEY);
1079         want.SetParam(SUPPORT_CONTINUE_PAGE_STACK_KEY, false);
1080 
1081         DmsContinueTime::GetInstance().SetDstAbilityName(sinkAbilityName);
1082     }
1083     return ERR_OK;
1084 }
1085 
DurationDumperBeforeStartAbility(std::shared_ptr<DSchedContinueDataCmd> cmd)1086 void DSchedContinue::DurationDumperBeforeStartAbility(std::shared_ptr<DSchedContinueDataCmd> cmd)
1087 {
1088     if (subServiceType_ == CONTINUE_PULL && cmd != nullptr) {
1089         std::string timeInfo = cmd->want_.GetStringParam(DMSDURATION_SAVETIME);
1090         DmsContinueTime::GetInstance().ReadDurationInfo(timeInfo.c_str());
1091         DmsContinueTime::GetInstance().SetSrcBundleName(continueInfo_.sourceBundleName_);
1092         DmsContinueTime::GetInstance().SetSrcAbilityName(cmd->want_.GetElement().GetAbilityName());
1093         DmsContinueTime::GetInstance().SetDstBundleName(continueInfo_.sinkBundleName_);
1094         DmsContinueTime::GetInstance().SetDstAbilityName(cmd->want_.GetElement().GetAbilityName());
1095     }
1096     DmsContinueTime::GetInstance().SetDurationBegin(CONTINUE_START_ABILITY_TIME, GetTickCount());
1097 }
1098 
WaitAbilityStateInitial(int32_t persistentId)1099 bool DSchedContinue::WaitAbilityStateInitial(int32_t persistentId)
1100 {
1101     int32_t retryTimeout = GET_ABILITY_STATE_RETRY_TIMES;
1102     int32_t err;
1103     do {
1104         bool state = false;
1105         err = AAFwk::AbilityManagerClient::GetInstance()->GetAbilityStateByPersistentId(persistentId, state);
1106         if (err == ERR_OK && state) {
1107             HILOGI("ability state initial.");
1108             return state;
1109         }
1110         HILOGI("waiting ability state initial...");
1111         std::this_thread::sleep_for(std::chrono::milliseconds(GET_ABILITY_STATE_SLEEP_TIME));
1112     } while (--retryTimeout > 0);
1113 
1114     HILOGE("wait timeout, persistentId: %{public}d, errorCode: %{public}d",
1115            persistentId, err);
1116     return false;
1117 }
1118 
StartAbility(OHOS::AAFwk::Want & want,int32_t requestCode)1119 int32_t DSchedContinue::StartAbility(OHOS::AAFwk::Want& want, int32_t requestCode)
1120 {
1121     want.SetParam(OHOS::AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0);
1122     int32_t ret = AAFwk::AbilityManagerClient::GetInstance()->Connect();
1123     if (ret != ERR_OK) {
1124         HILOGE("connect ability server failed %{public}d", ret);
1125         return ret;
1126     }
1127 
1128     continueInfo_.sinkAbilityName_ = want.GetElement().GetAbilityName();
1129     DmsRadar::GetInstance().ClickIconDmsStartAbility("StartAbility", ret);
1130 
1131     HILOGI("call StartAbility start, flag is %{public}d", want.GetFlags());
1132     ret = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, DEFAULT_REQUEST_CODE, accountId_);
1133     if (ret != ERR_OK) {
1134         HILOGE("failed %{public}d", ret);
1135         return ret;
1136     }
1137     return ret;
1138 }
1139 
ExecuteNotifyComplete(int32_t result)1140 int32_t DSchedContinue::ExecuteNotifyComplete(int32_t result)
1141 {
1142     HILOGI("ExecuteNotifyComplete start, result %{public}d", result);
1143     DmsContinueTime::GetInstance().SetDurationEnd(CONTINUE_START_ABILITY_TIME, GetTickCount());
1144 
1145     int32_t ret = 0;
1146     if (direction_ == CONTINUE_SINK) {
1147         auto cmd = std::make_shared<DSchedContinueEndCmd>();
1148         PackEndCmd(cmd, result);
1149 
1150         ret = SendCommand(cmd);
1151         if (ret != ERR_OK) {
1152             HILOGE("ExecuteNotifyComplete send end cmd failed, ret %{public}d", ret);
1153             return ret;
1154         }
1155 
1156         UpdateState(DSCHED_CONTINUE_SINK_END_STATE);
1157         HILOGI("ExecuteNotifyComplete end");
1158         return ERR_OK;
1159     }
1160 
1161     auto cmd = std::make_shared<DSchedContinueReplyCmd>();
1162     PackReplyCmd(cmd, DSCHED_CONTINUE_CMD_END, 0, result, "ExecuteNotifyComplete");
1163     ret = SendCommand(cmd);
1164     if (ret != ERR_OK) {
1165         HILOGE("ExecuteNotifyComplete send reply cmd failed, ret %{public}d", ret);
1166         return ret;
1167     }
1168 
1169     UpdateState(DSCHED_CONTINUE_SOURCE_END_STATE);
1170     PostContinueEndTask(result);
1171 
1172     HILOGI("ExecuteNotifyComplete end");
1173     return ERR_OK;
1174 }
1175 
PackReplyCmd(std::shared_ptr<DSchedContinueReplyCmd> cmd,int32_t replyCmd,int32_t appVersion,int32_t result,const std::string reason)1176 int32_t DSchedContinue::PackReplyCmd(std::shared_ptr<DSchedContinueReplyCmd> cmd, int32_t replyCmd, int32_t appVersion,
1177     int32_t result, const std::string reason)
1178 {
1179     if (cmd == nullptr) {
1180         HILOGE("cmd is null");
1181         return INVALID_PARAMETERS_ERR;
1182     }
1183     cmd->version_ = version_;
1184     cmd->serviceType_ = SERVICE_TYPE_CONTINUE;
1185     cmd->subServiceType_ = subServiceType_;
1186     cmd->command_ = DSCHED_CONTINUE_CMD_REPLY;
1187     cmd->srcDeviceId_ = continueInfo_.sourceDeviceId_;
1188     cmd->srcBundleName_ = continueInfo_.sourceBundleName_;
1189     cmd->dstDeviceId_ = continueInfo_.sinkDeviceId_;
1190     cmd->dstBundleName_ = continueInfo_.sinkBundleName_;
1191     cmd->continueType_ = continueInfo_.continueType_;
1192     cmd->sourceMissionId_ = continueInfo_.missionId_;
1193     cmd->continueByType_ = continueByType_;
1194     cmd->dmsVersion_ = DMS_VERSION;
1195 
1196     cmd->replyCmd_ = replyCmd;
1197     cmd->appVersion_ = appVersion;
1198     cmd->result_ = result;
1199     cmd->reason_ = reason;
1200     return ERR_OK;
1201 }
1202 
ExecuteContinueEnd(int32_t result)1203 int32_t DSchedContinue::ExecuteContinueEnd(int32_t result)
1204 {
1205     HILOGW("ExecuteContinueEnd start, result %{public}d", result);
1206 
1207     std::string peerDeviceId = (direction_ == CONTINUE_SOURCE) ?
1208         continueInfo_.sinkDeviceId_ : continueInfo_.sourceDeviceId_;
1209     if ((subServiceType_ == CONTINUE_PULL && direction_ == CONTINUE_SINK) ||
1210         (subServiceType_ == CONTINUE_PUSH && direction_ == CONTINUE_SOURCE)) {
1211         HILOGI("ExecuteContinueEnd disconnect peer device %{public}s", GetAnonymStr(peerDeviceId).c_str());
1212         DSchedTransportSoftbusAdapter::GetInstance().DisconnectDevice(peerDeviceId);
1213     }
1214 
1215     eventData_.state_ = result != ERR_OK ? DMS_DSCHED_EVENT_STOP : DMS_DSCHED_EVENT_FINISH;
1216     if (result == ERR_OK && direction_ == CONTINUE_SOURCE && isSourceExit_) {
1217         int32_t ret = AbilityManagerClient::GetInstance()->CleanMission(continueInfo_.missionId_);
1218         HILOGD("ExecuteContinueEnd clean mission result: %{public}d", ret);
1219     }
1220 
1221     if (direction_ == CONTINUE_SINK) {
1222         DmsRadar::GetInstance().ClickIconDmsRecvOver("NotifyContinuationResultFromRemote", result);
1223     }
1224 
1225     NotifyContinuationCallbackResult(result);
1226     NotifyDSchedEventResult(result);
1227     DurationDumperComplete(result);
1228     DmsHiAnalyticsReport::PublishContinueEvent(continueInfo_);
1229 
1230     DSchedContinueManager::GetInstance().OnContinueEnd(continueInfo_);
1231     HILOGI("ExecuteContinueEnd end");
1232     return ERR_OK;
1233 }
1234 
ConvertToDmsSdkErr(int32_t result)1235 int32_t DSchedContinue::ConvertToDmsSdkErr(int32_t result)
1236 {
1237     if (result == ERR_OK) {
1238         return result;
1239     }
1240 
1241     auto it = DMS_CONVERT_TO_SDK_ERR_MAP.find(result);
1242     if (it != DMS_CONVERT_TO_SDK_ERR_MAP.end()) {
1243         return it->second;
1244     }
1245     return DmsInterfaceSdkErr::ERR_DMS_WORK_ABNORMALLY;
1246 }
1247 
NotifyContinuationCallbackResult(int32_t result)1248 void DSchedContinue::NotifyContinuationCallbackResult(int32_t result)
1249 {
1250     HILOGD("continuation result is: %{public}d", result);
1251     if (callback_ == nullptr) {
1252         HILOGW("callback object null.");
1253         return;
1254     }
1255 
1256     MessageParcel data;
1257     if (!data.WriteInterfaceToken(NAPI_MISSION_CALLBACK_INTERFACE_TOKEN)) {
1258         HILOGE("write token failed");
1259         return;
1260     }
1261     PARCEL_WRITE_HELPER_NORET(data, Int32, ConvertToDmsSdkErr(result));
1262     MessageParcel reply;
1263     MessageOption option;
1264     int32_t ret = callback_->SendRequest(NOTIFY_MISSION_CALLBACK_RESULT, data, reply, option);
1265     callback_ = nullptr;
1266     if (ret != ERR_OK) {
1267         HILOGE("send request failed, ret: %{public}d", ret);
1268     }
1269     return;
1270 }
1271 
NotifyDSchedEventResult(int32_t result)1272 void DSchedContinue::NotifyDSchedEventResult(int32_t result)
1273 {
1274     result = (result == ERR_OK) ? ERR_OK : NOTIFYCOMPLETECONTINUATION_FAILED;
1275     DistributedSchedService::GetInstance().NotifyDSchedEventCallbackResult(result, eventData_);
1276 }
1277 
DurationDumperComplete(int32_t result)1278 void DSchedContinue::DurationDumperComplete(int32_t result)
1279 {
1280     if (result != ERR_OK) {
1281         return;
1282     }
1283     if ((subServiceType_ == CONTINUE_PULL && direction_ == CONTINUE_SINK) ||
1284         (subServiceType_ == CONTINUE_PUSH && direction_ == CONTINUE_SOURCE)) {
1285         std::string strEndTime = DmsContinueTime::GetInstance().GetCurrentTime();
1286         DmsContinueTime::GetInstance().SetDurationEnd(CONTINUE_TOTAL_TIME, GetTickCount());
1287         DmsContinueTime::GetInstance().SetDurationStrTime(CONTINUE_END_TIME, strEndTime);
1288 
1289         DmsUE::GetInstance().DmsContinueComplete(continueInfo_.sourceBundleName_, continueInfo_.sinkAbilityName_,
1290             continueInfo_.sourceDeviceId_, result);
1291 
1292         DmsContinueTime::GetInstance().AppendInfo();
1293         DmsContinueTime::GetInstance().SetPull(false);
1294     }
1295     return;
1296 }
1297 
ExecuteContinueError(int32_t result)1298 int32_t DSchedContinue::ExecuteContinueError(int32_t result)
1299 {
1300     HILOGI("start, result %{public}d", result);
1301     auto cmd = std::make_shared<DSchedContinueEndCmd>();
1302     PackEndCmd(cmd, result);
1303     SendCommand(cmd);
1304     if (direction_ == CONTINUE_SOURCE) {
1305         UpdateState(DSCHED_CONTINUE_SOURCE_END_STATE);
1306     } else {
1307         UpdateState(DSCHED_CONTINUE_SINK_END_STATE);
1308     }
1309     OnContinueEnd(result);
1310     HILOGI("ExecuteNotifyComplete end");
1311     return ERR_OK;
1312 }
1313 
ExecuteQuickStartSuccess()1314 int32_t DSchedContinue::ExecuteQuickStartSuccess()
1315 {
1316     int32_t missionId;
1317     if (continueInfo_.sinkMissionId_ != 0) {
1318         missionId = continueInfo_.sinkMissionId_;
1319     } else {
1320         int32_t ret = ContinueSceneSessionHandler::GetInstance().GetPersistentId(
1321             missionId, continueInfo_.continueSessionId_);
1322         if (ret != ERR_OK) {
1323             HILOGE("Get mission id failed for quickstart callback.");
1324             return ret;
1325         }
1326     }
1327 
1328     StateCallbackInfo stateCallbackInfo = StateCallbackInfo(
1329         missionId, continueInfo_.sinkBundleName_, eventData_.destModuleName_,
1330         continueInfo_.sinkAbilityName_);
1331     return DSchedContinueManager::GetInstance().NotifyQuickStartState(
1332         stateCallbackInfo, QUICK_START_SUCCESS, QUICK_START_SUCCESS_MESSAGE);
1333 }
1334 
ExecuteQuickStartFailed(int32_t result)1335 int32_t DSchedContinue::ExecuteQuickStartFailed(int32_t result)
1336 {
1337     int32_t missionId;
1338     if (continueInfo_.sinkMissionId_ != 0) {
1339         missionId = continueInfo_.sinkMissionId_;
1340     } else {
1341         int32_t ret = ContinueSceneSessionHandler::GetInstance().GetPersistentId(
1342             missionId, continueInfo_.continueSessionId_);
1343         if (ret != ERR_OK) {
1344             HILOGE("Get mission id failed for quickstart callback.");
1345             return ret;
1346         }
1347     }
1348     StateCallbackInfo stateCallbackInfo = StateCallbackInfo(
1349         missionId, continueInfo_.sinkBundleName_, eventData_.destModuleName_,
1350         continueInfo_.sinkAbilityName_);
1351     std::string message = QUICK_START_FAILED_MESSAGE + std::to_string(result);
1352     return DSchedContinueManager::GetInstance().NotifyQuickStartState(
1353         stateCallbackInfo, QUICK_START_FAILED, message);
1354 }
1355 
PackEndCmd(std::shared_ptr<DSchedContinueEndCmd> cmd,int32_t result)1356 int32_t DSchedContinue::PackEndCmd(std::shared_ptr<DSchedContinueEndCmd> cmd, int32_t result)
1357 {
1358     if (cmd == nullptr) {
1359         HILOGE("cmd is null");
1360         return INVALID_PARAMETERS_ERR;
1361     }
1362     cmd->version_ = version_;
1363     cmd->serviceType_ = SERVICE_TYPE_CONTINUE;
1364     cmd->subServiceType_ = subServiceType_;
1365     cmd->command_ = DSCHED_CONTINUE_CMD_END;
1366     cmd->srcDeviceId_ = continueInfo_.sourceDeviceId_;
1367     cmd->srcBundleName_ = continueInfo_.sourceBundleName_;
1368     cmd->dstDeviceId_ = continueInfo_.sinkDeviceId_;
1369     cmd->dstBundleName_ = continueInfo_.sinkBundleName_;
1370     cmd->continueType_ = continueInfo_.continueType_;
1371     cmd->sourceMissionId_ = continueInfo_.missionId_;
1372     cmd->continueByType_ = continueByType_;
1373     cmd->dmsVersion_ = DMS_VERSION;
1374 
1375     cmd->result_ = result;
1376     return ERR_OK;
1377 }
1378 
SendCommand(std::shared_ptr<DSchedContinueCmdBase> cmd)1379 int32_t DSchedContinue::SendCommand(std::shared_ptr<DSchedContinueCmdBase> cmd)
1380 {
1381     if (cmd == nullptr) {
1382         HILOGE("cmd is null");
1383         return INVALID_PARAMETERS_ERR;
1384     }
1385     HILOGI("SendCommand start, cmd %{public}d", cmd->command_);
1386     std::string jsonStr;
1387     int32_t ret = cmd->Marshal(jsonStr);
1388     if (ret != ERR_OK) {
1389         HILOGE("SendCommand marshal cmd %{public}d failed, ret %{public}d", cmd->command_, ret);
1390         return ret;
1391     }
1392     auto buffer = std::make_shared<DSchedDataBuffer>(jsonStr.length() + 1);
1393     ret = memcpy_s(buffer->Data(), buffer->Capacity(), jsonStr.c_str(), jsonStr.length());
1394     if (ret != ERR_OK) {
1395         HILOGE("SendCommand memcpy_s failed, cmd %{public}d, ret %{public}d", cmd->command_, ret);
1396         return ret;
1397     }
1398     ret = DSchedTransportSoftbusAdapter::GetInstance().SendData(softbusSessionId_, SERVICE_TYPE_CONTINUE, buffer);
1399     if (ret != ERR_OK) {
1400         HILOGE("SendCommand send data failed, cmd %{public}d, ret %{public}d", cmd->command_, ret);
1401         return ret;
1402     }
1403     HILOGI("SendCommand end, cmd %{public}d", cmd->command_);
1404     return ERR_OK;
1405 }
1406 
GetSessionId()1407 int32_t DSchedContinue::GetSessionId()
1408 {
1409     return softbusSessionId_;
1410 }
1411 
GetContinueInfo()1412 DSchedContinueInfo DSchedContinue::GetContinueInfo()
1413 {
1414     return continueInfo_;
1415 }
1416 
GetLocalDeviceId(std::string & localDeviceId)1417 bool DSchedContinue::GetLocalDeviceId(std::string& localDeviceId)
1418 {
1419     if (!DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalDeviceId(localDeviceId)) {
1420         HILOGE("GetLocalDeviceId failed");
1421         return false;
1422     }
1423     return true;
1424 }
1425 
CheckDeviceIdFromRemote(const std::string & localDevId,const std::string & destDevId,const std::string & srcDevId)1426 bool DSchedContinue::CheckDeviceIdFromRemote(const std::string& localDevId, const std::string& destDevId,
1427     const std::string& srcDevId)
1428 {
1429     if (localDevId.empty() || destDevId.empty() || srcDevId.empty()) {
1430         HILOGE("CheckDeviceIdFromRemote failed");
1431         return false;
1432     }
1433     // destDevId set by remote must be same with localDevId
1434     if (localDevId != destDevId) {
1435         HILOGE("destDevId is not same with localDevId");
1436         return false;
1437     }
1438     HILOGD("CheckDeviceIdFromRemote srcDevId %{public}s", GetAnonymStr(srcDevId).c_str());
1439     HILOGD("CheckDeviceIdFromRemote localDevId %{public}s", GetAnonymStr(localDevId).c_str());
1440     HILOGD("CheckDeviceIdFromRemote destDevId %{public}s", GetAnonymStr(destDevId).c_str());
1441 
1442     if (srcDevId == destDevId || srcDevId == localDevId) {
1443         HILOGE("destDevId is different with localDevId and destDevId");
1444         return false;
1445     }
1446 
1447     if (srcDevId != continueInfo_.sourceDeviceId_) {
1448         HILOGE("srcDevId is not correct");
1449         return false;
1450     }
1451     return true;
1452 }
1453 
OnDataRecv(int32_t command,std::shared_ptr<DSchedDataBuffer> dataBuffer)1454 void DSchedContinue::OnDataRecv(int32_t command, std::shared_ptr<DSchedDataBuffer> dataBuffer)
1455 {
1456     HILOGI("called, command %{public}d", command);
1457     if (dataBuffer == nullptr) {
1458         HILOGE("dataBuffer is null");
1459         return;
1460     }
1461     int32_t ret = 0;
1462     uint8_t *data = dataBuffer->Data();
1463     std::string jsonStr(reinterpret_cast<const char *>(data), dataBuffer->Capacity());
1464 
1465     switch (command) {
1466         case DSCHED_CONTINUE_CMD_START: {
1467             HILOGW("continue already started, cmd abort.");
1468             break;
1469         }
1470         case DSCHED_CONTINUE_CMD_DATA: {
1471             auto dataCmd = std::make_shared<DSchedContinueDataCmd>();
1472             ret = dataCmd->Unmarshal(jsonStr);
1473             if (ret != ERR_OK) {
1474                 HILOGE("Unmarshal data cmd failed, ret: %{public}d", ret);
1475                 return;
1476             }
1477             dataCmd->want_.SetBundle(dataCmd->dstBundleName_);
1478             OnContinueDataCmd(dataCmd);
1479             break;
1480         }
1481         case DSCHED_CONTINUE_CMD_REPLY: {
1482             auto replyCmd = std::make_shared<DSchedContinueReplyCmd>();
1483             ret = replyCmd->Unmarshal(jsonStr);
1484             if (ret != ERR_OK) {
1485                 HILOGE("Unmarshal reply cmd failed, ret: %{public}d", ret);
1486                 return;
1487             }
1488             OnReplyCmd(replyCmd);
1489             break;
1490         }
1491         case DSCHED_CONTINUE_CMD_END: {
1492             auto endCmd = std::make_shared<DSchedContinueEndCmd>();
1493             ret = endCmd->Unmarshal(jsonStr);
1494             if (ret != ERR_OK) {
1495                 HILOGE("Unmarshal end cmd failed, ret: %{public}d", ret);
1496                 return;
1497             }
1498             OnContinueEndCmd(endCmd);
1499             break;
1500         }
1501         default:
1502             HILOGW("Invalid command.");
1503             break;
1504     }
1505 }
1506 
UpdateState(DSchedContinueStateType stateType)1507 void DSchedContinue::UpdateState(DSchedContinueStateType stateType)
1508 {
1509     if (stateMachine_ == nullptr) {
1510         HILOGE("stateMachine is null");
1511         return;
1512     }
1513     stateMachine_->UpdateState(stateType);
1514 }
1515 
OnShutDown()1516 void DSchedContinue::OnShutDown()
1517 {
1518 }
1519 
OnBind()1520 void DSchedContinue::OnBind()
1521 {
1522 }
1523 }  // namespace DistributedSchedule
1524 }  // namespace OHOS
1525