summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--athena/athena.gyp6
-rw-r--r--athena/home/DEPS1
-rw-r--r--athena/home/home_card_impl.cc29
-rw-r--r--athena/input/DEPS13
-rw-r--r--athena/input/accelerator_manager_impl.cc190
-rw-r--r--athena/input/accelerator_manager_impl.h76
-rw-r--r--athena/input/accelerator_manager_unittest.cc120
-rw-r--r--athena/input/input_manager_impl.cc122
-rw-r--r--athena/input/public/DEPS4
-rw-r--r--athena/input/public/accelerator_manager.h72
-rw-r--r--athena/input/public/input_manager.h41
-rw-r--r--athena/main/DEPS1
-rw-r--r--athena/main/athena_launcher.cc3
13 files changed, 677 insertions, 1 deletions
diff --git a/athena/athena.gyp b/athena/athena.gyp
index c7adae5..6fdb64c 100644
--- a/athena/athena.gyp
+++ b/athena/athena.gyp
@@ -36,6 +36,11 @@
'home/app_list_view_delegate.h',
'home/home_card_impl.cc',
'home/public/home_card.h',
+ 'input/public/input_manager.h',
+ 'input/public/accelerator_manager.h',
+ 'input/input_manager_impl.cc',
+ 'input/accelerator_manager_impl.cc',
+ 'input/accelerator_manager_impl.h',
'screen/background_controller.cc',
'screen/background_controller.h',
'screen/public/screen_manager.h',
@@ -104,6 +109,7 @@
],
'sources': [
'test/athena_unittests.cc',
+ 'input/accelerator_manager_unittest.cc',
'wm/window_manager_unittest.cc',
],
}
diff --git a/athena/home/DEPS b/athena/home/DEPS
index 660f468..3c13d2d 100644
--- a/athena/home/DEPS
+++ b/athena/home/DEPS
@@ -1,4 +1,5 @@
include_rules = [
+ "+athena/input/public",
"+athena/screen/public",
"+third_party/skia/include",
"+ui/aura",
diff --git a/athena/home/home_card_impl.cc b/athena/home/home_card_impl.cc
index 13723af..949d551 100644
--- a/athena/home/home_card_impl.cc
+++ b/athena/home/home_card_impl.cc
@@ -5,6 +5,8 @@
#include "athena/home/public/home_card.h"
#include "athena/home/app_list_view_delegate.h"
+#include "athena/input/public/accelerator_manager.h"
+#include "athena/input/public/input_manager.h"
#include "athena/screen/public/screen_manager.h"
#include "ui/app_list/pagination_model.h"
#include "ui/app_list/views/app_list_view.h"
@@ -68,7 +70,7 @@ class HomeCardLayoutManager : public aura::LayoutManager {
DISALLOW_COPY_AND_ASSIGN(HomeCardLayoutManager);
};
-class HomeCardImpl : public HomeCard {
+class HomeCardImpl : public HomeCard, public AcceleratorHandler {
public:
HomeCardImpl();
virtual ~HomeCardImpl();
@@ -76,6 +78,20 @@ class HomeCardImpl : public HomeCard {
void Init();
private:
+ enum Command {
+ COMMAND_SHOW_HOME_CARD,
+ };
+ void InstallAccelerators();
+
+ // AcceleratorHandler:
+ virtual bool IsCommandEnabled(int command_id) const OVERRIDE { return true; }
+ virtual bool OnAcceleratorFired(int command_id,
+ const ui::Accelerator& accelerator) OVERRIDE {
+ DCHECK_EQ(COMMAND_SHOW_HOME_CARD, command_id);
+ home_card_widget_->Show();
+ return true;
+ }
+
views::Widget* home_card_widget_;
DISALLOW_COPY_AND_ASSIGN(HomeCardImpl);
@@ -94,6 +110,8 @@ HomeCardImpl::~HomeCardImpl() {
}
void HomeCardImpl::Init() {
+ InstallAccelerators();
+
aura::Window* container =
ScreenManager::Get()->CreateContainer("HomeCardContainer");
container->SetLayoutManager(new HomeCardLayoutManager(container));
@@ -111,6 +129,15 @@ void HomeCardImpl::Init() {
view->ShowWhenReady();
}
+void HomeCardImpl::InstallAccelerators() {
+ const AcceleratorData accelerator_data[] = {
+ {TRIGGER_ON_PRESS, ui::VKEY_L, ui::EF_CONTROL_DOWN,
+ COMMAND_SHOW_HOME_CARD, AF_NONE},
+ };
+ InputManager::Get()->GetAcceleratorManager()->RegisterAccelerators(
+ accelerator_data, arraysize(accelerator_data), this);
+}
+
} // namespace
// static
diff --git a/athena/input/DEPS b/athena/input/DEPS
new file mode 100644
index 0000000..5b66b22
--- /dev/null
+++ b/athena/input/DEPS
@@ -0,0 +1,13 @@
+include_rules = [
+ "+ui/aura",
+ "+ui/base",
+ "+ui/events",
+ "+ui/wm/core",
+ "+ui/wm/public",
+]
+
+specific_include_rules = {
+ ".*unittest\.cc": [
+ "+athena/test",
+ ],
+}
diff --git a/athena/input/accelerator_manager_impl.cc b/athena/input/accelerator_manager_impl.cc
new file mode 100644
index 0000000..cdd4673
--- /dev/null
+++ b/athena/input/accelerator_manager_impl.cc
@@ -0,0 +1,190 @@
+// Copyright 2014 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 "athena/input/accelerator_manager_impl.h"
+
+#include "athena/input/public/input_manager.h"
+#include "base/logging.h"
+#include "ui/aura/window.h"
+#include "ui/base/accelerators/accelerator_manager.h"
+#include "ui/events/event.h"
+#include "ui/events/event_target.h"
+#include "ui/wm/core/accelerator_delegate.h"
+#include "ui/wm/core/accelerator_filter.h"
+#include "ui/wm/core/nested_accelerator_controller.h"
+#include "ui/wm/core/nested_accelerator_delegate.h"
+#include "ui/wm/public/dispatcher_client.h"
+
+namespace athena {
+
+namespace {
+
+// Accelerators inside nested message loop are handled by
+// wm::NestedAcceleratorController while accelerators in normal case are
+// handled by wm::AcceleratorFilter. These delegates act bridges in these
+// two different environment so that AcceleratorManagerImpl can handle
+// accelerators in an uniform way.
+
+class NestedAcceleratorDelegate : public wm::NestedAcceleratorDelegate {
+ public:
+ explicit NestedAcceleratorDelegate(
+ AcceleratorManagerImpl* accelerator_manager)
+ : accelerator_manager_(accelerator_manager) {}
+ virtual ~NestedAcceleratorDelegate() {}
+
+ private:
+ // wm::NestedAcceleratorDelegate:
+ virtual Result ProcessAccelerator(
+ const ui::Accelerator& accelerator) OVERRIDE {
+ return accelerator_manager_->ProcessAccelerator(accelerator)
+ ? RESULT_PROCESSED
+ : RESULT_NOT_PROCESSED;
+ }
+
+ AcceleratorManagerImpl* accelerator_manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(NestedAcceleratorDelegate);
+};
+
+class AcceleratorDelegate : public wm::AcceleratorDelegate {
+ public:
+ explicit AcceleratorDelegate(AcceleratorManagerImpl* accelerator_manager)
+ : accelerator_manager_(accelerator_manager) {}
+ virtual ~AcceleratorDelegate() {}
+
+ private:
+ // wm::AcceleratorDelegate:
+ virtual bool ProcessAccelerator(const ui::KeyEvent& event,
+ const ui::Accelerator& accelerator,
+ KeyType key_type) OVERRIDE {
+ aura::Window* target = static_cast<aura::Window*>(event.target());
+ if (!target->IsRootWindow() &&
+ !accelerator_manager_->IsReservedAccelerator(accelerator)) {
+ // TODO(oshima): do the same when the active window is in fullscreen.
+ return false;
+ }
+ return accelerator_manager_->ProcessAccelerator(accelerator);
+ }
+
+ AcceleratorManagerImpl* accelerator_manager_;
+ DISALLOW_COPY_AND_ASSIGN(AcceleratorDelegate);
+};
+
+} // namespace
+
+class AcceleratorManagerImpl::InternalData {
+ public:
+ InternalData(int command_id, AcceleratorHandler* handler, int flags)
+ : command_id_(command_id), handler_(handler), flags_(flags) {}
+
+ bool IsNonAutoRepeatable() const { return flags_ & AF_NON_AUTO_REPEATABLE; }
+ bool IsDebug() const { return flags_ & AF_DEBUG; }
+ bool IsReserved() const { return flags_ & AF_RESERVED; }
+
+ bool IsCommandEnabled() const {
+ return handler_->IsCommandEnabled(command_id_);
+ }
+
+ bool OnAcceleratorFired(const ui::Accelerator& accelerator) {
+ return handler_->OnAcceleratorFired(command_id_, accelerator);
+ }
+
+ private:
+ int command_id_;
+ AcceleratorHandler* handler_;
+ int flags_;
+
+ // This class is copyable by design.
+};
+
+AcceleratorManagerImpl::AcceleratorManagerImpl()
+ : accelerator_manager_(new ui::AcceleratorManager) {
+}
+
+AcceleratorManagerImpl::~AcceleratorManagerImpl() {
+ nested_accelerator_controller_.reset();
+ accelerator_filter_.reset();
+}
+
+void AcceleratorManagerImpl::Init() {
+ ui::EventTarget* toplevel = InputManager::Get()->GetTopmostEventTarget();
+ nested_accelerator_controller_.reset(
+ new wm::NestedAcceleratorController(new NestedAcceleratorDelegate(this)));
+
+ scoped_ptr<wm::AcceleratorDelegate> accelerator_delegate(
+ new AcceleratorDelegate(this));
+
+ accelerator_filter_.reset(
+ new wm::AcceleratorFilter(accelerator_delegate.Pass()));
+ toplevel->AddPreTargetHandler(accelerator_filter_.get());
+}
+
+void AcceleratorManagerImpl::OnRootWindowCreated(aura::Window* root_window) {
+ aura::client::SetDispatcherClient(root_window,
+ nested_accelerator_controller_.get());
+}
+
+bool AcceleratorManagerImpl::IsReservedAccelerator(
+ const ui::Accelerator& accelerator) const {
+ std::map<ui::Accelerator, InternalData>::const_iterator iter =
+ accelerators_.find(accelerator);
+ if (iter == accelerators_.end())
+ return false;
+ return iter->second.IsReserved();
+}
+
+bool AcceleratorManagerImpl::ProcessAccelerator(
+ const ui::Accelerator& accelerator) {
+ return accelerator_manager_->Process(accelerator);
+}
+
+void AcceleratorManagerImpl::RegisterAccelerators(
+ const AcceleratorData accelerators[],
+ size_t num_accelerators,
+ AcceleratorHandler* handler) {
+ for (size_t i = 0; i < num_accelerators; ++i)
+ RegisterAccelerator(accelerators[i], handler);
+}
+
+void AcceleratorManagerImpl::EnableDebugAccelerators() {
+ debug_accelerators_enabled_ = true;
+}
+
+bool AcceleratorManagerImpl::AcceleratorPressed(
+ const ui::Accelerator& accelerator) {
+ std::map<ui::Accelerator, InternalData>::iterator iter =
+ accelerators_.find(accelerator);
+ DCHECK(iter != accelerators_.end());
+ if (iter == accelerators_.end())
+ return false;
+ InternalData& data = iter->second;
+ if (data.IsDebug() && !debug_accelerators_enabled_)
+ return false;
+ if (accelerator.IsRepeat() && data.IsNonAutoRepeatable())
+ return false;
+ return data.IsCommandEnabled() ? data.OnAcceleratorFired(accelerator) : false;
+}
+
+bool AcceleratorManagerImpl::CanHandleAccelerators() const {
+ return true;
+}
+
+void AcceleratorManagerImpl::RegisterAccelerator(
+ const AcceleratorData& accelerator_data,
+ AcceleratorHandler* handler) {
+ ui::Accelerator accelerator(accelerator_data.keycode,
+ accelerator_data.keyevent_flags);
+ accelerator.set_type(accelerator_data.trigger_event == TRIGGER_ON_PRESS
+ ? ui::ET_KEY_PRESSED
+ : ui::ET_KEY_RELEASED);
+ accelerator_manager_->Register(
+ accelerator, ui::AcceleratorManager::kNormalPriority, this);
+ accelerators_.insert(
+ std::make_pair(accelerator,
+ InternalData(accelerator_data.command_id,
+ handler,
+ accelerator_data.accelerator_flags)));
+}
+
+} // namespace athena
diff --git a/athena/input/accelerator_manager_impl.h b/athena/input/accelerator_manager_impl.h
new file mode 100644
index 0000000..1a5e8a9
--- /dev/null
+++ b/athena/input/accelerator_manager_impl.h
@@ -0,0 +1,76 @@
+// Copyright 2014 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.
+
+#ifndef ATHENA_INPUT_ACCELERATOR_MANAGER_H_
+#define ATHENA_INPUT_ACCELERATOR_MANAGER_H_
+
+#include "athena/input/public/accelerator_manager.h"
+
+#include <map>
+
+#include "base/macros.h"
+#include "ui/base/accelerators/accelerator.h"
+#include "ui/events/event_target_iterator.h"
+
+namespace aura {
+class Window;
+}
+
+namespace ui {
+class AcceleratorManager;
+}
+
+namespace wm {
+class AcceleratorFilter;
+class NestedAcceleratorController;
+}
+
+namespace athena {
+
+// AcceleratorManagerImpl provides a API to register accelerators
+// for athena modules. It hides various details on accelerator handling
+// such as how to handle accelerator in a nested loop, reserved accelerators
+// and repeated accelerators.
+class AcceleratorManagerImpl : public AcceleratorManager,
+ public ui::AcceleratorTarget {
+ public:
+ AcceleratorManagerImpl();
+ virtual ~AcceleratorManagerImpl();
+
+ void Init();
+
+ void OnRootWindowCreated(aura::Window* root_window);
+
+ bool IsReservedAccelerator(const ui::Accelerator& accelerator) const;
+ bool ProcessAccelerator(const ui::Accelerator& accelerator);
+
+ private:
+ // AcceleratorManager:
+ virtual void RegisterAccelerators(const AcceleratorData accelerators[],
+ size_t num_accelerators,
+ AcceleratorHandler* handler) OVERRIDE;
+ virtual void EnableDebugAccelerators() OVERRIDE;
+
+ // ui::AcceleratorTarget:
+ virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
+ virtual bool CanHandleAccelerators() const OVERRIDE;
+
+ class InternalData;
+
+ void RegisterAccelerator(const AcceleratorData& accelerator,
+ AcceleratorHandler* handler);
+
+ bool debug_accelerators_enabled_;
+ std::map<ui::Accelerator, InternalData> accelerators_;
+ scoped_ptr<ui::AcceleratorManager> accelerator_manager_;
+
+ scoped_ptr<wm::AcceleratorFilter> accelerator_filter_;
+ scoped_ptr<wm::NestedAcceleratorController> nested_accelerator_controller_;
+
+ DISALLOW_COPY_AND_ASSIGN(AcceleratorManagerImpl);
+};
+
+} // namespace athena
+
+#endif // ATHENA_INPUT_ACCELERATOR_MANAGER_H_
diff --git a/athena/input/accelerator_manager_unittest.cc b/athena/input/accelerator_manager_unittest.cc
new file mode 100644
index 0000000..cd80e86
--- /dev/null
+++ b/athena/input/accelerator_manager_unittest.cc
@@ -0,0 +1,120 @@
+// Copyright 2014 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 "athena/input/public/accelerator_manager.h"
+
+#include "athena/input/public/input_manager.h"
+#include "athena/test/athena_test_base.h"
+#include "ui/aura/test/event_generator.h"
+
+namespace athena {
+namespace {
+
+const int kInvalidCommandId = -1;
+
+class TestHandler : public AcceleratorHandler {
+ public:
+ TestHandler() : fired_command_id_(kInvalidCommandId), enabled_(true) {}
+ virtual ~TestHandler() {}
+
+ void set_enabled(bool enabled) { enabled_ = enabled; }
+
+ int GetFiredCommandIdAndReset() {
+ int fired = fired_command_id_;
+ fired_command_id_ = kInvalidCommandId;
+ return fired;
+ }
+
+ private:
+ // AcceleratorHandler:
+ virtual bool IsCommandEnabled(int command_id) const OVERRIDE {
+ return enabled_;
+ }
+ virtual bool OnAcceleratorFired(int command_id,
+ const ui::Accelerator& accelerator) OVERRIDE {
+ fired_command_id_ = command_id;
+ return true;
+ }
+
+ int fired_command_id_;
+ bool enabled_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestHandler);
+};
+
+} // namespace athena
+
+typedef test::AthenaTestBase InputManagerTest;
+
+TEST_F(InputManagerTest, Basic) {
+ enum TestCommandId {
+ COMMAND_A,
+ COMMAND_B,
+ COMMAND_C,
+ COMMAND_D,
+ COMMAND_E,
+ };
+ const AcceleratorData data[] = {
+ {TRIGGER_ON_PRESS, ui::VKEY_A, ui::EF_SHIFT_DOWN, COMMAND_A, AF_RESERVED},
+ {TRIGGER_ON_RELEASE, ui::VKEY_B, ui::EF_SHIFT_DOWN, COMMAND_B,
+ AF_RESERVED},
+ {TRIGGER_ON_PRESS, ui::VKEY_C, ui::EF_SHIFT_DOWN, COMMAND_C,
+ AF_RESERVED | AF_DEBUG},
+ {TRIGGER_ON_PRESS, ui::VKEY_D, ui::EF_SHIFT_DOWN, COMMAND_D,
+ AF_RESERVED | AF_NON_AUTO_REPEATABLE},
+ {TRIGGER_ON_PRESS, ui::VKEY_E, ui::EF_SHIFT_DOWN, COMMAND_E, AF_NONE},
+ };
+ AcceleratorManager* accelerator_manager =
+ InputManager::Get()->GetAcceleratorManager();
+ TestHandler test_handler;
+ accelerator_manager->RegisterAccelerators(
+ data, arraysize(data), &test_handler);
+
+ aura::test::EventGenerator generator(root_window());
+ generator.PressKey(ui::VKEY_A, ui::EF_NONE);
+ EXPECT_EQ(kInvalidCommandId, test_handler.GetFiredCommandIdAndReset());
+
+ // Trigger on press.
+ generator.PressKey(ui::VKEY_A, ui::EF_SHIFT_DOWN);
+ EXPECT_EQ(COMMAND_A, test_handler.GetFiredCommandIdAndReset());
+ generator.ReleaseKey(ui::VKEY_A, ui::EF_SHIFT_DOWN);
+ EXPECT_EQ(kInvalidCommandId, test_handler.GetFiredCommandIdAndReset());
+
+ // Trigger on release.
+ generator.PressKey(ui::VKEY_B, ui::EF_SHIFT_DOWN);
+ EXPECT_EQ(kInvalidCommandId, test_handler.GetFiredCommandIdAndReset());
+ generator.ReleaseKey(ui::VKEY_B, ui::EF_SHIFT_DOWN);
+ EXPECT_EQ(COMMAND_B, test_handler.GetFiredCommandIdAndReset());
+
+ // Disable command.
+ test_handler.set_enabled(false);
+ generator.PressKey(ui::VKEY_A, ui::EF_SHIFT_DOWN);
+ EXPECT_EQ(kInvalidCommandId, test_handler.GetFiredCommandIdAndReset());
+ test_handler.set_enabled(true);
+ generator.PressKey(ui::VKEY_A, ui::EF_SHIFT_DOWN);
+ EXPECT_EQ(COMMAND_A, test_handler.GetFiredCommandIdAndReset());
+
+ // Debug accelerators.
+ generator.PressKey(ui::VKEY_C, ui::EF_SHIFT_DOWN);
+ EXPECT_EQ(kInvalidCommandId, test_handler.GetFiredCommandIdAndReset());
+
+ accelerator_manager->EnableDebugAccelerators();
+ generator.PressKey(ui::VKEY_C, ui::EF_SHIFT_DOWN);
+ EXPECT_EQ(COMMAND_C, test_handler.GetFiredCommandIdAndReset());
+
+ // Non auto repeatable
+ generator.PressKey(ui::VKEY_D, ui::EF_SHIFT_DOWN);
+ EXPECT_EQ(COMMAND_D, test_handler.GetFiredCommandIdAndReset());
+ generator.PressKey(ui::VKEY_D, ui::EF_SHIFT_DOWN | ui::EF_IS_REPEAT);
+ EXPECT_EQ(kInvalidCommandId, test_handler.GetFiredCommandIdAndReset());
+
+ // Non reserved accelerator won't be handled unless there is
+ // a view's focus manager.
+ // TODO(oshima): Support view's focus manager. Investigate we can implement
+ // the non reserved behavior without view's focus manager.
+ generator.PressKey(ui::VKEY_E, ui::EF_SHIFT_DOWN);
+ EXPECT_EQ(kInvalidCommandId, test_handler.GetFiredCommandIdAndReset());
+}
+
+} // namespace athena
diff --git a/athena/input/input_manager_impl.cc b/athena/input/input_manager_impl.cc
new file mode 100644
index 0000000..3d1c803
--- /dev/null
+++ b/athena/input/input_manager_impl.cc
@@ -0,0 +1,122 @@
+// Copyright 2014 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 "athena/input/public/input_manager.h"
+
+#include "athena/input/accelerator_manager_impl.h"
+#include "base/logging.h"
+#include "ui/aura/client/event_client.h"
+#include "ui/aura/env.h"
+#include "ui/events/event_target.h"
+
+namespace athena {
+namespace {
+
+InputManager* instance = NULL;
+
+class InputManagerImpl : public InputManager,
+ public ui::EventTarget,
+ public aura::client::EventClient {
+ public:
+ InputManagerImpl();
+ virtual ~InputManagerImpl();
+
+ void Init();
+ void Shutdown();
+
+ private:
+ // InputManager:
+ virtual void OnRootWindowCreated(aura::Window* root_window) OVERRIDE;
+ virtual ui::EventTarget* GetTopmostEventTarget() OVERRIDE { return this; }
+ virtual AcceleratorManager* GetAcceleratorManager() OVERRIDE {
+ return accelerator_manager_.get();
+ }
+
+ // Overridden from aura::client::EventClient:
+ virtual bool CanProcessEventsWithinSubtree(
+ const aura::Window* window) const OVERRIDE {
+ return true;
+ }
+ virtual ui::EventTarget* GetToplevelEventTarget() OVERRIDE { return this; }
+
+ // ui::EventTarget:
+ virtual bool CanAcceptEvent(const ui::Event& event) OVERRIDE;
+ virtual ui::EventTarget* GetParentTarget() OVERRIDE;
+ virtual scoped_ptr<ui::EventTargetIterator> GetChildIterator() const OVERRIDE;
+ virtual ui::EventTargeter* GetEventTargeter() OVERRIDE;
+ virtual void OnEvent(ui::Event* event) OVERRIDE;
+
+ scoped_ptr<AcceleratorManagerImpl> accelerator_manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(InputManagerImpl);
+};
+
+InputManagerImpl::InputManagerImpl()
+ : accelerator_manager_(new AcceleratorManagerImpl) {
+ DCHECK(!instance);
+ instance = this;
+}
+
+InputManagerImpl::~InputManagerImpl() {
+ DCHECK_EQ(instance, this);
+ Shutdown();
+ instance = NULL;
+}
+
+void InputManagerImpl::Init() {
+ accelerator_manager_->Init();
+}
+
+void InputManagerImpl::Shutdown() {
+ accelerator_manager_.reset();
+}
+
+void InputManagerImpl::OnRootWindowCreated(aura::Window* root_window) {
+ aura::client::SetEventClient(root_window, this);
+ accelerator_manager_->OnRootWindowCreated(root_window);
+}
+
+bool InputManagerImpl::CanAcceptEvent(const ui::Event& event) {
+ return true;
+}
+
+ui::EventTarget* InputManagerImpl::GetParentTarget() {
+ return aura::Env::GetInstance();
+}
+
+scoped_ptr<ui::EventTargetIterator> InputManagerImpl::GetChildIterator() const {
+ return scoped_ptr<ui::EventTargetIterator>();
+}
+
+ui::EventTargeter* InputManagerImpl::GetEventTargeter() {
+ NOTREACHED();
+ return NULL;
+}
+
+void InputManagerImpl::OnEvent(ui::Event* event) {
+}
+
+} // namespace
+
+// static
+InputManager* InputManager::Create() {
+ (new InputManagerImpl)->Init();
+ DCHECK(instance);
+ return instance;
+}
+
+// static
+InputManager* InputManager::Get() {
+ DCHECK(instance);
+ return instance;
+}
+
+// static
+void InputManager::Shutdown() {
+ DCHECK(instance);
+ delete instance;
+ DCHECK(!instance);
+}
+
+} // namespace athena
diff --git a/athena/input/public/DEPS b/athena/input/public/DEPS
new file mode 100644
index 0000000..941cfac
--- /dev/null
+++ b/athena/input/public/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ "-athena/input",
+ "+athena/athena_export.h",
+]
diff --git a/athena/input/public/accelerator_manager.h b/athena/input/public/accelerator_manager.h
new file mode 100644
index 0000000..e0a1ad4
--- /dev/null
+++ b/athena/input/public/accelerator_manager.h
@@ -0,0 +1,72 @@
+// Copyright 2014 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.
+
+#ifndef ATHENA_INPUT_PUBLIC_ACCELERATOR_MANAGER_H_
+#define ATHENA_INPUT_PUBLIC_ACCELERATOR_MANAGER_H_
+
+#include "athena/athena_export.h"
+#include "ui/events/keycodes/keyboard_codes.h"
+
+namespace ui {
+class Accelerator;
+}
+
+namespace athena {
+
+enum TriggerEvent {
+ TRIGGER_ON_PRESS,
+ TRIGGER_ON_RELEASE,
+};
+
+// Accelerator flags.
+enum AcceleratorFlags {
+ AF_NONE = 0,
+ // Used for accelerators that should not be fired on auto repeated
+ // key event, such as toggling fullscrren.
+ AF_NON_AUTO_REPEATABLE = 1 << 0,
+ // Most key events are sent to applications first as they may
+ // want to consume them. Reserverd accelerators are reserved for OS
+ // and cannot be consumed by apps. (such as window cycling)
+ AF_RESERVED = 1 << 1,
+ // Used for accelerators that are useful only in debug mode.
+ AF_DEBUG = 1 << 2,
+};
+
+struct AcceleratorData {
+ // true if the accelerator should be triggered upon ui::ET_KEY_PRESSED
+ TriggerEvent trigger_event;
+ ui::KeyboardCode keycode; // KeyEvent event flags.
+ int keyevent_flags; // Combination of ui::KeyEventFlags
+ int command_id; // ID to distinguish
+ int accelerator_flags; // Combination of AcceleratorFlags;
+};
+
+// An interface that implements behavior for the set of
+// accelerators.
+class ATHENA_EXPORT AcceleratorHandler {
+ public:
+ virtual ~AcceleratorHandler() {}
+
+ virtual bool IsCommandEnabled(int command_id) const = 0;
+ virtual bool OnAcceleratorFired(int command_id,
+ const ui::Accelerator& accelerator) = 0;
+};
+
+class AcceleratorManager {
+ public:
+ virtual ~AcceleratorManager() {}
+
+ // Register accelerators and its handler that will be invoked when
+ // one of accelerator is fired.
+ virtual void RegisterAccelerators(const AcceleratorData accelerators[],
+ size_t num_accelerators,
+ AcceleratorHandler* handler) = 0;
+
+ // Enables accelerators that has a AF_DEBUG flag.
+ virtual void EnableDebugAccelerators() = 0;
+};
+
+} // namespace athena
+
+#endif // ATHENA_INPUT_PUBLIC_ACCELERATOR_MANAGER_H_
diff --git a/athena/input/public/input_manager.h b/athena/input/public/input_manager.h
new file mode 100644
index 0000000..cc70175
--- /dev/null
+++ b/athena/input/public/input_manager.h
@@ -0,0 +1,41 @@
+// Copyright 2014 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.
+
+#ifndef ATHENA_INPUT_PUBLIC_INPUT_MANAGER_H_
+#define ATHENA_INPUT_PUBLIC_INPUT_MANAGER_H_
+
+#include "athena/athena_export.h"
+
+namespace aura {
+class Window;
+}
+
+namespace ui {
+class EventTarget;
+}
+
+namespace athena {
+class AcceleratorManager;
+
+class ATHENA_EXPORT InputManager {
+ public:
+ // Creates and deletes the singleton object of the InputManager
+ // implementation.
+ static InputManager* Create();
+ static InputManager* Get();
+ static void Shutdown();
+
+ // TODO(oshima): Fix the initialization process and replace this
+ // with EnvObserver::WindowInitialized
+ virtual void OnRootWindowCreated(aura::Window* root_window) = 0;
+
+ virtual ui::EventTarget* GetTopmostEventTarget() = 0;
+ virtual AcceleratorManager* GetAcceleratorManager() = 0;
+
+ virtual ~InputManager() {}
+};
+
+} // namespace athena
+
+#endif // ATHENA_INPUT_PUBLIC_INPUT_MANAGER_H_
diff --git a/athena/main/DEPS b/athena/main/DEPS
index 9d9de5a..2f77e06 100644
--- a/athena/main/DEPS
+++ b/athena/main/DEPS
@@ -2,6 +2,7 @@ include_rules = [
"+athena/activity/public",
"+athena/content/public",
"+athena/home/public",
+ "+athena/input/public",
"+athena/screen/public",
"+athena/task/public",
"+athena/wm/public",
diff --git a/athena/main/athena_launcher.cc b/athena/main/athena_launcher.cc
index 89e8452..6faa396 100644
--- a/athena/main/athena_launcher.cc
+++ b/athena/main/athena_launcher.cc
@@ -7,6 +7,7 @@
#include "athena/activity/public/activity_factory.h"
#include "athena/activity/public/activity_manager.h"
#include "athena/home/public/home_card.h"
+#include "athena/input/public/input_manager.h"
#include "athena/main/placeholder.h"
#include "athena/screen/public/screen_manager.h"
#include "athena/wm/public/window_manager.h"
@@ -47,6 +48,7 @@ void StartAthena(aura::Window* root_window,
aura::client::SetVisibilityClient(root_window,
root_window_state->visibility_client.get());
+ athena::InputManager::Create()->OnRootWindowCreated(root_window);
athena::ScreenManager::Create(root_window);
athena::WindowManager::Create();
athena::HomeCard::Create();
@@ -61,6 +63,7 @@ void ShutdownAthena() {
athena::HomeCard::Shutdown();
athena::WindowManager::Shutdown();
athena::ScreenManager::Shutdown();
+ athena::InputManager::Shutdown();
}
} // namespace athena