14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file.
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/extensions/global_shortcut_listener_chromeos.h"
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ash/accelerators/accelerator_controller.h"
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ash/shell.h"
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using content::BrowserThread;
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace extensions {
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)GlobalShortcutListener* GlobalShortcutListener::GetInstance() {
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static GlobalShortcutListenerChromeOS* instance =
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new GlobalShortcutListenerChromeOS();
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return instance;
214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)GlobalShortcutListenerChromeOS::GlobalShortcutListenerChromeOS()
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    : is_listening_(false) {
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)GlobalShortcutListenerChromeOS::~GlobalShortcutListenerChromeOS() {
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (is_listening_)
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    StopListening();
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void GlobalShortcutListenerChromeOS::StartListening() {
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!is_listening_);  // Don't start twice.
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  is_listening_ = true;
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void GlobalShortcutListenerChromeOS::StopListening() {
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(is_listening_);  // No point if we are not already listening.
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  is_listening_ = false;
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool GlobalShortcutListenerChromeOS::RegisterAcceleratorImpl(
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ui::Accelerator& accelerator) {
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ash::AcceleratorController* controller =
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ash::Shell::GetInstance()->accelerator_controller();
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (controller->IsRegistered(accelerator))
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TODO(dtseng): Support search key mapping.
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  controller->Register(accelerator, this);
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return controller->IsRegistered(accelerator);
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void GlobalShortcutListenerChromeOS::UnregisterAcceleratorImpl(
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ui::Accelerator& accelerator) {
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // This code path gets called during object destruction.
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!ash::Shell::HasInstance())
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ash::Shell::GetInstance()->accelerator_controller()->Unregister(accelerator,
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                                  this);
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool GlobalShortcutListenerChromeOS::AcceleratorPressed(
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const ui::Accelerator& accelerator) {
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(is_listening_);
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ash::AcceleratorController* controller =
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ash::Shell::GetInstance()->accelerator_controller();
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ash::AcceleratorController::AcceleratorProcessingRestriction restriction =
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      controller->GetCurrentAcceleratorRestriction();
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (restriction == ash::AcceleratorController::RESTRICTION_NONE) {
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    NotifyKeyPressed(accelerator);
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return true;
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return restriction == ash::AcceleratorController::
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            RESTRICTION_PREVENT_PROCESSING_AND_PROPAGATION;
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool GlobalShortcutListenerChromeOS::CanHandleAccelerators() const {
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return is_listening_;
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace extensions
84