Home | History | Annotate | Download | only in extensions
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_ACTION_VIEW_CONTROLLER_H_
      6 #define CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_ACTION_VIEW_CONTROLLER_H_
      7 
      8 #include "chrome/browser/extensions/extension_action_icon_factory.h"
      9 #include "chrome/browser/extensions/extension_context_menu_model.h"
     10 #include "chrome/browser/ui/views/extensions/extension_popup.h"
     11 #include "ui/base/accelerators/accelerator.h"
     12 #include "ui/gfx/image/image.h"
     13 #include "ui/views/context_menu_controller.h"
     14 #include "ui/views/widget/widget_observer.h"
     15 
     16 class Browser;
     17 class ExtensionAction;
     18 class ExtensionActionViewDelegate;
     19 
     20 namespace content {
     21 class WebContents;
     22 }
     23 
     24 namespace extensions {
     25 class Command;
     26 class Extension;
     27 }
     28 
     29 namespace ui {
     30 class Accelerator;
     31 }
     32 
     33 namespace views {
     34 class MenuRunner;
     35 class View;
     36 class Widget;
     37 }
     38 
     39 // An abstract "View" for an ExtensionAction (either a BrowserAction or a
     40 // PageAction). This contains the logic for showing the action's popup and
     41 // the context menu. This class doesn't subclass View directly, as the
     42 // implementations for page actions/browser actions are different types of
     43 // views.
     44 // All common logic for executing extension actions should go in this class;
     45 // ExtensionActionViewDelegate classes should only have knowledge relating to
     46 // the views::View wrapper.
     47 class ExtensionActionViewController
     48     : public ExtensionActionIconFactory::Observer,
     49       public ExtensionContextMenuModel::PopupDelegate,
     50       public ui::AcceleratorTarget,
     51       public views::ContextMenuController,
     52       public views::WidgetObserver {
     53  public:
     54   ExtensionActionViewController(const extensions::Extension* extension,
     55                                 Browser* browser,
     56                                 ExtensionAction* extension_action,
     57                                 ExtensionActionViewDelegate* delegate);
     58   virtual ~ExtensionActionViewController();
     59 
     60   // ExtensionContextMenuModel::PopupDelegate:
     61   virtual void InspectPopup() OVERRIDE;
     62 
     63   // Executes the default extension action (typically showing the popup), and
     64   // attributes the action to a user (thus, only use this for actions that
     65   // *were* done by the user).
     66   void ExecuteActionByUser();
     67 
     68   // Executes the extension action with |show_action|. If
     69   // |grant_tab_permissions| is true, this will grant the extension active tab
     70   // permissions. Only do this if this was done through a user action (and not
     71   // e.g. an API). Returns true if a popup is shown.
     72   bool ExecuteAction(ExtensionPopup::ShowAction show_action,
     73                      bool grant_tab_permissions);
     74 
     75   // Hides the popup, if one is open.
     76   void HidePopup();
     77 
     78   // Returns the icon from the |icon_factory_|.
     79   gfx::Image GetIcon(int tab_id);
     80 
     81   // Returns the current tab id.
     82   int GetCurrentTabId() const;
     83 
     84   // Registers an accelerator for the extension action's command, if one
     85   // exists.
     86   void RegisterCommand();
     87 
     88   // Unregisters the accelerator for the extension action's command, if one
     89   // exists. If |only_if_removed| is true, then this will only unregister if the
     90   // command has been removed.
     91   void UnregisterCommand(bool only_if_removed);
     92 
     93   const extensions::Extension* extension() const { return extension_; }
     94   Browser* browser() { return browser_; }
     95   ExtensionAction* extension_action() { return extension_action_; }
     96   const ExtensionAction* extension_action() const { return extension_action_; }
     97   ExtensionPopup* popup() { return popup_; }
     98   bool is_menu_running() const { return menu_runner_.get() != NULL; }
     99 
    100  private:
    101   // ExtensionActionIconFactory::Observer:
    102   virtual void OnIconUpdated() OVERRIDE;
    103 
    104   // ui::AcceleratorTarget:
    105   virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
    106   virtual bool CanHandleAccelerators() const OVERRIDE;
    107 
    108   // views::WidgetObserver:
    109   virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE;
    110 
    111   // views::ContextMenuController:
    112   virtual void ShowContextMenuForView(views::View* source,
    113                                       const gfx::Point& point,
    114                                       ui::MenuSourceType source_type) OVERRIDE;
    115 
    116   // Shows the context menu for extension action.
    117   void DoShowContextMenu(ui::MenuSourceType source_type);
    118 
    119   // Shows the popup for the extension action, given the associated |popup_url|.
    120   // |grant_tab_permissions| is true if active tab permissions should be given
    121   // to the extension; this is only true if the popup is opened through a user
    122   // action.
    123   // Returns true if a popup is successfully shown.
    124   bool ShowPopupWithUrl(ExtensionPopup::ShowAction show_action,
    125                         const GURL& popup_url,
    126                         bool grant_tab_permissions);
    127 
    128   // Populates |command| with the command associated with |extension|, if one
    129   // exists. Returns true if |command| was populated.
    130   bool GetExtensionCommand(extensions::Command* command);
    131 
    132   // Closes the currently-active menu, if needed. This is the case when there
    133   // is an active menu that wouldn't close automatically when a new one is
    134   // opened.
    135   // Returns true if a menu was closed, false otherwise.
    136   bool CloseActiveMenuIfNeeded();
    137 
    138   // Cleans up after the popup. If |close_widget| is true, this will call
    139   // Widget::Close() on the popup's widget; otherwise it assumes the popup is
    140   // already closing.
    141   void CleanupPopup(bool close_widget);
    142 
    143   // The extension associated with the action we're displaying.
    144   const extensions::Extension* extension_;
    145 
    146   // The corresponding browser.
    147   Browser* browser_;
    148 
    149   // The browser action this view represents. The ExtensionAction is not owned
    150   // by this class.
    151   ExtensionAction* extension_action_;
    152 
    153   // Our delegate.
    154   ExtensionActionViewDelegate* delegate_;
    155 
    156   // The object that will be used to get the browser action icon for us.
    157   // It may load the icon asynchronously (in which case the initial icon
    158   // returned by the factory will be transparent), so we have to observe it for
    159   // updates to the icon.
    160   ExtensionActionIconFactory icon_factory_;
    161 
    162   // Responsible for running the menu.
    163   scoped_ptr<views::MenuRunner> menu_runner_;
    164 
    165   // The browser action's popup, if it is visible; NULL otherwise.
    166   ExtensionPopup* popup_;
    167 
    168   // The extension key binding accelerator this extension action is listening
    169   // for (to show the popup).
    170   scoped_ptr<ui::Accelerator> action_keybinding_;
    171 
    172   // If non-NULL, this is the next ExtensionActionViewController context menu
    173   // which wants to run once the current owner (this one) is done.
    174   base::Closure followup_context_menu_task_;
    175 
    176   base::WeakPtrFactory<ExtensionActionViewController> weak_factory_;
    177 
    178   DISALLOW_COPY_AND_ASSIGN(ExtensionActionViewController);
    179 };
    180 
    181 #endif  // CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_ACTION_VIEW_CONTROLLER_H_
    182