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