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_scene.h"
17
18 #include <algorithm>
19
20 #include "base/log/dump_log.h"
21 #include "base/log/log.h"
22
23 namespace OHOS::Ace {
24
GetAvailableSubscriptId()25 std::string MultiModalScene::GetAvailableSubscriptId()
26 {
27 if (cachedIds_.empty()) {
28 auto newId = currentAvailableId_++;
29 return std::to_string(newId);
30 }
31 auto cachedId = *(cachedIds_.begin());
32 cachedIds_.erase(cachedIds_.begin());
33 return cachedId;
34 }
35
RemoveSubscriptId(const std::string & subscriptId)36 void MultiModalScene::RemoveSubscriptId(const std::string& subscriptId)
37 {
38 cachedIds_.emplace(subscriptId);
39 }
40
GetCurrentMaxSubscriptId()41 std::string MultiModalScene::GetCurrentMaxSubscriptId()
42 {
43 return std::to_string(currentAvailableId_ - 1);
44 }
45
SubscribeVoiceEvent(const VoiceEvent & voiceEvent,const MultimodalEventCallback & callback)46 bool MultiModalScene::SubscribeVoiceEvent(const VoiceEvent& voiceEvent, const MultimodalEventCallback& callback)
47 {
48 if (!callback) {
49 LOGW("fail to subscribe voice event due to callback is null");
50 return false;
51 }
52 auto result = voiceEventCallbacks_.try_emplace(voiceEvent.GetVoiceContent(), callback);
53 if (!result.second) {
54 LOGW("subscribe duplicate voice event, voice label %{private}s", voiceEvent.GetVoiceContent().c_str());
55 return false;
56 }
57 voiceEvents_.emplace_back(voiceEvent);
58 if (!subscriber_) {
59 LOGE("fail to subscribe voice event due to subscriber is null");
60 return false;
61 }
62 if (!subscriber_->SubscribeVoiceEvents({ voiceEvent })) {
63 LOGE("fail to subscribe voice event due to subscribe fail");
64 return false;
65 }
66 return true;
67 }
68
UnSubscribeVoiceEvent(const VoiceEvent & voiceEvent)69 void MultiModalScene::UnSubscribeVoiceEvent(const VoiceEvent& voiceEvent)
70 {
71 voiceEventCallbacks_.erase(voiceEvent.GetVoiceContent());
72 auto iter = std::remove(voiceEvents_.begin(), voiceEvents_.end(), voiceEvent);
73 if (iter != voiceEvents_.end()) {
74 voiceEvents_.erase(iter);
75 if (subscriber_) {
76 subscriber_->UnSubscribeVoiceEvents({ voiceEvent });
77 }
78 }
79 }
80
SubscribeSubscriptSwitchEvent(const EventCallback<void (bool)> & callback)81 void MultiModalScene::SubscribeSubscriptSwitchEvent(const EventCallback<void(bool)>& callback)
82 {
83 subscriptSwitchListeners_.emplace_back(callback);
84 }
85
UnSubscribeSubscriptSwitchEvent(const EventCallback<void (bool)> & callback)86 void MultiModalScene::UnSubscribeSubscriptSwitchEvent(const EventCallback<void(bool)>& callback)
87 {
88 auto iter = std::remove(subscriptSwitchListeners_.begin(), subscriptSwitchListeners_.end(), callback);
89 if (iter != subscriptSwitchListeners_.end()) {
90 subscriptSwitchListeners_.erase(iter);
91 }
92 }
93
OnNotifyMultimodalEvent(const AceMultimodalEvent & event)94 void MultiModalScene::OnNotifyMultimodalEvent(const AceMultimodalEvent& event)
95 {
96 static const int32_t SHOW_BADGE = 6;
97 static const int32_t HIDE_BADGE = 7;
98 if (event.GetVoice().action == SHOW_BADGE || event.GetVoice().action == HIDE_BADGE) {
99 badgeFlag_ = event.GetVoice().action == SHOW_BADGE;
100 for (const auto& callback : subscriptSwitchListeners_) {
101 if (callback) {
102 callback(event.GetVoice().action == SHOW_BADGE);
103 }
104 }
105 }
106 auto voiceIter = voiceEventCallbacks_.find(event.GetVoice().hotWord);
107 if (voiceIter != voiceEventCallbacks_.end()) {
108 (voiceIter->second)(event);
109 return;
110 }
111 auto badgeIter = voiceEventCallbacks_.find(event.GetVoice().badge);
112 if (badgeIter != voiceEventCallbacks_.end()) {
113 (badgeIter->second)(event);
114 }
115 }
116
UnSubscribeAllEvents()117 void MultiModalScene::UnSubscribeAllEvents()
118 {
119 if (subscriber_ && !voiceEvents_.empty()) {
120 subscriber_->UnSubscribeVoiceEvents(voiceEvents_);
121 }
122 voiceEvents_.clear();
123 voiceEventCallbacks_.clear();
124 subscriptSwitchListeners_.clear();
125 }
126
Hide()127 void MultiModalScene::Hide()
128 {
129 if (subscriber_ && !voiceEvents_.empty()) {
130 subscriber_->UnSubscribeVoiceEvents(voiceEvents_);
131 }
132 }
133
Resume()134 void MultiModalScene::Resume()
135 {
136 if (subscriber_ && !voiceEvents_.empty()) {
137 subscriber_->SubscribeVoiceEvents(voiceEvents_);
138 }
139 }
140
~MultiModalScene()141 MultiModalScene::~MultiModalScene()
142 {
143 UnSubscribeAllEvents();
144 }
145
Dump() const146 void MultiModalScene::Dump() const
147 {
148 if (DumpLog::GetInstance().GetDumpFile()) {
149 for (const auto& event : voiceEvents_) {
150 DumpLog::GetInstance().AddDesc("voice event: ", event.GetVoiceContent());
151 DumpLog::GetInstance().AddDesc("badge event: ", event.IsBadge());
152 }
153 DumpLog::GetInstance().AddDesc("current badge id: ", currentAvailableId_);
154 DumpLog::GetInstance().AddDesc("badge flag: ", badgeFlag_);
155 DumpLog::GetInstance().Print(0, GetTypeName(), voiceEvents_.size());
156 }
157 }
158
159 } // namespace OHOS::Ace