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.
5 #ifndef CHROME_BROWSER_UI_EXTENSIONS_EXTENSION_ACTION_VIEW_CONTROLLER_H_
6 #define CHROME_BROWSER_UI_EXTENSIONS_EXTENSION_ACTION_VIEW_CONTROLLER_H_
8 #include "base/scoped_observer.h"
9 #include "chrome/browser/extensions/extension_action_icon_factory.h"
10 #include "chrome/browser/extensions/extension_context_menu_model.h"
11 #include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h"
12 #include "extensions/browser/extension_host_observer.h"
13 #include "ui/gfx/image/image.h"
16 class ExtensionAction
;
17 class ExtensionActionPlatformDelegate
;
20 namespace extensions
{
23 class ExtensionRegistry
;
24 class ExtensionViewHost
;
27 // The platform-independent controller for an ExtensionAction that is shown on
28 // the toolbar (such as a page or browser action).
29 // Since this class doesn't own the extension or extension action in question,
30 // be sure to check for validity using ExtensionIsValid() before using those
31 // members (see also comments above ExtensionIsValid()).
32 class ExtensionActionViewController
33 : public ToolbarActionViewController
,
34 public ExtensionActionIconFactory::Observer
,
35 public ExtensionContextMenuModel::PopupDelegate
,
36 public extensions::ExtensionHostObserver
{
38 // The different options for showing a popup.
39 enum PopupShowAction
{ SHOW_POPUP
, SHOW_POPUP_AND_INSPECT
};
41 ExtensionActionViewController(const extensions::Extension
* extension
,
43 ExtensionAction
* extension_action
);
44 ~ExtensionActionViewController() override
;
46 // ToolbarActionViewController:
47 const std::string
& GetId() const override
;
48 void SetDelegate(ToolbarActionViewDelegate
* delegate
) override
;
49 gfx::Image
GetIcon(content::WebContents
* web_contents
) override
;
50 gfx::ImageSkia
GetIconWithBadge() override
;
51 base::string16
GetActionName() const override
;
52 base::string16
GetAccessibleName(content::WebContents
* web_contents
) const
54 base::string16
GetTooltip(content::WebContents
* web_contents
) const override
;
55 bool IsEnabled(content::WebContents
* web_contents
) const override
;
56 bool WantsToRun(content::WebContents
* web_contents
) const override
;
57 bool HasPopup(content::WebContents
* web_contents
) const override
;
58 void HidePopup() override
;
59 gfx::NativeView
GetPopupNativeView() override
;
60 ui::MenuModel
* GetContextMenu() override
;
61 bool IsMenuRunning() const override
;
62 bool CanDrag() const override
;
63 bool ExecuteAction(bool by_user
) override
;
64 void UpdateState() override
;
65 void PaintExtra(gfx::Canvas
* canvas
,
66 const gfx::Rect
& bounds
,
67 content::WebContents
* web_contents
) const override
;
68 void RegisterCommand() override
;
70 // ExtensionContextMenuModel::PopupDelegate:
71 void InspectPopup() override
;
73 // Populates |command| with the command associated with |extension|, if one
74 // exists. Returns true if |command| was populated.
75 bool GetExtensionCommand(extensions::Command
* command
);
77 const extensions::Extension
* extension() const { return extension_
; }
78 Browser
* browser() { return browser_
; }
79 ExtensionAction
* extension_action() { return extension_action_
; }
80 const ExtensionAction
* extension_action() const { return extension_action_
; }
81 ToolbarActionViewDelegate
* view_delegate() { return view_delegate_
; }
82 bool is_showing_popup() const { return popup_host_
!= nullptr; }
84 void set_icon_observer(ExtensionActionIconFactory::Observer
* icon_observer
) {
85 icon_observer_
= icon_observer
;
89 // ExtensionActionIconFactory::Observer:
90 void OnIconUpdated() override
;
92 // ExtensionHostObserver:
93 void OnExtensionHostDestroyed(const extensions::ExtensionHost
* host
) override
;
95 // Checks if the associated |extension| is still valid by checking its
96 // status in the registry. Since the OnExtensionUnloaded() notifications are
97 // not in a deterministic order, it's possible that the view tries to refresh
98 // itself before we're notified to remove it.
99 bool ExtensionIsValid() const;
101 // Executes the extension action with |show_action|. If
102 // |grant_tab_permissions| is true, this will grant the extension active tab
103 // permissions. Only do this if this was done through a user action (and not
104 // e.g. an API). Returns true if a popup is shown.
105 bool ExecuteAction(PopupShowAction show_action
, bool grant_tab_permissions
);
107 // Shows the popup for the extension action, given the associated |popup_url|.
108 // |grant_tab_permissions| is true if active tab permissions should be given
109 // to the extension; this is only true if the popup is opened through a user
111 // Returns true if a popup is successfully shown.
112 bool ShowPopupWithUrl(PopupShowAction show_action
,
113 const GURL
& popup_url
,
114 bool grant_tab_permissions
);
116 // Handles cleanup after the popup closes.
117 void OnPopupClosed();
119 // The extension associated with the action we're displaying.
120 const extensions::Extension
* extension_
;
122 // The corresponding browser.
125 // The browser action this view represents. The ExtensionAction is not owned
127 ExtensionAction
* extension_action_
;
129 // The extension popup's host if the popup is visible; null otherwise.
130 extensions::ExtensionViewHost
* popup_host_
;
132 // The context menu model for the extension.
133 scoped_refptr
<ExtensionContextMenuModel
> context_menu_model_
;
135 // Our view delegate.
136 ToolbarActionViewDelegate
* view_delegate_
;
138 // The delegate to handle platform-specific implementations.
139 scoped_ptr
<ExtensionActionPlatformDelegate
> platform_delegate_
;
141 // The object that will be used to get the browser action icon for us.
142 // It may load the icon asynchronously (in which case the initial icon
143 // returned by the factory will be transparent), so we have to observe it for
144 // updates to the icon.
145 ExtensionActionIconFactory icon_factory_
;
147 // An additional observer that we need to notify when the icon of the button
149 ExtensionActionIconFactory::Observer
* icon_observer_
;
151 // The associated ExtensionRegistry; cached for quick checking.
152 extensions::ExtensionRegistry
* extension_registry_
;
154 ScopedObserver
<extensions::ExtensionHost
, extensions::ExtensionHostObserver
>
155 popup_host_observer_
;
157 DISALLOW_COPY_AND_ASSIGN(ExtensionActionViewController
);
160 #endif // CHROME_BROWSER_UI_EXTENSIONS_EXTENSION_ACTION_VIEW_CONTROLLER_H_