• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "dsched_collab_manager.h"
17 
18 #include <chrono>
19 #include <random>
20 #include <ctime>
21 #include <sys/prctl.h>
22 
23 #include "cJSON.h"
24 
25 #include "distributed_sched_utils.h"
26 #include "dsched_transport_softbus_adapter.h"
27 #include "dtbschedmgr_device_info_storage.h"
28 #include "dtbschedmgr_log.h"
29 #include "dtbcollabmgr_log.h"
30 #include "mission/distributed_bm_storage.h"
31 #include "mission/wifi_state_adapter.h"
32 #include "multi_user_manager.h"
33 
34 namespace OHOS {
35 namespace DistributedSchedule {
36 namespace {
37 const std::string TAG = "DSchedCollabManager";
38 const std::string DSCHED_COLLAB_MANAGER = "dsched_collab_manager";
39 constexpr static int32_t NO_NEED_TO_CHECK_ID = -1;
40 const int32_t RANDOM_STRING_LENGTH = 20;
41 std::map<int32_t, std::string> CMDDATA = {
42     {MIN_CMD, "MIN_CMD"},
43     {SINK_GET_VERSION_CMD, "SINK_GET_VERSION_CMD"},
44     {SOURCE_GET_VERSION_CMD, "SOURCE_GET_VERSION_CMD"},
45     {SINK_START_CMD, "SINK_START_CMD"},
46     {NOTIFY_RESULT_CMD, "NOTIFY_RESULT_CMD"},
47     {DISCONNECT_CMD, "DISCONNECT_CMD"},
48     {MAX_CMD, "MAX_CMD"},
49 };
50 }
51 
52 IMPLEMENT_SINGLE_INSTANCE(DSchedCollabManager);
53 
DSchedCollabManager()54 DSchedCollabManager::DSchedCollabManager()
55 {
56 }
57 
~DSchedCollabManager()58 DSchedCollabManager::~DSchedCollabManager()
59 {
60     HILOGI("DSchedCollabManager delete");
61     UnInit();
62 }
63 
CheckSynergisticRelation(const CollabInfo * sourceInfo,const CollabInfo * sinkInfo)64 static int32_t CheckSynergisticRelation(const CollabInfo *sourceInfo, const CollabInfo *sinkInfo)
65 {
66     if (sourceInfo == nullptr || sinkInfo == nullptr) {
67         HILOGE("Invalid parameters.");
68         return INVALID_PARAMETERS_ERR;
69     }
70     return DSchedCollabManager::GetInstance().CheckCollabRelation(sourceInfo, sinkInfo);
71 }
72 
73 IFeatureAbilityRelationChecker iAbilityRelationChecker = {
74     .CheckCollabRelation = CheckSynergisticRelation
75 };
76 
Init()77 void DSchedCollabManager::Init()
78 {
79     HILOGI("Init DSchedCollabManager start");
80     if (eventHandler_ != nullptr) {
81         HILOGI("DSchedCollabManager already inited, end.");
82         return;
83     }
84     DSchedTransportSoftbusAdapter::GetInstance().InitChannel();
85     softbusListener_ = std::make_shared<DSchedCollabManager::SoftbusListener>();
86     DSchedTransportSoftbusAdapter::GetInstance().RegisterListener(SERVICE_TYPE_COLLAB, softbusListener_);
87     int32_t ret =  RegisterRelationChecker(&iAbilityRelationChecker);
88     if (ret != ERR_OK) {
89         HILOGE("RegisterRelationChecker failed, ret: %{public}d", ret);
90         return;
91     }
92     eventThread_ = std::thread(&DSchedCollabManager::StartEvent, this);
93     std::unique_lock<std::mutex> lock(eventMutex_);
94     eventCon_.wait(lock, [this] {
95         return eventHandler_ != nullptr;
96     });
97     HILOGI("Init DSchedCollabManager end");
98 }
99 
CheckCollabRelation(const CollabInfo * sourceInfo,const CollabInfo * sinkInfo)100 int32_t DSchedCollabManager::CheckCollabRelation(const CollabInfo *sourceInfo, const CollabInfo *sinkInfo)
101 {
102     HILOGI("called");
103     if (collabs_.empty()) {
104         HILOGE("No collab in progress.");
105         return INVALID_PARAMETERS_ERR;
106     }
107     DSchedCollabInfo collabInfo;
108     for (auto iter = collabs_.begin(); iter != collabs_.end(); iter++) {
109         if (iter->second == nullptr) {
110             HILOGE("collab is nullptr");
111             continue;
112         }
113         collabInfo = iter->second->GetCollabInfo();
114         HILOGI("collabInfo: %{public}s", collabInfo.ToString().c_str());
115         if (CheckSrcCollabRelation(sourceInfo, &collabInfo) == ERR_OK &&
116             (sinkInfo->pid == NO_NEED_TO_CHECK_ID || CheckSinkCollabRelation(sinkInfo, &collabInfo) == ERR_OK)) {
117             HILOGI("the collaboration relationship is matched successfully.");
118             return ERR_OK;
119         }
120     }
121     HILOGE("failed to match the collaboration relationship.");
122     return INVALID_PARAMETERS_ERR;
123 }
124 
CheckSrcCollabRelation(const CollabInfo * sourceInfo,const DSchedCollabInfo * collabInfo)125 int32_t DSchedCollabManager::CheckSrcCollabRelation(const CollabInfo *sourceInfo, const DSchedCollabInfo *collabInfo)
126 {
127     HILOGI("called");
128     if (sourceInfo == nullptr) {
129         HILOGE("Invalid sourceInfo.");
130         return INVALID_PARAMETERS_ERR;
131     }
132     if (collabInfo == nullptr) {
133         HILOGE("collab is nullptr");
134         return INVALID_PARAMETERS_ERR;
135     }
136     if (std::string(sourceInfo->deviceId) == collabInfo->srcUdid_ &&
137         sourceInfo->pid == collabInfo->srcInfo_.pid_ &&
138         static_cast<int32_t>(sourceInfo->tokenId) == collabInfo->srcInfo_.accessToken_ &&
139         sourceInfo->userId == collabInfo->srcAccountInfo_.userId) {
140         HILOGI("the collaboration relationship is matched successfully.");
141         return ERR_OK;
142     }
143     HILOGW("deviceId: %{public}s, pid: %{public}d, tokenId: %{public}d, userId: %{public}d, srcUdid: %{public}s",
144         GetAnonymStr(std::string(sourceInfo->deviceId)).c_str(),
145         sourceInfo->pid, static_cast<int32_t>(sourceInfo->tokenId),
146         sourceInfo->userId, GetAnonymStr(collabInfo->srcUdid_).c_str());
147     return INVALID_PARAMETERS_ERR;
148 }
149 
CheckSinkCollabRelation(const CollabInfo * sinkInfo,const DSchedCollabInfo * collabInfo)150 int32_t DSchedCollabManager::CheckSinkCollabRelation(const CollabInfo *sinkInfo, const DSchedCollabInfo *collabInfo)
151 {
152     HILOGI("called");
153     if (sinkInfo == nullptr) {
154         HILOGE("Invalid sinkInfo.");
155         return INVALID_PARAMETERS_ERR;
156     }
157     if (collabInfo == nullptr) {
158         HILOGE("collab is nullptr");
159         return INVALID_PARAMETERS_ERR;
160     }
161     if (std::string(sinkInfo->deviceId) == collabInfo->sinkUdid_ &&
162         sinkInfo->pid == collabInfo->sinkInfo_.pid_ &&
163         static_cast<int32_t>(sinkInfo->tokenId) == collabInfo->sinkInfo_.accessToken_ &&
164         sinkInfo->userId == collabInfo->sinkUserId_) {
165         HILOGI("the collaboration relationship is matched successfully.");
166         return ERR_OK;
167     }
168     HILOGW("deviceId: %{public}s, pid: %{public}d, tokenId: %{public}d, userId: %{public}d, sinkUdid: %{public}s",
169         GetAnonymStr(std::string(sinkInfo->deviceId)).c_str(),
170         sinkInfo->pid, static_cast<int32_t>(sinkInfo->tokenId),
171         sinkInfo->userId, GetAnonymStr(collabInfo->sinkUdid_).c_str());
172     return INVALID_PARAMETERS_ERR;
173 }
174 
StartEvent()175 void DSchedCollabManager::StartEvent()
176 {
177     HILOGI("called");
178     prctl(PR_SET_NAME, DSCHED_COLLAB_MANAGER.c_str());
179     auto runner = AppExecFwk::EventRunner::Create(false);
180     {
181         std::lock_guard<std::mutex> lock(eventMutex_);
182         eventHandler_ = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner);
183     }
184     eventCon_.notify_one();
185     if (runner == nullptr) {
186         HILOGE("runner is nullptr");
187         return;
188     }
189     runner->Run();
190     HILOGI("StartEvent end");
191 }
192 
UnInit()193 void DSchedCollabManager::UnInit()
194 {
195     HILOGI("UnInit start");
196     DSchedTransportSoftbusAdapter::GetInstance().UnregisterListener(SERVICE_TYPE_COLLAB, softbusListener_);
197     DSchedTransportSoftbusAdapter::GetInstance().ReleaseChannel();
198     collabs_.clear();
199 
200     if (eventHandler_ != nullptr) {
201         eventHandler_->GetEventRunner()->Stop();
202         eventThread_.join();
203         eventHandler_ = nullptr;
204     } else {
205         HILOGE("eventHandler is nullptr");
206     }
207     HILOGI("UnInit end");
208 }
209 
GetSinkCollabVersion(DSchedCollabInfo & info)210 int32_t DSchedCollabManager::GetSinkCollabVersion(DSchedCollabInfo &info)
211 {
212     HILOGI("called, sessionId is: %{public}s", info.ToString().c_str());
213     if (info.srcCollabSessionId_ < 0 || info.sinkInfo_.deviceId_.empty() || info.srcClientCB_ == nullptr) {
214         HILOGE("invalid parameters.");
215         return INVALID_PARAMETERS_ERR;
216     }
217     if (!DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalDeviceId(info.srcInfo_.deviceId_)) {
218         HILOGE("get local deviceId failed!");
219         return FIND_LOCAL_DEVICEID_ERR;
220     }
221     auto func = [this, info]() {
222         HandleGetSinkCollabVersion(info);
223     };
224     if (eventHandler_ == nullptr) {
225         HILOGE("eventHandler is nullptr");
226         return INVALID_PARAMETERS_ERR;
227     }
228     eventHandler_->PostTask(func);
229     return ERR_OK;
230 }
231 
HandleGetSinkCollabVersion(const DSchedCollabInfo & info)232 void DSchedCollabManager::HandleGetSinkCollabVersion(const DSchedCollabInfo &info)
233 {
234     HILOGI("called");
235     const std::string collabToken = info.collabToken_;
236     auto newCollab = std::make_shared<DSchedCollab>(collabToken, info);
237     newCollab->Init();
238     newCollab->UpdateState(SOURCE_GET_PEER_VERSION_STATE);
239     collabs_.insert(std::make_pair(collabToken, newCollab));
240     newCollab->PostSrcGetPeerVersionTask();
241     SetTimeOut(collabToken, COLLAB_TIMEOUT);
242 
243 #ifdef COLLAB_ALL_CONNECT_DECISIONS
244     if (!DSchedTransportSoftbusAdapter::GetInstance().IsNeedAllConnect(SERVICE_TYPE_COLLAB)) {
245         HILOGW("don't need wait all connect decision");
246         return;
247     }
248     const std::string sinkDeviceId = info.sinkInfo_.deviceId_;
249     if (peerConnectDecision_.find(sinkDeviceId) != peerConnectDecision_.end()) {
250         peerConnectDecision_.erase(sinkDeviceId);
251     }
252     WaitAllConnectDecision(sinkDeviceId, newCollab);
253 #endif
254     HILOGI("end");
255 }
256 
CollabMission(DSchedCollabInfo & info)257 int32_t DSchedCollabManager::CollabMission(DSchedCollabInfo &info)
258 {
259     HILOGI("called, collabInfo is: %{public}s", info.ToString().c_str());
260     if (!MultiUserManager::GetInstance().IsCallerForeground(info.srcInfo_.uid_)) {
261         HILOGW("The current user is not foreground. callingUid: %{public}d .", info.srcInfo_.uid_);
262         return DMS_NOT_FOREGROUND_USER;
263     }
264     if (info.srcInfo_.bundleName_.empty() || info.sinkInfo_.bundleName_.empty() ||
265         info.srcInfo_.moduleName_.empty() || info.sinkInfo_.moduleName_.empty() ||
266         info.srcInfo_.abilityName_.empty() || info.sinkInfo_.abilityName_.empty()) {
267         HILOGE("input parameter validation error!");
268         return INVALID_PARAMETERS_ERR;
269     }
270     if (!DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalDeviceId(info.srcInfo_.deviceId_)) {
271         HILOGE("get local deviceId failed!");
272         return FIND_LOCAL_DEVICEID_ERR;
273     }
274     if (DtbschedmgrDeviceInfoStorage::GetInstance().GetDeviceInfoById(info.sinkInfo_.deviceId_) == nullptr &&
275         !DtbschedmgrDeviceInfoStorage::GetInstance().CheckNetworkIdByBundleName(info.sinkInfo_.bundleName_,
276         info.sinkInfo_.deviceId_)) {
277         HILOGE("failed to find sinkDeviceId.");
278         return FIND_REMOTE_DEVICEID_ERR;
279     }
280     auto dCollab = GetDSchedCollabByTokenId(info.collabToken_);
281     if (dCollab == nullptr) {
282         HILOGE("can't find collab");
283         return INVALID_PARAMETERS_ERR;
284     }
285     dCollab->SetSrcCollabInfo(info);
286     dCollab->UpdateState(SOURCE_START_STATE);
287     dCollab->PostSrcStartTask();
288     return ERR_OK;
289 }
290 
IsSessionExists(const DSchedCollabInfo & info)291 bool DSchedCollabManager::IsSessionExists(const DSchedCollabInfo &info)
292 {
293     HILOGI("called");
294     for (const auto& pair : collabs_) {
295         if (pair.second == nullptr) {
296             continue;
297         }
298         DSchedCollabInfo existCollabInfo = pair.second->GetCollabInfo();
299         if (existCollabInfo.srcInfo_.pid_ == info.srcInfo_.pid_ &&
300             existCollabInfo.srcCollabSessionId_ == info.srcCollabSessionId_) {
301             return true;
302         }
303     }
304     return false;
305 }
306 
GenerateCollabToken(const std::string & srcDeviceId)307 std::string DSchedCollabManager::GenerateCollabToken(const std::string &srcDeviceId)
308 {
309     HILOGI("called");
310     std::string characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
311     std::default_random_engine gen;
312     std::random_device rd;
313     gen.seed(rd());
314     std::uniform_int_distribution<> dis(0, characters.size() - 1);
315     std::string randomValue;
316     randomValue.resize(RANDOM_STRING_LENGTH);
317     size_t index = 0;
318     bool isUnique = false;
319     while (!isUnique) {
320         for (int32_t i = 0; i < RANDOM_STRING_LENGTH; ++i) {
321             index = static_cast<size_t>(dis(gen));
322             randomValue[i] = characters[index];
323         }
324         randomValue = srcDeviceId + randomValue;
325         if (collabs_.count(randomValue) == 0) {
326             isUnique = true;
327         }
328     }
329     HILOGI("end");
330     return randomValue;
331 }
332 
SetTimeOut(const std::string & collabToken,int32_t timeout)333 void DSchedCollabManager::SetTimeOut(const std::string &collabToken, int32_t timeout)
334 {
335     HILOGI("called, collabToken: %{public}s", GetAnonymStr(collabToken).c_str());
336     auto func = [this, collabToken]() {
337         if (collabs_.count(collabToken) == 0) {
338             HILOGW("collab not exist.");
339             return;
340         }
341         HILOGE("collab timeout! info: %{public}s", GetAnonymStr(collabToken).c_str());
342         auto dCollab = collabs_[collabToken];
343         if (dCollab != nullptr) {
344             dCollab->PostErrEndTask(COLLAB_ABILITY_TIMEOUT_ERR);
345         }
346     };
347     if (eventHandler_ == nullptr) {
348         HILOGE("eventHandler is nullptr");
349         return;
350     }
351     timeout > 0 ? eventHandler_->PostTask(func, collabToken, timeout) :
352         eventHandler_->PostTask(func);
353 }
354 
RemoveTimeout(const std::string & collabToken)355 void DSchedCollabManager::RemoveTimeout(const std::string &collabToken)
356 {
357     HILOGI("called, collabToken: %{public}s", GetAnonymStr(collabToken).c_str());
358     if (eventHandler_ == nullptr) {
359         HILOGE("eventHandler is nullptr");
360         return;
361     }
362     eventHandler_->RemoveTask(collabToken);
363 }
364 
WaitAllConnectDecision(const std::string & peerDeviceId,const std::shared_ptr<DSchedCollab> & dCollab)365 void DSchedCollabManager::WaitAllConnectDecision(const std::string &peerDeviceId,
366     const std::shared_ptr<DSchedCollab> &dCollab)
367 {
368 #ifdef DMSFWK_ALL_CONNECT_MGR
369     {
370         HILOGI("called");
371         std::unique_lock<std::mutex> decisionLock(connectDecisionMutex_);
372         connectDecisionCond_.wait_for(decisionLock, std::chrono::seconds(CONNECT_DECISION_TIME_OUT),
373             [this, peerDeviceId]() {
374                 return peerConnectDecision_.find(peerDeviceId) != peerConnectDecision_.end() &&
375                     peerConnectDecision_.at(peerDeviceId).load();
376             });
377 
378         if (peerConnectDecision_.find(peerDeviceId) == peerConnectDecision_.end()) {
379             HILOGE("Not find peerDeviceId %{public}s in peerConnectDecision.", GetAnonymStr(peerDeviceId).c_str());
380             if (dCollab != nullptr) {
381                 dCollab->PostErrEndTask(COLLAB_ABILITY_TIMEOUT_ERR);
382             }
383             return;
384         }
385         if (!peerConnectDecision_.at(peerDeviceId).load()) {
386             HILOGE("All connect manager refuse bind to PeerDeviceId %{public}s.", GetAnonymStr(peerDeviceId).c_str());
387             peerConnectDecision_.erase(peerDeviceId);
388             if (dCollab != nullptr) {
389                 dCollab->PostErrEndTask(COLLAB_ABILITY_TIMEOUT_ERR);
390             }
391             return;
392         }
393         peerConnectDecision_.erase(peerDeviceId);
394         HILOGI("end");
395     }
396 #endif
397 }
398 
NotifyAllConnectDecision(std::string peerDeviceId,bool isSupport)399 void DSchedCollabManager::NotifyAllConnectDecision(std::string peerDeviceId, bool isSupport)
400 {
401     HILOGI("Notify all connect decision, peerDeviceId %{public}s, isSupport %{public}d.",
402         GetAnonymStr(peerDeviceId).c_str(), isSupport);
403 #ifdef DMSFWK_ALL_CONNECT_MGR
404     std::lock_guard<std::mutex> decisionLock(connectDecisionMutex_);
405     peerConnectDecision_[peerDeviceId] = isSupport;
406     connectDecisionCond_.notify_all();
407 #endif
408 }
409 
NotifyStartAbilityResult(const std::string & collabToken,const int32_t & result,const int32_t & sinkPid,const int32_t & sinkUid,const int32_t & sinkAccessTokenId)410 int32_t DSchedCollabManager::NotifyStartAbilityResult(const std::string& collabToken, const int32_t &result,
411     const int32_t &sinkPid, const int32_t &sinkUid, const int32_t &sinkAccessTokenId)
412 {
413     HILOGI("called, result %{public}d", result);
414     auto dCollab = GetDSchedCollabByTokenId(collabToken);
415     if (dCollab == nullptr) {
416         HILOGE("can't find collab");
417         return INVALID_PARAMETERS_ERR;
418     }
419     if (result != ACCEPT) {
420         HILOGE("start ability failed");
421         return dCollab->PostErrEndTask(ConvertCollaborateResult(result));
422     }
423     dCollab->SaveSinkAbilityData(collabToken, result, sinkPid, sinkUid, sinkAccessTokenId);
424     HILOGI("end, info: %{public}s.", dCollab->GetCollabInfo().ToString().c_str());
425     return ERR_OK;
426 }
427 
ConvertCollaborateResult(int32_t result)428 int32_t DSchedCollabManager::ConvertCollaborateResult(int32_t result)
429 {
430     HILOGI("collaborate result is %{public}d.", result);
431     switch (result) {
432         case REJECT:
433             return DistributedCollab::PEER_APP_REJECTED;
434         case ON_COLLABORATE_ERR:
435             return DistributedCollab::PEER_ABILITY_NO_ONCOLLABORATE;
436         default:
437             return INVALID_PARAMETERS_ERR;
438     }
439 }
440 
NotifySinkPrepareResult(const std::string & collabToken,const int32_t & result,const int32_t & collabSessionId,const std::string & socketName,const sptr<IRemoteObject> & clientCB)441 int32_t DSchedCollabManager::NotifySinkPrepareResult(const std::string &collabToken, const int32_t &result,
442     const int32_t &collabSessionId, const std::string &socketName, const sptr<IRemoteObject> &clientCB)
443 {
444     HILOGI("called, collabToken: %{public}s, collabSessionId: %{public}d, result: %{public}d, socketName: %{public}s",
445         GetAnonymStr(collabToken).c_str(), collabSessionId, result, socketName.c_str());
446     auto func = [this, collabToken, result, collabSessionId, socketName, clientCB]() {
447         HandleCollabPrepareResult(collabToken, result, collabSessionId, socketName, clientCB);
448     };
449     if (eventHandler_ == nullptr) {
450         HILOGE("eventHandler is nullptr");
451         return INVALID_PARAMETERS_ERR;
452     }
453     eventHandler_->PostTask(func);
454     return ERR_OK;
455 }
456 
HandleCollabPrepareResult(const std::string & collabToken,const int32_t & result,const int32_t & collabSessionId,const std::string & socketName,const sptr<IRemoteObject> & clientCB)457 void DSchedCollabManager::HandleCollabPrepareResult(const std::string &collabToken, const int32_t &result,
458     const int32_t &collabSessionId, const std::string &socketName, const sptr<IRemoteObject> &clientCB)
459 {
460     HILOGI("called");
461     auto dCollab = GetDSchedCollabByTokenId(collabToken);
462     if (dCollab == nullptr) {
463         HILOGE("not find dCollab");
464         return;
465     }
466     dCollab->PostSinkPrepareResultTask(result, collabSessionId, socketName, clientCB);
467     RemoveTimeout(collabToken);
468     HILOGI("end, info: %{public}s.", dCollab->GetCollabInfo().ToString().c_str());
469     return;
470 }
471 
NotifySinkRejectReason(const std::string & collabToken,const std::string & reason)472 int32_t DSchedCollabManager::NotifySinkRejectReason(const std::string& collabToken, const std::string& reason)
473 {
474     HILOGI("called, resion: %{public}s", reason.c_str());
475     auto dCollab = GetDSchedCollabByTokenId(collabToken);
476     if (dCollab == nullptr) {
477         HILOGE("not find dCollab");
478         return INVALID_PARAMETERS_ERR;
479     }
480     return dCollab->PostAbilityRejectTask(reason);
481 }
482 
NotifyAbilityDied(const std::string & bundleName,const int32_t & pid)483 int32_t DSchedCollabManager::NotifyAbilityDied(const std::string &bundleName, const int32_t &pid)
484 {
485     HILOGI("called");
486     auto func = [this, bundleName, pid]() {
487         HandleCloseSessions(bundleName, pid);
488     };
489     if (eventHandler_ == nullptr) {
490         HILOGE("eventHandler is nullptr");
491         return INVALID_PARAMETERS_ERR;
492     }
493     eventHandler_->PostTask(func);
494     return ERR_OK;
495 }
496 
HandleCloseSessions(const std::string & bundleName,const int32_t & pid)497 int32_t DSchedCollabManager::HandleCloseSessions(const std::string &bundleName, const int32_t &pid)
498 {
499     HILOGI("called");
500     DSchedCollabInfo dSchedCollabInfo;
501     for (auto iter = collabs_.begin(); iter != collabs_.end(); iter++) {
502         if (iter->second == nullptr) {
503             continue;
504         }
505         dSchedCollabInfo = iter->second->GetCollabInfo();
506         if ((bundleName == dSchedCollabInfo.srcInfo_.bundleName_ && pid == dSchedCollabInfo.srcInfo_.pid_) ||
507             (bundleName == dSchedCollabInfo.srcInfo_.bundleName_ && pid == dSchedCollabInfo.sinkInfo_.pid_)) {
508             HILOGI("find collab, need be clear, collabInfo: %{public}s", dSchedCollabInfo.ToString().c_str());
509             return iter->second->PostEndTask();
510         }
511     }
512     return ERR_OK;
513 }
514 
ReleaseAbilityLink(const std::string & bundleName,const int32_t & pid)515 int32_t DSchedCollabManager::ReleaseAbilityLink(const std::string &bundleName, const int32_t &pid)
516 {
517     HILOGW("called");
518     DSchedCollabInfo dSchedCollabInfo;
519     std::string collabToken;
520     for (auto iter = collabs_.begin(); iter != collabs_.end(); iter++) {
521         if (iter->second == nullptr) {
522             continue;
523         }
524         dSchedCollabInfo = iter->second->GetCollabInfo();
525         if (bundleName == dSchedCollabInfo.srcInfo_.bundleName_ && pid == dSchedCollabInfo.srcInfo_.pid_) {
526             collabToken = dSchedCollabInfo.collabToken_;
527         }
528         if (bundleName == dSchedCollabInfo.srcInfo_.bundleName_ && pid == dSchedCollabInfo.sinkInfo_.pid_) {
529             collabToken = dSchedCollabInfo.collabToken_;
530         }
531     }
532     auto func = [this, bundleName, pid, collabToken]() {
533         HandleReleaseAbilityLink(bundleName, pid, collabToken);
534     };
535     const std::string taskName = bundleName + std::to_string(pid);
536     HILOGW("disconnect the existing link after 5S");
537     if (eventHandler_ == nullptr) {
538         HILOGE("eventHandler is nullptr");
539         return INVALID_PARAMETERS_ERR;
540     }
541     eventHandler_->PostTask(func, taskName, BACKGROUND_TIMEOUT);
542     return ERR_OK;
543 }
544 
HandleReleaseAbilityLink(const std::string & bundleName,const int32_t & pid,const std::string & collabToken)545 void DSchedCollabManager::HandleReleaseAbilityLink(const std::string &bundleName, const int32_t &pid,
546     const std::string &collabToken)
547 {
548     HILOGI("called");
549     auto dCollab = GetDSchedCollabByTokenId(collabToken);
550     if (dCollab == nullptr) {
551         HILOGE("can't find collab");
552         return;
553     }
554     DSchedCollabInfo dSchedCollabInfo = dCollab->GetCollabInfo();
555     if (pid == dSchedCollabInfo.srcInfo_.pid_) {
556         HILOGI("source ability been background, collabInfo: %{public}s", dSchedCollabInfo.ToString().c_str());
557         PrivilegeShutdown(static_cast<uint64_t>(dSchedCollabInfo.srcInfo_.accessToken_),
558             pid, dSchedCollabInfo.sinkInfo_.deviceId_.c_str());
559             dCollab->PostEndTask();
560     }
561     if (pid == dSchedCollabInfo.sinkInfo_.pid_) {
562         HILOGI("sink ability been background, collabInfo: %{public}s", dSchedCollabInfo.ToString().c_str());
563         dCollab->PostEndTask();
564     }
565     return;
566 }
567 
CancleReleaseAbilityLink(const std::string & bundleName,const int32_t & pid)568 int32_t DSchedCollabManager::CancleReleaseAbilityLink(const std::string &bundleName, const int32_t &pid)
569 {
570     HILOGW("called");
571     if (eventHandler_ == nullptr) {
572         HILOGE("eventHandler is nullptr");
573         return INVALID_PARAMETERS_ERR;
574     }
575     const std::string taskName = bundleName + std::to_string(pid);
576     eventHandler_->RemoveTask(taskName);
577     return ERR_OK;
578 }
579 
NotifyWifiOpen()580 void DSchedCollabManager::NotifyWifiOpen()
581 {
582     HILOGI("called");
583     for (auto iter = collabs_.begin(); iter != collabs_.end(); iter++) {
584         if (iter->second != nullptr) {
585             iter->second->NotifyWifiOpen();
586         }
587     }
588 }
589 
GetWifiStatus()590 bool DSchedCollabManager::GetWifiStatus()
591 {
592     return DistributedSchedule::WifiStateAdapter::GetInstance().IsWifiActive();
593 }
594 
NotifySessionClose(const std::string & collabToken)595 int32_t DSchedCollabManager::NotifySessionClose(const std::string &collabToken)
596 {
597     HILOGI("called, collabToken: %{public}s", GetAnonymStr(collabToken).c_str());
598     auto dCollab = GetDSchedCollabByTokenId(collabToken);
599     if (dCollab == nullptr) {
600         HILOGE("can't find collab");
601         return INVALID_PARAMETERS_ERR;
602     }
603     dCollab->PostEndTask();
604     HILOGI("end.");
605     return ERR_OK;
606 }
607 
CleanUpSession(const std::string & collabToken)608 int32_t DSchedCollabManager::CleanUpSession(const std::string &collabToken)
609 {
610     HILOGI("called, collabToken: %{public}s", GetAnonymStr(collabToken).c_str());
611     auto dCollab = GetDSchedCollabByTokenId(collabToken);
612     if (dCollab == nullptr) {
613         HILOGE("can't find collab");
614         return INVALID_PARAMETERS_ERR;
615     }
616     RemoveTimeout(collabToken);
617     collabs_.erase(collabToken);
618     HILOGI("end.");
619     return ERR_OK;
620 }
621 
GetDSchedCollabByTokenId(const std::string & tokenId)622 std::shared_ptr<DSchedCollab> DSchedCollabManager::GetDSchedCollabByTokenId(const std::string &tokenId)
623 {
624     HILOGI("called, tokenId: %{public}s", tokenId.c_str());
625     if (tokenId.empty() || collabs_.count(tokenId) == 0) {
626         HILOGE("no such collaboration in progress.");
627         return nullptr;
628     }
629     return collabs_[tokenId];
630 }
631 
OnDataRecv(int32_t softbusSessionId,std::shared_ptr<DSchedDataBuffer> dataBuffer)632 void DSchedCollabManager::OnDataRecv(int32_t softbusSessionId, std::shared_ptr<DSchedDataBuffer> dataBuffer)
633 {
634     auto func = [this, softbusSessionId, dataBuffer]() {
635         HandleDataRecv(softbusSessionId, dataBuffer);
636     };
637     if (eventHandler_ == nullptr) {
638         HILOGE("eventHandler is nullptr");
639         return;
640     }
641     eventHandler_->PostTask(func);
642 }
643 
HandleDataRecv(const int32_t & softbusSessionId,std::shared_ptr<DSchedDataBuffer> dataBuffer)644 void DSchedCollabManager::HandleDataRecv(const int32_t &softbusSessionId, std::shared_ptr<DSchedDataBuffer> dataBuffer)
645 {
646     HILOGI("called, softbusSessionId: %{public}d.", softbusSessionId);
647     if (dataBuffer == nullptr) {
648         HILOGE("dataBuffer is null.");
649         return;
650     }
651     uint8_t *data = dataBuffer->Data();
652     std::string jsonStr(reinterpret_cast<const char *>(data), dataBuffer->Capacity());
653     cJSON *rootValue = cJSON_Parse(jsonStr.c_str());
654     if (rootValue == nullptr) {
655         HILOGE("Parse jsonStr error.");
656         return;
657     }
658     cJSON *baseCmd = cJSON_GetObjectItemCaseSensitive(rootValue, "BaseCmd");
659     if (baseCmd == nullptr || !cJSON_IsString(baseCmd) || (baseCmd->valuestring == nullptr)) {
660         cJSON_Delete(rootValue);
661         HILOGE("Parse base cmd error.");
662         return;
663     }
664 
665     cJSON *cmdValue = cJSON_Parse(baseCmd->valuestring);
666     cJSON_Delete(rootValue);
667     if (cmdValue == nullptr) {
668         HILOGE("Parse cmd value error.");
669         return;
670     }
671 
672     cJSON *comvalue = cJSON_GetObjectItemCaseSensitive(cmdValue, "Command");
673     if (comvalue == nullptr || !cJSON_IsNumber(comvalue)) {
674         cJSON_Delete(cmdValue);
675         HILOGE("parse command failed");
676         return;
677     }
678     int32_t command = comvalue->valueint;
679     cJSON *collabTokenvalue = cJSON_GetObjectItemCaseSensitive(cmdValue, "CollabToken");
680     if (collabTokenvalue == nullptr || !cJSON_IsString(collabTokenvalue)) {
681         cJSON_Delete(cmdValue);
682         HILOGE("parse collabToken failed");
683         return;
684     }
685     const std::string collabToken = collabTokenvalue->valuestring;
686     cJSON_Delete(cmdValue);
687     NotifyDataRecv(softbusSessionId, command, jsonStr, dataBuffer, collabToken);
688     HILOGI("end");
689 }
690 
NotifyDataRecv(const int32_t & softbusSessionId,int32_t command,const std::string & jsonStr,std::shared_ptr<DSchedDataBuffer> dataBuffer,const std::string & collabToken)691 void DSchedCollabManager::NotifyDataRecv(const int32_t &softbusSessionId, int32_t command, const std::string& jsonStr,
692     std::shared_ptr<DSchedDataBuffer> dataBuffer, const std::string& collabToken)
693 {
694     HILOGI("called, parsed cmd %{public}s", CMDDATA[command].c_str());
695     for (auto iter = collabs_.begin(); iter != collabs_.end(); iter++) {
696         if (iter->second != nullptr && softbusSessionId == iter->second->GetSoftbusSessionId() &&
697             collabToken == iter->second->GetCollabInfo().collabToken_) {
698             HILOGI("softbusSessionId exist.");
699             const std::string peerDeviceId =
700                 DSchedTransportSoftbusAdapter::GetInstance().GetPeerDeviceIdBySocket(softbusSessionId);
701             iter->second->OnDataRecv(peerDeviceId, command, dataBuffer);
702             if (command == NOTIFY_RESULT_CMD) {
703                 RemoveTimeout(iter->first);
704             }
705             return;
706         }
707     }
708     if (command == SINK_GET_VERSION_CMD) {
709         auto getVersionCmd = std::make_shared<GetSinkCollabVersionCmd>();
710         int32_t ret = getVersionCmd->Unmarshal(jsonStr);
711         if (ret != ERR_OK) {
712             HILOGE("Unmarshal cmd failed, ret: %{public}d", ret);
713             return;
714         }
715         std::string localDevId;
716         if (!DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalDeviceId(localDevId)) {
717             HILOGE("get local deviceId failed!");
718             return;
719         }
720         if (getVersionCmd->sinkDeviceId_ != localDevId) {
721             HILOGE("Irrecognized deviceId! sinkDeviceId: %{public}s", getVersionCmd->sinkDeviceId_.c_str());
722             return;
723         }
724         auto newCollab = std::make_shared<DSchedCollab>(getVersionCmd, softbusSessionId);
725         newCollab->Init();
726         newCollab->UpdateState(SINK_GET_VERSION_STATE);
727         collabs_.insert(std::make_pair(getVersionCmd->collabToken_, newCollab));
728         newCollab->PostSinkGetVersionTask();
729         SetTimeOut(getVersionCmd->collabToken_, COLLAB_TIMEOUT);
730         HILOGI("end");
731         return;
732     }
733 }
734 
OnShutdown(int32_t socket,bool isSelfCalled)735 void DSchedCollabManager::OnShutdown(int32_t socket, bool isSelfCalled)
736 {
737     HILOGW("called,softbusSessionId: %{public}d, isSelfCalled: %{public}d", socket, isSelfCalled);
738     if (isSelfCalled) {
739         HILOGW("called, shutdown by local");
740         return;
741     }
742     auto func = [this, socket]() {
743         std::lock_guard<std::mutex> collabLock(collabMutex_);
744         if (collabs_.empty()) {
745             return;
746         }
747         for (auto iter = collabs_.begin(); iter != collabs_.end(); iter++) {
748             if (iter->second != nullptr && socket == iter->second->GetSoftbusSessionId()) {
749                 HILOGE("collab: %{public}s", iter->second->GetCollabInfo().ToString().c_str());
750                 iter->second->PostErrEndTask(COLLAB_SESSION_SHUTDOWN);
751             }
752         }
753     };
754     if (eventHandler_ == nullptr) {
755         HILOGE("eventHandler is nullptr");
756         return;
757     }
758     eventHandler_->PostTask(func);
759     return;
760 }
761 
OnBind(int32_t socket,PeerSocketInfo info)762 void DSchedCollabManager::SoftbusListener::OnBind(int32_t socket, PeerSocketInfo info)
763 {
764 }
765 
OnShutdown(int32_t socket,bool isSelfCalled)766 void DSchedCollabManager::SoftbusListener::OnShutdown(int32_t socket, bool isSelfCalled)
767 {
768     DSchedCollabManager::GetInstance().OnShutdown(socket, isSelfCalled);
769 }
770 
OnDataRecv(int32_t socket,std::shared_ptr<DSchedDataBuffer> dataBuffer)771 void DSchedCollabManager::SoftbusListener::OnDataRecv(int32_t socket, std::shared_ptr<DSchedDataBuffer> dataBuffer)
772 {
773     DSchedCollabManager::GetInstance().OnDataRecv(socket, dataBuffer);
774 }
775 }  // namespace DistributedSchedule
776 }  // namespace OHOS
777