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 "interaction.h"
17#include "common/common_macro.h"
18#include "common/event_comm.h"
19#include "common/reflect_registration.h"
20#include "common/sharing_log.h"
21#include "interaction/interaction_manager.h"
22#include "magic_enum.hpp"
23#include "scene/base_scene.h"
24
25namespace OHOS {
26namespace Sharing {
27
28Interaction::~Interaction()
29{
30    SHARING_LOGD("id: %{public}d.", GetId());
31}
32
33bool Interaction::CreateScene(const std::string &className)
34{
35    SHARING_LOGD("trace.");
36    scene_ = ClassReflector<BaseScene>::Class2Instance(className);
37    if (scene_ == nullptr) {
38        SHARING_LOGE("create scene error.");
39        return false;
40    }
41
42    scene_->SetInteractionId(GetId());
43    scene_->Initialize();
44    scene_->SetSharingAdapter(shared_from_this());
45
46    return true;
47}
48
49void Interaction::OnDomainMsg(std::shared_ptr<BaseDomainMsg> &msg)
50{
51    SHARING_LOGD("trace.");
52    if (scene_) {
53        scene_->OnDomainMsg(msg);
54    }
55}
56
57void Interaction::ForwardDomainMsg(std::shared_ptr<BaseDomainMsg> &msg)
58{
59    SHARING_LOGD("trace.");
60    InteractionManager::GetInstance().SendDomainMsg(msg);
61}
62
63void Interaction::ReleaseScene(uint32_t sceneId)
64{
65    SHARING_LOGD("trace.");
66    auto interactionMsg = std::make_shared<InteractionEventMsg>();
67    interactionMsg->toMgr = ModuleType::MODULE_INTERACTION;
68    interactionMsg->type = EVENT_INTERACTIONMGR_DESTROY_INTERACTION;
69
70    SharingEvent event;
71    event.eventMsg = std::move(interactionMsg);
72    event.eventMsg->fromMgr = ModuleType::MODULE_INTERACTION;
73    event.eventMsg->dstId = GetId();
74    SendEvent(event);
75}
76
77void Interaction::OnSceneNotifyDestroyed(uint32_t sceneId)
78{
79    SHARING_LOGE("scene destroyed will remove interactionId: %{public}u.", GetId());
80    auto interactionMsg = std::make_shared<InteractionEventMsg>();
81    interactionMsg->toMgr = ModuleType::MODULE_INTERACTION;
82    interactionMsg->type = EVENT_INTERACTIONMGR_REMOVE_INTERACTION;
83
84    SharingEvent event;
85    event.eventMsg = std::move(interactionMsg);
86    event.eventMsg->fromMgr = ModuleType::MODULE_INTERACTION;
87    event.eventMsg->dstId = GetId();
88    SendEvent(event);
89}
90
91void Interaction::Destroy()
92{
93    SHARING_LOGE("trace.");
94    if (scene_) {
95        scene_.reset();
96    }
97}
98
99int32_t Interaction::HandleEvent(SharingEvent &event)
100{
101    SHARING_LOGD("trace.");
102    RETURN_INVALID_IF_NULL(event.eventMsg);
103    SHARING_LOGI("fromMgr: %{public}u, srcId: %{public}u, toMgr: %{public}u, dstId: %{public}u, event: %{public}s.",
104                 event.eventMsg->fromMgr, event.eventMsg->srcId, event.eventMsg->toMgr, event.eventMsg->dstId,
105                 std::string(magic_enum::enum_name(event.eventMsg->type)).c_str());
106    auto interactionMsg = ConvertEventMsg<InteractionEventMsg>(event);
107    auto contextId = interactionMsg->contextId ? interactionMsg->contextId : interactionMsg->srcId;
108    auto agentId = interactionMsg->agentId;
109    auto agentType = interactionMsg->agentType;
110    auto errorCode = interactionMsg->errorCode;
111
112    switch (event.eventMsg->type) {
113        case EVENT_INTERACTION_MSG_ERROR: {
114            SHARING_LOGI("interaction handle error, errorCode: %{public}d.", errorCode);
115            if (scene_) {
116                scene_->OnInnerError(contextId, agentId, errorCode);
117                if (errorCode == ERR_NETWORK_ERROR || errorCode == ERR_CONNECTION_FAILURE ||
118                    errorCode == ERR_INTERACTION_FAILURE || errorCode == ERR_PROTOCOL_INTERACTION_TIMEOUT ||
119                    errorCode == ERR_INTAKE_TIMEOUT) {
120                    SHARING_LOGE("on inner destroy network error.");
121                    scene_->OnInnerDestroy(contextId, agentId, agentType);
122                    DestroyAgent(contextId, agentId);
123                }
124            }
125            break;
126        }
127        case EVENT_INTERACTION_STATE_AGENT_DESTROYED:
128        case EVENT_INTERACTION_STATE_CONTEXT_DESTROYED: {
129            SHARING_LOGI("interaction handle event, destroy result.");
130            if (scene_) {
131                scene_->OnInnerDestroy(contextId, agentId, agentType);
132            }
133            break;
134        }
135        default:
136            SHARING_LOGI("interaction forward event to scene.");
137            if (scene_) {
138                scene_->OnInnerEvent(event);
139            }
140            break;
141    }
142
143    return 0;
144}
145
146int32_t Interaction::NotifyEvent(EventMsg::Ptr eventMsg)
147{
148    SHARING_LOGD("trace.");
149    RETURN_INVALID_IF_NULL(eventMsg);
150    SharingEvent event;
151    event.eventMsg = std::move(eventMsg);
152    event.eventMsg->fromMgr = ModuleType::MODULE_INTERACTION;
153    event.eventMsg->srcId = GetId();
154    return SendEvent(event);
155}
156
157int32_t Interaction::CreateContext(uint32_t &contextId)
158{
159    SHARING_LOGD("trace.");
160    auto contextMsg = std::make_shared<ContextEventMsg>();
161    contextMsg->type = EventType::EVENT_CONTEXTMGR_CREATE;
162    contextMsg->toMgr = ModuleType::MODULE_CONTEXT;
163
164    SharingEvent event;
165    event.eventMsg = contextMsg;
166    event.eventMsg->fromMgr = ModuleType::MODULE_INTERACTION;
167    event.eventMsg->srcId = GetId();
168    int32_t ret = SendSyncEvent(event);
169    if (ret != -1) {
170        contextId = contextMsg->dstId;
171        SHARING_LOGI("create context success contextId: %{public}u.", contextId);
172    } else {
173        SHARING_LOGE("create context failed.");
174    }
175
176    return 0;
177}
178
179int32_t Interaction::DestroyContext(uint32_t contextId)
180{
181    SHARING_LOGD("contextId: %{public}u.", contextId);
182    auto contextMsg = std::make_shared<ContextEventMsg>();
183    contextMsg->type = EventType::EVENT_CONTEXTMGR_DESTROY;
184    contextMsg->toMgr = ModuleType::MODULE_CONTEXT;
185    contextMsg->dstId = contextId;
186
187    int32_t ret = NotifyEvent(contextMsg);
188    if (ret != -1) {
189        SHARING_LOGI("destroy context success contextId: %{public}u.", contextId);
190    } else {
191        SHARING_LOGE("destroy context failed.");
192    }
193
194    return ret;
195}
196
197int32_t Interaction::CreateAgent(uint32_t &contextId, uint32_t &agentId, AgentType agentType, std::string sessionName)
198{
199    SHARING_LOGD("contextId: %{public}u, agentId: %{public}u.", contextId, agentId);
200    auto contextMsg = std::make_shared<ContextEventMsg>();
201    contextMsg->type = EventType::EVENT_CONTEXTMGR_AGENT_CREATE;
202    contextMsg->toMgr = ModuleType::MODULE_CONTEXT;
203    contextMsg->dstId = contextId;
204    contextMsg->agentType = agentType;
205    contextMsg->className = std::move(sessionName);
206    contextMsg->agentId = agentId;
207
208    SharingEvent event;
209    event.eventMsg = contextMsg;
210    event.eventMsg->fromMgr = ModuleType::MODULE_INTERACTION;
211    event.eventMsg->srcId = GetId();
212    int32_t ret = SendSyncEvent(event);
213
214    SHARING_LOGI("notify create agent ret: %{public}d agentId: %{public}u.", ret, contextMsg->agentId);
215    if (ret != -1) {
216        if ((agentId == contextMsg->agentId) || contextMsg->agentId == INVALID_ID) {
217            agentId = INVALID_ID;
218        } else {
219            agentId = contextMsg->agentId;
220        }
221        contextId = contextMsg->dstId;
222        SHARING_LOGI("notify create agent success agentId: %{public}u.", agentId);
223    } else {
224        SHARING_LOGE("notify create agent failed!");
225    }
226
227    return ret;
228}
229
230int32_t Interaction::DestroyAgent(uint32_t contextId, uint32_t agentId)
231{
232    SHARING_LOGD("contextId: %{public}u, agentId: %{public}u.", contextId, agentId);
233    auto contextMsg = std::make_shared<AgentEventMsg>();
234    contextMsg->type = EventType::EVENT_CONTEXT_AGENT_DESTROY;
235    contextMsg->toMgr = ModuleType::MODULE_CONTEXT;
236    contextMsg->dstId = contextId;
237    contextMsg->agentId = agentId;
238
239    int32_t ret = NotifyEvent(contextMsg);
240    if (ret != -1) {
241        SHARING_LOGI("destroy agent success agentId: %{public}u.", agentId);
242    } else {
243        SHARING_LOGE("destroy agent failed, agentId: %{public}u.", agentId);
244    }
245
246    return ret;
247}
248
249int32_t Interaction::Stop(uint32_t contextId, uint32_t agentId)
250{
251    SHARING_LOGD("contextId: %{public}u, agentId: %{public}u.", contextId, agentId);
252    return 0;
253}
254
255int32_t Interaction::Start(uint32_t contextId, uint32_t agentId)
256{
257    SHARING_LOGD("contextId: %{public}u, agentId: %{public}u.", contextId, agentId);
258    auto agentMsg = std::make_shared<AgentEventMsg>();
259    agentMsg->type = EventType::EVENT_AGENT_START;
260    agentMsg->toMgr = ModuleType::MODULE_CONTEXT;
261    agentMsg->dstId = contextId;
262    agentMsg->agentId = agentId;
263    int32_t ret = NotifyEvent(agentMsg);
264    if (ret != -1) {
265        SHARING_LOGI("start agent success agentId: %{public}u.", agentId);
266    } else {
267        SHARING_LOGE("start agent failed, agentId: %{public}u.", agentId);
268    }
269
270    return ret;
271}
272
273int32_t Interaction::Pause(uint32_t contextId, uint32_t agentId, MediaType mediaType)
274{
275    SHARING_LOGD("contextId: %{public}u, agentId: %{public}u.", contextId, agentId);
276    auto agentMsg = std::make_shared<AgentEventMsg>();
277    agentMsg->type = EventType::EVENT_AGENT_PAUSE;
278    agentMsg->toMgr = ModuleType::MODULE_CONTEXT;
279    agentMsg->dstId = contextId;
280    agentMsg->agentId = agentId;
281    agentMsg->mediaType = mediaType;
282    int32_t ret = NotifyEvent(agentMsg);
283    if (ret != -1) {
284        SHARING_LOGI("pause agent success agentId: %{public}u.", agentId);
285    } else {
286        SHARING_LOGE("pause agent failed, agentId: %{public}u.", agentId);
287    }
288
289    return ret;
290}
291
292int32_t Interaction::Resume(uint32_t contextId, uint32_t agentId, MediaType mediaType)
293{
294    SHARING_LOGD("contextId: %{public}u, agentId: %{public}u.", contextId, agentId);
295    auto agentMsg = std::make_shared<AgentEventMsg>();
296    agentMsg->type = EventType::EVENT_AGENT_RESUME;
297    agentMsg->toMgr = ModuleType::MODULE_CONTEXT;
298    agentMsg->dstId = contextId;
299    agentMsg->agentId = agentId;
300    agentMsg->mediaType = mediaType;
301    int32_t ret = NotifyEvent(agentMsg);
302    if (ret != -1) {
303        SHARING_LOGI("resume agent success agentId: %{public}u.", agentId);
304    } else {
305        SHARING_LOGE("resume agent failed, agentId: %{public}u.", agentId);
306    }
307
308    return ret;
309}
310
311int32_t Interaction::ForwardEvent(uint32_t contextId, uint32_t agentId, SharingEvent &event, bool isSync)
312{
313    SHARING_LOGI("contextId: %{public}u, agentId: %{public}u.", contextId, agentId);
314    RETURN_INVALID_IF_NULL(event.eventMsg);
315    event.eventMsg->fromMgr = MODULE_INTERACTION;
316    event.eventMsg->srcId = GetId();
317    event.listenerType = CLASS_TYPE_SCHEDULER;
318
319    if (isSync) {
320        return SendSyncEvent(event);
321    } else {
322        return SendEvent(event);
323    }
324}
325
326int32_t Interaction::Play(uint32_t contextId, uint32_t agentId)
327{
328    SHARING_LOGI("contextId: %{public}u, agentId: %{public}u.", contextId, agentId);
329    auto agentMsg = std::make_shared<AgentEventMsg>();
330    agentMsg->type = EventType::EVENT_AGENT_PLAY_START;
331    agentMsg->toMgr = ModuleType::MODULE_CONTEXT;
332    agentMsg->dstId = contextId;
333    agentMsg->agentId = agentId;
334    int32_t ret = NotifyEvent(agentMsg);
335    if (ret != -1) {
336        SHARING_LOGI("agent play success agentId: %{public}u.", agentId);
337    } else {
338        SHARING_LOGE("agent play failed, agentId: %{public}u.", agentId);
339    }
340
341    return ret;
342}
343
344int32_t Interaction::Close(uint32_t contextId, uint32_t agentId)
345{
346    SHARING_LOGI("contextId: %{public}u, agentId: %{public}u.", contextId, agentId);
347    auto agentMsg = std::make_shared<AgentEventMsg>();
348    agentMsg->type = EventType::EVENT_AGENT_PLAY_STOP;
349    agentMsg->toMgr = ModuleType::MODULE_CONTEXT;
350    agentMsg->dstId = contextId;
351    agentMsg->agentId = agentId;
352    int32_t ret = NotifyEvent(agentMsg);
353    if (ret != -1) {
354        SHARING_LOGI("agent close success agentId: %{public}u.", agentId);
355    } else {
356        SHARING_LOGE("agent close failed, agentId: %{public}u.", agentId);
357    }
358
359    return ret;
360}
361
362int32_t Interaction::SetVolume(uint32_t contextId, uint32_t agentId, float volume)
363{
364    SHARING_LOGD("contextId: %{public}u, agentId: %{public}u.", contextId, agentId);
365    auto agentMsg = std::make_shared<AgentEventMsg>();
366    agentMsg->type = EventType::EVENT_AGENT_CHANNEL_SETVOLUME;
367    agentMsg->toMgr = ModuleType::MODULE_CONTEXT;
368    agentMsg->dstId = contextId;
369    agentMsg->agentId = agentId;
370    agentMsg->volume = volume;
371    int32_t ret = NotifyEvent(agentMsg);
372    if (ret != -1) {
373        SHARING_LOGI("agent set volume success agentId: %{public}u.", agentId);
374    } else {
375        SHARING_LOGE("agent set volume failed, agentId: %{public}u.", agentId);
376    }
377
378    return 0;
379}
380
381int32_t Interaction::SetKeyPlay(uint32_t contextId, uint32_t agentId, uint64_t surfaceId, bool keyFrame)
382{
383    SHARING_LOGD("contextId: %{public}u, agentId: %{public}u.", contextId, agentId);
384    auto agentMsg = std::make_shared<AgentEventMsg>();
385    agentMsg->type = EventType::EVENT_AGENT_CHANNEL_SETSCENETYPE;
386    agentMsg->toMgr = ModuleType::MODULE_CONTEXT;
387    agentMsg->dstId = contextId;
388    agentMsg->agentId = agentId;
389    agentMsg->surfaceId = surfaceId;
390    agentMsg->sceneType = keyFrame ? SceneType::BACKGROUND : SceneType::FOREGROUND;
391
392    int32_t ret = NotifyEvent(agentMsg);
393    if (ret != -1) {
394        SHARING_LOGI("agent set key play success agentId: %{public}u.", agentId);
395    } else {
396        SHARING_LOGE("agent set key play failed, agentId: %{public}u.", agentId);
397    }
398
399    return ret;
400}
401
402int32_t Interaction::SetKeyRedirect(uint32_t contextId, uint32_t agentId, uint64_t surfaceId, bool keyRedirect)
403{
404    SHARING_LOGD("contextId: %{public}u, agentId: %{public}u.", contextId, agentId);
405    auto agentMsg = std::make_shared<AgentEventMsg>();
406    agentMsg->type = EventType::EVENT_AGENT_CHANNEL_SETKEYREDIRECT;
407    agentMsg->toMgr = ModuleType::MODULE_CONTEXT;
408    agentMsg->dstId = contextId;
409    agentMsg->agentId = agentId;
410    agentMsg->surfaceId = surfaceId;
411    agentMsg->keyRedirect = keyRedirect;
412
413    int32_t ret = NotifyEvent(agentMsg);
414    if (ret != -1) {
415        SHARING_LOGI("agent set key play success agentId: %{public}u.", agentId);
416    } else {
417        SHARING_LOGE("agent set key play failed, agentId: %{public}u.", agentId);
418    }
419
420    return ret;
421}
422
423int32_t Interaction::AppendSurface(uint32_t contextId, uint32_t agentId, sptr<Surface> surface, SceneType sceneType)
424{
425    SHARING_LOGD("contextId: %{public}u, agentId: %{public}u.", contextId, agentId);
426    RETURN_INVALID_IF_NULL(surface);
427    auto agentMsg = std::make_shared<AgentEventMsg>();
428    agentMsg->type = EventType::EVENT_AGENT_CHANNEL_APPENDSURFACE;
429    agentMsg->toMgr = ModuleType::MODULE_CONTEXT;
430    agentMsg->dstId = contextId;
431    agentMsg->agentId = agentId;
432    agentMsg->surface = surface;
433    agentMsg->sceneType = sceneType;
434    agentMsg->requestId = GetRequestId();
435    int32_t ret = NotifyEvent(agentMsg);
436    if (ret != -1) {
437        SHARING_LOGI("agent set surface success agentId: %{public}u.", agentId);
438    } else {
439        SHARING_LOGE("agent set surface failed, agentId: %{public}u.", agentId);
440    }
441
442    return ret;
443}
444
445int32_t Interaction::RemoveSurface(uint32_t contextId, uint32_t agentId, uint64_t surfaceId)
446{
447    SHARING_LOGD("contextId: %{public}u, agentId: %{public}u.", contextId, agentId);
448    auto agentMsg = std::make_shared<AgentEventMsg>();
449    agentMsg->type = EventType::EVENT_AGENT_CHANNEL_REMOVESURFACE;
450    agentMsg->toMgr = ModuleType::MODULE_CONTEXT;
451    agentMsg->dstId = contextId;
452    agentMsg->agentId = agentId;
453    agentMsg->surfaceId = surfaceId;
454    agentMsg->requestId = GetRequestId();
455    int32_t ret = NotifyEvent(agentMsg);
456    if (ret != -1) {
457        SHARING_LOGI("agent del surface success agentId: %{public}u.", agentId);
458    } else {
459        SHARING_LOGE("agent del surface failed, agentId: %{public}u.", agentId);
460    }
461
462    return ret;
463}
464
465int32_t Interaction::DestroyWindow(int32_t windowId)
466{
467    SHARING_LOGD("trace.");
468    (void)windowId;
469    return 0;
470}
471
472int32_t Interaction::CreateWindow(int32_t &windowId, WindowProperty &windowProperty)
473{
474    SHARING_LOGD("trace.");
475    (void)windowId;
476    (void)windowProperty;
477    return 0;
478}
479
480int32_t Interaction::Hide(int32_t windowId)
481{
482    SHARING_LOGD("trace.");
483    (void)windowId;
484    return 0;
485}
486
487int32_t Interaction::Show(int32_t windowId)
488{
489    SHARING_LOGD("trace.");
490    (void)windowId;
491    return 0;
492}
493
494int32_t Interaction::SetFullScreen(int32_t windowId, bool isFull)
495{
496    SHARING_LOGD("trace.");
497    (void)windowId;
498    (void)isFull;
499    return 0;
500}
501
502int32_t Interaction::MoveTo(int32_t windowId, int32_t x, int32_t y)
503{
504    SHARING_LOGD("trace.");
505    (void)windowId;
506    (void)x;
507    (void)y;
508    return 0;
509}
510
511int32_t Interaction::GetSurface(int32_t windowId, sptr<Surface> &surface)
512{
513    SHARING_LOGD("trace.");
514    (void)windowId;
515    (void)surface;
516    return 0;
517}
518
519int32_t Interaction::ReSize(int32_t windowId, int32_t width, int32_t height)
520{
521    SHARING_LOGD("trace.");
522    (void)windowId;
523    (void)width;
524    (void)height;
525    return 0;
526}
527
528} // namespace Sharing
529} // namespace OHOS