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