1c29fa5a6Sopenharmony_ci/* 2c29fa5a6Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3c29fa5a6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4c29fa5a6Sopenharmony_ci * you may not use this file except in compliance with the License. 5c29fa5a6Sopenharmony_ci * You may obtain a copy of the License at 6c29fa5a6Sopenharmony_ci * 7c29fa5a6Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8c29fa5a6Sopenharmony_ci * 9c29fa5a6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10c29fa5a6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11c29fa5a6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12c29fa5a6Sopenharmony_ci * See the License for the specific language governing permissions and 13c29fa5a6Sopenharmony_ci * limitations under the License. 14c29fa5a6Sopenharmony_ci */ 15c29fa5a6Sopenharmony_ci 16c29fa5a6Sopenharmony_ci#include "key_gesture_manager.h" 17c29fa5a6Sopenharmony_ci 18c29fa5a6Sopenharmony_ci#include <algorithm> 19c29fa5a6Sopenharmony_ci 20c29fa5a6Sopenharmony_ci#include "account_manager.h" 21c29fa5a6Sopenharmony_ci#include "app_state_observer.h" 22c29fa5a6Sopenharmony_ci#include "define_multimodal.h" 23c29fa5a6Sopenharmony_ci#include "display_event_monitor.h" 24c29fa5a6Sopenharmony_ci#include "event_log_helper.h" 25c29fa5a6Sopenharmony_ci#include "timer_manager.h" 26c29fa5a6Sopenharmony_ci#include "util.h" 27c29fa5a6Sopenharmony_ci 28c29fa5a6Sopenharmony_ci#undef MMI_LOG_DOMAIN 29c29fa5a6Sopenharmony_ci#define MMI_LOG_DOMAIN MMI_LOG_HANDLER 30c29fa5a6Sopenharmony_ci#undef MMI_LOG_TAG 31c29fa5a6Sopenharmony_ci#define MMI_LOG_TAG "KeyGestureManager" 32c29fa5a6Sopenharmony_ci 33c29fa5a6Sopenharmony_cinamespace OHOS { 34c29fa5a6Sopenharmony_cinamespace MMI { 35c29fa5a6Sopenharmony_cinamespace { 36c29fa5a6Sopenharmony_ciconstexpr int32_t COMBINATION_KEY_TIMEOUT { 150 }; 37c29fa5a6Sopenharmony_ciconstexpr int32_t INVALID_ENTITY_ID { -1 }; 38c29fa5a6Sopenharmony_ciconstexpr int32_t REPEAT_ONCE { 1 }; 39c29fa5a6Sopenharmony_ciconstexpr size_t MAX_N_PRINTABLE_ITEMS { 5 }; 40c29fa5a6Sopenharmony_ciconstexpr size_t SINGLE_KEY_PRESSED { 1 }; 41c29fa5a6Sopenharmony_ci} 42c29fa5a6Sopenharmony_ci 43c29fa5a6Sopenharmony_ciKeyGestureManager::Handler::~Handler() 44c29fa5a6Sopenharmony_ci{ 45c29fa5a6Sopenharmony_ci ResetTimer(); 46c29fa5a6Sopenharmony_ci} 47c29fa5a6Sopenharmony_ci 48c29fa5a6Sopenharmony_civoid KeyGestureManager::Handler::ResetTimer() 49c29fa5a6Sopenharmony_ci{ 50c29fa5a6Sopenharmony_ci if (timerId_ >= 0) { 51c29fa5a6Sopenharmony_ci TimerMgr->RemoveTimer(timerId_); 52c29fa5a6Sopenharmony_ci timerId_ = INVALID_ENTITY_ID; 53c29fa5a6Sopenharmony_ci } 54c29fa5a6Sopenharmony_ci} 55c29fa5a6Sopenharmony_ci 56c29fa5a6Sopenharmony_civoid KeyGestureManager::Handler::Trigger(std::shared_ptr<KeyEvent> keyEvent) 57c29fa5a6Sopenharmony_ci{ 58c29fa5a6Sopenharmony_ci MMI_HILOGI("[Handler] Handler will run after %{public}dms", GetLongPressTime()); 59c29fa5a6Sopenharmony_ci keyEvent_ = KeyEvent::Clone(keyEvent); 60c29fa5a6Sopenharmony_ci timerId_ = TimerMgr->AddTimer(GetLongPressTime(), REPEAT_ONCE, 61c29fa5a6Sopenharmony_ci [this]() { 62c29fa5a6Sopenharmony_ci CHKPV(keyEvent_); 63c29fa5a6Sopenharmony_ci Run(keyEvent_); 64c29fa5a6Sopenharmony_ci keyEvent_ = nullptr; 65c29fa5a6Sopenharmony_ci timerId_ = INVALID_ENTITY_ID; 66c29fa5a6Sopenharmony_ci }); 67c29fa5a6Sopenharmony_ci if (timerId_ < 0) { 68c29fa5a6Sopenharmony_ci MMI_HILOGI("[Handler] AddTimer fail"); 69c29fa5a6Sopenharmony_ci } 70c29fa5a6Sopenharmony_ci} 71c29fa5a6Sopenharmony_ci 72c29fa5a6Sopenharmony_civoid KeyGestureManager::Handler::Run(std::shared_ptr<KeyEvent> keyEvent) const 73c29fa5a6Sopenharmony_ci{ 74c29fa5a6Sopenharmony_ci if (callback_ != nullptr) { 75c29fa5a6Sopenharmony_ci callback_(keyEvent); 76c29fa5a6Sopenharmony_ci } 77c29fa5a6Sopenharmony_ci} 78c29fa5a6Sopenharmony_ci 79c29fa5a6Sopenharmony_civoid KeyGestureManager::Handler::RunPending() 80c29fa5a6Sopenharmony_ci{ 81c29fa5a6Sopenharmony_ci if (keyEvent_ != nullptr) { 82c29fa5a6Sopenharmony_ci Run(keyEvent_); 83c29fa5a6Sopenharmony_ci keyEvent_ = nullptr; 84c29fa5a6Sopenharmony_ci } 85c29fa5a6Sopenharmony_ci} 86c29fa5a6Sopenharmony_ci 87c29fa5a6Sopenharmony_cibool KeyGestureManager::KeyGesture::IsWorking() 88c29fa5a6Sopenharmony_ci{ 89c29fa5a6Sopenharmony_ci return true; 90c29fa5a6Sopenharmony_ci} 91c29fa5a6Sopenharmony_ci 92c29fa5a6Sopenharmony_ciint32_t KeyGestureManager::KeyGesture::AddHandler(int32_t pid, int32_t longPressTime, 93c29fa5a6Sopenharmony_ci std::function<void(std::shared_ptr<KeyEvent>)> callback) 94c29fa5a6Sopenharmony_ci{ 95c29fa5a6Sopenharmony_ci static int32_t baseId { 0 }; 96c29fa5a6Sopenharmony_ci 97c29fa5a6Sopenharmony_ci longPressTime = std::max(longPressTime, COMBINATION_KEY_TIMEOUT); 98c29fa5a6Sopenharmony_ci return handlers_.emplace_back(++baseId, pid, longPressTime, callback).GetId(); 99c29fa5a6Sopenharmony_ci} 100c29fa5a6Sopenharmony_ci 101c29fa5a6Sopenharmony_cibool KeyGestureManager::KeyGesture::RemoveHandler(int32_t id) 102c29fa5a6Sopenharmony_ci{ 103c29fa5a6Sopenharmony_ci for (auto iter = handlers_.begin(); iter != handlers_.end(); ++iter) { 104c29fa5a6Sopenharmony_ci if (iter->GetId() == id) { 105c29fa5a6Sopenharmony_ci iter->ResetTimer(); 106c29fa5a6Sopenharmony_ci handlers_.erase(iter); 107c29fa5a6Sopenharmony_ci MMI_HILOGI("Handler(%{public}d) of key gesture was removed", iter->GetId()); 108c29fa5a6Sopenharmony_ci return true; 109c29fa5a6Sopenharmony_ci } 110c29fa5a6Sopenharmony_ci } 111c29fa5a6Sopenharmony_ci return false; 112c29fa5a6Sopenharmony_ci} 113c29fa5a6Sopenharmony_ci 114c29fa5a6Sopenharmony_civoid KeyGestureManager::KeyGesture::Reset() 115c29fa5a6Sopenharmony_ci{ 116c29fa5a6Sopenharmony_ci MarkActive(false); 117c29fa5a6Sopenharmony_ci ResetTimers(); 118c29fa5a6Sopenharmony_ci} 119c29fa5a6Sopenharmony_ci 120c29fa5a6Sopenharmony_civoid KeyGestureManager::KeyGesture::ResetTimers() 121c29fa5a6Sopenharmony_ci{ 122c29fa5a6Sopenharmony_ci for (auto &handler : handlers_) { 123c29fa5a6Sopenharmony_ci handler.ResetTimer(); 124c29fa5a6Sopenharmony_ci } 125c29fa5a6Sopenharmony_ci} 126c29fa5a6Sopenharmony_ci 127c29fa5a6Sopenharmony_cistd::set<int32_t> KeyGestureManager::KeyGesture::GetForegroundPids() const 128c29fa5a6Sopenharmony_ci{ 129c29fa5a6Sopenharmony_ci std::set<int32_t> pids; 130c29fa5a6Sopenharmony_ci std::vector<AppExecFwk::AppStateData> appStates = APP_OBSERVER_MGR->GetForegroundAppData(); 131c29fa5a6Sopenharmony_ci std::for_each(appStates.cbegin(), appStates.cend(), [&pids](auto &appState) { 132c29fa5a6Sopenharmony_ci pids.insert(appState.pid); 133c29fa5a6Sopenharmony_ci }); 134c29fa5a6Sopenharmony_ci 135c29fa5a6Sopenharmony_ci std::ostringstream sPids; 136c29fa5a6Sopenharmony_ci size_t nItems = 0; 137c29fa5a6Sopenharmony_ci 138c29fa5a6Sopenharmony_ci if (auto iter = pids.cbegin(); iter != pids.cend()) { 139c29fa5a6Sopenharmony_ci sPids << *iter; 140c29fa5a6Sopenharmony_ci ++nItems; 141c29fa5a6Sopenharmony_ci 142c29fa5a6Sopenharmony_ci for (++iter; iter != pids.cend(); ++iter) { 143c29fa5a6Sopenharmony_ci if (nItems > MAX_N_PRINTABLE_ITEMS) { 144c29fa5a6Sopenharmony_ci sPids << ",..."; 145c29fa5a6Sopenharmony_ci break; 146c29fa5a6Sopenharmony_ci } 147c29fa5a6Sopenharmony_ci sPids << "," << *iter; 148c29fa5a6Sopenharmony_ci ++nItems; 149c29fa5a6Sopenharmony_ci } 150c29fa5a6Sopenharmony_ci } 151c29fa5a6Sopenharmony_ci MMI_HILOGI("Foreground pids: {%{public}zu}[%{public}s]", pids.size(), sPids.str().c_str()); 152c29fa5a6Sopenharmony_ci return pids; 153c29fa5a6Sopenharmony_ci} 154c29fa5a6Sopenharmony_ci 155c29fa5a6Sopenharmony_cibool KeyGestureManager::KeyGesture::HaveForegroundHandler(const std::set<int32_t> &foregroundApps) const 156c29fa5a6Sopenharmony_ci{ 157c29fa5a6Sopenharmony_ci return std::any_of(handlers_.cbegin(), handlers_.cend(), [&foregroundApps](const auto &handler) { 158c29fa5a6Sopenharmony_ci return (foregroundApps.find(handler.GetPid()) != foregroundApps.cend()); 159c29fa5a6Sopenharmony_ci }); 160c29fa5a6Sopenharmony_ci} 161c29fa5a6Sopenharmony_ci 162c29fa5a6Sopenharmony_civoid KeyGestureManager::KeyGesture::TriggerHandlers(std::shared_ptr<KeyEvent> keyEvent) 163c29fa5a6Sopenharmony_ci{ 164c29fa5a6Sopenharmony_ci std::set<int32_t> foregroundPids = GetForegroundPids(); 165c29fa5a6Sopenharmony_ci bool haveForeground = HaveForegroundHandler(foregroundPids); 166c29fa5a6Sopenharmony_ci ShowHandlers(std::string("TriggerHandlers"), foregroundPids); 167c29fa5a6Sopenharmony_ci 168c29fa5a6Sopenharmony_ci for (auto &handler : handlers_) { 169c29fa5a6Sopenharmony_ci if (!haveForeground || (foregroundPids.find(handler.GetPid()) != foregroundPids.end())) { 170c29fa5a6Sopenharmony_ci handler.Trigger(keyEvent); 171c29fa5a6Sopenharmony_ci } 172c29fa5a6Sopenharmony_ci } 173c29fa5a6Sopenharmony_ci} 174c29fa5a6Sopenharmony_ci 175c29fa5a6Sopenharmony_civoid KeyGestureManager::KeyGesture::RunHandler(int32_t handlerId, std::shared_ptr<KeyEvent> keyEvent) 176c29fa5a6Sopenharmony_ci{ 177c29fa5a6Sopenharmony_ci for (auto &handler : handlers_) { 178c29fa5a6Sopenharmony_ci if (handler.GetId() == handlerId) { 179c29fa5a6Sopenharmony_ci handler.ResetTimer(); 180c29fa5a6Sopenharmony_ci handler.Run(keyEvent); 181c29fa5a6Sopenharmony_ci break; 182c29fa5a6Sopenharmony_ci } 183c29fa5a6Sopenharmony_ci } 184c29fa5a6Sopenharmony_ci} 185c29fa5a6Sopenharmony_ci 186c29fa5a6Sopenharmony_civoid KeyGestureManager::KeyGesture::NotifyHandlers(std::shared_ptr<KeyEvent> keyEvent) 187c29fa5a6Sopenharmony_ci{ 188c29fa5a6Sopenharmony_ci std::set<int32_t> foregroundPids = GetForegroundPids(); 189c29fa5a6Sopenharmony_ci bool haveForeground = HaveForegroundHandler(foregroundPids); 190c29fa5a6Sopenharmony_ci ShowHandlers(std::string("NotifyHandlers"), foregroundPids); 191c29fa5a6Sopenharmony_ci 192c29fa5a6Sopenharmony_ci for (auto &handler : handlers_) { 193c29fa5a6Sopenharmony_ci if (!haveForeground || (foregroundPids.find(handler.GetPid()) != foregroundPids.end())) { 194c29fa5a6Sopenharmony_ci handler.Run(keyEvent); 195c29fa5a6Sopenharmony_ci } 196c29fa5a6Sopenharmony_ci } 197c29fa5a6Sopenharmony_ci} 198c29fa5a6Sopenharmony_ci 199c29fa5a6Sopenharmony_civoid KeyGestureManager::KeyGesture::ShowHandlers( 200c29fa5a6Sopenharmony_ci const std::string &prefix, const std::set<int32_t> &foregroundPids) const 201c29fa5a6Sopenharmony_ci{ 202c29fa5a6Sopenharmony_ci std::ostringstream output; 203c29fa5a6Sopenharmony_ci size_t nHandlers = 0; 204c29fa5a6Sopenharmony_ci 205c29fa5a6Sopenharmony_ci for (const auto &handler : handlers_) { 206c29fa5a6Sopenharmony_ci if (nHandlers > MAX_N_PRINTABLE_ITEMS) { 207c29fa5a6Sopenharmony_ci output << "..."; 208c29fa5a6Sopenharmony_ci break; 209c29fa5a6Sopenharmony_ci } 210c29fa5a6Sopenharmony_ci ++nHandlers; 211c29fa5a6Sopenharmony_ci output << "[" << handler.GetId() << "," << handler.GetPid() 212c29fa5a6Sopenharmony_ci << (foregroundPids.find(handler.GetPid()) != foregroundPids.cend() ? ",F]" : ",B]"); 213c29fa5a6Sopenharmony_ci } 214c29fa5a6Sopenharmony_ci MMI_HILOGI("[KeyGesture] %{public}s {%{public}zu}%{public}s", 215c29fa5a6Sopenharmony_ci prefix.c_str(), handlers_.size(), output.str().c_str()); 216c29fa5a6Sopenharmony_ci} 217c29fa5a6Sopenharmony_ci 218c29fa5a6Sopenharmony_cibool KeyGestureManager::LongPressSingleKey::ShouldIntercept(std::shared_ptr<KeyOption> keyOption) const 219c29fa5a6Sopenharmony_ci{ 220c29fa5a6Sopenharmony_ci std::set<int32_t> keys = keyOption->GetPreKeys(); 221c29fa5a6Sopenharmony_ci return (keys.empty() && 222c29fa5a6Sopenharmony_ci (keyOption->GetFinalKey() == keyCode_) && 223c29fa5a6Sopenharmony_ci keyOption->IsFinalKeyDown() && 224c29fa5a6Sopenharmony_ci (keyOption->GetFinalKeyDownDuration() < COMBINATION_KEY_TIMEOUT)); 225c29fa5a6Sopenharmony_ci} 226c29fa5a6Sopenharmony_ci 227c29fa5a6Sopenharmony_cibool KeyGestureManager::LongPressSingleKey::Intercept(std::shared_ptr<KeyEvent> keyEvent) 228c29fa5a6Sopenharmony_ci{ 229c29fa5a6Sopenharmony_ci if ((keyEvent->GetKeyCode() == keyCode_) && (keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_DOWN)) { 230c29fa5a6Sopenharmony_ci if (IsActive()) { 231c29fa5a6Sopenharmony_ci int64_t now = GetSysClockTime(); 232c29fa5a6Sopenharmony_ci if (now >= (firstDownTime_ + MS2US(COMBINATION_KEY_TIMEOUT))) { 233c29fa5a6Sopenharmony_ci NotifyHandlers(keyEvent); 234c29fa5a6Sopenharmony_ci } 235c29fa5a6Sopenharmony_ci } else { 236c29fa5a6Sopenharmony_ci firstDownTime_ = GetSysClockTime(); 237c29fa5a6Sopenharmony_ci MarkActive(true); 238c29fa5a6Sopenharmony_ci TriggerHandlers(keyEvent); 239c29fa5a6Sopenharmony_ci } 240c29fa5a6Sopenharmony_ci return true; 241c29fa5a6Sopenharmony_ci } 242c29fa5a6Sopenharmony_ci if (IsActive()) { 243c29fa5a6Sopenharmony_ci Reset(); 244c29fa5a6Sopenharmony_ci RunPendingHandlers(); 245c29fa5a6Sopenharmony_ci } 246c29fa5a6Sopenharmony_ci return false; 247c29fa5a6Sopenharmony_ci} 248c29fa5a6Sopenharmony_ci 249c29fa5a6Sopenharmony_civoid KeyGestureManager::LongPressSingleKey::Dump(std::ostringstream &output) const 250c29fa5a6Sopenharmony_ci{ 251c29fa5a6Sopenharmony_ci output << "[" << keyCode_ << "] --> {"; 252c29fa5a6Sopenharmony_ci if (auto iter = handlers_.begin(); iter != handlers_.end()) { 253c29fa5a6Sopenharmony_ci output << iter->GetLongPressTime(); 254c29fa5a6Sopenharmony_ci for (++iter; iter != handlers_.end(); ++iter) { 255c29fa5a6Sopenharmony_ci output << "," << iter->GetLongPressTime(); 256c29fa5a6Sopenharmony_ci } 257c29fa5a6Sopenharmony_ci } 258c29fa5a6Sopenharmony_ci output << "}"; 259c29fa5a6Sopenharmony_ci} 260c29fa5a6Sopenharmony_ci 261c29fa5a6Sopenharmony_civoid KeyGestureManager::LongPressSingleKey::RunPendingHandlers() 262c29fa5a6Sopenharmony_ci{ 263c29fa5a6Sopenharmony_ci std::set<int32_t> foregroundPids = GetForegroundPids(); 264c29fa5a6Sopenharmony_ci bool haveForeground = HaveForegroundHandler(foregroundPids); 265c29fa5a6Sopenharmony_ci ShowHandlers(std::string("RunPendingHandlers"), foregroundPids); 266c29fa5a6Sopenharmony_ci 267c29fa5a6Sopenharmony_ci for (auto &handler : handlers_) { 268c29fa5a6Sopenharmony_ci if (!haveForeground || (foregroundPids.find(handler.GetPid()) != foregroundPids.end())) { 269c29fa5a6Sopenharmony_ci handler.RunPending(); 270c29fa5a6Sopenharmony_ci } 271c29fa5a6Sopenharmony_ci } 272c29fa5a6Sopenharmony_ci} 273c29fa5a6Sopenharmony_ci 274c29fa5a6Sopenharmony_cibool KeyGestureManager::LongPressCombinationKey::ShouldIntercept(std::shared_ptr<KeyOption> keyOption) const 275c29fa5a6Sopenharmony_ci{ 276c29fa5a6Sopenharmony_ci std::set<int32_t> keys = keyOption->GetPreKeys(); 277c29fa5a6Sopenharmony_ci keys.insert(keyOption->GetFinalKey()); 278c29fa5a6Sopenharmony_ci return (keys_ == keys); 279c29fa5a6Sopenharmony_ci} 280c29fa5a6Sopenharmony_ci 281c29fa5a6Sopenharmony_cibool KeyGestureManager::LongPressCombinationKey::Intercept(std::shared_ptr<KeyEvent> keyEvent) 282c29fa5a6Sopenharmony_ci{ 283c29fa5a6Sopenharmony_ci if ((keys_.find(keyEvent->GetKeyCode()) != keys_.end()) && 284c29fa5a6Sopenharmony_ci (keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_DOWN)) { 285c29fa5a6Sopenharmony_ci if (IsActive()) { 286c29fa5a6Sopenharmony_ci std::ostringstream output; 287c29fa5a6Sopenharmony_ci Dump(output); 288c29fa5a6Sopenharmony_ci if (EventLogHelper::IsBetaVersion() && !keyEvent->HasFlag(InputEvent::EVENT_FLAG_PRIVACY_MODE)) { 289c29fa5a6Sopenharmony_ci MMI_HILOGI("[LongPressCombinationKey] %{public}s is active now", output.str().c_str()); 290c29fa5a6Sopenharmony_ci } else { 291c29fa5a6Sopenharmony_ci MMI_HILOGI("[LongPressCombinationKey] %s is active now", output.str().c_str()); 292c29fa5a6Sopenharmony_ci } 293c29fa5a6Sopenharmony_ci return true; 294c29fa5a6Sopenharmony_ci } 295c29fa5a6Sopenharmony_ci if (!IsWorking()) { 296c29fa5a6Sopenharmony_ci std::ostringstream output; 297c29fa5a6Sopenharmony_ci Dump(output); 298c29fa5a6Sopenharmony_ci if (EventLogHelper::IsBetaVersion() && !keyEvent->HasFlag(InputEvent::EVENT_FLAG_PRIVACY_MODE)) { 299c29fa5a6Sopenharmony_ci MMI_HILOGI("[LongPressCombinationKey] Switch off %{public}s", output.str().c_str()); 300c29fa5a6Sopenharmony_ci } else { 301c29fa5a6Sopenharmony_ci MMI_HILOGI("[LongPressCombinationKey] Switch off %s", output.str().c_str()); 302c29fa5a6Sopenharmony_ci } 303c29fa5a6Sopenharmony_ci return false; 304c29fa5a6Sopenharmony_ci } 305c29fa5a6Sopenharmony_ci if (handlers_.empty()) { 306c29fa5a6Sopenharmony_ci std::ostringstream output; 307c29fa5a6Sopenharmony_ci Dump(output); 308c29fa5a6Sopenharmony_ci if (EventLogHelper::IsBetaVersion() && !keyEvent->HasFlag(InputEvent::EVENT_FLAG_PRIVACY_MODE)) { 309c29fa5a6Sopenharmony_ci MMI_HILOGI("[LongPressCombinationKey] No handler for %{public}s", output.str().c_str()); 310c29fa5a6Sopenharmony_ci } else { 311c29fa5a6Sopenharmony_ci MMI_HILOGI("[LongPressCombinationKey] No handler for %s", output.str().c_str()); 312c29fa5a6Sopenharmony_ci } 313c29fa5a6Sopenharmony_ci return false; 314c29fa5a6Sopenharmony_ci } 315c29fa5a6Sopenharmony_ci if (RecognizeGesture(keyEvent)) { 316c29fa5a6Sopenharmony_ci TriggerAll(keyEvent); 317c29fa5a6Sopenharmony_ci return true; 318c29fa5a6Sopenharmony_ci } 319c29fa5a6Sopenharmony_ci } 320c29fa5a6Sopenharmony_ci if (IsActive()) { 321c29fa5a6Sopenharmony_ci Reset(); 322c29fa5a6Sopenharmony_ci } 323c29fa5a6Sopenharmony_ci return false; 324c29fa5a6Sopenharmony_ci} 325c29fa5a6Sopenharmony_ci 326c29fa5a6Sopenharmony_civoid KeyGestureManager::LongPressCombinationKey::Dump(std::ostringstream &output) const 327c29fa5a6Sopenharmony_ci{ 328c29fa5a6Sopenharmony_ci output << "["; 329c29fa5a6Sopenharmony_ci if (auto keyIter = keys_.begin(); keyIter != keys_.end()) { 330c29fa5a6Sopenharmony_ci output << *keyIter; 331c29fa5a6Sopenharmony_ci for (++keyIter; keyIter != keys_.end(); ++keyIter) { 332c29fa5a6Sopenharmony_ci output << "," << *keyIter; 333c29fa5a6Sopenharmony_ci } 334c29fa5a6Sopenharmony_ci } 335c29fa5a6Sopenharmony_ci output << "] --> {"; 336c29fa5a6Sopenharmony_ci if (auto iter = handlers_.begin(); iter != handlers_.end()) { 337c29fa5a6Sopenharmony_ci output << "(ID:" << iter->GetId() << ",T:" << iter->GetLongPressTime() << ")"; 338c29fa5a6Sopenharmony_ci for (++iter; iter != handlers_.end(); ++iter) { 339c29fa5a6Sopenharmony_ci output << ",(ID:" << iter->GetId() << ",T:" << iter->GetLongPressTime() << ")"; 340c29fa5a6Sopenharmony_ci } 341c29fa5a6Sopenharmony_ci } 342c29fa5a6Sopenharmony_ci output << "}"; 343c29fa5a6Sopenharmony_ci} 344c29fa5a6Sopenharmony_ci 345c29fa5a6Sopenharmony_cibool KeyGestureManager::LongPressCombinationKey::RecognizeGesture(std::shared_ptr<KeyEvent> keyEvent) 346c29fa5a6Sopenharmony_ci{ 347c29fa5a6Sopenharmony_ci if (keyEvent->GetPressedKeys().size() == SINGLE_KEY_PRESSED) { 348c29fa5a6Sopenharmony_ci firstDownTime_ = GetSysClockTime(); 349c29fa5a6Sopenharmony_ci } 350c29fa5a6Sopenharmony_ci int64_t now = GetSysClockTime(); 351c29fa5a6Sopenharmony_ci return std::all_of(keys_.cbegin(), keys_.cend(), [this, keyEvent, now](auto keyCode) { 352c29fa5a6Sopenharmony_ci auto itemOpt = keyEvent->GetKeyItem(keyCode); 353c29fa5a6Sopenharmony_ci return (itemOpt && itemOpt->IsPressed() && 354c29fa5a6Sopenharmony_ci (now < (firstDownTime_ + MS2US(COMBINATION_KEY_TIMEOUT)))); 355c29fa5a6Sopenharmony_ci }); 356c29fa5a6Sopenharmony_ci} 357c29fa5a6Sopenharmony_ci 358c29fa5a6Sopenharmony_civoid KeyGestureManager::LongPressCombinationKey::TriggerAll(std::shared_ptr<KeyEvent> keyEvent) 359c29fa5a6Sopenharmony_ci{ 360c29fa5a6Sopenharmony_ci MarkActive(true); 361c29fa5a6Sopenharmony_ci std::ostringstream output; 362c29fa5a6Sopenharmony_ci Dump(output); 363c29fa5a6Sopenharmony_ci if (EventLogHelper::IsBetaVersion() && !keyEvent->HasFlag(InputEvent::EVENT_FLAG_PRIVACY_MODE)) { 364c29fa5a6Sopenharmony_ci MMI_HILOGI("[LongPressCombinationKey] trigger %{public}s", output.str().c_str()); 365c29fa5a6Sopenharmony_ci } else { 366c29fa5a6Sopenharmony_ci MMI_HILOGI("[LongPressCombinationKey] trigger %s", output.str().c_str()); 367c29fa5a6Sopenharmony_ci } 368c29fa5a6Sopenharmony_ci OnTriggerAll(keyEvent); 369c29fa5a6Sopenharmony_ci TriggerHandlers(keyEvent); 370c29fa5a6Sopenharmony_ci} 371c29fa5a6Sopenharmony_ci 372c29fa5a6Sopenharmony_ciKeyGestureManager::PullUpAccessibility::PullUpAccessibility() 373c29fa5a6Sopenharmony_ci : LongPressCombinationKey(std::set({ KeyEvent::KEYCODE_VOLUME_DOWN, KeyEvent::KEYCODE_VOLUME_UP })) 374c29fa5a6Sopenharmony_ci{} 375c29fa5a6Sopenharmony_ci 376c29fa5a6Sopenharmony_cibool KeyGestureManager::PullUpAccessibility::IsWorking() 377c29fa5a6Sopenharmony_ci{ 378c29fa5a6Sopenharmony_ci if ((DISPLAY_MONITOR->GetScreenStatus() == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF)) { 379c29fa5a6Sopenharmony_ci return false; 380c29fa5a6Sopenharmony_ci } 381c29fa5a6Sopenharmony_ci if (DISPLAY_MONITOR->GetScreenLocked()) { 382c29fa5a6Sopenharmony_ci return ACCOUNT_MGR->GetCurrentAccountSetting().GetAccShortcutEnabledOnScreenLocked(); 383c29fa5a6Sopenharmony_ci } else { 384c29fa5a6Sopenharmony_ci return ACCOUNT_MGR->GetCurrentAccountSetting().GetAccShortcutEnabled(); 385c29fa5a6Sopenharmony_ci } 386c29fa5a6Sopenharmony_ci} 387c29fa5a6Sopenharmony_ci 388c29fa5a6Sopenharmony_ciint32_t KeyGestureManager::PullUpAccessibility::AddHandler(int32_t pid, 389c29fa5a6Sopenharmony_ci int32_t longPressTime, std::function<void(std::shared_ptr<KeyEvent>)> callback) 390c29fa5a6Sopenharmony_ci{ 391c29fa5a6Sopenharmony_ci return KeyGesture::AddHandler(pid, ACCOUNT_MGR->GetCurrentAccountSetting().GetAccShortcutTimeout(), callback); 392c29fa5a6Sopenharmony_ci} 393c29fa5a6Sopenharmony_ci 394c29fa5a6Sopenharmony_civoid KeyGestureManager::PullUpAccessibility::OnTriggerAll(std::shared_ptr<KeyEvent> keyEvent) 395c29fa5a6Sopenharmony_ci{ 396c29fa5a6Sopenharmony_ci MMI_HILOGI("[PullUpAccessibility] Current AccShortcutTimeout setting: %{public}dms", 397c29fa5a6Sopenharmony_ci ACCOUNT_MGR->GetCurrentAccountSetting().GetAccShortcutTimeout()); 398c29fa5a6Sopenharmony_ci for (auto &handler : handlers_) { 399c29fa5a6Sopenharmony_ci handler.SetLongPressTime(ACCOUNT_MGR->GetCurrentAccountSetting().GetAccShortcutTimeout()); 400c29fa5a6Sopenharmony_ci } 401c29fa5a6Sopenharmony_ci} 402c29fa5a6Sopenharmony_ci 403c29fa5a6Sopenharmony_ciKeyGestureManager::KeyGestureManager() 404c29fa5a6Sopenharmony_ci{ 405c29fa5a6Sopenharmony_ci keyGestures_.push_back(std::make_unique<PullUpAccessibility>()); 406c29fa5a6Sopenharmony_ci keyGestures_.push_back(std::make_unique<LongPressSingleKey>(KeyEvent::KEYCODE_VOLUME_DOWN)); 407c29fa5a6Sopenharmony_ci keyGestures_.push_back(std::make_unique<LongPressSingleKey>(KeyEvent::KEYCODE_VOLUME_UP)); 408c29fa5a6Sopenharmony_ci} 409c29fa5a6Sopenharmony_ci 410c29fa5a6Sopenharmony_cibool KeyGestureManager::ShouldIntercept(std::shared_ptr<KeyOption> keyOption) const 411c29fa5a6Sopenharmony_ci{ 412c29fa5a6Sopenharmony_ci CALL_INFO_TRACE; 413c29fa5a6Sopenharmony_ci CHKPF(keyOption); 414c29fa5a6Sopenharmony_ci return std::any_of(keyGestures_.cbegin(), keyGestures_.cend(), 415c29fa5a6Sopenharmony_ci [keyOption](const auto &keyGesture) { 416c29fa5a6Sopenharmony_ci return keyGesture->ShouldIntercept(keyOption); 417c29fa5a6Sopenharmony_ci }); 418c29fa5a6Sopenharmony_ci} 419c29fa5a6Sopenharmony_ci 420c29fa5a6Sopenharmony_ciint32_t KeyGestureManager::AddKeyGesture(int32_t pid, std::shared_ptr<KeyOption> keyOption, 421c29fa5a6Sopenharmony_ci std::function<void(std::shared_ptr<KeyEvent>)> callback) 422c29fa5a6Sopenharmony_ci{ 423c29fa5a6Sopenharmony_ci CHKPR(keyOption, INVALID_ENTITY_ID); 424c29fa5a6Sopenharmony_ci for (auto &keyGesture : keyGestures_) { 425c29fa5a6Sopenharmony_ci if (keyGesture->ShouldIntercept(keyOption)) { 426c29fa5a6Sopenharmony_ci auto downDuration = std::max(keyOption->GetFinalKeyDownDuration(), COMBINATION_KEY_TIMEOUT); 427c29fa5a6Sopenharmony_ci return keyGesture->AddHandler(pid, downDuration, callback); 428c29fa5a6Sopenharmony_ci } 429c29fa5a6Sopenharmony_ci } 430c29fa5a6Sopenharmony_ci return INVALID_ENTITY_ID; 431c29fa5a6Sopenharmony_ci} 432c29fa5a6Sopenharmony_ci 433c29fa5a6Sopenharmony_civoid KeyGestureManager::RemoveKeyGesture(int32_t id) 434c29fa5a6Sopenharmony_ci{ 435c29fa5a6Sopenharmony_ci for (auto &keyGesture : keyGestures_) { 436c29fa5a6Sopenharmony_ci if (keyGesture->RemoveHandler(id)) { 437c29fa5a6Sopenharmony_ci break; 438c29fa5a6Sopenharmony_ci } 439c29fa5a6Sopenharmony_ci } 440c29fa5a6Sopenharmony_ci} 441c29fa5a6Sopenharmony_ci 442c29fa5a6Sopenharmony_cibool KeyGestureManager::Intercept(std::shared_ptr<KeyEvent> keyEvent) 443c29fa5a6Sopenharmony_ci{ 444c29fa5a6Sopenharmony_ci CALL_INFO_TRACE; 445c29fa5a6Sopenharmony_ci CHKPF(keyEvent); 446c29fa5a6Sopenharmony_ci for (auto iter = keyGestures_.begin(); iter != keyGestures_.end(); ++iter) { 447c29fa5a6Sopenharmony_ci if ((*iter)->Intercept(keyEvent)) { 448c29fa5a6Sopenharmony_ci std::ostringstream output; 449c29fa5a6Sopenharmony_ci (*iter)->Dump(output); 450c29fa5a6Sopenharmony_ci if (EventLogHelper::IsBetaVersion() && !keyEvent->HasFlag(InputEvent::EVENT_FLAG_PRIVACY_MODE)) { 451c29fa5a6Sopenharmony_ci MMI_HILOGI("Intercepted by %{public}s", output.str().c_str()); 452c29fa5a6Sopenharmony_ci } else { 453c29fa5a6Sopenharmony_ci MMI_HILOGI("Intercepted by %s", output.str().c_str()); 454c29fa5a6Sopenharmony_ci } 455c29fa5a6Sopenharmony_ci for (++iter; iter != keyGestures_.end(); ++iter) { 456c29fa5a6Sopenharmony_ci (*iter)->Reset(); 457c29fa5a6Sopenharmony_ci } 458c29fa5a6Sopenharmony_ci return true; 459c29fa5a6Sopenharmony_ci } 460c29fa5a6Sopenharmony_ci } 461c29fa5a6Sopenharmony_ci return false; 462c29fa5a6Sopenharmony_ci} 463c29fa5a6Sopenharmony_ci 464c29fa5a6Sopenharmony_civoid KeyGestureManager::ResetAll() 465c29fa5a6Sopenharmony_ci{ 466c29fa5a6Sopenharmony_ci for (auto &keyGesture : keyGestures_) { 467c29fa5a6Sopenharmony_ci keyGesture->Reset(); 468c29fa5a6Sopenharmony_ci } 469c29fa5a6Sopenharmony_ci} 470c29fa5a6Sopenharmony_ci 471c29fa5a6Sopenharmony_civoid KeyGestureManager::Dump() const 472c29fa5a6Sopenharmony_ci{ 473c29fa5a6Sopenharmony_ci for (const auto &keyGesture : keyGestures_) { 474c29fa5a6Sopenharmony_ci std::ostringstream output; 475c29fa5a6Sopenharmony_ci keyGesture->Dump(output); 476c29fa5a6Sopenharmony_ci MMI_HILOGI("%s", output.str().c_str()); 477c29fa5a6Sopenharmony_ci } 478c29fa5a6Sopenharmony_ci} 479c29fa5a6Sopenharmony_ci} // namespace MMI 480c29fa5a6Sopenharmony_ci} // namespace OHOS 481