Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / extension_keybinding_registry.h
index 723a6bb..85ec8d8 100644 (file)
@@ -5,16 +5,21 @@
 #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_KEYBINDING_REGISTRY_H_
 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_KEYBINDING_REGISTRY_H_
 
+#include <list>
 #include <map>
 #include <string>
 
 #include "base/compiler_specific.h"
+#include "base/scoped_observer.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_source.h"
+#include "extensions/browser/extension_registry_observer.h"
 
-class Profile;
+namespace content {
+class BrowserContext;
+}
 
 namespace ui {
 class Accelerator;
@@ -24,11 +29,13 @@ namespace extensions {
 
 class ActiveTabPermissionGranter;
 class Extension;
+class ExtensionRegistry;
 
 // The ExtensionKeybindingRegistry is a class that handles the cross-platform
 // logic for keyboard accelerators. See platform-specific implementations for
 // implementation details for each platform.
-class ExtensionKeybindingRegistry : public content::NotificationObserver {
+class ExtensionKeybindingRegistry : public content::NotificationObserver,
+                                    public ExtensionRegistryObserver {
  public:
   enum ExtensionFilter {
     ALL_EXTENSIONS,
@@ -44,20 +51,20 @@ class ExtensionKeybindingRegistry : public content::NotificationObserver {
 
   // If |extension_filter| is not ALL_EXTENSIONS, only keybindings by
   // by extensions that match the filter will be registered.
-  ExtensionKeybindingRegistry(Profile* profile,
+  ExtensionKeybindingRegistry(content::BrowserContext* context,
                               ExtensionFilter extension_filter,
                               Delegate* delegate);
 
   virtual ~ExtensionKeybindingRegistry();
 
-  // Enables/Disables general shortcut handing in Chrome. Implemented in
+  // Enables/Disables general shortcut handling in Chrome. Implemented in
   // platform-specific ExtensionKeybindingsRegistry* files.
   static void SetShortcutHandlingSuspended(bool suspended);
 
-  // Overridden from content::NotificationObserver:
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) OVERRIDE;
+  // Execute the command bound to |accelerator| and provided by the extension
+  // with |extension_id|, if it exists.
+  void ExecuteCommand(const std::string& extension_id,
+                      const ui::Accelerator& accelerator);
 
  protected:
   // Add extension keybinding for the events defined by the |extension|.
@@ -84,28 +91,67 @@ class ExtensionKeybindingRegistry : public content::NotificationObserver {
   // commands are currently ignored, since they are handled elsewhere.
   bool ShouldIgnoreCommand(const std::string& command) const;
 
+  // Fire event targets which the specified |accelerator| is binding with.
+  // Returns true if we can find the appropriate event targets.
+  bool NotifyEventTargets(const ui::Accelerator& accelerator);
+
   // Notifies appropriate parties that a command has been executed.
   void CommandExecuted(const std::string& extension_id,
                        const std::string& command);
 
-  // Maps an accelerator to a string pair (extension id, command name) for
-  // commands that have been registered. This keeps track of the targets for the
-  // keybinding event (which named command to call in which extension). On GTK,
-  // this map contains registration for pageAction and browserAction commands,
-  // whereas on other platforms it does not.
-  typedef std::map< ui::Accelerator,
-                    std::pair<std::string, std::string> > EventTargets;
-  EventTargets event_targets_;
+  // Check whether the specified |accelerator| has been registered.
+  bool IsAcceleratorRegistered(const ui::Accelerator& accelerator) const;
+
+  // Add event target (extension_id, command name) to the target list of
+  // |accelerator|. Note that only media keys can have more than one event
+  // target.
+  void AddEventTarget(const ui::Accelerator& accelerator,
+                      const std::string& extension_id,
+                      const std::string& command_name);
+
+  // Get the first event target by the given |accelerator|. For a valid
+  // accelerator it should have only one event target, except for media keys.
+  // Returns true if we can find it, |extension_id| and |command_name| will be
+  // set to the right target; otherwise, false is returned and |extension_id|,
+  // |command_name| are unchanged.
+  bool GetFirstTarget(const ui::Accelerator& accelerator,
+                      std::string* extension_id,
+                      std::string* command_name) const;
+
+  // Returns true if the |event_targets_| is empty; otherwise returns false.
+  bool IsEventTargetsEmpty() const;
+
+  // Returns the BrowserContext for this registry.
+  content::BrowserContext* browser_context() const { return browser_context_; }
 
  private:
+  // Overridden from content::NotificationObserver:
+  virtual void Observe(int type,
+                       const content::NotificationSource& source,
+                       const content::NotificationDetails& details) OVERRIDE;
+
+  // ExtensionRegistryObserver implementation.
+  virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
+                                 const Extension* extension) OVERRIDE;
+  virtual void OnExtensionUnloaded(
+      content::BrowserContext* browser_context,
+      const Extension* extension,
+      UnloadedExtensionInfo::Reason reason) OVERRIDE;
+
   // Returns true if the |extension| matches our extension filter.
   bool ExtensionMatchesFilter(const extensions::Extension* extension);
 
+  // Execute commands for |accelerator|. If |extension_id| is empty, execute all
+  // commands bound to |accelerator|, otherwise execute only commands bound by
+  // the corresponding extension. Returns true if at least one command was
+  // executed.
+  bool ExecuteCommands(const ui::Accelerator& accelerator,
+                       const std::string& extension_id);
+
   // The content notification registrar for listening to extension events.
   content::NotificationRegistrar registrar_;
 
-  // Weak pointer to our profile. Not owned by us.
-  Profile* profile_;
+  content::BrowserContext* browser_context_;
 
   // What extensions to register keybindings for.
   ExtensionFilter extension_filter_;
@@ -113,6 +159,21 @@ class ExtensionKeybindingRegistry : public content::NotificationObserver {
   // Weak pointer to our delegate. Not owned by us. Must outlive this class.
   Delegate* delegate_;
 
+  // Maps an accelerator to a list of string pairs (extension id, command name)
+  // for commands that have been registered. This keeps track of the targets for
+  // the keybinding event (which named command to call in which extension). On
+  // GTK this map contains registration for pageAction and browserAction
+  // commands, whereas on other platforms it does not. Note that normal
+  // accelerator (which isn't media keys) has only one target, while the media
+  // keys can have more than one.
+  typedef std::list<std::pair<std::string, std::string> > TargetList;
+  typedef std::map<ui::Accelerator, TargetList> EventTargets;
+  EventTargets event_targets_;
+
+  // Listen to extension load, unloaded notifications.
+  ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
+      extension_registry_observer_;
+
   DISALLOW_COPY_AND_ASSIGN(ExtensionKeybindingRegistry);
 };