1 /*
2 * Copyright (c) 2021-2022 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 "key_event_input_subscribe_manager.h"
17
18 #include "bytrace_adapter.h"
19 #include "define_multimodal.h"
20 #include "error_multimodal.h"
21 #include "multimodal_event_handler.h"
22
23 #undef MMI_LOG_TAG
24 #define MMI_LOG_TAG "KeyEventInputSubscribeManager"
25
26 namespace OHOS {
27 namespace MMI {
28 namespace {
29 constexpr int32_t INVALID_SUBSCRIBE_ID { -1 };
30 constexpr size_t PRE_KEYS_NUM { 4 };
31 } // namespace
32 int32_t KeyEventInputSubscribeManager::subscribeIdManager_ = 0;
33
operator <(const MonitorIdentity & other) const34 bool KeyEventInputSubscribeManager::MonitorIdentity::operator<(const MonitorIdentity &other) const
35 {
36 if (key_ != other.key_) {
37 return (key_ < other.key_);
38 }
39 if (action_ != other.action_) {
40 return (action_ < other.action_);
41 }
42 return (isRepeat_ < other.isRepeat_);
43 }
44
Dump() const45 std::string KeyEventInputSubscribeManager::MonitorIdentity::Dump() const
46 {
47 std::ostringstream sMonitor;
48 sMonitor << "Key:" << key_ << ",Action:" << action_
49 << ",IsRepeat:" << std::boolalpha << isRepeat_;
50 return std::move(sMonitor).str();
51 }
52
Want(std::shared_ptr<KeyEvent> keyEvent) const53 bool KeyEventInputSubscribeManager::MonitorIdentity::Want(std::shared_ptr<KeyEvent> keyEvent) const
54 {
55 return ((key_ == keyEvent->GetKeyCode()) &&
56 (action_ == keyEvent->GetKeyAction()) &&
57 (isRepeat_ ||
58 (keyEvent->GetKeyAction() != KeyEvent::KEY_ACTION_DOWN) ||
59 !keyEvent->IsRepeatKey()));
60 }
61
KeyEventInputSubscribeManager()62 KeyEventInputSubscribeManager::KeyEventInputSubscribeManager() {}
~KeyEventInputSubscribeManager()63 KeyEventInputSubscribeManager::~KeyEventInputSubscribeManager() {}
64
SubscribeKeyEventInfo(std::shared_ptr<KeyOption> keyOption,std::function<void (std::shared_ptr<KeyEvent>)> callback)65 KeyEventInputSubscribeManager::SubscribeKeyEventInfo::SubscribeKeyEventInfo(
66 std::shared_ptr<KeyOption> keyOption,
67 std::function<void(std::shared_ptr<KeyEvent>)> callback)
68 : keyOption_(keyOption), callback_(callback)
69 {
70 if (KeyEventInputSubscribeManager::subscribeIdManager_ >= std::numeric_limits<int32_t>::max()) {
71 subscribeId_ = -1;
72 MMI_HILOGE("The subscribeId has reached the upper limit, cannot continue the subscription");
73 return;
74 }
75 subscribeId_ = KeyEventInputSubscribeManager::subscribeIdManager_;
76 ++KeyEventInputSubscribeManager::subscribeIdManager_;
77 }
78
operator <(const KeyOption & first,const KeyOption & second)79 static bool operator<(const KeyOption &first, const KeyOption &second)
80 {
81 if (first.GetFinalKey() != second.GetFinalKey()) {
82 return (first.GetFinalKey() < second.GetFinalKey());
83 }
84 const std::set<int32_t> sPrekeys { first.GetPreKeys() };
85 const std::set<int32_t> tPrekeys { second.GetPreKeys() };
86 std::set<int32_t>::const_iterator sIter = sPrekeys.cbegin();
87 std::set<int32_t>::const_iterator tIter = tPrekeys.cbegin();
88 for (; sIter != sPrekeys.cend() && tIter != tPrekeys.cend(); ++sIter, ++tIter) {
89 if (*sIter != *tIter) {
90 return (*sIter < *tIter);
91 }
92 }
93 if (sIter != sPrekeys.cend() || tIter != tPrekeys.cend()) {
94 return (tIter != tPrekeys.cend());
95 }
96 if (first.IsFinalKeyDown()) {
97 if (!second.IsFinalKeyDown()) {
98 return false;
99 }
100 } else {
101 if (second.IsFinalKeyDown()) {
102 return true;
103 }
104 }
105 return (first.GetFinalKeyDownDuration() < second.GetFinalKeyDownDuration());
106 }
107
SubscribeKeyEventInfo(const SubscribeKeyEventInfo & other)108 KeyEventInputSubscribeManager::SubscribeKeyEventInfo::SubscribeKeyEventInfo(const SubscribeKeyEventInfo &other)
109 : keyOption_(other.keyOption_), callback_(other.callback_), subscribeId_(other.subscribeId_)
110 {}
111
operator =(const KeyEventInputSubscribeManager::SubscribeKeyEventInfo & other)112 KeyEventInputSubscribeManager::SubscribeKeyEventInfo& KeyEventInputSubscribeManager::SubscribeKeyEventInfo::operator=(
113 const KeyEventInputSubscribeManager::SubscribeKeyEventInfo &other)
114 {
115 if (this != &other) {
116 keyOption_ = other.keyOption_;
117 callback_ = other.callback_;
118 subscribeId_ = other.subscribeId_;
119 }
120 return *this;
121 }
122
operator <(const SubscribeKeyEventInfo & other) const123 bool KeyEventInputSubscribeManager::SubscribeKeyEventInfo::operator<(const SubscribeKeyEventInfo &other) const
124 {
125 if (keyOption_ == nullptr) {
126 return (other.keyOption_ != nullptr);
127 } else if (other.keyOption_ == nullptr) {
128 return false;
129 }
130 return (*keyOption_ < *other.keyOption_);
131 }
132
SubscribeKeyEvent(std::shared_ptr<KeyOption> keyOption,std::function<void (std::shared_ptr<KeyEvent>)> callback)133 int32_t KeyEventInputSubscribeManager::SubscribeKeyEvent(std::shared_ptr<KeyOption> keyOption,
134 std::function<void(std::shared_ptr<KeyEvent>)> callback)
135 {
136 CALL_DEBUG_ENTER;
137 CHKPR(keyOption, INVALID_SUBSCRIBE_ID);
138 CHKPR(callback, INVALID_SUBSCRIBE_ID);
139 std::set<int32_t> preKeys = keyOption->GetPreKeys();
140 if (preKeys.size() > PRE_KEYS_NUM) {
141 MMI_HILOGE("PreKeys number invalid");
142 return INVALID_SUBSCRIBE_ID;
143 }
144 MMI_HILOGI("PRE:[%{private}s],FINAL:%{private}d,KA:%{public}s,HT:%{public}d",
145 DumpSet(preKeys).c_str(), keyOption->GetFinalKey(),
146 (keyOption->IsFinalKeyDown() ? "down" : "up"), keyOption->GetFinalKeyDownDuration());
147
148 if (!MMIEventHdl.InitClient()) {
149 MMI_HILOGE("Client init failed");
150 return INVALID_SUBSCRIBE_ID;
151 }
152 std::lock_guard<std::mutex> guard(mtx_);
153 auto [tIter, isOk] = subscribeInfos_.emplace(keyOption, callback);
154 if (!isOk) {
155 MMI_HILOGW("Subscription is duplicated");
156 return tIter->GetSubscribeId();
157 }
158 int32_t ret = MMIEventHdl.SubscribeKeyEvent(*tIter);
159 if (ret != RET_OK) {
160 MMI_HILOGE("Subscribing key event failed");
161 subscribeInfos_.erase(tIter);
162 return ret;
163 }
164 MMI_HILOGI("The subscribeId:%{public}d, preKeys:[%{private}s], finalKey:%{private}d,"
165 "keyOption->isFinalKeyDown:%{public}s, keyOption->finalKeyDownDuration:%{public}d",
166 tIter->GetSubscribeId(), DumpSet(preKeys).c_str(), keyOption->GetFinalKey(),
167 keyOption->IsFinalKeyDown() ? "true" : "false", keyOption->GetFinalKeyDownDuration());
168 return tIter->GetSubscribeId();
169 }
170
UnsubscribeKeyEvent(int32_t subscribeId)171 int32_t KeyEventInputSubscribeManager::UnsubscribeKeyEvent(int32_t subscribeId)
172 {
173 CALL_INFO_TRACE;
174 if (subscribeId < 0) {
175 MMI_HILOGE("The subscribe id is less than 0");
176 return RET_ERR;
177 }
178
179 if (!MMIEventHdl.InitClient()) {
180 MMI_HILOGE("Client init failed");
181 return INVALID_SUBSCRIBE_ID;
182 }
183 std::lock_guard<std::mutex> guard(mtx_);
184 if (subscribeInfos_.empty()) {
185 MMI_HILOGE("The subscribe Infos is empty");
186 return RET_ERR;
187 }
188
189 for (auto it = subscribeInfos_.begin(); it != subscribeInfos_.end(); ++it) {
190 if (it->GetSubscribeId() == subscribeId) {
191 if (MMIEventHdl.UnsubscribeKeyEvent(subscribeId) != RET_OK) {
192 MMI_HILOGE("Leave, unsubscribe key event failed");
193 return RET_ERR;
194 }
195 subscribeInfos_.erase(it);
196 return RET_OK;
197 }
198 }
199 return RET_ERR;
200 }
201
SubscribeHotkey(std::shared_ptr<KeyOption> keyOption,std::function<void (std::shared_ptr<KeyEvent>)> callback)202 int32_t KeyEventInputSubscribeManager::SubscribeHotkey(std::shared_ptr<KeyOption> keyOption,
203 std::function<void(std::shared_ptr<KeyEvent>)> callback)
204 {
205 CALL_DEBUG_ENTER;
206 CHKPR(keyOption, INVALID_SUBSCRIBE_ID);
207 CHKPR(callback, INVALID_SUBSCRIBE_ID);
208 std::set<int32_t> preKeys = keyOption->GetPreKeys();
209 if (preKeys.size() > PRE_KEYS_NUM) {
210 MMI_HILOGE("PreKeys number invalid");
211 return INVALID_SUBSCRIBE_ID;
212 }
213 MMI_HILOGI("PRE:[%{private}s],FINAL:%{private}d,KA:%{public}s,HT:%{public}d",
214 DumpSet(preKeys).c_str(), keyOption->GetFinalKey(),
215 (keyOption->IsFinalKeyDown() ? "down" : "up"), keyOption->GetFinalKeyDownDuration());
216
217 if (!MMIEventHdl.InitClient()) {
218 MMI_HILOGE("Client init failed");
219 return INVALID_SUBSCRIBE_ID;
220 }
221
222 std::lock_guard<std::mutex> guard(mtx_);
223 auto [tIter, isOk] = subscribeInfos_.emplace(keyOption, callback);
224 if (!isOk) {
225 MMI_HILOGW("Subscription is duplicated");
226 return tIter->GetSubscribeId();
227 }
228 int32_t ret = MMIEventHdl.SubscribeHotkey(*tIter);
229 if (ret != RET_OK) {
230 MMI_HILOGE("SubscribeHotkey fail, error:%{public}d", ret);
231 subscribeInfos_.erase(tIter);
232 return ret;
233 }
234
235 MMI_HILOGI("The subscribeId:%{public}d, preKeys:%{private}s, finalKey:%{private}d,"
236 "keyOption->isFinalKeyDown:%{public}s, keyOption->finalKeyDownDuration:%{public}d",
237 tIter->GetSubscribeId(), DumpSet(preKeys).c_str(), keyOption->GetFinalKey(),
238 keyOption->IsFinalKeyDown() ? "true" : "false", keyOption->GetFinalKeyDownDuration());
239 return tIter->GetSubscribeId();
240 }
241
UnsubscribeHotkey(int32_t subscribeId)242 int32_t KeyEventInputSubscribeManager::UnsubscribeHotkey(int32_t subscribeId)
243 {
244 CALL_INFO_TRACE;
245 if (subscribeId < 0) {
246 MMI_HILOGE("Subscribe id is less than 0");
247 return RET_ERR;
248 }
249
250 if (!MMIEventHdl.InitClient()) {
251 MMI_HILOGE("Client init failed");
252 return INVALID_SUBSCRIBE_ID;
253 }
254
255 std::lock_guard<std::mutex> guard(mtx_);
256 if (subscribeInfos_.empty()) {
257 MMI_HILOGE("Subscribe Infos is empty");
258 return RET_ERR;
259 }
260
261 for (auto it = subscribeInfos_.begin(); it != subscribeInfos_.end(); ++it) {
262 if (it->GetSubscribeId() == subscribeId) {
263 if (MMIEventHdl.UnsubscribeHotkey(subscribeId) != RET_OK) {
264 MMI_HILOGE("UnsubscribeHotkey fail");
265 return RET_ERR;
266 }
267 subscribeInfos_.erase(it);
268 return RET_OK;
269 }
270 }
271 return RET_ERR;
272 }
273
SubscribeKeyMonitor(const KeyMonitorOption & keyOption,std::function<void (std::shared_ptr<KeyEvent>)> callback)274 int32_t KeyEventInputSubscribeManager::SubscribeKeyMonitor(
275 const KeyMonitorOption &keyOption,
276 std::function<void(std::shared_ptr<KeyEvent>)> callback)
277 {
278 CHKPR(callback, INVALID_SUBSCRIBE_ID);
279 std::lock_guard<std::mutex> guard(mtx_);
280 MonitorIdentity monitorId {
281 .key_ = keyOption.GetKey(),
282 .action_ = keyOption.GetAction(),
283 .isRepeat_ = keyOption.IsRepeat(),
284 };
285 auto iter = monitors_.find(monitorId);
286 if (iter == monitors_.end()) {
287 MMI_HILOGI("Subscribe key monitor(%{public}s) to server", monitorId.Dump().c_str());
288 int32_t ret = MMIEventHdl.SubscribeKeyMonitor(keyOption);
289 if (ret != RET_OK) {
290 MMI_HILOGE("SubscribeKeyMonitor fail, error:%{public}d", ret);
291 return ret;
292 }
293 auto [tIter, _] = monitors_.emplace(monitorId, std::map<int32_t, Monitor> {});
294 iter = tIter;
295 }
296 auto &monitors = iter->second;
297 auto [mIter, _] = monitors.emplace(
298 GenerateId(),
299 Monitor {
300 .callback_ = callback,
301 });
302 MMI_HILOGI("Subscribe key monitor(ID:%{public}d, %{public}s)", mIter->first, monitorId.Dump().c_str());
303 return mIter->first;
304 }
305
UnsubscribeKeyMonitor(int32_t subscriberId)306 void KeyEventInputSubscribeManager::UnsubscribeKeyMonitor(int32_t subscriberId)
307 {
308 std::lock_guard<std::mutex> guard(mtx_);
309 for (auto iter = monitors_.begin(); iter != monitors_.end(); ++iter) {
310 auto &monitorId = iter->first;
311 auto &monitors = iter->second;
312
313 auto tIter = monitors.find(subscriberId);
314 if (tIter == monitors.end()) {
315 continue;
316 }
317 MMI_HILOGI("Unsubscribe key monitor(ID:%{public}d, %{public}s)", subscriberId, monitorId.Dump().c_str());
318 monitors.erase(tIter);
319
320 if (monitors.empty()) {
321 MMI_HILOGI("Unsubscribe key monitor(%{public}s) from server", monitorId.Dump().c_str());
322 KeyMonitorOption keyOption {};
323 keyOption.SetKey(monitorId.key_);
324 keyOption.SetAction(monitorId.action_);
325 keyOption.SetRepeat(monitorId.isRepeat_);
326
327 auto ret = MMIEventHdl.UnsubscribeKeyMonitor(keyOption);
328 if (ret != RET_OK) {
329 MMI_HILOGE("UnsubscribeKeyMonitor fail, error:%{public}d", ret);
330 }
331 monitors_.erase(iter);
332 }
333 return;
334 }
335 MMI_HILOGI("No subscriber of key monitor with ID(%{public}d)", subscriberId);
336 }
337
OnSubscribeKeyEventCallback(std::shared_ptr<KeyEvent> event,int32_t subscribeId)338 int32_t KeyEventInputSubscribeManager::OnSubscribeKeyEventCallback(std::shared_ptr<KeyEvent> event,
339 int32_t subscribeId)
340 {
341 CHK_PID_AND_TID();
342 CHKPR(event, ERROR_NULL_POINTER);
343 if (subscribeId < 0) {
344 MMI_HILOGE("Leave, the subscribe id is less than 0");
345 return RET_ERR;
346 }
347
348 BytraceAdapter::StartBytrace(event, BytraceAdapter::TRACE_STOP, BytraceAdapter::KEY_SUBSCRIBE_EVENT);
349 std::shared_ptr<const KeyEventInputSubscribeManager::SubscribeKeyEventInfo> info =
350 GetSubscribeKeyEvent(subscribeId);
351 CHKPR(info, ERROR_NULL_POINTER);
352 auto callback = info->GetCallback();
353 if (!callback) {
354 MMI_HILOGE("Callback is null");
355 return RET_ERR;
356 }
357 callback(event);
358 MMI_HILOGD("Key event id:%{public}d, keyCode:%{private}d", subscribeId, event->GetKeyCode());
359 return RET_OK;
360 }
361
OnSubscribeKeyMonitor(std::shared_ptr<KeyEvent> event)362 int32_t KeyEventInputSubscribeManager::OnSubscribeKeyMonitor(std::shared_ptr<KeyEvent> event)
363 {
364 CHKPR(event, RET_ERR);
365 auto callbacks = CheckKeyMonitors(event);
366 std::for_each(callbacks.cbegin(), callbacks.cend(), [event](auto callback) {
367 if (callback) {
368 callback(event);
369 }
370 });
371 return RET_OK;
372 }
373
OnConnected()374 void KeyEventInputSubscribeManager::OnConnected()
375 {
376 CALL_DEBUG_ENTER;
377 std::lock_guard<std::mutex> guard(mtx_);
378 for (const auto& subscriberInfo : subscribeInfos_) {
379 if (MMIEventHdl.SubscribeKeyEvent(subscriberInfo) != RET_OK) {
380 MMI_HILOGE("Subscribe key event failed");
381 }
382 }
383 for (const auto &[monitorId, _] : monitors_) {
384 MMI_HILOGI("Subscribe key monitor(%{public}s) to server", monitorId.Dump().c_str());
385 KeyMonitorOption keyOption {};
386 keyOption.SetKey(monitorId.key_);
387 keyOption.SetAction(monitorId.action_);
388 keyOption.SetRepeat(monitorId.isRepeat_);
389
390 auto ret = MMIEventHdl.SubscribeKeyMonitor(keyOption);
391 if (ret != RET_OK) {
392 MMI_HILOGE("SubscribeKeyMonitor fail, error:%{public}d", ret);
393 }
394 }
395 }
396
397 std::shared_ptr<const KeyEventInputSubscribeManager::SubscribeKeyEventInfo>
GetSubscribeKeyEvent(int32_t id)398 KeyEventInputSubscribeManager::GetSubscribeKeyEvent(int32_t id)
399 {
400 if (id < 0) {
401 MMI_HILOGE("Invalid input param id:%{public}d", id);
402 return nullptr;
403 }
404 std::lock_guard<std::mutex> guard(mtx_);
405 for (const auto &subscriber : subscribeInfos_) {
406 if (subscriber.GetSubscribeId() == id) {
407 return std::make_shared<const SubscribeKeyEventInfo>(subscriber);
408 }
409 }
410 return nullptr;
411 }
412
GenerateId()413 int32_t KeyEventInputSubscribeManager::GenerateId()
414 {
415 return KeyEventInputSubscribeManager::subscribeIdManager_++;
416 }
417
CheckKeyMonitors(std::shared_ptr<KeyEvent> event)418 std::vector<std::function<void(std::shared_ptr<KeyEvent>)>> KeyEventInputSubscribeManager::CheckKeyMonitors(
419 std::shared_ptr<KeyEvent> event)
420 {
421 std::vector<std::function<void(std::shared_ptr<KeyEvent>)>> keyMonitors;
422 std::lock_guard<std::mutex> guard(mtx_);
423
424 for (const auto &[monitorId, monitors] : monitors_) {
425 if (!monitorId.Want(event)) {
426 continue;
427 }
428 std::for_each(monitors.cbegin(), monitors.cend(), [&](const auto &item) {
429 keyMonitors.emplace_back(item.second.callback_);
430 });
431 }
432 return keyMonitors;
433 }
434 } // namespace MMI
435 } // namespace OHOS
436