• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "agent/agent.h"
17 #include "agent.h"
18 #include "common/common_macro.h"
19 #include "common/event_channel.h"
20 #include "common/reflect_registration.h"
21 #include "common/sharing_log.h"
22 #include "magic_enum.hpp"
23 
24 namespace OHOS {
25 namespace Sharing {
26 
Agent(AgentType agentType)27 Agent::Agent(AgentType agentType) : agentType_(agentType)
28 {
29     SHARING_LOGD("trace.");
30 }
31 
CreateSession(const std::string & className)32 SharingErrorCode Agent::CreateSession(const std::string &className)
33 {
34     SHARING_LOGD("trace.");
35     session_ = std::static_pointer_cast<BaseSession>(ReflectRegistration::GetInstance().CreateObject(className));
36     if (session_) {
37         session_->SetSessionListener(shared_from_this());
38         SHARING_LOGI("create session classname: %{public}s, agentId: %{public}u, sessionId: %{public}u.",
39                      className.c_str(), GetId(), session_->GetId());
40         SetRunningStatus(AGENT_STEP_CREATE, AGENT_STATUS_DONE);
41         return SharingErrorCode::ERR_OK;
42     }
43 
44     SetRunningStatus(AGENT_STEP_CREATE, AGENT_STATUS_ERROR);
45     return SharingErrorCode::ERR_SESSION_CREATE;
46 }
47 
HandleEvent(SharingEvent & event)48 int32_t Agent::HandleEvent(SharingEvent &event)
49 {
50     SHARING_LOGD("trace.");
51     RETURN_INVALID_IF_NULL(event.eventMsg);
52     SHARING_LOGI("contextId: %{public}u, agentId: %{public}u, mediaChannelId: %{public}u, "
53                  "fromMgr: %{public}u, srcId: %{public}u channel event: %{public}s.",
54                  event.eventMsg->dstId, GetId(), mediaChannelId_, event.eventMsg->fromMgr, event.eventMsg->srcId,
55                  std::string(magic_enum::enum_name(event.eventMsg->type)).c_str());
56 
57     if (EventType::EVENT_AGENT_PROSUMER_ERROR == event.eventMsg->type) {
58         std::lock_guard<std::mutex> lock(runStepMutex_);
59         SetRunningStatus(runStep_, AGENT_STATUS_ERROR);
60     }
61 
62     bool isCached = false;
63     SharingErrorCode retCode = CheckRunStep(event, isCached);
64     if (((retCode != ERR_OK) || isCached) && runningStatus_ != AGENT_STATUS_INTERRUPT) {
65         SHARING_LOGW("check run step return, agentId: %{public}u.", GetId());
66         return retCode;
67     }
68 
69     auto statusMsg = std::make_shared<SessionStatusMsg>();
70     RETURN_INVALID_IF_NULL(statusMsg);
71     statusMsg->msg = std::make_shared<EventMsg>();
72     RETURN_INVALID_IF_NULL(statusMsg->msg);
73     statusMsg->msg->type = event.eventMsg->type;
74     statusMsg->msg->requestId = event.eventMsg->requestId;
75     statusMsg->msg->errorCode = event.eventMsg->errorCode;
76 
77     if (runningStatus_ == AGENT_STATUS_INTERRUPT) {
78         if (session_) {
79             SHARING_LOGW("agentId: %{public}u, interrupt.", GetId());
80             statusMsg->status = SESSION_INTERRUPT;
81             session_->UpdateOperation(statusMsg);
82         }
83         return retCode;
84     }
85 
86     auto inputMsg = ConvertEventMsg<AgentEventMsg>(event);
87     if (inputMsg == nullptr) {
88         SHARING_LOGE("unknow msg.");
89         return -1;
90     }
91 
92     switch (event.eventMsg->type) {
93         case EventType::EVENT_AGENT_START:
94             statusMsg->status = SESSION_START;
95             UpdateSessionStatus(statusMsg);
96             break;
97         case EventType::EVENT_AGENT_DESTROY:
98             statusMsg->status = SESSION_STOP;
99             UpdateSessionStatus(statusMsg);
100             break;
101         case EventType::EVENT_AGENT_PAUSE:
102             statusMsg->status = SESSION_PAUSE;
103             statusMsg->mediaType = inputMsg->mediaType;
104             UpdateSessionStatus(statusMsg);
105             break;
106         case EventType::EVENT_AGENT_RESUME:
107             statusMsg->status = SESSION_RESUME;
108             statusMsg->mediaType = inputMsg->mediaType;
109             UpdateSessionStatus(statusMsg);
110             break;
111         case EventType::EVENT_AGENT_STATE_PROSUMER_CREATE: {
112             prosumerId_ = inputMsg->prosumerId;
113             statusMsg->prosumerId = prosumerId_;
114             HandleProsumerState(statusMsg);
115             break;
116         }
117         case EventType::EVENT_AGENT_STATE_PROSUMER_START:  // fall-through
118         case EventType::EVENT_AGENT_STATE_PROSUMER_PAUSE:  // fall-through
119         case EventType::EVENT_AGENT_STATE_PROSUMER_RESUME: // fall-through
120         case EventType::EVENT_AGENT_STATE_PROSUMER_STOP:   // fall-through
121         case EventType::EVENT_AGENT_STATE_PROSUMER_DESTROY:
122             statusMsg->prosumerId = inputMsg->prosumerId;
123             HandleProsumerState(statusMsg);
124             break;
125         case EventType::EVENT_AGENT_PROSUMER_ERROR:
126             statusMsg->prosumerId = inputMsg->prosumerId;
127             HandleProsumerError(statusMsg);
128             break;
129         case EventType::EVENT_AGENT_PLAY_START:
130             SendChannelEvent(statusMsg, EVENT_MEDIA_PLAY_START);
131             break;
132         case EventType::EVENT_AGENT_PLAY_STOP:
133             SendChannelEvent(statusMsg, EVENT_MEDIA_PLAY_STOP);
134             break;
135         case EventType::EVENT_AGENT_STATE_PLAY_START:
136             if (statusMsg->msg->errorCode == ERR_OK) {
137                 PushNextStep(statusMsg);
138             } else {
139                 std::lock_guard<std::mutex> lock(runStepMutex_);
140                 SetRunningStatus(runStep_, AGENT_STATUS_ERROR);
141             }
142             break;
143         case EventType::EVENT_AGENT_STATE_PLAY_STOP:
144             if (statusMsg->msg->errorCode == ERR_OK) {
145                 PushNextStep(statusMsg);
146             } else {
147                 std::lock_guard<std::mutex> lock(runStepMutex_);
148                 SetRunningStatus(runStep_, AGENT_STATUS_ERROR);
149             }
150             break;
151         case EventType::EVENT_AGENT_CHANNEL_APPENDSURFACE:
152             statusMsg->surface = inputMsg->surface;
153             statusMsg->sceneType = inputMsg->sceneType;
154             SendChannelAppendSurfaceEvent(statusMsg, EVENT_MEDIA_CHANNEL_APPENDSURFACE);
155             break;
156         case EventType::EVENT_AGENT_CHANNEL_REMOVESURFACE:
157             statusMsg->surfaceId = inputMsg->surfaceId;
158             SendChannelRemoveSurfaceEvent(statusMsg, EVENT_MEDIA_CHANNEL_REMOVESURFACE);
159             break;
160         case EventType::EVENT_AGENT_STATE_CHANNEL_APPENDSURFACE:
161             if (statusMsg->msg->errorCode == ERR_OK) {
162                 PushNextStep(statusMsg);
163             } else {
164                 std::lock_guard<std::mutex> lock(runStepMutex_);
165                 SetRunningStatus(runStep_, AGENT_STATUS_ERROR);
166             }
167             break;
168         case EventType::EVENT_AGENT_STATE_CHANNEL_REMOVESURFACE:
169             PushNextStep(statusMsg);
170             statusMsg->surfaceId = inputMsg->surfaceId;
171             SendInteractionEvent(statusMsg, EVENT_INTERACTION_STATE_REMOVE_SURFACE);
172             break;
173         case EventType::EVENT_AGENT_CHANNEL_SETSCENETYPE:
174             statusMsg->surfaceId = inputMsg->surfaceId;
175             statusMsg->sceneType = inputMsg->sceneType;
176             SendChannelSceneTypeEvent(statusMsg, EVENT_MEDIA_CHANNEL_SETSCENETYPE);
177             break;
178         case EventType::EVENT_AGENT_CHANNEL_SETVOLUME:
179             statusMsg->volume = inputMsg->volume;
180             SendChannelSetVolumeEvent(statusMsg, EVENT_MEDIA_CHANNEL_SETVOLUME);
181             break;
182         case EventType::EVENT_AGENT_CHANNEL_SETKEYREDIRECT:
183             statusMsg->surfaceId = inputMsg->surfaceId;
184             statusMsg->keyRedirect = inputMsg->keyRedirect;
185             SendChannelKeyRedirectEvent(statusMsg, EVENT_MEDIA_CHANNEL_KEY_REDIRECT);
186             break;
187         case EventType::EVENT_AGEINT_ACCELERATION_DONE:
188             statusMsg->surfaceId = inputMsg->surfaceId;
189             SendInteractionEvent(statusMsg, EVENT_INTERACTION_ACCELERATION_DONE);
190             break;
191         case EventType::EVENT_AGENT_DECODER_DIED:
192             statusMsg->surfaceId = inputMsg->surfaceId;
193             SendInteractionEvent(statusMsg, EVENT_INTERACTION_DECODER_DIED);
194             break;
195         default: {
196             if (session_) {
197                 session_->HandleEvent(event);
198             }
199         }
200     }
201 
202     return 0;
203 }
204 
HandleProsumerError(SessionStatusMsg::Ptr & statusMsg)205 void Agent::HandleProsumerError(SessionStatusMsg::Ptr &statusMsg)
206 {
207     SHARING_LOGD("trace.");
208     RETURN_IF_NULL(statusMsg);
209     RETURN_IF_NULL(statusMsg->msg);
210     SHARING_LOGI("agentId: %{public}u, handle prosumerId: %{public}u, errorCode: %{public}d.", GetId(),
211                  statusMsg->prosumerId, statusMsg->msg->errorCode);
212     SendInteractionEvent(statusMsg, EVENT_INTERACTION_MSG_ERROR);
213     switch (statusMsg->msg->errorCode) {
214         case ERR_PROSUMER_INIT:          // fall-through
215         case ERR_PROSUMER_CREATE:        // fall-through
216         case ERR_PROSUMER_START:         // fall-through
217         case ERR_PROSUMER_VIDEO_CAPTURE: // fall-through
218         case ERR_PROSUMER_TIMEOUT:
219             statusMsg->status = SESSION_STOP;
220             UpdateSessionStatus(statusMsg);
221             break;
222         case ERR_PROSUMER_STOP:
223             statusMsg->status = SESSION_DESTROY;
224             UpdateSessionStatus(statusMsg);
225             break;
226         case ERR_PROSUMER_DESTROY: {
227             if (agentType_ == SINK_AGENT) {
228                 SendChannelEvent(statusMsg, EVENT_MEDIA_CHANNEL_DESTROY);
229             } else if (agentType_ == SRC_AGENT) {
230                 SendContextEvent(statusMsg, EVENT_CONTEXT_STATE_AGENT_DESTROY);
231             }
232             break;
233         }
234         default:
235             SHARING_LOGI("none process case.");
236             break;
237     }
238 }
239 
HandleProsumerState(SessionStatusMsg::Ptr & statusMsg)240 void Agent::HandleProsumerState(SessionStatusMsg::Ptr &statusMsg)
241 {
242     SHARING_LOGD("trace.");
243     RETURN_IF_NULL(statusMsg);
244     RETURN_IF_NULL(statusMsg->msg);
245     SHARING_LOGI("agentId: %{public}u, handle prosumerId: %{public}u, eventType: %{public}s.", GetId(),
246                  statusMsg->prosumerId,
247                  std::string(magic_enum::enum_name(static_cast<EventType>(statusMsg->msg->type))).c_str());
248     if (session_ == nullptr) {
249         SHARING_LOGE("session_ is null, agentId: %{public}u.", GetId());
250         return;
251     }
252 
253     MediaNotifyStatus mediaStatus = STATE_PROSUMER_NONE;
254     switch (statusMsg->msg->type) {
255         case EVENT_AGENT_STATE_PROSUMER_CREATE:
256             mediaStatus = STATE_PROSUMER_CREATE_SUCCESS;
257             break;
258         case EVENT_AGENT_STATE_PROSUMER_START:
259             mediaStatus = STATE_PROSUMER_START_SUCCESS;
260             break;
261         case EVENT_AGENT_STATE_PROSUMER_STOP:
262             mediaStatus = STATE_PROSUMER_STOP_SUCCESS;
263             break;
264         case EVENT_AGENT_STATE_PROSUMER_PAUSE:
265             mediaStatus = STATE_PROSUMER_PAUSE_SUCCESS;
266             break;
267         case EVENT_AGENT_STATE_PROSUMER_RESUME:
268             mediaStatus = STATE_PROSUMER_RESUME_SUCCESS;
269             break;
270         case EVENT_AGENT_STATE_PROSUMER_DESTROY:
271             mediaStatus = STATE_PROSUMER_DESTROY_SUCCESS;
272             break;
273         default:
274             SHARING_LOGI("none process case.");
275             break;
276     }
277 
278     statusMsg->status = mediaStatus;
279     session_->UpdateMediaStatus(statusMsg);
280     PushNextStep(statusMsg);
281 }
282 
PushNextStep(SessionStatusMsg::Ptr & statusMsg)283 void Agent::PushNextStep(SessionStatusMsg::Ptr &statusMsg)
284 {
285     SHARING_LOGD("trace.");
286     RETURN_IF_NULL(statusMsg);
287     RETURN_IF_NULL(statusMsg->msg);
288     switch (statusMsg->msg->type) {
289         case EVENT_AGENT_STATE_PROSUMER_START:
290             PopNextStep(AGENT_STEP_START, AGENT_STATUS_DONE);
291             break;
292         case EVENT_AGENT_STATE_PROSUMER_STOP:
293             statusMsg->status = SESSION_DESTROY;
294             UpdateSessionStatus(statusMsg);
295             break;
296         case EVENT_AGENT_STATE_PROSUMER_DESTROY: {
297             PopNextStep(AGENT_STEP_DESTROY, AGENT_STATUS_DONE);
298             if (agentType_ == SINK_AGENT) {
299                 SendChannelEvent(statusMsg, EVENT_MEDIA_CHANNEL_DESTROY);
300             } else if (agentType_ == SRC_AGENT) {
301                 SendContextEvent(statusMsg, EVENT_CONTEXT_STATE_AGENT_DESTROY);
302             }
303             break;
304         }
305         case EVENT_AGENT_STATE_PLAY_START:
306             PopNextStep(AGENT_STEP_PLAY, AGENT_STATUS_DONE);
307             break;
308         case EVENT_AGENT_STATE_PLAY_STOP:
309             PopNextStep(AGENT_STEP_PLAYSTOP, AGENT_STATUS_DONE);
310             break;
311         case EVENT_AGENT_STATE_CHANNEL_APPENDSURFACE:
312             PopNextStep(AGENT_STEP_APPENDSURFACE, AGENT_STATUS_DONE);
313             break;
314         case EVENT_AGENT_STATE_CHANNEL_REMOVESURFACE:
315             PopNextStep(AGENT_STEP_REMOVESURFACE, AGENT_STATUS_DONE);
316             break;
317         default:
318             SHARING_LOGI("none process case.");
319             break;
320     }
321 }
322 
OnSessionNotify(SessionStatusMsg::Ptr & statusMsg)323 void Agent::OnSessionNotify(SessionStatusMsg::Ptr &statusMsg)
324 {
325     SHARING_LOGD("trace.");
326     RETURN_IF_NULL(statusMsg);
327     SHARING_LOGI("agentId: %{public}u OnSessionNotify status: %{public}s.", GetId(),
328                  std::string(magic_enum::enum_name(static_cast<SessionNotifyStatus>(statusMsg->status))).c_str());
329     statusMsg->prosumerId = prosumerId_;
330     switch (statusMsg->status) {
331         case SessionNotifyStatus::NOTIFY_SESSION_PRIVATE_EVENT:
332             NotifyPrivateEvent(statusMsg);
333             break;
334         case SessionNotifyStatus::STATE_SESSION_ERROR:
335             HandleSessionError(statusMsg);
336             break;
337         default:
338             SHARING_LOGI("none process case.");
339             break;
340     }
341 }
342 
HandleSessionError(SessionStatusMsg::Ptr & statusMsg)343 void Agent::HandleSessionError(SessionStatusMsg::Ptr &statusMsg)
344 {
345     SHARING_LOGD("trace.");
346     RETURN_IF_NULL(statusMsg);
347     RETURN_IF_NULL(statusMsg->msg);
348     SHARING_LOGI("agentId: %{public}u, error: %{public}d.", GetId(), statusMsg->msg->errorCode);
349     SendInteractionEvent(statusMsg, EVENT_INTERACTION_MSG_ERROR);
350     switch (statusMsg->msg->errorCode) {
351         case ERR_SESSION_START:                // fall-through
352         case ERR_CONNECTION_FAILURE:           // fall-through
353         case ERR_INVALID_URL:                  // fall-through
354         case ERR_DECODE_FORMAT:                // fall-through
355         case ERR_UNAUTHORIZED:                 // fall-through
356         case ERR_INTERACTION_FAILURE:          // fall-through
357         case ERR_PROTOCOL_INTERACTION_TIMEOUT: // fall-through
358         case ERR_NETWORK_ERROR:                // fall-through
359         case ERR_INTAKE_TIMEOUT:
360             PopNextStep(runStep_, AGENT_STATUS_ERROR);
361             break;
362         default:
363             SHARING_LOGI("none process case.");
364             break;
365     }
366 }
367 
UpdateSessionStatus(SessionStatusMsg::Ptr & statusMsg)368 void Agent::UpdateSessionStatus(SessionStatusMsg::Ptr &statusMsg)
369 {
370     SHARING_LOGI("handle session: %{public}s agentId: %{public}u.",
371                  std::string(magic_enum::enum_name(static_cast<SessionRunningStatus>(statusMsg->status))).c_str(),
372                  GetId());
373     if (session_) {
374         session_->UpdateOperation(statusMsg);
375     }
376 }
377 
NotifyPrivateEvent(SessionStatusMsg::Ptr & statusMsg)378 uint32_t Agent::NotifyPrivateEvent(SessionStatusMsg::Ptr &statusMsg)
379 {
380     SHARING_LOGD("trace.");
381     RETURN_INVALID_IF_NULL(statusMsg);
382     RETURN_INVALID_IF_NULL(statusMsg->msg);
383 
384     SHARING_LOGI("agentId: %{public}u, send session event, type: %{public}s.", GetId(),
385                  std::string(magic_enum::enum_name(statusMsg->msg->type)).c_str());
386     auto toMgr = statusMsg->msg->toMgr;
387     if (toMgr != ModuleType::MODULE_MEDIACHANNEL && toMgr != ModuleType::MODULE_INTERACTION) {
388         SHARING_LOGE("agentId: %{public}u, toMgr: %{public}d, eventType: %{public}s, error!", GetId(), toMgr,
389                      std::string(magic_enum::enum_name(statusMsg->msg->type)).c_str());
390         return ERR_GENERAL_ERROR;
391     }
392 
393     if (toMgr == ModuleType::MODULE_MEDIACHANNEL) {
394         SHARING_LOGI("agentId: %{public}u, send session event to mediachannel mediaChannelId: %{public}u.", GetId(),
395                      mediaChannelId_);
396         statusMsg->msg->dstId = mediaChannelId_;
397         auto channelMsg = std::static_pointer_cast<ChannelEventMsg>(statusMsg->msg);
398         channelMsg->prosumerId = prosumerId_;
399         channelMsg->agentId = GetId();
400         channelMsg->errorCode = statusMsg->msg->errorCode;
401         channelMsg->requestId = statusMsg->msg->requestId;
402     } else if (toMgr == ModuleType::MODULE_INTERACTION) {
403         SHARING_LOGI("agentId: %{public}u, send session event to interaction.", GetId());
404     }
405 
406     auto listener = agentListener_.lock();
407     if (listener) {
408         auto agentMsg = std::static_pointer_cast<AgentStatusMsg>(statusMsg);
409         agentMsg->agentId = GetId();
410         listener->OnAgentNotify(agentMsg);
411     }
412 
413     return ERR_OK;
414 }
415 
SetRunningStatus(AgentRunStep step,AgentRunningStatus status)416 void Agent::SetRunningStatus(AgentRunStep step, AgentRunningStatus status)
417 {
418     SHARING_LOGD("agentId: %{public}u, set agent running step: %{public}s, status: %{public}s.", GetId(),
419                  std::string(magic_enum::enum_name(step)).c_str(), std::string(magic_enum::enum_name(status)).c_str());
420     runStep_ = step;
421     runningStatus_ = status;
422 }
423 
SendInteractionEvent(SessionStatusMsg::Ptr & statusMsg,EventType eventType)424 void Agent::SendInteractionEvent(SessionStatusMsg::Ptr &statusMsg, EventType eventType)
425 {
426     SHARING_LOGD("trace.");
427     RETURN_IF_NULL(statusMsg);
428     RETURN_IF_NULL(statusMsg->msg);
429     auto listener = agentListener_.lock();
430     if (listener) {
431         SHARING_LOGI("agentId: %{public}u, notify interaction: %{public}s.", GetId(),
432                      std::string(magic_enum::enum_name(statusMsg->msg->type)).c_str());
433         auto interactionMsg = std::make_shared<InteractionEventMsg>();
434         RETURN_IF_NULL(interactionMsg);
435         interactionMsg->agentId = GetId();
436         interactionMsg->agentType = GetAgentType();
437         interactionMsg->toMgr = ModuleType::MODULE_INTERACTION;
438         interactionMsg->type = eventType;
439         interactionMsg->errorCode = statusMsg->msg->errorCode;
440         interactionMsg->requestId = statusMsg->msg->requestId;
441         interactionMsg->surfaceId = statusMsg->surfaceId;
442 
443         auto agentMsg = std::make_shared<AgentStatusMsg>();
444         RETURN_IF_NULL(agentMsg);
445         agentMsg->agentId = GetId();
446         agentMsg->msg = std::move(interactionMsg);
447         listener->OnAgentNotify(agentMsg);
448     }
449 }
450 
SendChannelEvent(SessionStatusMsg::Ptr & statusMsg,EventType eventType)451 void Agent::SendChannelEvent(SessionStatusMsg::Ptr &statusMsg, EventType eventType)
452 {
453     SHARING_LOGD("trace.");
454     RETURN_IF_NULL(statusMsg);
455     RETURN_IF_NULL(statusMsg->msg);
456     auto listener = agentListener_.lock();
457     if (listener) {
458         SHARING_LOGI("agentId: %{public}u, notify to channelmgr, eventType: %{public}s.", GetId(),
459                      std::string(magic_enum::enum_name(statusMsg->msg->type)).c_str());
460 
461         auto channelMsg = std::make_shared<ChannelEventMsg>();
462         RETURN_IF_NULL(channelMsg);
463         channelMsg->agentId = GetId();
464         channelMsg->toMgr = ModuleType::MODULE_MEDIACHANNEL;
465         channelMsg->dstId = mediaChannelId_;
466         channelMsg->prosumerId = prosumerId_;
467         channelMsg->type = eventType;
468         channelMsg->errorCode = statusMsg->msg->errorCode;
469         channelMsg->requestId = statusMsg->msg->requestId;
470 
471         AgentStatusMsg::Ptr agentMsg = std::make_shared<AgentStatusMsg>();
472         RETURN_IF_NULL(agentMsg);
473         agentMsg->msg = std::move(channelMsg);
474         agentMsg->agentId = GetId();
475         listener->OnAgentNotify(agentMsg);
476     }
477 }
478 
SendChannelAppendSurfaceEvent(SessionStatusMsg::Ptr & statusMsg,EventType eventType)479 void Agent::SendChannelAppendSurfaceEvent(SessionStatusMsg::Ptr &statusMsg, EventType eventType)
480 {
481     SHARING_LOGD("trace.");
482     RETURN_IF_NULL(statusMsg);
483     RETURN_IF_NULL(statusMsg->msg);
484     auto listener = agentListener_.lock();
485     if (listener) {
486         SHARING_LOGI("agentId: %{public}u, notify to channelmgr, eventType: %{public}s.", GetId(),
487                      std::string(magic_enum::enum_name(statusMsg->msg->type)).c_str());
488 
489         auto channelMsg = std::make_shared<ChannelAppendSurfaceEventMsg>();
490         RETURN_IF_NULL(channelMsg);
491         channelMsg->agentId = GetId();
492         channelMsg->toMgr = ModuleType::MODULE_MEDIACHANNEL;
493         channelMsg->dstId = mediaChannelId_;
494         channelMsg->prosumerId = prosumerId_;
495         channelMsg->type = eventType;
496         channelMsg->surface = statusMsg->surface;
497         channelMsg->sceneType = statusMsg->sceneType;
498         channelMsg->errorCode = statusMsg->msg->errorCode;
499         channelMsg->requestId = statusMsg->msg->requestId;
500 
501         AgentStatusMsg::Ptr agentMsg = std::make_shared<AgentStatusMsg>();
502         RETURN_IF_NULL(agentMsg);
503         agentMsg->msg = std::move(channelMsg);
504         agentMsg->agentId = GetId();
505         listener->OnAgentNotify(agentMsg);
506     }
507 }
508 
SendChannelRemoveSurfaceEvent(SessionStatusMsg::Ptr & statusMsg,EventType eventType)509 void Agent::SendChannelRemoveSurfaceEvent(SessionStatusMsg::Ptr &statusMsg, EventType eventType)
510 {
511     SHARING_LOGD("trace.");
512     RETURN_IF_NULL(statusMsg);
513     RETURN_IF_NULL(statusMsg->msg);
514     auto listener = agentListener_.lock();
515     if (listener) {
516         SHARING_LOGI("agentId: %{public}u, notify to channelmgr, eventType: %{public}s.", GetId(),
517                      std::string(magic_enum::enum_name(statusMsg->msg->type)).c_str());
518 
519         auto channelMsg = std::make_shared<ChannelRemoveSurfaceEventMsg>();
520         RETURN_IF_NULL(channelMsg);
521         channelMsg->agentId = GetId();
522         channelMsg->toMgr = ModuleType::MODULE_MEDIACHANNEL;
523         channelMsg->dstId = mediaChannelId_;
524         channelMsg->prosumerId = prosumerId_;
525         channelMsg->type = eventType;
526         channelMsg->surfaceId = statusMsg->surfaceId;
527         channelMsg->errorCode = statusMsg->msg->errorCode;
528         channelMsg->requestId = statusMsg->msg->requestId;
529 
530         AgentStatusMsg::Ptr agentMsg = std::make_shared<AgentStatusMsg>();
531         RETURN_IF_NULL(agentMsg);
532         agentMsg->msg = std::move(channelMsg);
533         agentMsg->agentId = GetId();
534         listener->OnAgentNotify(agentMsg);
535     }
536 }
537 
SendChannelSceneTypeEvent(SessionStatusMsg::Ptr & statusMsg,EventType eventType)538 void Agent::SendChannelSceneTypeEvent(SessionStatusMsg::Ptr &statusMsg, EventType eventType)
539 {
540     SHARING_LOGD("trace.");
541     RETURN_IF_NULL(statusMsg);
542     RETURN_IF_NULL(statusMsg->msg);
543     auto listener = agentListener_.lock();
544     if (listener) {
545         SHARING_LOGI("agentId: %{public}u, notify to channelmgr, eventType: %{public}s.", GetId(),
546                      std::string(magic_enum::enum_name(statusMsg->msg->type)).c_str());
547 
548         auto channelMsg = std::make_shared<ChannelSetSceneTypeEventMsg>();
549         RETURN_IF_NULL(channelMsg);
550         channelMsg->agentId = GetId();
551         channelMsg->toMgr = ModuleType::MODULE_MEDIACHANNEL;
552         channelMsg->dstId = mediaChannelId_;
553         channelMsg->prosumerId = prosumerId_;
554         channelMsg->type = eventType;
555         channelMsg->surfaceId = statusMsg->surfaceId;
556         channelMsg->sceneType = statusMsg->sceneType;
557         channelMsg->errorCode = statusMsg->msg->errorCode;
558         channelMsg->requestId = statusMsg->msg->requestId;
559 
560         AgentStatusMsg::Ptr agentMsg = std::make_shared<AgentStatusMsg>();
561         RETURN_IF_NULL(agentMsg);
562         agentMsg->msg = std::move(channelMsg);
563         agentMsg->agentId = GetId();
564         listener->OnAgentNotify(agentMsg);
565     }
566 }
567 
SendChannelKeyRedirectEvent(SessionStatusMsg::Ptr & statusMsg,EventType eventType)568 void Agent::SendChannelKeyRedirectEvent(SessionStatusMsg::Ptr &statusMsg, EventType eventType)
569 {
570     SHARING_LOGD("trace.");
571     RETURN_IF_NULL(statusMsg);
572     RETURN_IF_NULL(statusMsg->msg);
573     auto listener = agentListener_.lock();
574     if (listener) {
575         SHARING_LOGI("agentId: %{public}u, notify to channelmgr, eventType: %{public}s.", GetId(),
576                      std::string(magic_enum::enum_name(statusMsg->msg->type)).c_str());
577 
578         auto channelMsg = std::make_shared<ChannelSetKeyRedirectEventMsg>();
579         RETURN_IF_NULL(channelMsg);
580         channelMsg->agentId = GetId();
581         channelMsg->toMgr = ModuleType::MODULE_MEDIACHANNEL;
582         channelMsg->dstId = mediaChannelId_;
583         channelMsg->prosumerId = prosumerId_;
584         channelMsg->type = eventType;
585         channelMsg->surfaceId = statusMsg->surfaceId;
586         channelMsg->keyRedirect = statusMsg->keyRedirect;
587         channelMsg->errorCode = statusMsg->msg->errorCode;
588         channelMsg->requestId = statusMsg->msg->requestId;
589 
590         AgentStatusMsg::Ptr agentMsg = std::make_shared<AgentStatusMsg>();
591         RETURN_IF_NULL(agentMsg);
592         agentMsg->msg = std::move(channelMsg);
593         agentMsg->agentId = GetId();
594         listener->OnAgentNotify(agentMsg);
595     }
596 }
597 
SendChannelSetVolumeEvent(SessionStatusMsg::Ptr & statusMsg,EventType eventType)598 void Agent::SendChannelSetVolumeEvent(SessionStatusMsg::Ptr &statusMsg, EventType eventType)
599 {
600     SHARING_LOGD("trace.");
601     RETURN_IF_NULL(statusMsg);
602     RETURN_IF_NULL(statusMsg->msg);
603     auto listener = agentListener_.lock();
604     if (listener) {
605         SHARING_LOGI("agentId: %{public}u, notify to channelmgr, eventType: %{public}s.", GetId(),
606                      std::string(magic_enum::enum_name(statusMsg->msg->type)).c_str());
607 
608         auto channelMsg = std::make_shared<ChannelSetVolumeEventMsg>();
609         RETURN_IF_NULL(channelMsg);
610         channelMsg->agentId = GetId();
611         channelMsg->toMgr = ModuleType::MODULE_MEDIACHANNEL;
612         channelMsg->dstId = mediaChannelId_;
613         channelMsg->prosumerId = prosumerId_;
614         channelMsg->type = eventType;
615         channelMsg->volume = statusMsg->volume;
616         channelMsg->errorCode = statusMsg->msg->errorCode;
617         channelMsg->requestId = statusMsg->msg->requestId;
618 
619         AgentStatusMsg::Ptr agentMsg = std::make_shared<AgentStatusMsg>();
620         RETURN_IF_NULL(agentMsg);
621         agentMsg->msg = std::move(channelMsg);
622         agentMsg->agentId = GetId();
623         listener->OnAgentNotify(agentMsg);
624     }
625 }
626 
SendContextEvent(SessionStatusMsg::Ptr & statusMsg,EventType eventType)627 void Agent::SendContextEvent(SessionStatusMsg::Ptr &statusMsg, EventType eventType)
628 {
629     SHARING_LOGD("trace.");
630     RETURN_IF_NULL(statusMsg);
631     RETURN_IF_NULL(statusMsg->msg);
632     auto listener = agentListener_.lock();
633     if (listener) {
634         SHARING_LOGI("agentId: %{public}u, notify to context, eventType: %{public}s.", GetId(),
635                      std::string(magic_enum::enum_name(statusMsg->msg->type)).c_str());
636         auto contextMsg = std::make_shared<ContextEventMsg>();
637         RETURN_IF_NULL(contextMsg);
638         contextMsg->type = eventType;
639         contextMsg->toMgr = ModuleType::MODULE_CONTEXT;
640         contextMsg->fromMgr = ModuleType::MODULE_AGENT;
641         contextMsg->srcId = GetId();
642         contextMsg->agentId = GetId();
643         contextMsg->agentType = agentType_;
644         contextMsg->errorCode = statusMsg->msg->errorCode;
645         contextMsg->requestId = statusMsg->msg->requestId;
646 
647         AgentStatusMsg::Ptr agentMsg = std::make_shared<AgentStatusMsg>();
648         RETURN_IF_NULL(agentMsg);
649         agentMsg->msg = std::move(contextMsg);
650         agentMsg->agentId = GetId();
651         listener->OnAgentNotify(agentMsg);
652     }
653 }
654 
GetRunStep(EventType eventType)655 AgentRunStep Agent::GetRunStep(EventType eventType)
656 {
657     SHARING_LOGD("trace.");
658     AgentRunStep step = AGENT_STEP_IDLE;
659     switch (eventType) {
660         case EVENT_AGENT_START:
661             step = AGENT_STEP_START;
662             break;
663         case EVENT_AGENT_CHANNEL_APPENDSURFACE:
664             step = AGENT_STEP_APPENDSURFACE;
665             break;
666         case EVENT_AGENT_CHANNEL_REMOVESURFACE:
667             step = AGENT_STEP_REMOVESURFACE;
668             break;
669         case EVENT_AGENT_PLAY_START:
670             step = AGENT_STEP_PLAY;
671             break;
672         case EVENT_AGENT_PLAY_STOP:
673             step = AGENT_STEP_PLAYSTOP;
674             break;
675         case EVENT_AGENT_PROSUMER_ERROR:
676             step = AGENT_STEP_DESTROY;
677             break;
678         case EVENT_AGENT_DESTROY:
679             step = AGENT_STEP_DESTROY;
680             break;
681         default:
682             SHARING_LOGI("none process case.");
683             break;
684     }
685 
686     return step;
687 }
688 
GetRunStepWeight(AgentRunStep runStep)689 AgentRunStepWeight Agent::GetRunStepWeight(AgentRunStep runStep)
690 {
691     SHARING_LOGD("trace.");
692     AgentRunStepWeight weight = AGENT_STEP_WEIGHT_IDLE;
693     switch (runStep) {
694         case AGENT_STEP_START:
695             weight = AGENT_STEP_WEIGHT_START;
696             break;
697         // case AGENT_STEP_PAUSE:
698         // case AGENT_STEP_RESUME:
699         case AGENT_STEP_APPENDSURFACE: // fall-through
700         case AGENT_STEP_REMOVESURFACE: // fall-through
701         case AGENT_STEP_PLAY:          // fall-through
702         case AGENT_STEP_PLAYSTOP:
703             weight = AGENT_STEP_WEIGHT_REUSABLE;
704             break;
705         case AGENT_STEP_DESTROY:
706             weight = AGENT_STEP_WEIGHT_DESTROY;
707             break;
708         default:
709             SHARING_LOGI("none process case.");
710             break;
711     }
712 
713     return weight;
714 }
715 
CheckRunStep(SharingEvent & event,bool & isCached)716 SharingErrorCode Agent::CheckRunStep(SharingEvent &event, bool &isCached)
717 {
718     SHARING_LOGD("check run step, now step: %{public}s, now status: %{public}s, agentId: %{public}u.",
719                  std::string(magic_enum::enum_name(runStep_)).c_str(),
720                  std::string(magic_enum::enum_name(runningStatus_)).c_str(), GetId());
721     SharingErrorCode retCode = ERR_OK;
722     AgentRunStep step = GetRunStep(event.eventMsg->type);
723     if (step == AGENT_STEP_IDLE) {
724         return retCode;
725     }
726 
727     AgentRunStepWeight weight = GetRunStepWeight(step);
728     AgentRunStepKey nextKey = {event.eventMsg->requestId, step, weight};
729 
730     std::lock_guard<std::mutex> lock(runStepMutex_);
731     switch (runningStatus_) {
732         case AGENT_STATUS_DONE:
733             if (runStep_ == AGENT_STEP_DESTROY) {
734                 return ERR_GENERAL_ERROR;
735             }
736             if ((runStep_ < AGENT_STEP_START) && (step > AGENT_STEP_START) && (step < AGENT_STEP_DESTROY)) {
737                 runEvents_.emplace(nextKey, event);
738                 isCached = true;
739                 SHARING_LOGD("cache event: %{public}s agentId: %{public}u.",
740                              std::string(magic_enum::enum_name(event.eventMsg->type)).c_str(), GetId());
741             } else {
742                 SetRunningStatus(step, AGENT_STATUS_RUNNING);
743             }
744             break;
745         case AGENT_STATUS_RUNNING: {
746             if ((step == runStep_) || (runStep_ >= AGENT_STEP_DESTROY) || (runEvents_.count(nextKey))) {
747                 SHARING_LOGW("already has event: %{public}s, agentId: %{public}u.",
748                              std::string(magic_enum::enum_name(event.eventMsg->type)).c_str(), GetId());
749                 retCode = ERR_GENERAL_ERROR;
750             } else {
751                 if (step == AGENT_STEP_DESTROY && runStep_ < step) {
752                     SHARING_LOGW("agentId: %{public}u, interrupt the step: %{public}d.", GetId(), runStep_);
753                     SetRunningStatus(runStep_, AGENT_STATUS_INTERRUPT);
754                 }
755                 runEvents_.emplace(nextKey, event);
756                 isCached = true;
757                 SHARING_LOGW("cache event: %{public}s, agentId: %{public}u.",
758                              std::string(magic_enum::enum_name(event.eventMsg->type)).c_str(), GetId());
759             }
760             break;
761         }
762         case AGENT_STATUS_ERROR: {
763             if (step == AGENT_STEP_DESTROY) {
764                 SetRunningStatus(step, AGENT_STATUS_RUNNING);
765             } else {
766                 retCode = ERR_GENERAL_ERROR;
767             }
768             break;
769         }
770         default:
771             SHARING_LOGI("none process case.");
772             break;
773     }
774 
775     SHARING_LOGD("check run step, set step: %{public}s, set status: %{public}s, agentId: %{public}u.",
776                  std::string(magic_enum::enum_name(runStep_)).c_str(),
777                  std::string(magic_enum::enum_name(runningStatus_)).c_str(), GetId());
778     return retCode;
779 }
780 
PopNextStep(AgentRunStep step,AgentRunningStatus status)781 void Agent::PopNextStep(AgentRunStep step, AgentRunningStatus status)
782 {
783     SHARING_LOGD("pop run step, now step: %{public}s, now status: %{public}s, agentId: %{public}u.",
784                  std::string(magic_enum::enum_name(runStep_)).c_str(),
785                  std::string(magic_enum::enum_name(runningStatus_)).c_str(), GetId());
786     SharingEvent event;
787     bool ret = false;
788     {
789         std::lock_guard<std::mutex> lock(runStepMutex_);
790         if (step != runStep_) {
791             SHARING_LOGW(
792                 "pop run step, set step: %{public}s is not equal to now step: %{public}s, agentId: %{public}u.",
793                 std::string(magic_enum::enum_name(step)).c_str(), std::string(magic_enum::enum_name(runStep_)).c_str(),
794                 GetId());
795         } else {
796             SetRunningStatus(step, status);
797             SHARING_LOGD("pop run step, set step: %{public}s, set status: %{public}s, agentId: %{public}u.",
798                          std::string(magic_enum::enum_name(runStep_)).c_str(),
799                          std::string(magic_enum::enum_name(runningStatus_)).c_str(), GetId());
800             if (runEvents_.size() > 0) {
801                 auto it = runEvents_.begin();
802                 event = std::move(it->second);
803                 SHARING_LOGD("agentId: %{public}u, next eventType: %{public}s.", GetId(),
804                              std::string(magic_enum::enum_name(event.eventMsg->type)).c_str());
805                 runEvents_.erase(it);
806                 ret = true;
807             }
808         }
809     }
810 
811     if (ret) {
812         SHARING_LOGI("agentId: %{public}u, pop to handle next event: %{public}s.", GetId(),
813                      std::string(magic_enum::enum_name(event.eventMsg->type)).c_str());
814         HandleEvent(event);
815     }
816 }
817 
818 } // namespace Sharing
819 } // namespace OHOS