blob: 3bbdb08a6a65400c05d205db83bf470dfe94465f [file] [log] [blame]
rdevlin.cronin09530742014-11-03 19:23:281// 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_EXTENSIONS_EXTENSION_ACTION_VIEW_CONTROLLER_H_
6#define CHROME_BROWSER_UI_EXTENSIONS_EXTENSION_ACTION_VIEW_CONTROLLER_H_
7
rdevlin.cronin42efb7dd2015-02-11 17:50:528#include "base/scoped_observer.h"
rdevlin.cronin09530742014-11-03 19:23:289#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"
rdevlin.cronin42efb7dd2015-02-11 17:50:5212#include "extensions/browser/extension_host_observer.h"
rdevlin.cronin09530742014-11-03 19:23:2813#include "ui/gfx/image/image.h"
14
15class Browser;
16class ExtensionAction;
17class ExtensionActionPlatformDelegate;
18class GURL;
19
20namespace extensions {
21class Command;
22class Extension;
rdevlin.cronin651153652014-11-15 00:34:4823class ExtensionRegistry;
rdevlin.croninb43d48e2015-01-29 17:51:4124class ExtensionViewHost;
rdevlin.cronin09530742014-11-03 19:23:2825}
26
27// The platform-independent controller for an ExtensionAction that is shown on
28// the toolbar (such as a page or browser action).
rdevlin.cronin651153652014-11-15 00:34:4829// 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()).
rdevlin.cronin09530742014-11-03 19:23:2832class ExtensionActionViewController
33 : public ToolbarActionViewController,
34 public ExtensionActionIconFactory::Observer,
rdevlin.croninb43d48e2015-01-29 17:51:4135 public ExtensionContextMenuModel::PopupDelegate,
rdevlin.cronin42efb7dd2015-02-11 17:50:5236 public extensions::ExtensionHostObserver {
rdevlin.cronin09530742014-11-03 19:23:2837 public:
38 // The different options for showing a popup.
39 enum PopupShowAction { SHOW_POPUP, SHOW_POPUP_AND_INSPECT };
40
41 ExtensionActionViewController(const extensions::Extension* extension,
42 Browser* browser,
43 ExtensionAction* extension_action);
44 ~ExtensionActionViewController() override;
45
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
53 override;
54 base::string16 GetTooltip(content::WebContents* web_contents) const override;
55 bool IsEnabled(content::WebContents* web_contents) const override;
rdevlin.croninf762e8da2014-12-02 20:57:1056 bool WantsToRun(content::WebContents* web_contents) const override;
rdevlin.cronin09530742014-11-03 19:23:2857 bool HasPopup(content::WebContents* web_contents) const override;
58 void HidePopup() override;
59 gfx::NativeView GetPopupNativeView() override;
rdevlin.croninc10ac9e2015-01-16 21:10:0860 ui::MenuModel* GetContextMenu() override;
rdevlin.cronin09530742014-11-03 19:23:2861 bool IsMenuRunning() const override;
62 bool CanDrag() const override;
63 bool ExecuteAction(bool by_user) override;
rdevlin.cronin1b9a3a12014-11-13 17:15:1164 void UpdateState() override;
rdevlin.cronin09530742014-11-03 19:23:2865 void PaintExtra(gfx::Canvas* canvas,
66 const gfx::Rect& bounds,
67 content::WebContents* web_contents) const override;
68 void RegisterCommand() override;
69
70 // ExtensionContextMenuModel::PopupDelegate:
71 void InspectPopup() override;
72
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);
76
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_; }
rdevlin.croninb43d48e2015-01-29 17:51:4182 bool is_showing_popup() const { return popup_host_ != nullptr; }
rdevlin.cronin09530742014-11-03 19:23:2883
84 void set_icon_observer(ExtensionActionIconFactory::Observer* icon_observer) {
85 icon_observer_ = icon_observer;
86 }
87
88 private:
89 // ExtensionActionIconFactory::Observer:
90 void OnIconUpdated() override;
91
rdevlin.cronin42efb7dd2015-02-11 17:50:5292 // ExtensionHostObserver:
93 void OnExtensionHostDestroyed(const extensions::ExtensionHost* host) override;
rdevlin.croninb43d48e2015-01-29 17:51:4194
rdevlin.cronin651153652014-11-15 00:34:4895 // 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;
100
rdevlin.cronin09530742014-11-03 19:23:28101 // 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);
106
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
110 // action.
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);
115
rdevlin.croninb43d48e2015-01-29 17:51:41116 // Handles cleanup after the popup closes.
117 void OnPopupClosed();
118
rdevlin.cronin09530742014-11-03 19:23:28119 // The extension associated with the action we're displaying.
120 const extensions::Extension* extension_;
121
122 // The corresponding browser.
123 Browser* browser_;
124
125 // The browser action this view represents. The ExtensionAction is not owned
126 // by this class.
127 ExtensionAction* extension_action_;
128
rdevlin.croninb43d48e2015-01-29 17:51:41129 // The extension popup's host if the popup is visible; null otherwise.
130 extensions::ExtensionViewHost* popup_host_;
131
rdevlin.croninc10ac9e2015-01-16 21:10:08132 // The context menu model for the extension.
133 scoped_refptr<ExtensionContextMenuModel> context_menu_model_;
134
rdevlin.cronin09530742014-11-03 19:23:28135 // Our view delegate.
136 ToolbarActionViewDelegate* view_delegate_;
137
138 // The delegate to handle platform-specific implementations.
139 scoped_ptr<ExtensionActionPlatformDelegate> platform_delegate_;
140
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_;
146
147 // An additional observer that we need to notify when the icon of the button
148 // has been updated.
149 ExtensionActionIconFactory::Observer* icon_observer_;
150
rdevlin.cronin651153652014-11-15 00:34:48151 // The associated ExtensionRegistry; cached for quick checking.
152 extensions::ExtensionRegistry* extension_registry_;
153
rdevlin.cronin42efb7dd2015-02-11 17:50:52154 ScopedObserver<extensions::ExtensionHost, extensions::ExtensionHostObserver>
155 popup_host_observer_;
rdevlin.croninb43d48e2015-01-29 17:51:41156
rdevlin.cronin09530742014-11-03 19:23:28157 DISALLOW_COPY_AND_ASSIGN(ExtensionActionViewController);
158};
159
160#endif // CHROME_BROWSER_UI_EXTENSIONS_EXTENSION_ACTION_VIEW_CONTROLLER_H_