1 /*
2  * Copyright (c) 2021 Huawei Device 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 "core/event/multimodal/multimodal_manager.h"
17 
18 #include "base/log/dump_log.h"
19 #include "core/pipeline/pipeline_context.h"
20 
21 namespace OHOS::Ace {
22 
GetMultiModalScene(int32_t pageId)23 RefPtr<MultiModalScene> MultiModalManager::GetMultiModalScene(int32_t pageId)
24 {
25     auto iter = multiModalScenes_.find(pageId);
26     if (iter == multiModalScenes_.end()) {
27         auto newScene = multiModalScenes_.try_emplace(pageId, MakeRefPtr<MultiModalScene>(pageId, subscriber_));
28         return newScene.first->second;
29     }
30     return iter->second;
31 }
32 
PushActiveScene(int32_t newPageId)33 void MultiModalManager::PushActiveScene(int32_t newPageId)
34 {
35     if (activeSceneId_ == newPageId) {
36         return;
37     }
38     if (activeSceneId_ > 0) {
39         GetMultiModalScene(activeSceneId_)->Hide();
40     }
41     activeSceneId_ = newPageId;
42 }
43 
PopActiveScene(int32_t poppedPageId,int32_t incomingPageId)44 void MultiModalManager::PopActiveScene(int32_t poppedPageId, int32_t incomingPageId)
45 {
46     RemoveMultimodalScene(poppedPageId);
47     if (activeSceneId_ == incomingPageId) {
48         return;
49     }
50     GetMultiModalScene(incomingPageId)->Resume();
51     activeSceneId_ = incomingPageId;
52 }
53 
GetCurrentMultiModalScene()54 RefPtr<MultiModalScene> MultiModalManager::GetCurrentMultiModalScene()
55 {
56     if (activeSceneId_ < 0) {
57         return nullptr;
58     }
59     return GetMultiModalScene(activeSceneId_);
60 }
61 
ReplaceActiveScene(int32_t newPageId,int32_t replaceId)62 void MultiModalManager::ReplaceActiveScene(int32_t newPageId, int32_t replaceId)
63 {
64     RemoveMultimodalScene(replaceId);
65     if (activeSceneId_ == newPageId) {
66         return;
67     }
68     activeSceneId_ = newPageId;
69 }
70 
RemoveMultimodalScene(int32_t pageId)71 void MultiModalManager::RemoveMultimodalScene(int32_t pageId)
72 {
73     multiModalScenes_.erase(pageId);
74 }
75 
RemoveInactiveScene(int32_t pageId)76 void MultiModalManager::RemoveInactiveScene(int32_t pageId)
77 {
78     if (activeSceneId_ == pageId) {
79         LOGW("fail to remove scene due to it is active");
80         return;
81     }
82     RemoveMultimodalScene(pageId);
83 }
84 
SetMultimodalSubscriber(const RefPtr<MultimodalSubscriber> & subscriber)85 void MultiModalManager::SetMultimodalSubscriber(const RefPtr<MultimodalSubscriber>& subscriber)
86 {
87     if (subscriber) {
88         subscriber_ = subscriber;
89     }
90 }
91 
OpenChannel(const RefPtr<PipelineContext> & context)92 void MultiModalManager::OpenChannel(const RefPtr<PipelineContext>& context)
93 {
94     if (!subscriber_) {
95         return;
96     }
97     if (isRegistered_) {
98         return;
99     }
100     auto callback = [weak = WeakClaim(this), weakContext = WeakPtr<PipelineContext>(context)](
101                         const AceMultimodalEvent& event) {
102         auto manager = weak.Upgrade();
103         if (!manager) {
104             LOGE("fail to get manager to notify event");
105             return;
106         }
107         auto context = weakContext.Upgrade();
108         if (!context) {
109             LOGE("fail to get context to notify event");
110             return;
111         }
112         auto scene = manager->GetCurrentMultiModalScene();
113         if (!scene) {
114             LOGE("fail to get current multi modal scene");
115             return;
116         }
117         auto weakScene = AceType::WeakClaim(AceType::RawPtr(scene));
118         context->GetTaskExecutor()->PostSyncTask(
119             [event, weakScene]() {
120                 auto scene = weakScene.Upgrade();
121                 if (scene == nullptr) {
122                     LOGE("scene is null!");
123                     return;
124                 }
125             scene->OnNotifyMultimodalEvent(event);
126             },
127             TaskExecutor::TaskType::UI, "ArkUINotifyMultimodalEvent");
128     };
129     subscriber_->RegisterCallback(callback, [weak = WeakClaim(this)]() {
130         auto manager = weak.Upgrade();
131         if (!manager) {
132             LOGE("fail to get manager to notify event");
133             return;
134         }
135         manager->isRegistered_ = true;
136     });
137 }
138 
DumpMultimodalScene()139 void MultiModalManager::DumpMultimodalScene()
140 {
141     if (DumpLog::GetInstance().GetDumpFile()) {
142         DumpLog::GetInstance().AddDesc("ActiveScene: ", activeSceneId_);
143         DumpLog::GetInstance().AddDesc("totalScene: ", multiModalScenes_.size());
144         DumpLog::GetInstance().AddDesc("registered: ", isRegistered_);
145         DumpLog::GetInstance().Print(0, GetTypeName(), multiModalScenes_.size());
146     }
147     GetCurrentMultiModalScene()->Dump();
148 }
149 
150 } // namespace OHOS::Ace