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