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