• 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 
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