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