• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 "accessibility_short_key.h"
17 #include "accessible_ability_manager_service.h"
18 #include "hilog_wrapper.h"
19 
20 namespace OHOS {
21 namespace Accessibility {
22 namespace {
23     constexpr size_t KEY_ITEM_COUNT_1 = 1;
24     constexpr uint32_t SHORT_KEY_TIMEOUT_MSG = 1;
25     constexpr int32_t MULTI_PRESS_TIMER = 300; // ms
26     constexpr int32_t TRIPLE_PRESS_COUNT = 3;
27 } // namespace
28 
AccessibilityShortKey()29 AccessibilityShortKey::AccessibilityShortKey()
30 {
31     HILOG_DEBUG();
32 
33     std::shared_ptr<AppExecFwk::EventRunner> runner =
34         Singleton<AccessibleAbilityManagerService>::GetInstance().GetMainRunner();
35     if (!runner) {
36         HILOG_ERROR("get runner failed");
37         return;
38     }
39 
40     timeoutHandler_ = std::make_shared<ShortKeyEventHandler>(runner, *this);
41     if (!timeoutHandler_) {
42         HILOG_ERROR("create event handler failed");
43     }
44 }
45 
~AccessibilityShortKey()46 AccessibilityShortKey::~AccessibilityShortKey()
47 {
48     HILOG_DEBUG();
49 
50     cachedKeyEvents_.clear();
51     timeoutHandler_ = nullptr;
52     lastKeyAction_ = MMI::KeyEvent::KEY_ACTION_UNKNOWN;
53 }
54 
OnKeyEvent(MMI::KeyEvent & event)55 bool AccessibilityShortKey::OnKeyEvent(MMI::KeyEvent &event)
56 {
57     HILOG_DEBUG();
58 
59     int32_t keycode = event.GetKeyCode();
60     size_t pressedKeyCount = event.GetPressedKeys().size();
61     if ((keycode != MMI::KeyEvent::KEYCODE_POWER) ||
62         (pressedKeyCount > KEY_ITEM_COUNT_1)) {
63         HILOG_DEBUG("key[%{public}d] is not power key, or the number[%{public}zu]\
64             of keys pressed is greater than 1.", keycode, pressedKeyCount);
65         EventTransmission::OnKeyEvent(event);
66         return false;
67     }
68 
69     RecognizeShortKey(event);
70     return true;
71 }
72 
SendKeyEventToNext()73 void AccessibilityShortKey::SendKeyEventToNext()
74 {
75     HILOG_DEBUG();
76 
77     for (const auto &keyEvent : cachedKeyEvents_) {
78         EventTransmission::OnKeyEvent(*keyEvent);
79     }
80 
81     ClearCachedEventsAndMsg();
82 }
83 
DestroyEvents()84 void AccessibilityShortKey::DestroyEvents()
85 {
86     HILOG_DEBUG();
87 
88     ClearCachedEventsAndMsg();
89     EventTransmission::DestroyEvents();
90 }
91 
RecognizeShortKey(MMI::KeyEvent & event)92 void AccessibilityShortKey::RecognizeShortKey(MMI::KeyEvent &event)
93 {
94     HILOG_DEBUG();
95 
96     int32_t action = event.GetKeyAction();
97     size_t pressedKeyCount = event.GetPressedKeys().size();
98     std::shared_ptr<MMI::KeyEvent> keyEvent = std::make_shared<MMI::KeyEvent>(event);
99     AddCachedKeyEvent(keyEvent);
100 
101     if (action == MMI::KeyEvent::KEY_ACTION_DOWN) {
102         if (pressedKeyCount != KEY_ITEM_COUNT_1) {
103             SendKeyEventToNext();
104             return;
105         }
106         if (lastKeyAction_ != MMI::KeyEvent::KEY_ACTION_DOWN) {
107             timeoutHandler_->RemoveEvent(SHORT_KEY_TIMEOUT_MSG);
108             timeoutHandler_->SendEvent(SHORT_KEY_TIMEOUT_MSG, 0, MULTI_PRESS_TIMER);
109         }
110         lastKeyAction_ = action;
111     } else if (action == MMI::KeyEvent::KEY_ACTION_UP) {
112         if (pressedKeyCount || !IsUpValid()) {
113             SendKeyEventToNext();
114             return;
115         }
116         lastKeyAction_ = action;
117         if (IsTriplePress()) {
118             OnShortKey();
119         }
120     } else {
121         SendKeyEventToNext();
122     }
123 }
124 
OnShortKey()125 void AccessibilityShortKey::OnShortKey()
126 {
127     HILOG_DEBUG();
128 
129     ClearCachedEventsAndMsg();
130     Singleton<AccessibleAbilityManagerService>::GetInstance().OnShortKeyProcess();
131 }
132 
AddCachedKeyEvent(std::shared_ptr<MMI::KeyEvent> & event)133 void AccessibilityShortKey::AddCachedKeyEvent(std::shared_ptr<MMI::KeyEvent> &event)
134 {
135     HILOG_DEBUG();
136 
137     cachedKeyEvents_.emplace_back(event);
138 }
139 
IsTriplePress()140 bool AccessibilityShortKey::IsTriplePress()
141 {
142     HILOG_DEBUG();
143 
144     uint32_t upEventCount = 0;
145     int32_t action = MMI::KeyEvent::KEY_ACTION_UNKNOWN;
146     for (auto &keyEvent : cachedKeyEvents_) {
147         action = keyEvent->GetKeyAction();
148         if (action == MMI::KeyEvent::KEY_ACTION_UP) {
149             upEventCount++;
150         }
151     }
152 
153     if (upEventCount >= TRIPLE_PRESS_COUNT) {
154         return true;
155     }
156     return false;
157 }
158 
IsUpValid()159 bool AccessibilityShortKey::IsUpValid()
160 {
161     HILOG_DEBUG();
162 
163     if (lastKeyAction_ == MMI::KeyEvent::KEY_ACTION_DOWN) {
164         return true;
165     }
166     return false;
167 }
168 
ClearCachedEventsAndMsg()169 void AccessibilityShortKey::ClearCachedEventsAndMsg()
170 {
171     HILOG_DEBUG();
172 
173     cachedKeyEvents_.clear();
174     lastKeyAction_ = MMI::KeyEvent::KEY_ACTION_UNKNOWN;
175     timeoutHandler_->RemoveEvent(SHORT_KEY_TIMEOUT_MSG);
176 }
177 
ShortKeyEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> & runner,AccessibilityShortKey & shortKey)178 AccessibilityShortKey::ShortKeyEventHandler::ShortKeyEventHandler(
179     const std::shared_ptr<AppExecFwk::EventRunner> &runner,
180     AccessibilityShortKey &shortKey) : AppExecFwk::EventHandler(runner), shortKey_(shortKey)
181 {
182     HILOG_DEBUG();
183 }
184 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)185 void AccessibilityShortKey::ShortKeyEventHandler::ProcessEvent(
186     const AppExecFwk::InnerEvent::Pointer &event)
187 {
188     HILOG_DEBUG();
189 
190     switch (event->GetInnerEventId()) {
191         case SHORT_KEY_TIMEOUT_MSG:
192             shortKey_.SendKeyEventToNext();
193             break;
194         default:
195             break;
196     }
197 }
198 } // namespace Accessibility
199 } // namespace OHOS