Chromium Code Reviews| Index: chrome/browser/chromeos/accessibility/switch_access_event_handler.cc |
| diff --git a/chrome/browser/chromeos/accessibility/switch_access_event_handler.cc b/chrome/browser/chromeos/accessibility/switch_access_event_handler.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..f8f009cef67e124df12972bdb1ac93347057ae10 |
| --- /dev/null |
| +++ b/chrome/browser/chromeos/accessibility/switch_access_event_handler.cc |
| @@ -0,0 +1,137 @@ |
| +// Copyright 2017 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/browser/chromeos/accessibility/switch_access_event_handler.h" |
| + |
| +#include "ash/shell.h" |
| +#include "base/logging.h" |
| +#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" |
| +#include "chrome/browser/profiles/profile_manager.h" |
| +#include "chrome/common/extensions/extension_constants.h" |
| +#include "content/public/browser/render_view_host.h" |
| +#include "content/public/browser/render_widget_host.h" |
| +#include "extensions/browser/extension_host.h" |
| +#include "extensions/browser/extension_registry.h" |
| +#include "extensions/browser/process_manager.h" |
| +#include "ui/events/event.h" |
| + |
| +namespace chromeos { |
| + |
| +SwitchAccessEventHandler::SwitchAccessEventHandler() { |
| + if (ash::Shell::HasInstance()) |
| + ash::Shell::GetInstance()->AddPreTargetHandler(this); |
| +} |
| + |
| +SwitchAccessEventHandler::~SwitchAccessEventHandler() { |
| + if (ash::Shell::HasInstance()) |
| + ash::Shell::GetInstance()->RemovePreTargetHandler(this); |
| +} |
| + |
| +void SwitchAccessEventHandler::OnKeyEvent(ui::KeyEvent* event) { |
| + DCHECK(event); |
| + if (event->key_code() == ui::VKEY_1) { |
| + CancelEvent(event); |
| + if (event->type() == ui::ET_KEY_PRESSED && state_ == INACTIVE) { |
| + state_ = ONE_KEY_DOWN; |
|
dmazzoni
2017/02/24 23:06:54
The state machine made a lot of sense for select-t
elichtenberg
2017/02/28 00:28:42
Done.
|
| + LOG(ERROR) << "One key was pressed!"; |
| + } else if (event->type() == ui::ET_KEY_RELEASED && state_ == ONE_KEY_DOWN) { |
| + state_ = INACTIVE; |
| + LOG(ERROR) << "One key was released!"; |
| + bool result = DispatchKeyEventToSwitchAccess(*event); |
| + LOG(ERROR) << "Result of dispatching one key was: " << std::boolalpha |
| + << result; |
| + } |
| + } else if (event->key_code() == ui::VKEY_2) { |
| + CancelEvent(event); |
| + if (event->type() == ui::ET_KEY_PRESSED && state_ == INACTIVE) { |
| + state_ = TWO_KEY_DOWN; |
| + LOG(ERROR) << "Two key was pressed!"; |
| + } else if (event->type() == ui::ET_KEY_RELEASED && state_ == TWO_KEY_DOWN) { |
| + state_ = INACTIVE; |
| + LOG(ERROR) << "Two key was released!"; |
| + bool result = DispatchKeyEventToSwitchAccess(*event); |
| + LOG(ERROR) << "Result of dispatching two key was: " << std::boolalpha |
| + << result; |
| + } |
| + } else if (event->key_code() == ui::VKEY_3) { |
| + CancelEvent(event); |
| + if (event->type() == ui::ET_KEY_PRESSED && state_ == INACTIVE) { |
| + state_ = THREE_KEY_DOWN; |
| + LOG(ERROR) << "Three key was pressed!"; |
| + } else if (event->type() == ui::ET_KEY_RELEASED && |
| + state_ == THREE_KEY_DOWN) { |
| + state_ = INACTIVE; |
| + LOG(ERROR) << "Three key was released!"; |
| + bool result = DispatchKeyEventToSwitchAccess(*event); |
| + LOG(ERROR) << "Result of dispatching three key was: " << std::boolalpha |
| + << result; |
| + } |
| + } else if (event->key_code() == ui::VKEY_4) { |
| + CancelEvent(event); |
| + if (event->type() == ui::ET_KEY_PRESSED && state_ == INACTIVE) { |
| + state_ = FOUR_KEY_DOWN; |
| + LOG(ERROR) << "Four key was pressed!"; |
| + } else if (event->type() == ui::ET_KEY_RELEASED && |
| + state_ == FOUR_KEY_DOWN) { |
| + state_ = INACTIVE; |
| + LOG(ERROR) << "Four key was released!"; |
| + bool result = DispatchKeyEventToSwitchAccess(*event); |
| + LOG(ERROR) << "Result of dispatching four key was: " << std::boolalpha |
| + << result; |
| + } |
| + } else if (event->key_code() == ui::VKEY_5) { |
| + CancelEvent(event); |
| + if (event->type() == ui::ET_KEY_PRESSED && state_ == INACTIVE) { |
| + state_ = FIVE_KEY_DOWN; |
| + LOG(ERROR) << "Five key was pressed!"; |
| + } else if (event->type() == ui::ET_KEY_RELEASED && |
| + state_ == FIVE_KEY_DOWN) { |
| + state_ = INACTIVE; |
| + LOG(ERROR) << "Five key was released!"; |
| + bool result = DispatchKeyEventToSwitchAccess(*event); |
| + LOG(ERROR) << "Result of dispatching five key was: " << std::boolalpha |
| + << result; |
| + } |
| + } |
| +} |
| + |
| +void SwitchAccessEventHandler::CancelEvent(ui::Event* event) { |
| + DCHECK(event); |
| + if (event->cancelable()) { |
| + event->SetHandled(); |
| + event->StopPropagation(); |
| + } |
| +} |
| + |
| +bool SwitchAccessEventHandler::DispatchKeyEventToSwitchAccess( |
|
dmazzoni
2017/02/24 23:06:54
Please refactor this into a common utility functio
elichtenberg
2017/02/28 00:28:42
Done. Did event_handler_common.h and event_handler
|
| + const ui::KeyEvent& event) { |
| + if (!AccessibilityManager::Get()) |
| + return false; |
| + |
| + content::BrowserContext* context = ProfileManager::GetActiveUserProfile(); |
| + if (!context) |
| + return false; |
| + |
| + const extensions::Extension* extension = |
| + extensions::ExtensionRegistry::Get(context)->enabled_extensions().GetByID( |
| + extension_misc::kSwitchAccessExtensionId); |
| + if (!extension) |
| + return false; |
| + |
| + extensions::ExtensionHost* host = |
| + extensions::ProcessManager::Get(context)->GetBackgroundHostForExtension( |
| + extension->id()); |
| + if (!host) |
| + return false; |
| + |
| + content::RenderViewHost* rvh = host->render_view_host(); |
| + if (!rvh) |
| + return false; |
| + |
| + const content::NativeWebKeyboardEvent web_event(event); |
| + rvh->GetWidget()->ForwardKeyboardEvent(web_event); |
| + return true; |
| +} |
| + |
| +} // namespace chromeos |