1/*
2 * Copyright (c) 2024 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_CONTINUE_H
17#define OHOS_DSCHED_CONTINUE_H
18
19#include <condition_variable>
20#include <mutex>
21#include <thread>
22#include <string>
23
24#include "ability_manager_client.h"
25#include "distributedWant/distributed_want.h"
26#include "distributedWant/distributed_want_params.h"
27#include "distributed_sched_interface.h"
28#include "distributed_sched_utils.h"
29#include "dsched_data_buffer.h"
30#include "dsched_continue_event.h"
31#include "dsched_continue_event_handler.h"
32#include "dsched_continue_state_machine.h"
33#include "mission/distributed_bm_storage.h"
34#include "event_handler.h"
35
36namespace OHOS {
37namespace DistributedSchedule {
38
39using AccountInfo = IDistributedSched::AccountInfo;
40
41class DSchedContinueInfo {
42public:
43    DSchedContinueInfo() = default;
44    DSchedContinueInfo(const std::string& sourceDeviceId, const std::string& sourceBundleName,
45        const std::string& sinkDeviceId, const std::string& sinkBundleName, const std::string& continueType)
46        : sourceDeviceId_(sourceDeviceId), sourceBundleName_(sourceBundleName), sinkDeviceId_(sinkDeviceId),
47        sinkBundleName_(sinkBundleName), continueType_(continueType) {}
48
49    DSchedContinueInfo(const std::string& sourceDeviceId, const std::string& sinkDeviceId, int32_t missionId)
50        : sourceDeviceId_(sourceDeviceId), sinkDeviceId_(sinkDeviceId), missionId_(missionId) {}
51    ~DSchedContinueInfo() = default;
52
53    bool operator == (const DSchedContinueInfo &index) const
54    {
55        std::string compareInfo = this->sourceDeviceId_ + this->sourceBundleName_ + this->sinkDeviceId_ +
56            this->sinkBundleName_;
57        std::string otherCompareInfo = index.sourceDeviceId_ + index.sourceBundleName_ + index.sinkDeviceId_ +
58            index.sinkBundleName_;
59        return compareInfo.compare(otherCompareInfo) == 0;
60    }
61
62    bool operator < (const DSchedContinueInfo &index) const
63    {
64        std::string compareInfo = this->sourceDeviceId_ + this->sourceBundleName_ + this->sinkDeviceId_ +
65            this->sinkBundleName_;
66        std::string otherCompareInfo = index.sourceDeviceId_ + index.sourceBundleName_ + index.sinkDeviceId_ +
67            index.sinkBundleName_;
68        return compareInfo < otherCompareInfo;
69    }
70
71    std::string ToStringIgnoreMissionId() const
72    {
73        return "SrcDevId: " + GetAnonymStr(this->sourceDeviceId_) + " " +
74            "SrcBundle: " + this->sourceBundleName_ + " " +
75            "DstDevId: "+ GetAnonymStr(this->sinkDeviceId_) + " " +
76            "DstBundle: " + this->sinkBundleName_ + " " +
77            "ContiType: " + this->continueType_;
78    }
79
80    std::string toString() const
81    {
82        return "SrcDevId: " + GetAnonymStr(this->sourceDeviceId_) + " " +
83            "SrcBundle: " + this->sourceBundleName_ + " " +
84            "DstDevId: "+ GetAnonymStr(this->sinkDeviceId_) + " " +
85            "DstBundle: " + this->sinkBundleName_ + " " +
86            "ContiType: " + this->continueType_ + " " +
87            "MissionId: " + std::to_string(this->missionId_);
88    }
89
90    std::string sourceDeviceId_;
91    std::string sourceBundleName_;
92    std::string sinkDeviceId_;
93    std::string sinkBundleName_;
94    std::string continueType_;
95    std::string sinkAbilityName_;
96    int32_t missionId_ = 0;
97};
98
99typedef enum {
100    CONTINUE_SOURCE = 0,
101    CONTINUE_SINK = 1
102} DSchedContinueDirection;
103
104typedef enum {
105    CONTINUE_PULL = 0,
106    CONTINUE_PUSH = 1
107} DSchedContinueSubType;
108
109struct ContinueAbilityData {
110    OHOS::AAFwk::Want want;
111    int32_t callerUid;
112    uint32_t accessToken;
113};
114
115struct ContinueEventData {
116    std::string moduleName;
117    std::string abilityName;
118};
119
120class DSchedContinue : public std::enable_shared_from_this<DSchedContinue> {
121    friend class DSchedContinueManager;
122    friend class DSchedContinueEventHandler;
123    friend class DSchedContinueSourceStartState;
124    friend class DSchedContinueAbilityState;
125    friend class DSchedContinueWaitEndState;
126    friend class DSchedContinueEndState;
127    friend class DSchedContinueSinkStartState;
128    friend class DSchedContinueDataState;
129    friend class DSchedContinueSinkWaitEndState;
130    friend class DSchedContinueSinkEndState;
131
132public:
133    DSchedContinue(int32_t subServiceType, int32_t direction,  const sptr<IRemoteObject>& callback,
134        const DSchedContinueInfo& continueInfo);
135    DSchedContinue(std::shared_ptr<DSchedContinueStartCmd> startCmd, int32_t sessionId);
136    ~DSchedContinue();
137
138private:
139    int32_t Init();
140    void StartEventHandler();
141    void ProcessEvent(const AppExecFwk::InnerEvent::Pointer& event);
142
143    int32_t PostStartTask(const OHOS::AAFwk::WantParams& wantParams);
144    int32_t PostReplyTask(std::shared_ptr<DSchedContinueReplyCmd> cmd);
145    int32_t PostCotinueAbilityTask(int32_t appVersion);
146    int32_t PostContinueSendTask(const OHOS::AAFwk::Want& want, int32_t callerUid, int32_t status,
147        uint32_t accessToken);
148    int32_t PostContinueDataTask(std::shared_ptr<DSchedContinueDataCmd> cmd);
149    int32_t PostNotifyCompleteTask(int32_t result);
150    int32_t PostContinueEndTask(int32_t result);
151
152    int32_t ExecuteContinueReq(std::shared_ptr<DistributedWantParams> wantParams);
153    int32_t ExecuteContinueAbility(int32_t appVersion);
154    int32_t ExecuteContinueReply();
155    int32_t ExecuteContinueSend(std::shared_ptr<ContinueAbilityData> data);
156    int32_t ExecuteContinueData(std::shared_ptr<DSchedContinueDataCmd> cmd);
157    int32_t ExecuteNotifyComplete(int32_t result);
158    int32_t ExecuteContinueEnd(int32_t result);
159    int32_t ExecuteContinueError(int32_t result);
160
161    int32_t OnContinueMission(const OHOS::AAFwk::WantParams& wantParams);
162    int32_t OnStartCmd(int32_t appVersion);
163    int32_t OnReplyCmd(std::shared_ptr<DSchedContinueReplyCmd> cmd);
164    int32_t OnStartContinuation(const OHOS::AAFwk::Want& want, int32_t callerUid, int32_t status,
165        uint32_t accessToken);
166    int32_t OnContinueDataCmd(std::shared_ptr<DSchedContinueDataCmd> cmd);
167    int32_t OnNotifyComplete(int32_t missionId, bool isSuccess);
168    int32_t OnContinueEndCmd(std::shared_ptr<DSchedContinueEndCmd> cmd);
169    int32_t OnContinueEnd(int32_t result);
170
171    void OnDataRecv(int32_t command, std::shared_ptr<DSchedDataBuffer> dataBuffer);
172    void OnShutDown();
173    void OnBind();
174
175    int32_t GetSessionId();
176    DSchedContinueInfo GetContinueInfo();
177
178    int32_t PackStartCmd(std::shared_ptr<DSchedContinueStartCmd>& cmd,
179        std::shared_ptr<DistributedWantParams> wantParams);
180    int32_t PackDataCmd(std::shared_ptr<DSchedContinueDataCmd>& cmd, const OHOS::AAFwk::Want& want,
181        const AppExecFwk::AbilityInfo& abilityInfo, const CallerInfo& callerInfo,
182        const AccountInfo& accountInfo);
183    int32_t CheckStartPermission(std::shared_ptr<DSchedContinueDataCmd> cmd);
184    int32_t PackEndCmd(std::shared_ptr<DSchedContinueEndCmd> cmd, int32_t result);
185    int32_t PackReplyCmd(std::shared_ptr<DSchedContinueReplyCmd> cmd, int32_t replyCmd, int32_t appVersion,
186        int32_t result, const std::string reason);
187    int32_t SendCommand(std::shared_ptr<DSchedContinueCmdBase> cmd);
188
189    int32_t SetWantForContinuation(AAFwk::Want& newWant);
190    void SetCleanMissionFlag(const OHOS::AAFwk::Want& want);
191    int32_t ConvertToDmsSdkErr(int32_t result);
192    void NotifyContinuationCallbackResult(int32_t result);
193    bool GetLocalDeviceId(std::string& localDeviceId);
194    bool CheckDeviceIdFromRemote(const std::string& localDevId, const std::string& destDevId,
195        const std::string& srcDevId);
196    int32_t GetMissionIdByBundleName();
197    int32_t CheckContinueAbilityPermission();
198    void DurationDumperStart();
199    void DurationDumperBeforeStartRemoteAbility();
200    void DurationDumperBeforeStartAbility(std::shared_ptr<DSchedContinueDataCmd> cmd);
201    void DurationDumperComplete(int32_t result);
202    void NotifyDSchedEventResult(int32_t result);
203    bool WaitAbilityStateInitial(int32_t persistentId);
204    int32_t StartAbility(const OHOS::AAFwk::Want& want, int32_t requestCode);
205    std::string QuerySinkAbilityName();
206    int32_t QuickStartAbility();
207    int32_t UpdateWantForContinueType(OHOS::AAFwk::Want& want);
208    bool CheckQuickStartConfiguration();
209    std::string GetAbilityNameByContinueType();
210    void SetEventData();
211    void UpdateState(DSchedContinueStateType stateType);
212
213private:
214    static constexpr int32_t INVALID_SESSION_ID = -1;
215    static constexpr int32_t ERROR_BASE_DSOFTBUS_WIFI = -200000;
216    static constexpr int32_t ERROR_PEER_THREE_VAP_CONFLICT = ERROR_BASE_DSOFTBUS_WIFI - 6604;
217    static const std::map<int32_t, int32_t> DMS_CONVERT_TO_SDK_ERR_MAP;
218
219    std::shared_ptr<DSchedContinueStateMachine> stateMachine_;
220    std::shared_ptr<DSchedContinueEventHandler> eventHandler_;
221    std::condition_variable eventCon_;
222    std::thread eventThread_;
223    std::mutex eventMutex_;
224
225    int32_t version_ = 0;
226    int32_t subServiceType_ = 0;
227    int32_t continueByType_ = 0;
228    int32_t direction_ = 0;
229    DSchedContinueInfo continueInfo_;
230    bool isSourceExit_ = true;
231    int32_t softbusSessionId_ = INVALID_SESSION_ID;
232    sptr<IRemoteObject> callback_ = nullptr;
233    EventNotify eventData_;
234};
235}  // namespace DistributedSchedule
236}  // namespace OHOS
237#endif  // OHOS_DSCHED_CONTINUE_H