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