• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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_subscriber_handler.h"
17 
18 #include "app_state_observer.h"
19 #include "bytrace_adapter.h"
20 #include "define_multimodal.h"
21 #include "dfx_hisysevent.h"
22 #include "error_multimodal.h"
23 #include "input_event_data_transformation.h"
24 #include "input_event_handler.h"
25 #include "net_packet.h"
26 #include "proto.h"
27 #include "timer_manager.h"
28 #include "util_ex.h"
29 
30 namespace OHOS {
31 namespace MMI {
32 namespace {
33 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "KeySubscriberHandler" };
34 constexpr uint32_t MAX_PRE_KEY_COUNT = 4;
35 constexpr int32_t REMOVE_OBSERVER = -2;
36 constexpr int32_t UNOBSERVED = -1;
37 constexpr int32_t ACTIVE_EVENT = 2;
38 } // namespace
39 
40 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)41 void KeySubscriberHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
42 {
43     CHKPV(keyEvent);
44     if (OnSubscribeKeyEvent(keyEvent)) {
45         MMI_HILOGD("Subscribe keyEvent filter success. keyCode:%{public}d", keyEvent->GetKeyCode());
46         BytraceAdapter::StartBytrace(keyEvent, BytraceAdapter::KEY_SUBSCRIBE_EVENT);
47         return;
48     }
49     CHKPV(nextHandler_);
50     nextHandler_->HandleKeyEvent(keyEvent);
51 }
52 #endif // OHOS_BUILD_ENABLE_KEYBOARD
53 
54 #ifdef OHOS_BUILD_ENABLE_POINTER
HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)55 void KeySubscriberHandler::HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)
56 {
57     CHKPV(pointerEvent);
58     CHKPV(nextHandler_);
59     nextHandler_->HandlePointerEvent(pointerEvent);
60 }
61 #endif // OHOS_BUILD_ENABLE_POINTER
62 
63 #ifdef OHOS_BUILD_ENABLE_TOUCH
HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)64 void KeySubscriberHandler::HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)
65 {
66     CHKPV(pointerEvent);
67     CHKPV(nextHandler_);
68     nextHandler_->HandleTouchEvent(pointerEvent);
69 }
70 #endif // OHOS_BUILD_ENABLE_TOUCH
71 
SubscribeKeyEvent(SessionPtr sess,int32_t subscribeId,std::shared_ptr<KeyOption> keyOption)72 int32_t KeySubscriberHandler::SubscribeKeyEvent(
73     SessionPtr sess, int32_t subscribeId, std::shared_ptr<KeyOption> keyOption)
74 {
75     CALL_DEBUG_ENTER;
76     if (subscribeId < 0) {
77         MMI_HILOGE("Invalid subscribe");
78         return RET_ERR;
79     }
80     CHKPR(sess, ERROR_NULL_POINTER);
81     CHKPR(keyOption, ERROR_NULL_POINTER);
82     uint32_t preKeySize = keyOption->GetPreKeys().size();
83     if (preKeySize > MAX_PRE_KEY_COUNT) {
84         MMI_HILOGE("Leave, preKeySize:%{public}u", preKeySize);
85         return RET_ERR;
86     }
87 
88     for (const auto &keyCode : keyOption->GetPreKeys()) {
89         MMI_HILOGD("keyOption->prekey:%{public}d", keyCode);
90     }
91     MMI_HILOGI("SubscribeId:%{public}d, finalKey:%{public}d,"
92         "isFinalKeyDown:%{public}s, finalKeyDownDuration:%{public}d, pid:%{public}d",
93         subscribeId, keyOption->GetFinalKey(), keyOption->IsFinalKeyDown() ? "true" : "false",
94         keyOption->GetFinalKeyDownDuration(), sess->GetPid());
95     auto subscriber = std::make_shared<Subscriber>(subscribeId, sess, keyOption);
96     AddSubscriber(subscriber, keyOption);
97     InitSessionDeleteCallback();
98     return RET_OK;
99 }
100 
UnsubscribeKeyEvent(SessionPtr sess,int32_t subscribeId)101 int32_t KeySubscriberHandler::UnsubscribeKeyEvent(SessionPtr sess, int32_t subscribeId)
102 {
103     CALL_INFO_TRACE;
104     CHKPR(sess, ERROR_NULL_POINTER);
105     MMI_HILOGI("SubscribeId:%{public}d, pid:%{public}d", subscribeId, sess->GetPid());
106     return RemoveSubscriber(sess, subscribeId);
107 }
108 
RemoveSubscriber(SessionPtr sess,int32_t subscribeId)109 int32_t KeySubscriberHandler::RemoveSubscriber(SessionPtr sess, int32_t subscribeId)
110 {
111     CALL_DEBUG_ENTER;
112     for (auto iter = subscriberMap_.begin(); iter != subscriberMap_.end(); iter++) {
113         auto &subscribers = iter->second;
114         for (auto it = subscribers.begin(); it != subscribers.end(); it++) {
115             if ((*it)->id_ == subscribeId && (*it)->sess_ == sess) {
116                 ClearTimer(*it);
117                 auto option = (*it)->keyOption_;
118                 CHKPR(option, ERROR_NULL_POINTER);
119                 MMI_HILOGI("SubscribeId:%{public}d, finalKey:%{public}d, isFinalKeyDown:%{public}s,"
120                     "finalKeyDownDuration:%{public}d, pid:%{public}d", subscribeId, option->GetFinalKey(),
121                     option->IsFinalKeyDown() ? "true" : "false", option->GetFinalKeyDownDuration(), sess->GetPid());
122                 subscribers.erase(it);
123                 return RET_OK;
124             }
125         }
126     }
127     return RET_ERR;
128 }
129 
AddSubscriber(std::shared_ptr<Subscriber> subscriber,std::shared_ptr<KeyOption> option)130 void KeySubscriberHandler::AddSubscriber(std::shared_ptr<Subscriber> subscriber,
131     std::shared_ptr<KeyOption> option)
132 {
133     CALL_DEBUG_ENTER;
134     CHKPV(subscriber);
135     CHKPV(option);
136     PrintKeyOption(option);
137     for (auto &iter : subscriberMap_) {
138         if (IsEqualKeyOption(option, iter.first)) {
139             MMI_HILOGI("add subscriber Id:%{public}d", subscriber->id_);
140             iter.second.push_back(std::move(subscriber));
141             MMI_HILOGI("subscriber size:%{public}zu", iter.second.size());
142             return;
143         }
144     }
145     MMI_HILOGI("add subscriber Id:%{public}d", subscriber->id_);
146     subscriberMap_[option] = {subscriber};
147 }
148 
IsEqualKeyOption(std::shared_ptr<KeyOption> newOption,std::shared_ptr<KeyOption> oldOption)149 bool KeySubscriberHandler::IsEqualKeyOption(std::shared_ptr<KeyOption> newOption,
150     std::shared_ptr<KeyOption> oldOption)
151 {
152     CALL_DEBUG_ENTER;
153     CHKPF(newOption);
154     CHKPF(oldOption);
155     if (!IsEqualPreKeys(newOption->GetPreKeys(), oldOption->GetPreKeys())) {
156         MMI_HILOGD("pre key not match");
157         return false;
158     }
159     if (newOption->GetFinalKey() != oldOption->GetFinalKey()) {
160         MMI_HILOGD("final key not match");
161         return false;
162     }
163     if (newOption->IsFinalKeyDown() != oldOption->IsFinalKeyDown()) {
164         MMI_HILOGD("is final key down not match");
165         return false;
166     }
167     if (newOption->GetFinalKeyDownDuration() != oldOption->GetFinalKeyDownDuration()) {
168         MMI_HILOGD("final key down duration not match");
169         return false;
170     }
171     if (newOption->GetFinalKeyUpDelay() != oldOption->GetFinalKeyUpDelay()) {
172         MMI_HILOGD("is final key up delay not match");
173         return false;
174     }
175     MMI_HILOGD("key option match");
176     return true;
177 }
178 
GetForegroundPids(std::set<int32_t> & pids)179 void KeySubscriberHandler::GetForegroundPids(std::set<int32_t> &pids)
180 {
181     CALL_DEBUG_ENTER;
182     std::vector<AppExecFwk::AppStateData> list = APP_OBSERVER_MGR->GetForegroundAppData();
183     for (auto iter = list.begin(); iter != list.end(); iter++) {
184         MMI_HILOGD("foreground process pid:%{public}d", (*iter).pid);
185         pids.insert((*iter).pid);
186     }
187 }
188 
EnableCombineKey(bool enable)189 int32_t KeySubscriberHandler::EnableCombineKey(bool enable)
190 {
191     enableCombineKey_ = enable;
192     MMI_HILOGI("Enable combineKey is successful in subscribe handler, enable:%{public}d", enable);
193     return RET_OK;
194 }
195 
IsEnableCombineKey(const std::shared_ptr<KeyEvent> keyEvent)196 bool KeySubscriberHandler::IsEnableCombineKey(const std::shared_ptr<KeyEvent> keyEvent)
197 {
198     CHKPF(keyEvent);
199     if (enableCombineKey_) {
200         return true;
201     }
202     if (keyEvent->GetKeyCode() == KeyEvent::KEYCODE_POWER && keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_UP) {
203         auto items = keyEvent->GetKeyItems();
204         if (items.size() != 1) {
205             return enableCombineKey_;
206         }
207         return true;
208     }
209     if (keyEvent->GetKeyCode() == KeyEvent::KEYCODE_L) {
210         for (const auto &item : keyEvent->GetKeyItems()) {
211             int32_t keyCode = item.GetKeyCode();
212             if (keyCode != KeyEvent::KEYCODE_L && keyCode != KeyEvent::KEYCODE_META_LEFT &&
213                 keyCode != KeyEvent::KEYCODE_META_RIGHT) {
214                 return enableCombineKey_;
215             }
216         }
217         return true;
218     }
219     return enableCombineKey_;
220 }
221 
OnSubscribeKeyEvent(std::shared_ptr<KeyEvent> keyEvent)222 bool KeySubscriberHandler::OnSubscribeKeyEvent(std::shared_ptr<KeyEvent> keyEvent)
223 {
224     CHKPF(keyEvent);
225     if (!IsEnableCombineKey(keyEvent)) {
226         MMI_HILOGI("Combine key is taken over in subscribe keyEvent");
227         return false;
228     }
229     if (IsRepeatedKeyEvent(keyEvent)) {
230         MMI_HILOGD("Repeat KeyEvent, skip");
231         return true;
232     }
233     keyEvent_ = KeyEvent::Clone(keyEvent);
234     int32_t keyAction = keyEvent->GetKeyAction();
235     MMI_HILOGD("keyCode:%{public}d, keyAction:%{public}s", keyEvent->GetKeyCode(),
236         KeyEvent::ActionToString(keyAction));
237     for (const auto &keyCode : keyEvent->GetPressedKeys()) {
238         MMI_HILOGD("Pressed KeyCode:%{public}d", keyCode);
239     }
240     bool handled = false;
241     if (keyAction == KeyEvent::KEY_ACTION_DOWN) {
242         handled = HandleKeyDown(keyEvent);
243     } else if (keyAction == KeyEvent::KEY_ACTION_UP) {
244         hasEventExecuting_ = false;
245         handled = HandleKeyUp(keyEvent);
246     } else if (keyAction == KeyEvent::KEY_ACTION_CANCEL) {
247         hasEventExecuting_ = false;
248         handled = HandleKeyCancel(keyEvent);
249     } else {
250         MMI_HILOGW("keyAction exception");
251     }
252     return handled;
253 }
254 
OnSessionDelete(SessionPtr sess)255 void KeySubscriberHandler::OnSessionDelete(SessionPtr sess)
256 {
257     CALL_DEBUG_ENTER;
258     CHKPV(sess);
259     for (auto iter = subscriberMap_.begin(); iter != subscriberMap_.end(); iter++) {
260         auto &subscribers = iter->second;
261         for (auto it = subscribers.begin(); it != subscribers.end();) {
262             if ((*it)->sess_ == sess) {
263                 ClearTimer(*it);
264                 subscribers.erase(it++);
265                 continue;
266             }
267             ++it;
268         }
269     }
270 }
271 
IsPreKeysMatch(const std::set<int32_t> & preKeys,const std::vector<int32_t> & pressedKeys) const272 bool KeySubscriberHandler::IsPreKeysMatch(const std::set<int32_t> &preKeys,
273                                           const std::vector<int32_t> &pressedKeys) const
274 {
275     if (preKeys.size() == 0) {
276         return true;
277     }
278 
279     if (preKeys.size() != pressedKeys.size()) {
280         return false;
281     }
282 
283     for (const auto &pressedKey : pressedKeys) {
284         auto it = std::find(preKeys.begin(), preKeys.end(), pressedKey);
285         if (it == preKeys.end()) {
286             return false;
287         }
288     }
289 
290     return true;
291 }
292 
IsEqualPreKeys(const std::set<int32_t> & preKeys,const std::set<int32_t> & pressedKeys)293 bool KeySubscriberHandler::IsEqualPreKeys(const std::set<int32_t> &preKeys, const std::set<int32_t> &pressedKeys)
294 {
295     if (preKeys.size() != pressedKeys.size()) {
296         MMI_HILOGD("pre key size not equal");
297         return false;
298     }
299 
300     for (const auto &pressedKey : pressedKeys) {
301         auto it = std::find(preKeys.begin(), preKeys.end(), pressedKey);
302         if (it == preKeys.end()) {
303             return false;
304         }
305     }
306     MMI_HILOGD("equal prekeys");
307     return true;
308 }
309 
IsMatchForegroundPid(std::list<std::shared_ptr<Subscriber>> subs,std::set<int32_t> foregroundPids)310 bool KeySubscriberHandler::IsMatchForegroundPid(std::list<std::shared_ptr<Subscriber>> subs,
311     std::set<int32_t> foregroundPids)
312 {
313     CALL_DEBUG_ENTER;
314     isForegroundExits_ = false;
315     foregroundPids_.clear();
316     for (const auto &item : subs) {
317         CHKPF(item);
318         auto sess = item->sess_;
319         CHKPF(sess);
320         if (foregroundPids.find(sess->GetPid()) != foregroundPids.end()) {
321             MMI_HILOGD("subscriber foregroundPid:%{public}d", sess->GetPid());
322             foregroundPids_.insert(sess->GetPid());
323             isForegroundExits_ = true;
324         }
325     }
326     MMI_HILOGD("isForegroundExits_:%{public}d, foregroundPids:%{public}zu",
327         isForegroundExits_, foregroundPids_.size());
328     return isForegroundExits_;
329 }
330 
NotifyKeyDownSubscriber(const std::shared_ptr<KeyEvent> & keyEvent,std::shared_ptr<KeyOption> keyOption,std::list<std::shared_ptr<Subscriber>> & subscribers,bool & handled)331 void KeySubscriberHandler::NotifyKeyDownSubscriber(const std::shared_ptr<KeyEvent> &keyEvent,
332     std::shared_ptr<KeyOption> keyOption, std::list<std::shared_ptr<Subscriber>> &subscribers, bool &handled)
333 {
334     CALL_DEBUG_ENTER;
335     CHKPV(keyEvent);
336     CHKPV(keyOption);
337     MMI_HILOGI("notify key down subscribers size:%{public}zu", subscribers.size());
338     if (keyOption->GetFinalKeyDownDuration() <= 0) {
339         NotifyKeyDownRightNow(keyEvent, subscribers, handled);
340     } else {
341         NotifyKeyDownDelay(keyEvent, subscribers, handled);
342     }
343 }
NotifyKeyDownRightNow(const std::shared_ptr<KeyEvent> & keyEvent,std::list<std::shared_ptr<Subscriber>> & subscribers,bool & handled)344 void KeySubscriberHandler::NotifyKeyDownRightNow(const std::shared_ptr<KeyEvent> &keyEvent,
345     std::list<std::shared_ptr<Subscriber>> &subscribers, bool &handled)
346 {
347     CALL_DEBUG_ENTER;
348     for (auto &subscriber : subscribers) {
349         CHKPC(subscriber);
350         auto sess = subscriber->sess_;
351         CHKPC(sess);
352         if (!isForegroundExits_ || keyEvent->GetKeyCode() == KeyEvent::KEYCODE_POWER ||
353             foregroundPids_.find(sess->GetPid()) != foregroundPids_.end()) {
354             MMI_HILOGD("keyOption->GetFinalKeyDownDuration() <= 0");
355             NotifySubscriber(keyEvent, subscriber);
356             handled = true;
357         }
358     }
359 }
360 
NotifyKeyDownDelay(const std::shared_ptr<KeyEvent> & keyEvent,std::list<std::shared_ptr<Subscriber>> & subscribers,bool & handled)361 void KeySubscriberHandler::NotifyKeyDownDelay(const std::shared_ptr<KeyEvent> &keyEvent,
362     std::list<std::shared_ptr<Subscriber>> &subscribers, bool &handled)
363 {
364     CALL_DEBUG_ENTER;
365     for (auto &subscriber : subscribers) {
366         CHKPC(subscriber);
367         auto sess = subscriber->sess_;
368         CHKPC(sess);
369         if (!isForegroundExits_ || keyEvent->GetKeyCode() == KeyEvent::KEYCODE_POWER ||
370             foregroundPids_.find(sess->GetPid()) != foregroundPids_.end()) {
371             MMI_HILOGD("add timer");
372             if (!AddTimer(subscriber, keyEvent)) {
373                 MMI_HILOGE("add time failed, subscriberId:%{public}d", subscriber->id_);
374                 continue;
375             }
376             handled = true;
377         }
378     }
379 }
380 
NotifyKeyUpSubscriber(const std::shared_ptr<KeyEvent> & keyEvent,std::list<std::shared_ptr<Subscriber>> subscribers,bool & handled)381 void KeySubscriberHandler::NotifyKeyUpSubscriber(const std::shared_ptr<KeyEvent> &keyEvent,
382     std::list<std::shared_ptr<Subscriber>> subscribers, bool &handled)
383 {
384     CALL_DEBUG_ENTER;
385     MMI_HILOGD("subscribers size:%{public}zu", subscribers.size());
386     for (auto &subscriber : subscribers) {
387         CHKPC(subscriber);
388         auto sess = subscriber->sess_;
389         CHKPC(sess);
390         if (!isForegroundExits_ || foregroundPids_.find(sess->GetPid()) != foregroundPids_.end()) {
391             HandleKeyUpWithDelay(keyEvent, subscriber);
392             handled = true;
393         }
394     }
395 }
396 
NotifySubscriber(std::shared_ptr<KeyEvent> keyEvent,const std::shared_ptr<Subscriber> & subscriber)397 void KeySubscriberHandler::NotifySubscriber(std::shared_ptr<KeyEvent> keyEvent,
398     const std::shared_ptr<Subscriber> &subscriber)
399 {
400     CALL_DEBUG_ENTER;
401     CHKPV(keyEvent);
402     CHKPV(subscriber);
403     auto udsServerPtr = InputHandler->GetUDSServer();
404     CHKPV(udsServerPtr);
405     if (keyEvent->GetKeyCode() == KeyEvent::KEYCODE_POWER) {
406         DfxHisysevent::ReportPowerInfo(keyEvent, OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC);
407     }
408     SubscriberNotifyNap(subscriber);
409     NetPacket pkt(MmiMessageId::ON_SUBSCRIBE_KEY);
410     InputEventDataTransformation::KeyEventToNetPacket(keyEvent, pkt);
411     auto sess = subscriber->sess_;
412     CHKPV(sess);
413     int32_t fd = sess->GetFd();
414     pkt << fd << subscriber->id_;
415     MMI_HILOGI("Notify subscriber id:%{public}d, keycode:%{public}d, pid:%{public}d",
416         subscriber->id_, keyEvent->GetKeyCode(), sess->GetPid());
417     if (pkt.ChkRWError()) {
418         MMI_HILOGE("Packet write dispatch subscriber failed");
419         return;
420     }
421     if (!udsServerPtr->SendMsg(fd, pkt)) {
422         MMI_HILOGE("Leave, server dispatch subscriber failed");
423         return;
424     }
425 }
426 
AddTimer(const std::shared_ptr<Subscriber> & subscriber,const std::shared_ptr<KeyEvent> & keyEvent)427 bool KeySubscriberHandler::AddTimer(const std::shared_ptr<Subscriber> &subscriber,
428                                     const std::shared_ptr<KeyEvent> &keyEvent)
429 {
430     CALL_DEBUG_ENTER;
431     CHKPF(keyEvent);
432     CHKPF(subscriber);
433 
434     if (subscriber->timerId_ >= 0) {
435         MMI_HILOGW("Leave, timer already added, it may have been added by injection");
436         return true;
437     }
438 
439     auto &keyOption = subscriber->keyOption_;
440     bool isKeyDown = keyOption->IsFinalKeyDown();
441     int32_t duration = isKeyDown ? keyOption->GetFinalKeyDownDuration() : keyOption->GetFinalKeyUpDelay();
442     if (duration <= 0) {
443         MMI_HILOGE("Leave, duration <= 0");
444         return true;
445     }
446 
447     if (!CloneKeyEvent(keyEvent)) {
448         MMI_HILOGE("Leave, cloneKeyEvent failed");
449         return false;
450     }
451 
452     std::weak_ptr<Subscriber> weakSubscriber = subscriber;
453     subscriber->timerId_ = TimerMgr->AddTimer(duration, 1, [this, weakSubscriber] () {
454         MMI_HILOGD("Timer callback");
455         auto subscriber = weakSubscriber.lock();
456         CHKPV(subscriber);
457         OnTimer(subscriber);
458     });
459 
460     if (subscriber->timerId_ < 0) {
461         MMI_HILOGE("Leave, addTimer failed");
462         return false;
463     }
464     subscriber->keyEvent_ = keyEvent_;
465     hasEventExecuting_ = true;
466     MMI_HILOGD("Leave, add timer success, subscribeId:%{public}d,"
467         "duration:%{public}d, timerId:%{public}d",
468         subscriber->id_, duration, subscriber->timerId_);
469     return true;
470 }
471 
ClearSubscriberTimer(std::list<std::shared_ptr<Subscriber>> subscribers)472 void KeySubscriberHandler::ClearSubscriberTimer(std::list<std::shared_ptr<Subscriber>> subscribers)
473 {
474     CALL_DEBUG_ENTER;
475     MMI_HILOGD("clear subscriber timer size:%{public}zu", subscribers.size());
476     for (auto &subscriber : subscribers) {
477         CHKPC(subscriber);
478         ClearTimer(subscriber);
479     }
480 }
481 
ClearTimer(const std::shared_ptr<Subscriber> & subscriber)482 void KeySubscriberHandler::ClearTimer(const std::shared_ptr<Subscriber> &subscriber)
483 {
484     CALL_DEBUG_ENTER;
485     CHKPV(subscriber);
486 
487     if (subscriber->timerId_ < 0) {
488         MMI_HILOGD("Leave, subscribeId:%{public}d, null timerId < 0", subscriber->id_);
489         return;
490     }
491 
492     TimerMgr->RemoveTimer(subscriber->timerId_);
493     auto timerId = subscriber->timerId_;
494     subscriber->keyEvent_.reset();
495     subscriber->timerId_ = -1;
496     hasEventExecuting_ = false;
497     MMI_HILOGD("subscribeId:%{public}d, timerId:%{public}d", subscriber->id_, timerId);
498 }
499 
OnTimer(const std::shared_ptr<Subscriber> subscriber)500 void KeySubscriberHandler::OnTimer(const std::shared_ptr<Subscriber> subscriber)
501 {
502     CALL_DEBUG_ENTER;
503     CHKPV(subscriber);
504     subscriber->timerId_ = -1;
505     if (subscriber->keyEvent_ == nullptr) {
506         MMI_HILOGE("Leave, subscriber->keyEvent is nullptr, subscribeId:%{public}d", subscriber->id_);
507         return;
508     }
509 
510     NotifySubscriber(subscriber->keyEvent_, subscriber);
511     subscriber->keyEvent_.reset();
512     MMI_HILOGD("subscribeId:%{public}d", subscriber->id_);
513 }
514 
InitSessionDeleteCallback()515 bool KeySubscriberHandler::InitSessionDeleteCallback()
516 {
517     CALL_DEBUG_ENTER;
518     if (callbackInitialized_) {
519         MMI_HILOGD("Session delete callback has already been initialized");
520         return true;
521     }
522     auto udsServerPtr = InputHandler->GetUDSServer();
523     CHKPF(udsServerPtr);
524     std::function<void(SessionPtr)> callback =
525         std::bind(&KeySubscriberHandler::OnSessionDelete, this, std::placeholders::_1);
526     udsServerPtr->AddSessionDeletedCallback(callback);
527     callbackInitialized_ = true;
528     return true;
529 }
530 
HandleKeyDown(const std::shared_ptr<KeyEvent> & keyEvent)531 bool KeySubscriberHandler::HandleKeyDown(const std::shared_ptr<KeyEvent> &keyEvent)
532 {
533     CALL_DEBUG_ENTER;
534     CHKPF(keyEvent);
535     bool handled = false;
536     auto keyCode = keyEvent->GetKeyCode();
537     std::vector<int32_t> pressedKeys = keyEvent->GetPressedKeys();
538     RemoveKeyCode(keyCode, pressedKeys);
539     std::set<int32_t> pids;
540     GetForegroundPids(pids);
541     MMI_HILOGI("foreground pid size:%{public}zu", pids.size());
542     for (auto &iter : subscriberMap_) {
543         auto keyOption = iter.first;
544         auto subscribers = iter.second;
545         PrintKeyOption(keyOption);
546         IsMatchForegroundPid(subscribers, pids);
547         if (!keyOption->IsFinalKeyDown()) {
548             MMI_HILOGD("!keyOption->IsFinalKeyDown()");
549             continue;
550         }
551         if (keyCode != keyOption->GetFinalKey()) {
552             MMI_HILOGD("keyCode != keyOption->GetFinalKey()");
553             ClearSubscriberTimer(subscribers);
554             continue;
555         }
556         if (!IsPreKeysMatch(keyOption->GetPreKeys(), pressedKeys)) {
557             MMI_HILOGD("preKeysMatch failed");
558             ClearSubscriberTimer(subscribers);
559             continue;
560         }
561         NotifyKeyDownSubscriber(keyEvent, keyOption, subscribers, handled);
562     }
563     MMI_HILOGD("Handle key down:%{public}s", handled ? "true" : "false");
564     return handled;
565 }
566 
SubscriberNotifyNap(const std::shared_ptr<Subscriber> subscriber)567 void KeySubscriberHandler::SubscriberNotifyNap(const std::shared_ptr<Subscriber> subscriber)
568 {
569     CALL_DEBUG_ENTER;
570     CHKPV(subscriber);
571     int32_t state = NapProcess::GetInstance()->GetNapClientPid();
572     if (state == REMOVE_OBSERVER || state == UNOBSERVED) {
573         MMI_HILOGW("nap client status:%{public}d", state);
574         return;
575     }
576 
577     auto sess = subscriber->sess_;
578     CHKPV(sess);
579     OHOS::MMI::NapProcess::NapStatusData napData;
580     napData.pid = sess->GetPid();
581     napData.uid = sess->GetUid();
582     napData.bundleName = sess->GetProgramName();
583     if (NapProcess::GetInstance()->IsNeedNotify(napData)) {
584         int32_t syncState = ACTIVE_EVENT;
585         NapProcess::GetInstance()->AddMmiSubscribedEventData(napData, syncState);
586         NapProcess::GetInstance()->NotifyBundleName(napData, syncState);
587     }
588 }
589 
HandleKeyUp(const std::shared_ptr<KeyEvent> & keyEvent)590 bool KeySubscriberHandler::HandleKeyUp(const std::shared_ptr<KeyEvent> &keyEvent)
591 {
592     CALL_DEBUG_ENTER;
593     CHKPF(keyEvent);
594     bool handled = false;
595     auto keyCode = keyEvent->GetKeyCode();
596     std::vector<int32_t> pressedKeys = keyEvent->GetPressedKeys();
597     RemoveKeyCode(keyCode, pressedKeys);
598     std::set<int32_t> pids;
599     GetForegroundPids(pids);
600     for (auto &iter : subscriberMap_) {
601         auto keyOption = iter.first;
602         auto subscribers = iter.second;
603         PrintKeyOption(keyOption);
604         IsMatchForegroundPid(subscribers, pids);
605         if (keyOption->IsFinalKeyDown()) {
606             MMI_HILOGD("keyOption->IsFinalKeyDown()");
607             ClearSubscriberTimer(subscribers);
608             continue;
609         }
610         if (keyCode != keyOption->GetFinalKey()) {
611             MMI_HILOGD("keyCode != keyOption->GetFinalKey()");
612             continue;
613         }
614         if (!IsPreKeysMatch(keyOption->GetPreKeys(), pressedKeys)) {
615             MMI_HILOGD("PreKeysMatch failed");
616             continue;
617         }
618         if (!IsNotifyPowerKeySubsciber(keyOption->GetFinalKey(), pressedKeys)) {
619             MMI_HILOGD("In special case, subscriber are not notified");
620             continue;
621         }
622         auto duration = keyOption->GetFinalKeyDownDuration();
623         if (duration <= 0) {
624             NotifyKeyUpSubscriber(keyEvent, subscribers, handled);
625             continue;
626         }
627         std::optional<KeyEvent::KeyItem> keyItem = keyEvent->GetKeyItem();
628         CHK_KEY_ITEM(keyItem);
629         auto upTime = keyEvent->GetActionTime();
630         auto downTime = keyItem->GetDownTime();
631         if (upTime - downTime >= (static_cast<int64_t>(duration) * 1000)) {
632             MMI_HILOGE("upTime - downTime >= duration");
633             continue;
634         }
635         NotifyKeyUpSubscriber(keyEvent, subscribers, handled);
636     }
637     MMI_HILOGD("Handle key up:%{public}s", handled ? "true" : "false");
638     return handled;
639 }
640 
HandleKeyCancel(const std::shared_ptr<KeyEvent> & keyEvent)641 bool KeySubscriberHandler::HandleKeyCancel(const std::shared_ptr<KeyEvent> &keyEvent)
642 {
643     CALL_DEBUG_ENTER;
644     CHKPF(keyEvent);
645     for (auto &iter : subscriberMap_) {
646         auto keyOption = iter.first;
647         auto subscribers = iter.second;
648         for (auto &subscriber : subscribers) {
649             PrintKeyUpLog(subscriber);
650             ClearTimer(subscriber);
651         }
652     }
653     return false;
654 }
655 
IsKeyEventSubscribed(int32_t keyCode,int32_t trrigerType)656 bool KeySubscriberHandler::IsKeyEventSubscribed(int32_t keyCode, int32_t trrigerType)
657 {
658     CALL_DEBUG_ENTER;
659     for (const auto &iter : subscriberMap_) {
660         auto keyOption = iter.first;
661         auto subscribers = iter.second;
662         MMI_HILOGD("keyOption->finalKey:%{public}d, keyOption->isFinalKeyDown:%{public}s, "
663             "keyOption->finalKeyDownDuration:%{public}d",
664             keyOption->GetFinalKey(), keyOption->IsFinalKeyDown() ? "true" : "false",
665             keyOption->GetFinalKeyDownDuration());
666         int32_t keyAction = KeyEvent::KEY_ACTION_UP;
667         if (keyOption->IsFinalKeyDown()) {
668             MMI_HILOGD("keyOption is final key down");
669             keyAction = KeyEvent::KEY_ACTION_DOWN;
670         }
671         if (keyCode == keyOption->GetFinalKey() && trrigerType == keyAction && subscribers.size() > 0) {
672             MMI_HILOGD("current key event is subscribed.");
673             return true;
674         }
675     }
676     return false;
677 }
678 
CloneKeyEvent(std::shared_ptr<KeyEvent> keyEvent)679 bool KeySubscriberHandler::CloneKeyEvent(std::shared_ptr<KeyEvent> keyEvent)
680 {
681     CHKPF(keyEvent);
682     if (keyEvent_ == nullptr) {
683         MMI_HILOGW("keyEvent_ is nullptr");
684         keyEvent_ = KeyEvent::Clone(keyEvent);
685     }
686     CHKPF(keyEvent_);
687     return true;
688 }
689 
RemoveKeyCode(int32_t keyCode,std::vector<int32_t> & keyCodes)690 void KeySubscriberHandler::RemoveKeyCode(int32_t keyCode, std::vector<int32_t> &keyCodes)
691 {
692     for (auto it = keyCodes.begin(); it != keyCodes.end(); ++it) {
693         if (*it == keyCode) {
694             keyCodes.erase(it);
695             return;
696         }
697     }
698 }
699 
IsRepeatedKeyEvent(std::shared_ptr<KeyEvent> keyEvent)700 bool KeySubscriberHandler::IsRepeatedKeyEvent(std::shared_ptr<KeyEvent> keyEvent)
701 {
702     CHKPF(keyEvent);
703     if (!hasEventExecuting_) {
704         return false;
705     }
706 
707     if (keyEvent->GetKeyCode() != keyEvent_->GetKeyCode()) {
708         return false;
709     }
710 
711     if (keyEvent->GetKeyAction() != keyEvent_->GetKeyAction()) {
712         return false;
713     }
714 
715     if (keyEvent->GetKeyItems().size() != keyEvent_->GetKeyItems().size()) {
716         return false;
717     }
718 
719     for (const auto &item : keyEvent->GetKeyItems()) {
720         int32_t keyCode = item.GetKeyCode();
721         bool findResult = false;
722         for (const auto &item1 : keyEvent_->GetKeyItems()) {
723             if (keyCode == item1.GetKeyCode()) {
724                 findResult = true;
725                 break;
726             }
727         }
728         if (!findResult) {
729             return false;
730         }
731     }
732     return true;
733 }
734 
RemoveSubscriberKeyUpTimer(int32_t keyCode)735 void KeySubscriberHandler::RemoveSubscriberKeyUpTimer(int32_t keyCode)
736 {
737     for (auto iter = subscriberMap_.begin(); iter != subscriberMap_.end(); iter++) {
738         auto &subscribers = iter->second;
739         for (auto it = subscribers.begin(); it != subscribers.end(); it++) {
740             if (((*it)->timerId_ >= 0) && ((*it)->keyOption_->GetFinalKey() == keyCode)) {
741                 ClearTimer(*it);
742             }
743         }
744     }
745 }
746 
IsNotifyPowerKeySubsciber(int32_t keyCode,const std::vector<int32_t> & keyCodes)747 bool KeySubscriberHandler::IsNotifyPowerKeySubsciber(int32_t keyCode, const std::vector<int32_t> &keyCodes)
748 {
749     if (keyCode != KeyEvent::KEYCODE_POWER) {
750         return true;
751     }
752 
753     for (const auto& pressedKey: keyCodes) {
754         if (pressedKey == KeyEvent::KEYCODE_VOLUME_DOWN || pressedKey == KeyEvent::KEYCODE_VOLUME_UP) {
755             return false;
756         }
757     }
758     return true;
759 }
760 
HandleKeyUpWithDelay(std::shared_ptr<KeyEvent> keyEvent,const std::shared_ptr<Subscriber> & subscriber)761 void KeySubscriberHandler::HandleKeyUpWithDelay(std::shared_ptr<KeyEvent> keyEvent,
762     const std::shared_ptr<Subscriber> &subscriber)
763 {
764     auto keyUpDelay = subscriber->keyOption_->GetFinalKeyUpDelay();
765     if (keyUpDelay <= 0) {
766         NotifySubscriber(keyEvent, subscriber);
767     } else {
768         if (!AddTimer(subscriber, keyEvent)) {
769             MMI_HILOGE("Leave, add timer failed");
770         }
771     }
772 }
773 
PrintKeyOption(const std::shared_ptr<KeyOption> keyOption)774 void KeySubscriberHandler::PrintKeyOption(const std::shared_ptr<KeyOption> keyOption)
775 {
776     CHKPV(keyOption);
777     MMI_HILOGD("keyOption->finalKey:%{public}d,keyOption->isFinalKeyDown:%{public}s, "
778         "keyOption->finalKeyDownDuration:%{public}d",
779         keyOption->GetFinalKey(), keyOption->IsFinalKeyDown() ? "true" : "false",
780         keyOption->GetFinalKeyDownDuration());
781     for (const auto &keyCode : keyOption->GetPreKeys()) {
782         MMI_HILOGD("keyOption->prekey:%{public}d", keyCode);
783     }
784 }
785 
PrintKeyUpLog(const std::shared_ptr<Subscriber> & subscriber)786 void KeySubscriberHandler::PrintKeyUpLog(const std::shared_ptr<Subscriber> &subscriber)
787 {
788     CHKPV(subscriber);
789     auto &keyOption = subscriber->keyOption_;
790     MMI_HILOGD("subscribeId:%{public}d, keyOption->finalKey:%{public}d,"
791         "keyOption->isFinalKeyDown:%{public}s, keyOption->finalKeyDownDuration:%{public}d,"
792         "keyOption->finalKeyUpDelay:%{public}d",
793         subscriber->id_, keyOption->GetFinalKey(), keyOption->IsFinalKeyDown() ? "true" : "false",
794         keyOption->GetFinalKeyDownDuration(), keyOption->GetFinalKeyUpDelay());
795     for (const auto &keyCode : keyOption->GetPreKeys()) {
796         MMI_HILOGD("keyOption->prekey:%{public}d", keyCode);
797     }
798 }
799 
Dump(int32_t fd,const std::vector<std::string> & args)800 void KeySubscriberHandler::Dump(int32_t fd, const std::vector<std::string> &args)
801 {
802     CALL_DEBUG_ENTER;
803     mprintf(fd, "Subscriber information:\t");
804     mprintf(fd, "subscribers: count = %d", subscriberMap_.size());
805 
806     for (auto iter = subscriberMap_.begin(); iter != subscriberMap_.end(); iter++) {
807         auto &subscribers = iter->second;
808         for (auto item = subscribers.begin(); item != subscribers.end(); item++) {
809             std::shared_ptr<Subscriber> subscriber = *item;
810             CHKPV(subscriber);
811             SessionPtr session = subscriber->sess_;
812             CHKPV(session);
813             std::shared_ptr<KeyOption> keyOption = subscriber->keyOption_;
814             CHKPV(keyOption);
815             mprintf(fd,
816                     "subscriber id:%d | timer id:%d | Pid:%d | Uid:%d | Fd:%d "
817                     "| FinalKey:%d | finalKeyDownDuration:%d | IsFinalKeyDown:%s\t",
818                     subscriber->id_, subscriber->timerId_, session->GetPid(),
819                     session->GetUid(), session->GetFd(), keyOption->GetFinalKey(),
820                     keyOption->GetFinalKeyDownDuration(), keyOption->IsFinalKeyDown() ? "true" : "false");
821             std::set<int32_t> preKeys = keyOption->GetPreKeys();
822             for (const auto &preKey : preKeys) {
823                 mprintf(fd, "preKeys:%d\t", preKey);
824             }
825         }
826     }
827 }
828 } // namespace MMI
829 } // namespace OHOS
830