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