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