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