1 /*
2  * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 "screen_capture_session.h"
17 #include "common/common.h"
18 #include "common/common_macro.h"
19 #include "common/reflect_registration.h"
20 #include "common/sharing_log.h"
21 #include "extend/magic_enum/magic_enum.hpp"
22 #include "screen_capture_def.h"
23 
24 namespace OHOS {
25 namespace Sharing {
ScreenCaptureSession()26 ScreenCaptureSession::ScreenCaptureSession()
27 {
28     SHARING_LOGD("id: %{public}u.", GetId());
29 }
30 
~ScreenCaptureSession()31 ScreenCaptureSession::~ScreenCaptureSession()
32 {
33     SHARING_LOGD("id: %{public}u.", GetId());
34 }
35 
HandleEvent(SharingEvent &event)36 int32_t ScreenCaptureSession::HandleEvent(SharingEvent &event)
37 {
38     SHARING_LOGD("trace.");
39     RETURN_INVALID_IF_NULL(event.eventMsg);
40 
41     SHARING_LOGI("eventType: %{public}s, capture sessionId: %{public}u.",
42                  std::string(magic_enum::enum_name(event.eventMsg->type)).c_str(), GetId());
43     switch (event.eventMsg->type) {
44         case EventType::EVENT_WFD_NOTIFY_RTSP_PLAYED:
45             HandleRtspPlay(event);
46             SHARING_LOGI("get event EVENT_WFD_NOTIFY_RTSP_PLAYED");
47             break;
48         case EventType::EVENT_SESSION_INIT:
49             HandleSessionInit(event);
50             break;
51         case EventType::EVENT_AGENT_STATE_PROSUMER_INIT:
52             HandleProsumerInitState(event);
53             break;
54         default:
55             SHARING_LOGI("none process case.");
56             break;
57     }
58 
59     return 0;
60 }
61 
HandleRtspPlay(SharingEvent &event)62 void ScreenCaptureSession::HandleRtspPlay(SharingEvent &event)
63 {
64     SHARING_LOGD("trace.");
65     auto inputMsg = ConvertEventMsg<ScreenCaptureSessionEventMsg>(event);
66     auto statusMsg = std::make_shared<SessionStatusMsg>();
67     auto eventMsg = std::make_shared<ScreenCaptureConsumerEventMsg>();
68     eventMsg->type = EventType::EVENT_WFD_NOTIFY_RTSP_PLAYED;
69     eventMsg->toMgr = ModuleType::MODULE_MEDIACHANNEL;
70     eventMsg->screenId = screenId_;
71     switch (captureType_) {
72         case MEDIA_TYPE_AV:
73             Common::SetVideoTrack(eventMsg->videoTrack, videoFormat_);
74             Common::SetAudioTrack(eventMsg->audioTrack, inputMsg->codecId, inputMsg->audioFormat);
75             break;
76         case MEDIA_TYPE_VIDEO:
77             Common::SetVideoTrack(eventMsg->videoTrack, videoFormat_);
78             break;
79         case MEDIA_TYPE_AUDIO:
80             Common::SetAudioTrack(eventMsg->audioTrack, inputMsg->codecId, inputMsg->audioFormat);
81             break;
82         default:
83             SHARING_LOGI("none process case.");
84             break;
85     }
86     SHARING_LOGI("after SetVideoTrack, vtype:%{public}d, vFormat:%{public}d, vcodecId:%{public}d.", captureType_,
87                  videoFormat_, eventMsg->videoTrack.codecId);
88     statusMsg->msg = std::move(eventMsg);
89     statusMsg->status = NOTIFY_SESSION_PRIVATE_EVENT;
90 
91     NotifyAgentSessionStatus(statusMsg);
92 }
93 
HandleSessionInit(SharingEvent &event)94 void ScreenCaptureSession::HandleSessionInit(SharingEvent &event)
95 {
96     SHARING_LOGD("trace.");
97     RETURN_IF_NULL(event.eventMsg);
98 
99     auto inputMsg = ConvertEventMsg<ScreenCaptureSessionEventMsg>(event);
100     if (inputMsg) {
101         captureType_ = inputMsg->mediaType;
102         videoFormat_ = inputMsg->videoFormat;
103         audioFormat_ = inputMsg->audioFormat;
104         screenId_ = inputMsg->screenId;
105         SHARING_LOGI("videoFormat_: %{public}d, type: %{public}d, screenId: %{public}" SCNu64
106                      ", audioFormat_: %{public}d.",
107                      videoFormat_, captureType_, screenId_, audioFormat_);
108     } else {
109         SHARING_LOGE("unknow event msg.");
110     }
111 }
112 
HandleProsumerInitState(SharingEvent &event)113 void ScreenCaptureSession::HandleProsumerInitState(SharingEvent &event)
114 {
115     SHARING_LOGD("trace.");
116     RETURN_IF_NULL(event.eventMsg);
117 
118     auto inputMsg = ConvertEventMsg<ScreenCaptureSessionEventMsg>(event);
119     auto statusMsg = std::make_shared<SessionStatusMsg>();
120     statusMsg->msg = std::make_shared<EventMsg>();
121     statusMsg->status = STATE_SESSION_ERROR;
122     statusMsg->msg->errorCode = ERR_SESSION_START;
123 
124     if (inputMsg) {
125         statusMsg->msg->requestId = inputMsg->requestId;
126 
127         if (inputMsg->errorCode == ERR_OK) {
128             statusMsg->status = STATE_SESSION_STARTED;
129             statusMsg->msg->errorCode = ERR_OK;
130         } else {
131             SHARING_LOGE("consumer inited failed, id: %{public}u.", inputMsg->prosumerId);
132         }
133     } else {
134         SHARING_LOGE("consumer inited failed: unknow msg.");
135         return;
136     }
137 
138     NotifyAgentSessionStatus(statusMsg);
139 }
140 
UpdateOperation(SessionStatusMsg::Ptr &statusMsg)141 void ScreenCaptureSession::UpdateOperation(SessionStatusMsg::Ptr &statusMsg)
142 {
143     SHARING_LOGD("trace.");
144     RETURN_IF_NULL(statusMsg);
145     RETURN_IF_NULL(statusMsg->msg);
146 
147     status_ = static_cast<SessionRunningStatus>(statusMsg->status);
148     SHARING_LOGI("status: %{public}s.", std::string(magic_enum::enum_name(status_)).c_str());
149     switch (status_) {
150         case SESSION_START:
151             statusMsg->status = NOTIFY_PROSUMER_CREATE;
152             break;
153         case SESSION_STOP:
154             statusMsg->status = STATE_SESSION_STOPED;
155             break;
156         case SESSION_PAUSE:
157             statusMsg->status = STATE_SESSION_PAUSED;
158             break;
159         case SESSION_RESUME:
160             statusMsg->status = STATE_SESSION_RESUMED;
161             break;
162         case SESSION_DESTROY:
163             statusMsg->status = STATE_SESSION_DESTROYED;
164             break;
165         default:
166             SHARING_LOGI("none process case.");
167             break;
168     }
169 
170     NotifyAgentSessionStatus(statusMsg);
171 }
172 
NotifyProsumerInit(SessionStatusMsg::Ptr &statusMsg)173 void ScreenCaptureSession::NotifyProsumerInit(SessionStatusMsg::Ptr &statusMsg)
174 {
175     SHARING_LOGD("trace.");
176     auto eventMsg = std::make_shared<ScreenCaptureConsumerEventMsg>();
177     eventMsg->type = EventType::EVENT_SCREEN_CAPTURE_INIT;
178     eventMsg->toMgr = ModuleType::MODULE_MEDIACHANNEL;
179     eventMsg->screenId = screenId_;
180     switch (captureType_) {
181         case MEDIA_TYPE_AV:
182             Common::SetVideoTrack(eventMsg->videoTrack, videoFormat_);
183             Common::SetAudioTrack(eventMsg->audioTrack, audioFormat_);
184             break;
185         case MEDIA_TYPE_VIDEO:
186             Common::SetVideoTrack(eventMsg->videoTrack, videoFormat_);
187             break;
188         case MEDIA_TYPE_AUDIO:
189             Common::SetAudioTrack(eventMsg->audioTrack, audioFormat_);
190             break;
191         default:
192             SHARING_LOGI("none process case.");
193             break;
194     }
195     SHARING_LOGI("afer SetVideoTrack, vtype:%{public}d, vFormat:%{public}d, vcodecId:%{public}d.", captureType_,
196                  videoFormat_, eventMsg->videoTrack.codecId);
197     statusMsg->msg = std::move(eventMsg);
198     statusMsg->status = NOTIFY_SESSION_PRIVATE_EVENT;
199 
200     NotifyAgentSessionStatus(statusMsg);
201 }
202 
UpdateMediaStatus(SessionStatusMsg::Ptr &statusMsg)203 void ScreenCaptureSession::UpdateMediaStatus(SessionStatusMsg::Ptr &statusMsg)
204 {
205     SHARING_LOGD("trace.");
206     RETURN_IF_NULL(statusMsg);
207     RETURN_IF_NULL(statusMsg->msg);
208 
209     SHARING_LOGI("update media notify status: %{public}s.",
210                  std::string(magic_enum::enum_name(static_cast<MediaNotifyStatus>(statusMsg->status))).c_str());
211     switch (statusMsg->status) {
212         case STATE_PROSUMER_CREATE_SUCCESS:
213             NotifyProsumerInit(statusMsg);
214             break;
215         case STATE_PROSUMER_START_SUCCESS:
216             break;
217         case STATE_PROSUMER_STOP_SUCCESS:
218             break;
219         case STATE_PROSUMER_DESTROY_SUCCESS:
220             break;
221         default:
222             SHARING_LOGI("none process case.");
223             break;
224     }
225 }
226 
NotifyAgentSessionStatus(SessionStatusMsg::Ptr &statusMsg)227 void ScreenCaptureSession::NotifyAgentSessionStatus(SessionStatusMsg::Ptr &statusMsg)
228 {
229     SHARING_LOGD("trace.");
230     RETURN_IF_NULL(statusMsg);
231 
232     if (statusMsg->status == NOTIFY_PROSUMER_CREATE) {
233         statusMsg->className = "ScreenCaptureConsumer";
234     }
235 
236     Notify(statusMsg);
237 }
238 
239 REGISTER_CLASS_REFLECTOR(ScreenCaptureSession);
240 } // namespace Sharing
241 } // namespace OHOS
242