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 #ifndef OHOS_DSCHED_COLLAB_H 17 #define OHOS_DSCHED_COLLAB_H 18 19 #include <condition_variable> 20 #include <mutex> 21 #include <thread> 22 #include <string> 23 24 #include "ability_manager_client.h" 25 #include "ability_state_observer.h" 26 #include "distributed_sched_service.h" 27 #include "dsched_collab_event.h" 28 #include "dsched_collab_event_handler.h" 29 #include "dsched_collab_state_machine.h" 30 #include "dsched_data_buffer.h" 31 #include "distributed_sched_utils.h" 32 #include "event_handler.h" 33 #include "want.h" 34 35 namespace OHOS { 36 namespace DistributedSchedule { 37 38 using AccountInfo = IDistributedSched::AccountInfo; 39 40 struct CollabMessage : public Parcelable { 41 int32_t pid_ = -1; 42 int32_t uid_ = -1; 43 int32_t accessToken_ = -1; 44 std::string deviceId_; 45 std::string bundleName_; 46 std::string abilityName_; 47 std::string moduleName_; 48 std::string serverId_; 49 std::string socketName_; 50 ReadFromParcelCollabMessage51 bool ReadFromParcel(Parcel &parcel) 52 { 53 deviceId_ = Str16ToStr8(parcel.ReadString16()); 54 bundleName_ = Str16ToStr8(parcel.ReadString16()); 55 moduleName_ = Str16ToStr8(parcel.ReadString16()); 56 abilityName_ = Str16ToStr8(parcel.ReadString16()); 57 serverId_ = Str16ToStr8(parcel.ReadString16()); 58 return true; 59 } 60 MarshallingCollabMessage61 virtual bool Marshalling(Parcel &parcel) const override 62 { 63 return true; 64 } 65 UnmarshallingCollabMessage66 static CollabMessage *Unmarshalling(Parcel &parcel) 67 { 68 CollabMessage *collabInfo = new (std::nothrow) CollabMessage(); 69 if (collabInfo && !collabInfo->ReadFromParcel(parcel)) { 70 delete collabInfo; 71 collabInfo = nullptr; 72 } 73 return collabInfo; 74 } 75 }; 76 77 struct ConnectOpt : public Parcelable { 78 bool needSendBigData_ = false; 79 bool needSendStream_ = false; 80 bool needRecvStream_ = false; 81 AAFwk::WantParams startParams_; 82 AAFwk::WantParams messageParams_; 83 ReadFromParcelConnectOpt84 bool ReadFromParcel(Parcel &parcel) 85 { 86 needSendBigData_ = parcel.ReadBool(); 87 needSendStream_ = parcel.ReadBool(); 88 needRecvStream_ = parcel.ReadBool(); 89 std::shared_ptr<AAFwk::WantParams> startParamsPtr(parcel.ReadParcelable<AAFwk::WantParams>()); 90 if (startParamsPtr == nullptr) { 91 return false; 92 } 93 startParams_ = *startParamsPtr; 94 95 std::shared_ptr<AAFwk::WantParams> wantParamsPtr(parcel.ReadParcelable<AAFwk::WantParams>()); 96 if (wantParamsPtr == nullptr) { 97 return false; 98 } 99 messageParams_ = *wantParamsPtr; 100 return true; 101 } 102 MarshallingConnectOpt103 virtual bool Marshalling(Parcel &parcel) const override 104 { 105 return true; 106 } 107 UnmarshallingConnectOpt108 static ConnectOpt *Unmarshalling(Parcel &parcel) 109 { 110 ConnectOpt *connectOpt = new (std::nothrow) ConnectOpt(); 111 if (connectOpt && !connectOpt->ReadFromParcel(parcel)) { 112 delete connectOpt; 113 connectOpt = nullptr; 114 } 115 return connectOpt; 116 } 117 }; 118 119 typedef enum { 120 COLLAB_SOURCE = 0, 121 COLLAB_SINK = 1 122 } DSchedCollabDirection; 123 124 class DSchedCollabInfo { 125 public: 126 DSchedCollabInfo() = default; DSchedCollabInfo(const int32_t & collabSessionId,const CollabMessage & localInfo,const CollabMessage & peerInfo,const ConnectOpt & opt,const sptr<IRemoteObject> & clientCB)127 DSchedCollabInfo(const int32_t &collabSessionId, const CollabMessage &localInfo, const CollabMessage &peerInfo, 128 const ConnectOpt &opt, const sptr<IRemoteObject> &clientCB) 129 : srcCollabSessionId_(collabSessionId), srcInfo_(localInfo), sinkInfo_(peerInfo), 130 srcOpt_(opt), srcClientCB_(clientCB) {} 131 ~DSchedCollabInfo() = default; 132 ToString()133 std::string ToString() const 134 { 135 return "srcCollabVersion: " + std::to_string(this->srcCollabVersion_) + " " + 136 "srcAppVersion: " + std::to_string(this->srcAppVersion_) + " " + 137 "srcCollabSessionId: " + std::to_string(this->srcCollabSessionId_) + " " + 138 "collabToken: " + GetAnonymStr(this->collabToken_) + " " + 139 "needSendBigData: " + std::to_string(this->srcOpt_.needSendBigData_) + " " + 140 "needSendStream: " + std::to_string(this->srcOpt_.needSendStream_) + " " + 141 "needRecvStream: " + std::to_string(this->srcOpt_.needRecvStream_) + " " + 142 "srcDevId: " + GetAnonymStr(this->srcInfo_.deviceId_) + " " + 143 "srcBundle: " + this->srcInfo_.bundleName_ + " " + 144 "srcAbility: " + this->srcInfo_.abilityName_ + " " + 145 "srcModuleName: "+ this->srcInfo_.moduleName_ + " " + 146 "srcServerId: "+ this->srcInfo_.serverId_ + " " + 147 "srcPid: "+ std::to_string(this->srcInfo_.pid_) + " " + 148 "srcUid: "+ std::to_string(this->srcInfo_.uid_) + " " + 149 "srcAccessToken: "+ GetAnonymStr(std::to_string(this->srcInfo_.accessToken_)) + " " + 150 "srcUserId: " + std::to_string(this->srcAccountInfo_.userId) + " " + 151 "srcActiveAccountId: " + GetAnonymStr(this->srcAccountInfo_.activeAccountId) + " " + 152 "srcSocketName: "+ this->srcInfo_.socketName_ + " " + 153 "sinkCollabSessionId: " + std::to_string(this->sinkCollabSessionId_) + " " + 154 "sinkDevId: "+ GetAnonymStr(this->sinkInfo_.deviceId_) + " " + 155 "sinkBundle: " + this->sinkInfo_.bundleName_ + " " + 156 "sinkAbility: " + this->sinkInfo_.abilityName_ + " " + 157 "sinkModuleName: " + this->sinkInfo_.moduleName_ + " " + 158 "sinkServerId: " + this->sinkInfo_.serverId_ + " " + 159 "sinkPid: " + std::to_string(this->sinkInfo_.pid_) + " " + 160 "sinkUid: " + std::to_string(this->sinkInfo_.uid_) + " " + 161 "sinkAccessToken: " + GetAnonymStr(std::to_string(this->sinkInfo_.accessToken_)) + " " + 162 "sinkUserId: " + std::to_string(this->sinkUserId_) + " " + 163 "sinkSocketName: " + this->sinkInfo_.socketName_ + " "; 164 } 165 166 int32_t srcCollabSessionId_ = -1; 167 int32_t sinkCollabSessionId_ = -1; 168 int32_t sinkUserId_ = -1; 169 int32_t srcCollabVersion_ = 0; 170 int32_t sinkCollabVersion_ = 0; 171 int32_t srcAppVersion_ = 0; 172 int32_t direction_ = COLLAB_SOURCE; 173 std::string collabToken_; 174 std::string srcUdid_; 175 std::string sinkUdid_; 176 int32_t sinkAccountId_; 177 CallerInfo callerInfo_; 178 AccountInfo srcAccountInfo_; 179 CollabMessage srcInfo_; 180 CollabMessage sinkInfo_; 181 ConnectOpt srcOpt_; 182 sptr<IRemoteObject> srcClientCB_ = nullptr; 183 sptr<IRemoteObject> sinkClientCB_ = nullptr; 184 }; 185 186 class DSchedCollab : public std::enable_shared_from_this<DSchedCollab> { 187 friend class DSchedCollabManager; 188 friend class DSchedCollabEventHandler; 189 friend class CollabSrcGetPeerVersionState; 190 friend class CollabSrcStartState; 191 friend class CollabSrcWaitResultState; 192 friend class CollabSrcWaitEndState; 193 friend class CollabSinkGetVersionState; 194 friend class CollabSinkStartState; 195 friend class CollabSinkConnectState; 196 friend class CollabSinkWaitEndState; 197 friend class CollabSinkEndState; 198 199 public: 200 DSchedCollab(const std::string &collabToken, const DSchedCollabInfo &info); 201 DSchedCollab(std::shared_ptr<GetSinkCollabVersionCmd> startCmd, const int32_t &softbusSessionId); 202 ~DSchedCollab(); 203 204 private: 205 int32_t Init(); 206 void StartEventHandler(); 207 void ProcessEvent(const AppExecFwk::InnerEvent::Pointer& event); 208 209 void SetSrcCollabInfo(DSchedCollabInfo &info); 210 void SetSinkCollabInfo(std::shared_ptr<SinkStartCmd> startCmd); 211 int32_t PostSrcGetPeerVersionTask(); 212 int32_t PostSrcGetVersionTask(); 213 int32_t PostSinkGetVersionTask(); 214 int32_t PostSrcStartTask(); 215 int32_t PostSinkStartTask(const std::string &peerDeviceId); 216 int32_t PostSinkPrepareResultTask(const int32_t &result, const int32_t &collabSessionId, 217 const std::string &socketName, const sptr<IRemoteObject> &clientCB); 218 int32_t PostSrcResultTask(std::shared_ptr<NotifyResultCmd> replyCmd); 219 int32_t PostErrEndTask(const int32_t &result); 220 int32_t PostAbilityRejectTask(const std::string &reason); 221 int32_t PostEndTask(); 222 223 int32_t ExeSrcGetPeerVersion(); 224 int32_t ExeSrcGetVersion(); 225 int32_t ExeSrcStart(); 226 int32_t ExeStartAbility(const std::string &peerDeviceId); 227 int32_t ExeAbilityRejectError(const std::string &reason); 228 int32_t ExeSinkPrepareResult(const int32_t &result); 229 int32_t ExeSrcCollabResult(const int32_t &result, const std::string reason = ""); 230 int32_t ExeSrcGetPeerVersionError(const int32_t &result); 231 int32_t NotifyWifiOpen(); 232 int32_t ExeSrcStartError(const int32_t &result); 233 int32_t ExeSrcWaitResultError(const int32_t &result); 234 int32_t ExeSinkStartError(const int32_t &result); 235 int32_t ExeSinkConnectError(const int32_t &result); 236 int32_t ExeSinkError(const int32_t &result); 237 int32_t ExeSinkGetVersion(); 238 int32_t ExeSinkGetVersionError(const int32_t &result); 239 int32_t ExeDisconnect(); 240 int32_t SrcPeerVersionNotify(); 241 int32_t ExeSrcClientNotify(const int32_t &result, const std::string reason = ""); 242 int32_t ExeClientDisconnectNotify(); 243 244 int32_t PackGetPeerVersionCmd(std::shared_ptr<GetSinkCollabVersionCmd>& cmd); 245 int32_t PackSinkCollabVersionCmd(std::shared_ptr<GetSinkCollabVersionCmd>& cmd); 246 int32_t PackStartCmd(std::shared_ptr<SinkStartCmd>& cmd); 247 int32_t PackPartCmd(std::shared_ptr<SinkStartCmd>& cmd); 248 int32_t PackNotifyResultCmd(std::shared_ptr<NotifyResultCmd> cmd, const int32_t &result, 249 const std::string &abilityRejectReason = ""); 250 int32_t PackDisconnectCmd(std::shared_ptr<DisconnectCmd> cmd); 251 int32_t SendCommand(std::shared_ptr<BaseCmd> cmd); 252 253 int32_t GetSoftbusSessionId(); 254 DSchedCollabInfo GetCollabInfo(); 255 AAFwk::Want GenerateCollabWant(); 256 bool IsStartForeground(); 257 int32_t SaveSinkAbilityData(const std::string& collabToken, const int32_t &result, 258 const int32_t &sinkPid, const int32_t &sinkUid, const int32_t &sinkAccessTokenId); 259 int32_t CleanUpSession(); 260 void UpdateState(CollabStateType stateType); 261 262 sptr<AppExecFwk::IAppMgr> GetAppManager(); 263 bool RegisterAbilityLifecycleObserver(const std::string &bundleName); 264 void UnregisterAbilityLifecycleObserver(); 265 266 void OnDataRecv(const std::string &peerDeviceId, int32_t command, std::shared_ptr<DSchedDataBuffer> dataBuffer); 267 void OnShutDown(); 268 void OnBind(); 269 void SetScreenLockParameters(AAFwk::WantParams& wantParams); 270 271 private: 272 static constexpr int32_t INVALID_SESSION_ID = -1; 273 static constexpr int32_t ERROR_BASE_DSOFTBUS_WIFI = -200000; 274 static constexpr int32_t ERROR_PEER_THREE_VAP_CONFLICT = ERROR_BASE_DSOFTBUS_WIFI - 6604; 275 static const std::map<int32_t, int32_t> DMS_CONVERT_TO_SDK_ERR_MAP; 276 277 std::shared_ptr<DSchedCollabStateMachine> stateMachine_; 278 std::shared_ptr<DSchedCollabEventHandler> eventHandler_; 279 std::condition_variable eventCon_; 280 std::thread eventThread_; 281 std::mutex eventMutex_; 282 283 DSchedCollabInfo collabInfo_; 284 int32_t softbusSessionId_ = INVALID_SESSION_ID; 285 sptr<AbilityLifecycleObserver> appStateObserver_ = nullptr; 286 }; 287 } // namespace DistributedSchedule 288 } // namespace OHOS 289 #endif // OHOS_DSCHED_COLLAB_H 290