• 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 <chrono>
17 #include <sys/prctl.h>
18 #include <thread>
19 
20 #include "dsched_collab.h"
21 
22 #include "ability_connection_wrapper_stub.h"
23 #include "ability_manager_client.h"
24 #include "bool_wrapper.h"
25 #include "bundle/bundle_manager_internal.h"
26 #include "distributed_sched_permission.h"
27 #include "dsched_collab_manager.h"
28 #include "dsched_transport_softbus_adapter.h"
29 #include "dtbschedmgr_device_info_storage.h"
30 #include "ipc_skeleton.h"
31 #include "iservice_registry.h"
32 #include "parcel_helper.h"
33 #ifdef DMS_CHECK_SCREENLOCK
34 #include "screenlock_manager.h"
35 #endif
36 #include "string_wrapper.h"
37 #include "system_ability_definition.h"
38 
39 namespace OHOS {
40 namespace DistributedSchedule {
41 using namespace AAFwk;
42 namespace {
43 const std::string TAG = "DSchedCollab";
44 const std::string DMS_VERSION_ID = "dmsVersion";
45 const std::u16string NAPI_COLLAB_CALLBACK_INTERFACE_TOKEN = u"OHOS.DistributedCollab.IAbilityConnectionManager";
46 const std::string KEY_START_OPTION = "ohos.collabrate.key.start.option";
47 const std::string VALUE_START_OPTION_FOREGROUND = "ohos.collabrate.value.foreground";
48 const std::string VALUE_START_OPTION_BACKGROUND = "ohos.collabrate.value.background";
49 
50 constexpr int32_t DSCHED_COLLAB_PROTOCOL_VERSION = 1;
51 constexpr int32_t NOTIFY_COLLAB_PREPARE_RESULT = 0;
52 constexpr int32_t NOTIFY_COLLAB_DISCONNECT = 1;
53 constexpr int32_t NOTIFY_WIFI_OPEN = 2;
54 constexpr int32_t NOTIFY_PEER_COLLAB_VERSION = 3;
55 constexpr int32_t DMS_VERSION = 5;
56 constexpr int32_t START_PERMISSION = 0;
57 std::map<int32_t, std::string> CMDDATA = {
58     {MIN_CMD, "MIN_CMD"},
59     {SINK_GET_VERSION_CMD, "SINK_GET_VERSION_CMD"},
60     {SOURCE_GET_VERSION_CMD, "SOURCE_GET_VERSION_CMD"},
61     {SINK_START_CMD, "SINK_START_CMD"},
62     {NOTIFY_RESULT_CMD, "NOTIFY_RESULT_CMD"},
63     {DISCONNECT_CMD, "DISCONNECT_CMD"},
64     {MAX_CMD, "MAX_CMD"},
65 };
66 std::map<int32_t, std::string> EVENTDATA = {
67     {SOURCE_GET_PEER_VERSION_EVENT, "SOURCE_GET_PEER_VERSION_EVENT"},
68     {SOURCE_START_EVENT, "SOURCE_START_EVENT"},
69     {NOTIFY_RESULT_EVENT, "NOTIFY_RESULT_EVENT"},
70     {GET_SINK_VERSION_EVENT, "GET_SINK_VERSION_EVENT"},
71     {START_ABILITY_EVENT, "START_ABILITY_EVENT"},
72     {NOTIFY_PREPARE_RESULT_EVENT, "NOTIFY_PREPARE_RESULT_EVENT"},
73     {ERR_END_EVENT, "ERR_END_EVENT"},
74     {END_EVENT, "END_EVENT"},
75 };
76 std::map<int32_t, std::string> STATEDATA = {
77     {SOURCE_GET_PEER_VERSION_STATE, "SOURCE_GET_PEER_VERSION_STATE"},
78     {SOURCE_START_STATE, "SOURCE_START_STATE"},
79     {SOURCE_WAIT_RESULT_STATE, "SOURCE_WAIT_RESULT_STATE"},
80     {SOURCE_WAIT_END_STATE, "SOURCE_WAIT_END_STATE"},
81     {SINK_GET_VERSION_STATE, "SINK_GET_VERSION_STATE"},
82     {SINK_START_STATE, "SINK_START_STATE"},
83     {SINK_CONNECT_STATE, "SINK_CONNECT_STATE"},
84     {SINK_WAIT_END_STATE, "SINK_WAIT_END_STATE"},
85 };
86 }
87 
DSchedCollab(const std::string & collabToken,const DSchedCollabInfo & info)88 DSchedCollab::DSchedCollab(const std::string &collabToken, const DSchedCollabInfo &info)
89 {
90     HILOGI("create");
91     collabInfo_ = info;
92     collabInfo_.collabToken_ = collabToken;
93     collabInfo_.srcCollabVersion_ = DSCHED_COLLAB_PROTOCOL_VERSION;
94     HILOGI("created successfully. collabInfo: %{public}s", collabInfo_.ToString().c_str());
95 }
96 
DSchedCollab(std::shared_ptr<GetSinkCollabVersionCmd> startCmd,const int32_t & softbusSessionId)97 DSchedCollab::DSchedCollab(std::shared_ptr<GetSinkCollabVersionCmd> startCmd, const int32_t &softbusSessionId)
98 {
99     HILOGI("create by recvCmd");
100     if (startCmd == nullptr) {
101         HILOGE("startCmd is null");
102         return;
103     }
104     collabInfo_.srcCollabSessionId_ = startCmd->srcCollabSessionId_;
105     collabInfo_.collabToken_ = startCmd->collabToken_;
106     collabInfo_.srcInfo_.pid_ = startCmd->srcPid_;
107     collabInfo_.srcInfo_.uid_ = startCmd->srcUid_;
108     collabInfo_.srcInfo_.accessToken_ = startCmd->srcAccessToken_;
109     collabInfo_.direction_ = COLLAB_SINK;
110     softbusSessionId_ = softbusSessionId;
111     HILOGI("created successfully. collabInfo: %{public}s", collabInfo_.ToString().c_str());
112 }
113 
SetSrcCollabInfo(DSchedCollabInfo & info)114 void DSchedCollab::SetSrcCollabInfo(DSchedCollabInfo &info)
115 {
116     HILOGI("called");
117     info.srcClientCB_ = collabInfo_.srcClientCB_;
118     collabInfo_ = info;
119     HILOGI("end");
120 }
121 
SetSinkCollabInfo(std::shared_ptr<SinkStartCmd> startCmd)122 void DSchedCollab::SetSinkCollabInfo(std::shared_ptr<SinkStartCmd> startCmd)
123 {
124     HILOGI("create by recvCmd");
125     if (startCmd == nullptr) {
126         HILOGE("startCmd is null");
127         return;
128     }
129     collabInfo_.srcCollabVersion_ = startCmd->collabVersion_;
130     collabInfo_.srcOpt_.needSendBigData_ = startCmd->needSendBigData_;
131     collabInfo_.srcOpt_.needSendStream_ = startCmd->needSendStream_;
132     collabInfo_.srcOpt_.needRecvStream_ = startCmd->needRecvStream_;
133     collabInfo_.srcOpt_.startParams_ = startCmd->startParams_;
134     collabInfo_.srcOpt_.messageParams_ = startCmd->messageParams_;
135     collabInfo_.srcInfo_.deviceId_ = startCmd->srcDeviceId_;
136     collabInfo_.srcInfo_.bundleName_ = startCmd->srcBundleName_;
137     collabInfo_.srcInfo_.abilityName_ = startCmd->srcAbilityName_;
138     collabInfo_.srcInfo_.moduleName_ = startCmd->srcModuleName_;
139     collabInfo_.srcInfo_.serverId_ = startCmd->srcServerId_;
140     collabInfo_.srcInfo_.pid_ = startCmd->srcPid_;
141     collabInfo_.srcInfo_.uid_ = startCmd->srcUid_;
142     collabInfo_.srcInfo_.accessToken_ = startCmd->srcAccessToken_;
143     collabInfo_.sinkInfo_.deviceId_ = startCmd->sinkDeviceId_;
144     collabInfo_.sinkInfo_.bundleName_ = startCmd->sinkBundleName_;
145     collabInfo_.sinkInfo_.abilityName_ = startCmd->sinkAbilityName_;
146     collabInfo_.srcAppVersion_ = startCmd->appVersion_;
147     collabInfo_.callerInfo_ = startCmd->callerInfo_;
148     collabInfo_.srcAccountInfo_ = startCmd->accountInfo_;
149 
150 #ifdef OS_ACCOUNT_PART
151     std::vector<int32_t> ids;
152     int32_t ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
153     if (ret != ERR_OK || ids.empty()) {
154         HILOGE("Get userId from active Os AccountIds fail, ret : %{public}d", ret);
155         return;
156     }
157     collabInfo_.sinkUserId_ = ids[0];
158 #endif
159     HILOGI("created successfully. collabInfo: %{public}s", collabInfo_.ToString().c_str());
160 }
161 
~DSchedCollab()162 DSchedCollab::~DSchedCollab()
163 {
164     HILOGI("delete enter");
165     UnregisterAbilityLifecycleObserver();
166     if ((eventHandler_ != nullptr) && (eventHandler_->GetEventRunner() != nullptr)) {
167         eventHandler_->GetEventRunner()->Stop();
168     }
169 
170     if (eventThread_.joinable()) {
171         eventThread_.join();
172     }
173 
174     eventHandler_ = nullptr;
175     HILOGI("delete end");
176 }
177 
Init()178 int32_t DSchedCollab::Init()
179 {
180     HILOGI("called");
181     if (eventHandler_ != nullptr) {
182         HILOGI("already inited, end.");
183         return ERR_OK;
184     }
185     auto dCollab = std::shared_ptr<DSchedCollab>(shared_from_this());
186     stateMachine_ = std::make_shared<DSchedCollabStateMachine>(dCollab);
187 
188     eventThread_ = std::thread(&DSchedCollab::StartEventHandler, this);
189     std::unique_lock<std::mutex> lock(eventMutex_);
190     eventCon_.wait(lock, [this] {
191         return eventHandler_ != nullptr;
192     });
193     HILOGI("end");
194     return ERR_OK;
195 }
196 
StartEventHandler()197 void DSchedCollab::StartEventHandler()
198 {
199     HILOGI("called");
200     std::string eventThreadName = "DSchedCollab_EventHandler";
201     prctl(PR_SET_NAME, eventThreadName.c_str());
202     auto runner = AppExecFwk::EventRunner::Create(false);
203     if (runner == nullptr) {
204         HILOGE("continue start eventHandler failed.");
205         return;
206     }
207     {
208         std::lock_guard<std::mutex> lock(eventMutex_);
209         eventHandler_ = std::make_shared<DSchedCollabEventHandler>(runner, shared_from_this());
210     }
211     eventCon_.notify_one();
212     runner->Run();
213 }
214 
PostSrcGetPeerVersionTask()215 int32_t DSchedCollab::PostSrcGetPeerVersionTask()
216 {
217     HILOGI("called");
218     if (eventHandler_ == nullptr) {
219         HILOGE("eventHandler is nullptr");
220         return INVALID_PARAMETERS_ERR;
221     }
222     DSchedCollabEventType eventType = SOURCE_GET_PEER_VERSION_EVENT;
223     auto msgEvent = AppExecFwk::InnerEvent::Get(eventType);
224     if (!eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
225         HILOGE("send event type %{public}s fail", EVENTDATA[eventType].c_str());
226         return COLLAB_SEND_EVENT_FAILED;
227     }
228     return ERR_OK;
229 }
230 
PostSrcGetVersionTask()231 int32_t DSchedCollab::PostSrcGetVersionTask()
232 {
233     HILOGI("called");
234     if (eventHandler_ == nullptr) {
235         HILOGE("eventHandler is nullptr");
236         return INVALID_PARAMETERS_ERR;
237     }
238     DSchedCollabEventType eventType = SOURCE_GET_VERSION_EVENT;
239     auto msgEvent = AppExecFwk::InnerEvent::Get(eventType);
240     if (!eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
241         HILOGE("send event type %{public}s fail", EVENTDATA[eventType].c_str());
242         return COLLAB_SEND_EVENT_FAILED;
243     }
244     return ERR_OK;
245 }
246 
PostSrcStartTask()247 int32_t DSchedCollab::PostSrcStartTask()
248 {
249     HILOGI("called");
250     if (eventHandler_ == nullptr) {
251         HILOGE("eventHandler is nullptr");
252         return INVALID_PARAMETERS_ERR;
253     }
254     DSchedCollabEventType eventType = SOURCE_START_EVENT;
255     auto msgEvent = AppExecFwk::InnerEvent::Get(eventType);
256     if (!eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
257         HILOGE("send event type %{public}s fail", EVENTDATA[eventType].c_str());
258         return COLLAB_SEND_EVENT_FAILED;
259     }
260     return ERR_OK;
261 }
262 
PostSinkGetVersionTask()263 int32_t DSchedCollab::PostSinkGetVersionTask()
264 {
265     HILOGI("called");
266     if (eventHandler_ == nullptr) {
267         HILOGE("eventHandler is nullptr");
268         return INVALID_PARAMETERS_ERR;
269     }
270     DSchedCollabEventType eventType = GET_SINK_VERSION_EVENT;
271     auto msgEvent = AppExecFwk::InnerEvent::Get(eventType);
272     if (!eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
273         HILOGE("send event type %{public}s fail", EVENTDATA[eventType].c_str());
274         return COLLAB_SEND_EVENT_FAILED;
275     }
276     return ERR_OK;
277 }
278 
PostSinkStartTask(const std::string & peerDeviceId)279 int32_t DSchedCollab::PostSinkStartTask(const std::string &peerDeviceId)
280 {
281     HILOGI("called");
282     if (eventHandler_ == nullptr) {
283         HILOGE("eventHandler is nullptr");
284         return INVALID_PARAMETERS_ERR;
285     }
286     DSchedCollabEventType eventType = START_ABILITY_EVENT;
287     auto data = std::make_shared<std::string>(peerDeviceId);
288     auto msgEvent = AppExecFwk::InnerEvent::Get(eventType, data, 0);
289     if (!eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
290         HILOGE("send event type %{public}s fail", EVENTDATA[eventType].c_str());
291         return COLLAB_SEND_EVENT_FAILED;
292     }
293     return ERR_OK;
294 }
295 
PostSinkPrepareResultTask(const int32_t & result,const int32_t & collabSessionId,const std::string & socketName,const sptr<IRemoteObject> & clientCB)296 int32_t DSchedCollab::PostSinkPrepareResultTask(const int32_t &result, const int32_t &collabSessionId,
297     const std::string &socketName, const sptr<IRemoteObject> &clientCB)
298 {
299     HILOGI("called, collabSessionId: %{public}d, result: %{public}d, socketName: %{public}s",
300         collabSessionId, result, socketName.c_str());
301     if (eventHandler_ == nullptr) {
302         HILOGE("eventHandler is nullptr");
303         return INVALID_PARAMETERS_ERR;
304     }
305     collabInfo_.sinkCollabSessionId_ = collabSessionId;
306     collabInfo_.sinkInfo_.socketName_ = socketName;
307     collabInfo_.sinkClientCB_ = clientCB;
308     auto data = std::make_shared<int32_t>(result);
309     DSchedCollabEventType eventType = NOTIFY_PREPARE_RESULT_EVENT;
310     auto msgEvent = AppExecFwk::InnerEvent::Get(eventType, data, 0);
311     if (!eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
312         HILOGE("send event type %{public}s fail", EVENTDATA[eventType].c_str());
313         return COLLAB_SEND_EVENT_FAILED;
314     }
315     HILOGI("end");
316     return ERR_OK;
317 }
318 
PostSrcResultTask(std::shared_ptr<NotifyResultCmd> notifyResultCmd)319 int32_t DSchedCollab::PostSrcResultTask(std::shared_ptr<NotifyResultCmd> notifyResultCmd)
320 {
321     HILOGI("called, collabInfo %{public}s", collabInfo_.ToString().c_str());
322     if (eventHandler_ == nullptr) {
323         HILOGE("eventHandler is nullptr");
324         return INVALID_PARAMETERS_ERR;
325     }
326     if (!notifyResultCmd->abilityRejectReason_.empty()) {
327         DSchedCollabEventType eventType = ABILITY_REJECT_EVENT;
328         auto data = std::make_shared<std::string>(notifyResultCmd->abilityRejectReason_);
329         auto msgEvent = AppExecFwk::InnerEvent::Get(eventType, data, 0);
330         if (!eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
331             HILOGE("send event type %{public}s fail", EVENTDATA[eventType].c_str());
332             return COLLAB_SEND_EVENT_FAILED;
333         }
334         return ERR_OK;
335     }
336     collabInfo_.sinkCollabSessionId_ = notifyResultCmd->sinkCollabSessionId_;
337     collabInfo_.sinkInfo_.socketName_ = notifyResultCmd->sinkSocketName_;
338     collabInfo_.sinkInfo_.pid_ = notifyResultCmd->sinkPid_;
339     collabInfo_.sinkInfo_.accessToken_ = notifyResultCmd->sinkAccessToken_;
340     collabInfo_.sinkUserId_ = notifyResultCmd->sinkUserId_;
341     collabInfo_.sinkAccountId_ = notifyResultCmd->sinkAccountId_;
342     collabInfo_.sinkUdid_ = DtbschedmgrDeviceInfoStorage::GetInstance().GetUdidByNetworkId(
343         collabInfo_.sinkInfo_.deviceId_);
344     collabInfo_.srcUdid_ = DtbschedmgrDeviceInfoStorage::GetInstance().GetUdidByNetworkId(
345         collabInfo_.srcInfo_.deviceId_);
346     DSchedCollabEventType eventType = NOTIFY_RESULT_EVENT;
347     auto data = std::make_shared<int32_t>(notifyResultCmd->result_);
348     auto msgEvent = AppExecFwk::InnerEvent::Get(eventType, data, 0);
349     if (!eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
350         HILOGE("send event type %{public}s fail", EVENTDATA[eventType].c_str());
351         return COLLAB_SEND_EVENT_FAILED;
352     }
353     return ERR_OK;
354 }
355 
PostErrEndTask(const int32_t & result)356 int32_t DSchedCollab::PostErrEndTask(const int32_t &result)
357 {
358     HILOGI("called, collabInfo %{public}s", collabInfo_.ToString().c_str());
359     if (eventHandler_ == nullptr) {
360         HILOGE("eventHandler is nullptr");
361         return INVALID_PARAMETERS_ERR;
362     }
363     DSchedCollabEventType eventType = ERR_END_EVENT;
364     auto data = std::make_shared<int32_t>(result);
365     auto msgEvent = AppExecFwk::InnerEvent::Get(eventType, data, 0);
366     if (!eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
367         HILOGE("send event type %{public}s fail", EVENTDATA[eventType].c_str());
368         return COLLAB_SEND_EVENT_FAILED;
369     }
370     return ERR_OK;
371 }
372 
PostAbilityRejectTask(const std::string & reason)373 int32_t DSchedCollab::PostAbilityRejectTask(const std::string &reason)
374 {
375     HILOGI("called, reason: %{public}s", reason.c_str());
376     if (eventHandler_ == nullptr) {
377         HILOGE("eventHandler is nullptr");
378         return INVALID_PARAMETERS_ERR;
379     }
380     DSchedCollabEventType eventType = ABILITY_REJECT_EVENT;
381     auto data = std::make_shared<std::string>(reason);
382     auto msgEvent = AppExecFwk::InnerEvent::Get(eventType, data, 0);
383     if (!eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
384         HILOGE("send event type %{public}s fail", EVENTDATA[eventType].c_str());
385         return COLLAB_SEND_EVENT_FAILED;
386     }
387     return ERR_OK;
388 }
389 
PostEndTask()390 int32_t DSchedCollab::PostEndTask()
391 {
392     HILOGI("called, collabInfo %{public}s", collabInfo_.ToString().c_str());
393     if (eventHandler_ == nullptr) {
394         HILOGE("eventHandler is nullptr");
395         return INVALID_PARAMETERS_ERR;
396     }
397     DSchedCollabEventType eventType = END_EVENT;
398     auto msgEvent = AppExecFwk::InnerEvent::Get(eventType);
399     if (!eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
400         HILOGE("send event type %{public}s fail", EVENTDATA[eventType].c_str());
401         return COLLAB_SEND_EVENT_FAILED;
402     }
403     HILOGI("end");
404     return ERR_OK;
405 }
406 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)407 void DSchedCollab::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
408 {
409     if (event == nullptr || stateMachine_ == nullptr) {
410         HILOGE("event or state machine is null");
411         return;
412     }
413     auto eventId = event->GetInnerEventId();
414     HILOGI("process event: %{public}s with state %{public}s",
415         EVENTDATA[eventId].c_str(), STATEDATA[stateMachine_->GetStateType()].c_str());
416     int32_t ret = stateMachine_->Execute(event);
417     if (ret != ERR_OK) {
418         HILOGE("event %{public}s execute failed, ret %{public}d", EVENTDATA[eventId].c_str(), ret);
419         PostErrEndTask(ret);
420     }
421     return;
422 }
423 
ExeSrcGetPeerVersion()424 int32_t DSchedCollab::ExeSrcGetPeerVersion()
425 {
426     HILOGI("called");
427     const std::string sinkDeviceId = collabInfo_.sinkInfo_.deviceId_;
428     int32_t ret = DSchedTransportSoftbusAdapter::GetInstance().ConnectDevice(sinkDeviceId,
429         softbusSessionId_, SERVICE_TYPE_COLLAB);
430     if (ret != ERR_OK) {
431         HILOGE("connect peer device failed, ret %{public}d", ret);
432         return ret;
433     }
434     HILOGI("this bind is successful, softbusSessionId %{public}d", softbusSessionId_);
435 
436     auto getPeerVersionCmd = std::make_shared<GetSinkCollabVersionCmd>();
437     ret = PackGetPeerVersionCmd(getPeerVersionCmd);
438     if (ret != ERR_OK) {
439         HILOGE("pack failed, ret %{public}d", ret);
440         return ret;
441     }
442     ret = SendCommand(getPeerVersionCmd);
443     if (ret != ERR_OK) {
444         HILOGE("send failed, ret %{public}d", ret);
445         return ret;
446     }
447 
448     HILOGI("end");
449     return ERR_OK;
450 }
451 
ExeSrcGetVersion()452 int32_t DSchedCollab::ExeSrcGetVersion()
453 {
454     HILOGI("called");
455     int32_t ret = SrcPeerVersionNotify();
456     if (ret != ERR_OK) {
457         HILOGE("failed, ret: %{public}d", ret);
458         return PostErrEndTask(ret);
459     }
460     HILOGI("end");
461     return ERR_OK;
462 }
463 
ExeSrcStart()464 int32_t DSchedCollab::ExeSrcStart()
465 {
466     HILOGI("called");
467     auto startCmd = std::make_shared<SinkStartCmd>();
468     int32_t ret = PackStartCmd(startCmd);
469     if (ret != ERR_OK) {
470         HILOGE("pack startCmd failed, ret %{public}d", ret);
471         return ret;
472     }
473     ret = SendCommand(startCmd);
474     if (ret != ERR_OK) {
475         HILOGE("send startCmd failed, ret %{public}d", ret);
476         return ret;
477     }
478 
479     UpdateState(SOURCE_WAIT_RESULT_STATE);
480     RegisterAbilityLifecycleObserver(collabInfo_.srcInfo_.bundleName_);
481     HILOGI("end");
482     return ERR_OK;
483 }
484 
PackGetPeerVersionCmd(std::shared_ptr<GetSinkCollabVersionCmd> & cmd)485 int32_t DSchedCollab::PackGetPeerVersionCmd(std::shared_ptr<GetSinkCollabVersionCmd>& cmd)
486 {
487     if (cmd == nullptr) {
488         HILOGE("cmd or is null");
489         return INVALID_PARAMETERS_ERR;
490     }
491     cmd->command_ = SINK_GET_VERSION_CMD;
492     cmd->srcCollabSessionId_ = collabInfo_.srcCollabSessionId_;
493     cmd->collabToken_ = collabInfo_.collabToken_;
494     cmd->sinkDeviceId_ = collabInfo_.sinkInfo_.deviceId_;
495     cmd->srcDeviceId_ = collabInfo_.srcInfo_.deviceId_;
496     return ERR_OK;
497 }
498 
PackSinkCollabVersionCmd(std::shared_ptr<GetSinkCollabVersionCmd> & cmd)499 int32_t DSchedCollab::PackSinkCollabVersionCmd(std::shared_ptr<GetSinkCollabVersionCmd>& cmd)
500 {
501     if (cmd == nullptr) {
502         HILOGE("cmd or is null");
503         return INVALID_PARAMETERS_ERR;
504     }
505     cmd->command_ = SOURCE_GET_VERSION_CMD;
506     cmd->collabToken_ = collabInfo_.collabToken_;
507     cmd->sinkCollabVersion_ = DSCHED_COLLAB_PROTOCOL_VERSION;
508     cmd->srcDeviceId_ = collabInfo_.srcInfo_.deviceId_;
509     cmd->sinkDeviceId_ = collabInfo_.sinkInfo_.deviceId_;
510     return ERR_OK;
511 }
512 
PackStartCmd(std::shared_ptr<SinkStartCmd> & cmd)513 int32_t DSchedCollab::PackStartCmd(std::shared_ptr<SinkStartCmd>& cmd)
514 {
515     if (cmd == nullptr) {
516         HILOGE("cmd or is null");
517         return INVALID_PARAMETERS_ERR;
518     }
519     cmd->collabVersion_ = collabInfo_.srcCollabVersion_;
520     cmd->dmsVersion_ = DMS_VERSION;
521     cmd->command_ = SINK_START_CMD;
522     cmd->srcCollabSessionId_ = collabInfo_.srcCollabSessionId_;
523     cmd->collabToken_ = collabInfo_.collabToken_;
524     cmd->srcPid_ = collabInfo_.srcInfo_.pid_;
525     cmd->srcUid_ = collabInfo_.srcInfo_.uid_;
526     cmd->srcAccessToken_ = collabInfo_.srcInfo_.accessToken_;
527     cmd->srcServerId_ = collabInfo_.srcInfo_.serverId_;
528     cmd->sinkServerId_ = collabInfo_.sinkInfo_.serverId_;
529     cmd->srcDeviceId_ = collabInfo_.srcInfo_.deviceId_;
530     cmd->sinkDeviceId_ = collabInfo_.sinkInfo_.deviceId_;
531     cmd->srcBundleName_ = collabInfo_.srcInfo_.bundleName_;
532     cmd->sinkBundleName_ = collabInfo_.sinkInfo_.bundleName_;
533     cmd->srcAbilityName_ = collabInfo_.srcInfo_.abilityName_;
534     cmd->sinkAbilityName_ = collabInfo_.sinkInfo_.abilityName_;
535     cmd->srcModuleName_ = collabInfo_.srcInfo_.moduleName_;
536     cmd->sinkModuleName_ = collabInfo_.sinkInfo_.moduleName_;
537     cmd->needSendBigData_ = collabInfo_.srcOpt_.needSendBigData_;
538     cmd->needSendStream_ = collabInfo_.srcOpt_.needSendStream_;
539     cmd->needRecvStream_ = collabInfo_.srcOpt_.needRecvStream_;
540     cmd->startParams_ = collabInfo_.srcOpt_.startParams_;
541     cmd->messageParams_ = collabInfo_.srcOpt_.messageParams_;
542     return PackPartCmd(cmd);
543 }
544 
PackPartCmd(std::shared_ptr<SinkStartCmd> & cmd)545 int32_t DSchedCollab::PackPartCmd(std::shared_ptr<SinkStartCmd>& cmd)
546 {
547     AppExecFwk::BundleInfo localBundleInfo;
548     int32_t ret = BundleManagerInternal::GetLocalBundleInfoV9(cmd->srcBundleName_, localBundleInfo);
549     if (ret != ERR_OK) {
550         HILOGE("pack start cmd failed, the bundle is not installed on local device.");
551         return ret;
552     }
553     cmd->appVersion_ = static_cast<int32_t>(localBundleInfo.versionCode);
554     CallerInfo callerInfo;
555     callerInfo.sourceDeviceId = collabInfo_.srcInfo_.deviceId_;
556     callerInfo.uid = collabInfo_.srcInfo_.uid_;
557     callerInfo.accessToken = static_cast<uint32_t>(collabInfo_.srcInfo_.accessToken_);
558     if (!BundleManagerInternal::GetCallerAppIdFromBms(callerInfo.uid, callerInfo.callerAppId)) {
559         HILOGE("GetCallerAppIdFromBms failed");
560         return GET_APPID_ERR;
561     }
562     if (!BundleManagerInternal::GetBundleNameListFromBms(callerInfo.uid, callerInfo.bundleNames)) {
563         HILOGE("GetBundleNameListFromBms failed");
564         return GET_BUNDLENAMELIST_ERR;
565     }
566     callerInfo.extraInfoJson[DMS_VERSION_ID] = DMS_VERSION;
567     AccountInfo accountInfo;
568     ret = DistributedSchedPermission::GetInstance().GetAccountInfo(collabInfo_.sinkInfo_.deviceId_,
569         callerInfo, accountInfo);
570     if (ret != ERR_OK) {
571         HILOGE("get or check accountInfo failed");
572         return GET_ACCOUNT_INFO_ERR;
573     }
574     cmd->callerInfo_ = callerInfo;
575     collabInfo_.callerInfo_ = callerInfo;
576     cmd->accountInfo_ = accountInfo;
577     collabInfo_.srcAccountInfo_ = accountInfo;
578     return ERR_OK;
579 }
580 
ExeStartAbility(const std::string & peerDeviceId)581 int32_t DSchedCollab::ExeStartAbility(const std::string &peerDeviceId)
582 {
583     HILOGI("called, peerDeviceId: %{public}s", GetAnonymStr(peerDeviceId).c_str());
584     if (collabInfo_.callerInfo_.sourceDeviceId != peerDeviceId) {
585         HILOGE("Irrecognized srcDeviceId!");
586         return INVALID_PARAMETERS_ERR;
587     }
588     AAFwk::Want want = GenerateCollabWant();
589     int32_t ret = DistributedSchedService::GetInstance().CheckCollabStartPermission(want, collabInfo_.callerInfo_,
590         collabInfo_.srcAccountInfo_, START_PERMISSION);
591     if (ret != ERR_OK) {
592         HILOGE("CheckTargetPermission failed!");
593         return ret;
594     }
595 
596     HILOGI("flag is %{public}d", want.GetFlags());
597     ret = AAFwk::AbilityManagerClient::GetInstance()->Connect();
598     if (ret != ERR_OK) {
599         HILOGE("connect ability server failed %{public}d", ret);
600         return ret;
601     }
602     sptr<IRemoteObject> callbackWrapper = sptr<AbilityConnectionWrapperStub>(new AbilityConnectionWrapperStub());
603     ret = AAFwk::AbilityManagerClient::GetInstance()->StartAbilityByCall(want,
604         iface_cast<AAFwk::IAbilityConnection>(callbackWrapper));
605     if (ret != ERR_OK) {
606         HILOGE("startAbilityByCall failed! ret: %{public}d", ret);
607         ret = PostErrEndTask(ret);
608         return ret;
609     }
610 
611     UpdateState(SINK_CONNECT_STATE);
612     RegisterAbilityLifecycleObserver(collabInfo_.sinkInfo_.bundleName_);
613     HILOGI("end");
614     return ERR_OK;
615 }
616 
GenerateCollabWant()617 AAFwk::Want DSchedCollab::GenerateCollabWant()
618 {
619     HILOGI("called");
620     AAFwk::Want want;
621     want.AddFlags(want.FLAG_ABILITY_ON_COLLABORATE);
622     want.SetParam("deviceId", collabInfo_.sinkInfo_.deviceId_);
623     want.SetElementName(collabInfo_.sinkInfo_.deviceId_, collabInfo_.sinkInfo_.bundleName_,
624         collabInfo_.sinkInfo_.abilityName_);
625 
626     AAFwk::WantParams peerInfoParams;
627     peerInfoParams.SetParam("deviceId", AAFwk::String::Box(collabInfo_.srcInfo_.deviceId_));
628     peerInfoParams.SetParam("bundleName", AAFwk::String::Box(collabInfo_.srcInfo_.bundleName_));
629     peerInfoParams.SetParam("moduleName", AAFwk::String::Box(collabInfo_.srcInfo_.moduleName_));
630     peerInfoParams.SetParam("abilityName", AAFwk::String::Box(collabInfo_.srcInfo_.abilityName_));
631     peerInfoParams.SetParam("serverId", AAFwk::String::Box(collabInfo_.srcInfo_.serverId_));
632 
633     AAFwk::WantParams optParams;
634     optParams.SetParam("needSendData", AAFwk::Boolean::Box(collabInfo_.srcOpt_.needSendBigData_));
635     optParams.SetParam("needSendStream", AAFwk::Boolean::Box(collabInfo_.srcOpt_.needSendStream_));
636     optParams.SetParam("needReceiveStream", AAFwk::Boolean::Box(collabInfo_.srcOpt_.needRecvStream_));
637     optParams.SetParam("parameters", AAFwk::WantParamWrapper::Box(collabInfo_.srcOpt_.messageParams_));
638 
639     AAFwk::WantParams collabParams;
640     collabParams.SetParam("PeerInfo", AAFwk::WantParamWrapper::Box(peerInfoParams));
641     collabParams.SetParam("ConnectOption", AAFwk::WantParamWrapper::Box(optParams));
642     collabParams.SetParam("ohos.dms.collabToken", AAFwk::String::Box(collabInfo_.collabToken_));
643 
644     AAFwk::WantParams wantParams;
645     SetScreenLockParameters(wantParams);
646     wantParams.SetParam("ohos.extra.param.key.supportCollaborateIndex", AAFwk::WantParamWrapper::Box(collabParams));
647     HILOGI("ohos.aafwk.param.callAbilityToForeground is %{public}d", IsStartForeground());
648     wantParams.SetParam("ohos.aafwk.param.callAbilityToForeground", AAFwk::Boolean::Box(IsStartForeground()));
649     want.SetParams(wantParams);
650     return want;
651 }
652 
SetScreenLockParameters(AAFwk::WantParams & wantParams)653 void DSchedCollab::SetScreenLockParameters(AAFwk::WantParams& wantParams)
654 {
655 #ifdef DMS_CHECK_SCREENLOCK
656     bool isSecureMode = OHOS::ScreenLock::ScreenLockManager::GetInstance()->GetSecure();
657     bool isLocked = false;
658     OHOS::ScreenLock::ScreenLockManager::GetInstance()->IsLocked(isLocked);
659     HILOGI("isSecureMode is %{public}d, isLocked is %{public}d", isSecureMode, isLocked);
660     wantParams.SetParam("isSecureMode", AAFwk::Boolean::Box(isSecureMode));
661     wantParams.SetParam("isFromScreenLock", AAFwk::Boolean::Box(isLocked));
662 #endif
663 }
664 
IsStartForeground()665 bool DSchedCollab::IsStartForeground()
666 {
667     auto value = collabInfo_.srcOpt_.startParams_.GetParam(KEY_START_OPTION);
668     IString *ao = IString::Query(value);
669     if (ao != nullptr) {
670         std::string startOpt = AAFwk::String::Unbox(ao);
671         HILOGI("startOpt is: %{public}s", startOpt.c_str());
672         return (startOpt == VALUE_START_OPTION_BACKGROUND) ? false : true;
673     }
674     return true;
675 }
676 
SaveSinkAbilityData(const std::string & collabToken,const int32_t & result,const int32_t & sinkPid,const int32_t & sinkUid,const int32_t & sinkAccessTokenId)677 int32_t DSchedCollab::SaveSinkAbilityData(const std::string& collabToken, const int32_t &result,
678     const int32_t &sinkPid, const int32_t &sinkUid, const int32_t &sinkAccessTokenId)
679 {
680     HILOGI("called, pid: %{public}d, uid: %{public}d, accessTokenId: %{public}d", sinkPid, sinkUid, sinkAccessTokenId);
681     collabInfo_.sinkInfo_.pid_ = sinkPid;
682     collabInfo_.sinkInfo_.uid_ = sinkUid;
683     collabInfo_.sinkInfo_.accessToken_ = sinkAccessTokenId;
684     HILOGI("end, continueInfo %{public}s", collabInfo_.ToString().c_str());
685     return ERR_OK;
686 }
687 
ExeAbilityRejectError(const std::string & reason)688 int32_t DSchedCollab::ExeAbilityRejectError(const std::string &reason)
689 {
690     HILOGI("called");
691     auto cmd = std::make_shared<NotifyResultCmd>();
692     PackNotifyResultCmd(cmd, COLLAB_ABILITY_REJECT_ERR, reason);
693     SendCommand(cmd);
694     CleanUpSession();
695     HILOGI("end");
696     return ERR_OK;
697 }
698 
ExeSinkPrepareResult(const int32_t & result)699 int32_t DSchedCollab::ExeSinkPrepareResult(const int32_t &result)
700 {
701     HILOGI("called");
702     if (result != ERR_OK && result != COLLAB_ABILITY_REJECT_ERR) {
703         HILOGE("failed %{public}d", result);
704         return PostErrEndTask(result);
705     }
706     auto notifyResCmd = std::make_shared<NotifyResultCmd>();
707     PackNotifyResultCmd(notifyResCmd, result);
708     int32_t ret = SendCommand(notifyResCmd);
709     if (ret != ERR_OK) {
710         HILOGE("send notifyResCmd failed, ret %{public}d", ret);
711         return ret;
712     }
713     UpdateState(SINK_WAIT_END_STATE);
714     collabInfo_.srcUdid_ = DtbschedmgrDeviceInfoStorage::GetInstance().GetUdidByNetworkId(
715         collabInfo_.srcInfo_.deviceId_);
716     collabInfo_.sinkUdid_ = DtbschedmgrDeviceInfoStorage::GetInstance().GetUdidByNetworkId(
717         collabInfo_.sinkInfo_.deviceId_);
718     HILOGI("end, info: %{public}s.", collabInfo_.ToString().c_str());
719     return ERR_OK;
720 }
721 
PackNotifyResultCmd(std::shared_ptr<NotifyResultCmd> cmd,const int32_t & result,const std::string & abilityRejectReason)722 int32_t DSchedCollab::PackNotifyResultCmd(std::shared_ptr<NotifyResultCmd> cmd, const int32_t &result,
723     const std::string &abilityRejectReason)
724 {
725     if (cmd == nullptr) {
726         HILOGE("cmd is null");
727         return INVALID_PARAMETERS_ERR;
728     }
729     cmd->command_ = NOTIFY_RESULT_CMD;
730     cmd->result_ = result;
731     cmd->collabToken_ = collabInfo_.collabToken_;
732     cmd->sinkSocketName_ = collabInfo_.sinkInfo_.socketName_;
733     cmd->sinkCollabSessionId_ = collabInfo_.sinkCollabSessionId_;
734     cmd->abilityRejectReason_ = abilityRejectReason;
735     cmd->sinkPid_ = collabInfo_.sinkInfo_.pid_;
736     cmd->sinkAccessToken_ = collabInfo_.sinkInfo_.accessToken_;
737     cmd->sinkUserId_ = collabInfo_.sinkUserId_;
738     cmd->sinkAccountId_ = collabInfo_.sinkAccountId_;
739     return ERR_OK;
740 }
741 
ExeSrcCollabResult(const int32_t & result,const std::string reason)742 int32_t DSchedCollab::ExeSrcCollabResult(const int32_t &result, const std::string reason)
743 {
744     HILOGI("called, collabInfo: %{public}s", collabInfo_.ToString().c_str());
745     if (result != ERR_OK && result != COLLAB_ABILITY_REJECT_ERR) {
746         HILOGE("failed, result: %{public}d", result);
747         return PostErrEndTask(result);
748     }
749     int32_t ret = ExeSrcClientNotify(result, reason);
750     if (!reason.empty()) {
751         HILOGE("reason: %{public}s", reason.c_str());
752         return CleanUpSession();
753     }
754     if (ret != ERR_OK) {
755         HILOGE("failed, ret: %{public}d", ret);
756         return PostErrEndTask(result);
757     }
758     UpdateState(SOURCE_WAIT_END_STATE);
759     HILOGI("end");
760     return ERR_OK;
761 }
762 
CleanUpSession()763 int32_t DSchedCollab::CleanUpSession()
764 {
765     if (collabInfo_.direction_ == COLLAB_SOURCE) {
766         const std::string peerDeviceId = collabInfo_.sinkInfo_.deviceId_;
767         HILOGI("disconnect peer device %{public}s", GetAnonymStr(peerDeviceId).c_str());
768         DSchedTransportSoftbusAdapter::GetInstance().DisconnectDevice(peerDeviceId);
769     }
770     ExeClientDisconnectNotify();
771     return DSchedCollabManager::GetInstance().CleanUpSession(collabInfo_.collabToken_);
772 }
773 
SrcPeerVersionNotify()774 int32_t DSchedCollab::SrcPeerVersionNotify()
775 {
776     HILOGI("called");
777     MessageParcel data;
778     if (!data.WriteInterfaceToken(NAPI_COLLAB_CALLBACK_INTERFACE_TOKEN)) {
779         HILOGE("write token failed");
780         return INVALID_PARAMETERS_ERR;
781     }
782     PARCEL_WRITE_HELPER(data, Int32, collabInfo_.srcCollabSessionId_);
783     PARCEL_WRITE_HELPER(data, Int32, collabInfo_.sinkCollabVersion_);
784     MessageParcel reply;
785     MessageOption option;
786     int32_t ret = collabInfo_.srcClientCB_->SendRequest(NOTIFY_PEER_COLLAB_VERSION, data, reply, option);
787     return ret;
788 }
789 
ExeSrcClientNotify(const int32_t & result,const std::string reason)790 int32_t DSchedCollab::ExeSrcClientNotify(const int32_t &result, const std::string reason)
791 {
792     HILOGI("called, result: %{public}d, collabInfo: %{public}s", result, collabInfo_.ToString().c_str());
793     if (collabInfo_.srcClientCB_ == nullptr) {
794         HILOGW("callback object null.");
795         return INVALID_PARAMETERS_ERR;
796     }
797 
798     MessageParcel data;
799     if (!data.WriteInterfaceToken(NAPI_COLLAB_CALLBACK_INTERFACE_TOKEN)) {
800         HILOGE("write token failed");
801         return INVALID_PARAMETERS_ERR;
802     }
803     PARCEL_WRITE_HELPER(data, Int32, collabInfo_.srcCollabSessionId_);
804     PARCEL_WRITE_HELPER(data, Int32, result);
805     PARCEL_WRITE_HELPER(data, String, collabInfo_.sinkInfo_.socketName_);
806     PARCEL_WRITE_HELPER(data, String, collabInfo_.collabToken_);
807     PARCEL_WRITE_HELPER(data, String, reason);
808     MessageParcel reply;
809     MessageOption option;
810     int32_t ret = collabInfo_.srcClientCB_->SendRequest(NOTIFY_COLLAB_PREPARE_RESULT, data, reply, option);
811     if (ret != ERR_OK) {
812         HILOGE("send request failed, ret: %{public}d", ret);
813     }
814     HILOGI("end");
815     return ret;
816 }
817 
ExeClientDisconnectNotify()818 int32_t DSchedCollab::ExeClientDisconnectNotify()
819 {
820     HILOGI("called");
821     int32_t collabSessionId;
822     sptr<IRemoteObject> clientCB;
823     if (collabInfo_.direction_ == COLLAB_SOURCE) {
824         if (collabInfo_.srcClientCB_ == nullptr) {
825             HILOGW("srcClientCB object null.");
826             return ERR_NULL_OBJECT;
827         }
828         collabSessionId = collabInfo_.srcCollabSessionId_;
829         clientCB = collabInfo_.srcClientCB_;
830     } else {
831         if (collabInfo_.sinkClientCB_ == nullptr) {
832             HILOGW("sinkClientCB object null.");
833             return ERR_NULL_OBJECT;
834         }
835         collabSessionId = collabInfo_.sinkCollabSessionId_;
836         clientCB = collabInfo_.sinkClientCB_;
837     }
838 
839     MessageParcel data;
840     if (!data.WriteInterfaceToken(NAPI_COLLAB_CALLBACK_INTERFACE_TOKEN)) {
841         HILOGE("write token failed");
842         return SEND_REQUEST_DEF_FAIL;
843     }
844     PARCEL_WRITE_HELPER(data, Int32, collabSessionId);
845     MessageParcel reply;
846     MessageOption option;
847     int32_t ret = clientCB->SendRequest(NOTIFY_COLLAB_DISCONNECT, data, reply, option);
848     if (ret != ERR_OK) {
849         HILOGE("send request failed, ret: %{public}d", ret);
850         return SEND_REQUEST_DEF_FAIL;
851     }
852     HILOGI("end");
853     return ERR_OK;
854 }
855 
NotifyWifiOpen()856 int32_t DSchedCollab::NotifyWifiOpen()
857 {
858     HILOGI("called");
859     int32_t collabSessionId;
860     sptr<IRemoteObject> clientCB;
861     if (collabInfo_.direction_ == COLLAB_SOURCE) {
862         if (collabInfo_.srcClientCB_ == nullptr) {
863             HILOGW("srcClientCB object null.");
864             return ERR_NULL_OBJECT;
865         }
866         collabSessionId = collabInfo_.srcCollabSessionId_;
867         clientCB = collabInfo_.srcClientCB_;
868     } else {
869         if (collabInfo_.sinkClientCB_ == nullptr) {
870             HILOGW("sinkClientCB object null.");
871             return ERR_NULL_OBJECT;
872         }
873         collabSessionId = collabInfo_.sinkCollabSessionId_;
874         clientCB = collabInfo_.sinkClientCB_;
875     }
876 
877     MessageParcel data;
878     if (!data.WriteInterfaceToken(NAPI_COLLAB_CALLBACK_INTERFACE_TOKEN)) {
879         HILOGE("write token failed");
880         return SEND_REQUEST_DEF_FAIL;
881     }
882     PARCEL_WRITE_HELPER(data, Int32, collabSessionId);
883     MessageParcel reply;
884     MessageOption option;
885     int32_t ret = clientCB->SendRequest(NOTIFY_WIFI_OPEN, data, reply, option);
886     if (ret != ERR_OK) {
887         HILOGE("send request failed, ret: %{public}d", ret);
888         return SEND_REQUEST_DEF_FAIL;
889     }
890     HILOGI("end");
891     return ERR_OK;
892 }
893 
ExeSrcGetPeerVersionError(const int32_t & result)894 int32_t DSchedCollab::ExeSrcGetPeerVersionError(const int32_t &result)
895 {
896     HILOGE("called, reason: %{public}d", result);
897     ExeSrcClientNotify(result);
898     CleanUpSession();
899     HILOGI("end");
900     return ERR_OK;
901 }
902 
ExeSrcStartError(const int32_t & result)903 int32_t DSchedCollab::ExeSrcStartError(const int32_t &result)
904 {
905     HILOGE("called, reason: %{public}d", result);
906     ExeSrcClientNotify(result);
907     CleanUpSession();
908     HILOGI("end");
909     return ERR_OK;
910 }
911 
ExeSrcWaitResultError(const int32_t & result)912 int32_t DSchedCollab::ExeSrcWaitResultError(const int32_t &result)
913 {
914     HILOGE("called, reason: %{public}d", result);
915     auto cmd = std::make_shared<NotifyResultCmd>();
916     PackNotifyResultCmd(cmd, result);
917     SendCommand(cmd);
918     ExeSrcClientNotify(result);
919     CleanUpSession();
920     HILOGI("end");
921     return ERR_OK;
922 }
923 
ExeSinkGetVersion()924 int32_t DSchedCollab::ExeSinkGetVersion()
925 {
926     HILOGI("end");
927     auto sinkCollabVersionCmd = std::make_shared<GetSinkCollabVersionCmd>();
928     PackSinkCollabVersionCmd(sinkCollabVersionCmd);
929     SendCommand(sinkCollabVersionCmd);
930     UpdateState(SINK_START_STATE);
931     return ERR_OK;
932 }
933 
ExeSinkError(const int32_t & result)934 int32_t DSchedCollab::ExeSinkError(const int32_t &result)
935 {
936     HILOGE("called, reason: %{public}d", result);
937     auto cmd = std::make_shared<NotifyResultCmd>();
938     PackNotifyResultCmd(cmd, result);
939     SendCommand(cmd);
940     CleanUpSession();
941     HILOGI("end");
942     return ERR_OK;
943 }
944 
ExeSinkGetVersionError(const int32_t & result)945 int32_t DSchedCollab::ExeSinkGetVersionError(const int32_t &result)
946 {
947     HILOGE("called, reason: %{public}d", result);
948     auto cmd = std::make_shared<NotifyResultCmd>();
949     PackNotifyResultCmd(cmd, result);
950     SendCommand(cmd);
951     CleanUpSession();
952     HILOGI("end");
953     return ERR_OK;
954 }
955 
ExeSinkStartError(const int32_t & result)956 int32_t DSchedCollab::ExeSinkStartError(const int32_t &result)
957 {
958     HILOGE("called, reason: %{public}d", result);
959     auto cmd = std::make_shared<NotifyResultCmd>();
960     PackNotifyResultCmd(cmd, result);
961     SendCommand(cmd);
962     CleanUpSession();
963     HILOGI("end");
964     return ERR_OK;
965 }
966 
ExeSinkConnectError(const int32_t & result)967 int32_t DSchedCollab::ExeSinkConnectError(const int32_t &result)
968 {
969     HILOGE("called, reason: %{public}d", result);
970     auto cmd = std::make_shared<NotifyResultCmd>();
971     PackNotifyResultCmd(cmd, result);
972     SendCommand(cmd);
973     CleanUpSession();
974     HILOGI("end");
975     return ERR_OK;
976 }
977 
ExeDisconnect()978 int32_t DSchedCollab::ExeDisconnect()
979 {
980     HILOGI("called");
981     auto cmd = std::make_shared<DisconnectCmd>();
982     PackDisconnectCmd(cmd);
983     SendCommand(cmd);
984     CleanUpSession();
985     HILOGI("end");
986     return ERR_OK;
987 }
988 
PackDisconnectCmd(std::shared_ptr<DisconnectCmd> cmd)989 int32_t DSchedCollab::PackDisconnectCmd(std::shared_ptr<DisconnectCmd> cmd)
990 {
991     if (cmd == nullptr) {
992         HILOGE("cmd is null");
993         return INVALID_PARAMETERS_ERR;
994     }
995     cmd->command_ = DISCONNECT_CMD;
996     cmd->collabToken_ = collabInfo_.collabToken_;
997     return ERR_OK;
998 }
999 
SendCommand(std::shared_ptr<BaseCmd> cmd)1000 int32_t DSchedCollab::SendCommand(std::shared_ptr<BaseCmd> cmd)
1001 {
1002     if (cmd == nullptr) {
1003         HILOGE("cmd is null");
1004         return INVALID_PARAMETERS_ERR;
1005     }
1006     HILOGI("called, cmd %{public}s", CMDDATA[cmd->command_].c_str());
1007     std::string jsonStr;
1008     int32_t ret = cmd->Marshal(jsonStr);
1009     if (ret != ERR_OK) {
1010         HILOGE("marshal cmd %{public}s failed, ret %{public}d", CMDDATA[cmd->command_].c_str(), ret);
1011         return ret;
1012     }
1013     auto buffer = std::make_shared<DSchedDataBuffer>(jsonStr.length() + 1);
1014     ret = memcpy_s(buffer->Data(), buffer->Capacity(), jsonStr.c_str(), jsonStr.length());
1015     if (ret != ERR_OK) {
1016         HILOGE("memcpy_s failed, cmd %{public}s, ret %{public}d", CMDDATA[cmd->command_].c_str(), ret);
1017         return ret;
1018     }
1019     ret = DSchedTransportSoftbusAdapter::GetInstance().SendData(softbusSessionId_, SERVICE_TYPE_COLLAB, buffer);
1020     if (ret != ERR_OK) {
1021         HILOGE("send data failed, cmd %{public}s, ret %{public}d", CMDDATA[cmd->command_].c_str(), ret);
1022         return ret;
1023     }
1024     HILOGI("end");
1025     return ERR_OK;
1026 }
1027 
GetSoftbusSessionId()1028 int32_t DSchedCollab::GetSoftbusSessionId()
1029 {
1030     return softbusSessionId_;
1031 }
1032 
GetCollabInfo()1033 DSchedCollabInfo DSchedCollab::GetCollabInfo()
1034 {
1035     return collabInfo_;
1036 }
1037 
OnDataRecv(const std::string & peerDeviceId,int32_t command,std::shared_ptr<DSchedDataBuffer> dataBuffer)1038 void DSchedCollab::OnDataRecv(const std::string &peerDeviceId, int32_t command,
1039     std::shared_ptr<DSchedDataBuffer> dataBuffer)
1040 {
1041     if (dataBuffer == nullptr) {
1042         HILOGE("dataBuffer is null");
1043         return;
1044     }
1045     int32_t ret = 0;
1046     uint8_t *data = dataBuffer->Data();
1047     std::string jsonStr(reinterpret_cast<const char *>(data), dataBuffer->Capacity());
1048     switch (command) {
1049         case SOURCE_GET_VERSION_CMD: {
1050             auto getSinkCollabVersionCmd = std::make_shared<GetSinkCollabVersionCmd>();
1051             ret = getSinkCollabVersionCmd->Unmarshal(jsonStr);
1052             if (ret != ERR_OK) {
1053                 PostErrEndTask(ret);
1054                 return;
1055             }
1056             collabInfo_.sinkCollabVersion_ = getSinkCollabVersionCmd->sinkCollabVersion_;
1057             PostSrcGetVersionTask();
1058             break;
1059         }
1060         case SINK_START_CMD: {
1061             auto startCmd = std::make_shared<SinkStartCmd>();
1062             ret = startCmd->Unmarshal(jsonStr);
1063             if (ret != ERR_OK) {
1064                 PostErrEndTask(ret);
1065                 return;
1066             }
1067             SetSinkCollabInfo(startCmd);
1068             PostSinkStartTask(peerDeviceId);
1069             break;
1070         }
1071         case NOTIFY_RESULT_CMD: {
1072             auto notifyResultCmd = std::make_shared<NotifyResultCmd>();
1073             ret = notifyResultCmd->Unmarshal(jsonStr);
1074             if (ret != ERR_OK) {
1075                 PostErrEndTask(ret);
1076                 return;
1077             }
1078             PostSrcResultTask(notifyResultCmd);
1079             break;
1080         }
1081         case DISCONNECT_CMD: {
1082             CleanUpSession();
1083             break;
1084         }
1085         default:
1086             break;
1087     }
1088 }
1089 
UpdateState(CollabStateType stateType)1090 void DSchedCollab::UpdateState(CollabStateType stateType)
1091 {
1092     HILOGI("called");
1093     if (stateMachine_ == nullptr) {
1094         HILOGE("stateMachine is null");
1095         return;
1096     }
1097     stateMachine_->UpdateState(stateType);
1098 }
1099 
RegisterAbilityLifecycleObserver(const std::string & bundleName)1100 bool DSchedCollab::RegisterAbilityLifecycleObserver(const std::string &bundleName)
1101 {
1102     HILOGI("called");
1103     sptr<AppExecFwk::IAppMgr> appObject = GetAppManager();
1104     if (appObject == nullptr) {
1105         HILOGE("failed to get app manager service");
1106         return false;
1107     }
1108     std::vector<std::string> bundleNameList = {bundleName};
1109     appStateObserver_ = sptr<AbilityLifecycleObserver>(new (std::nothrow) AbilityLifecycleObserver());
1110     int ret = appObject->RegisterApplicationStateObserver(appStateObserver_, bundleNameList);
1111     if (ret != ERR_OK) {
1112         HILOGE("failed to register observer, ret = %{public}d", ret);
1113         return false;
1114     }
1115     HILOGI("success");
1116     return true;
1117 }
1118 
UnregisterAbilityLifecycleObserver()1119 void DSchedCollab::UnregisterAbilityLifecycleObserver()
1120 {
1121     HILOGI("called");
1122     if (appStateObserver_ == nullptr) {
1123         HILOGW("no need to unregister");
1124         return;
1125     }
1126     sptr<AppExecFwk::IAppMgr> appObject = GetAppManager();
1127     if (appObject == nullptr) {
1128         HILOGE("failed to get app manager service");
1129         return;
1130     }
1131     int ret = appObject->UnregisterApplicationStateObserver(appStateObserver_);
1132     if (ret != ERR_OK) {
1133         HILOGE("failed to unregister observer, ret = %{public}d", ret);
1134         return;
1135     }
1136     HILOGI("success");
1137 }
1138 
GetAppManager()1139 sptr<AppExecFwk::IAppMgr> DSchedCollab::GetAppManager()
1140 {
1141     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1142     if (samgr == nullptr) {
1143         HILOGE("system ability manager is nullptr.");
1144         return nullptr;
1145     }
1146 
1147     sptr<AppExecFwk::IAppMgr> appObject =
1148         iface_cast<AppExecFwk::IAppMgr>(samgr->GetSystemAbility(APP_MGR_SERVICE_ID));
1149     if (appObject == nullptr) {
1150         HILOGE("failed to get app manager service");
1151         return nullptr;
1152     }
1153     return appObject;
1154 }
1155 
OnShutDown()1156 void DSchedCollab::OnShutDown()
1157 {
1158 }
1159 
OnBind()1160 void DSchedCollab::OnBind()
1161 {
1162 }
1163 }  // namespace DistributedSchedule
1164 }  // namespace OHOS
1165