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