blob: a6a903fa91e4654dc05ec903fd9e8b5a86331184 [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
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/toolbar/toolbar_action_view_controller.h"
11#include "ui/gfx/image/image.h"
12
13class Browser;
14class ExtensionAction;
15class ExtensionActionPlatformDelegate;
16class GURL;
17
18namespace extensions {
19class Command;
20class Extension;
rdevlin.cronin651153652014-11-15 00:34:4821class ExtensionRegistry;
rdevlin.cronin09530742014-11-03 19:23:2822}
23
24// The platform-independent controller for an ExtensionAction that is shown on
25// the toolbar (such as a page or browser action).
rdevlin.cronin651153652014-11-15 00:34:4826// Since this class doesn't own the extension or extension action in question,
27// be sure to check for validity using ExtensionIsValid() before using those
28// members (see also comments above ExtensionIsValid()).
rdevlin.cronin09530742014-11-03 19:23:2829class ExtensionActionViewController
30 : public ToolbarActionViewController,
31 public ExtensionActionIconFactory::Observer,
32 public ExtensionContextMenuModel::PopupDelegate {
33 public:
34 // The different options for showing a popup.
35 enum PopupShowAction { SHOW_POPUP, SHOW_POPUP_AND_INSPECT };
36
37 ExtensionActionViewController(const extensions::Extension* extension,
38 Browser* browser,
39 ExtensionAction* extension_action);
40 ~ExtensionActionViewController() override;
41
42 // ToolbarActionViewController:
43 const std::string& GetId() const override;
44 void SetDelegate(ToolbarActionViewDelegate* delegate) override;
45 gfx::Image GetIcon(content::WebContents* web_contents) override;
46 gfx::ImageSkia GetIconWithBadge() override;
47 base::string16 GetActionName() const override;
48 base::string16 GetAccessibleName(content::WebContents* web_contents) const
49 override;
50 base::string16 GetTooltip(content::WebContents* web_contents) const override;
51 bool IsEnabled(content::WebContents* web_contents) const override;
rdevlin.croninf762e8da2014-12-02 20:57:1052 bool WantsToRun(content::WebContents* web_contents) const override;
rdevlin.cronin09530742014-11-03 19:23:2853 bool HasPopup(content::WebContents* web_contents) const override;
54 void HidePopup() override;
55 gfx::NativeView GetPopupNativeView() override;
rdevlin.croninc10ac9e2015-01-16 21:10:0856 ui::MenuModel* GetContextMenu() override;
rdevlin.cronin09530742014-11-03 19:23:2857 bool IsMenuRunning() const override;
58 bool CanDrag() const override;
59 bool ExecuteAction(bool by_user) override;
rdevlin.cronin1b9a3a12014-11-13 17:15:1160 void UpdateState() override;
rdevlin.cronin09530742014-11-03 19:23:2861 void PaintExtra(gfx::Canvas* canvas,
62 const gfx::Rect& bounds,
63 content::WebContents* web_contents) const override;
64 void RegisterCommand() override;
65
66 // ExtensionContextMenuModel::PopupDelegate:
67 void InspectPopup() override;
68
69 // Populates |command| with the command associated with |extension|, if one
70 // exists. Returns true if |command| was populated.
71 bool GetExtensionCommand(extensions::Command* command);
72
73 const extensions::Extension* extension() const { return extension_; }
74 Browser* browser() { return browser_; }
75 ExtensionAction* extension_action() { return extension_action_; }
76 const ExtensionAction* extension_action() const { return extension_action_; }
77 ToolbarActionViewDelegate* view_delegate() { return view_delegate_; }
78
79 void set_icon_observer(ExtensionActionIconFactory::Observer* icon_observer) {
80 icon_observer_ = icon_observer;
81 }
82
83 private:
84 // ExtensionActionIconFactory::Observer:
85 void OnIconUpdated() override;
86
rdevlin.cronin651153652014-11-15 00:34:4887 // Checks if the associated |extension| is still valid by checking its
88 // status in the registry. Since the OnExtensionUnloaded() notifications are
89 // not in a deterministic order, it's possible that the view tries to refresh
90 // itself before we're notified to remove it.
91 bool ExtensionIsValid() const;
92
rdevlin.cronin09530742014-11-03 19:23:2893 // Executes the extension action with |show_action|. If
94 // |grant_tab_permissions| is true, this will grant the extension active tab
95 // permissions. Only do this if this was done through a user action (and not
96 // e.g. an API). Returns true if a popup is shown.
97 bool ExecuteAction(PopupShowAction show_action, bool grant_tab_permissions);
98
99 // Shows the popup for the extension action, given the associated |popup_url|.
100 // |grant_tab_permissions| is true if active tab permissions should be given
101 // to the extension; this is only true if the popup is opened through a user
102 // action.
103 // Returns true if a popup is successfully shown.
104 bool ShowPopupWithUrl(PopupShowAction show_action,
105 const GURL& popup_url,
106 bool grant_tab_permissions);
107
108 // The extension associated with the action we're displaying.
109 const extensions::Extension* extension_;
110
111 // The corresponding browser.
112 Browser* browser_;
113
114 // The browser action this view represents. The ExtensionAction is not owned
115 // by this class.
116 ExtensionAction* extension_action_;
117
rdevlin.croninc10ac9e2015-01-16 21:10:08118 // The context menu model for the extension.
119 scoped_refptr<ExtensionContextMenuModel> context_menu_model_;
120
rdevlin.cronin09530742014-11-03 19:23:28121 // Our view delegate.
122 ToolbarActionViewDelegate* view_delegate_;
123
124 // The delegate to handle platform-specific implementations.
125 scoped_ptr<ExtensionActionPlatformDelegate> platform_delegate_;
126
127 // The object that will be used to get the browser action icon for us.
128 // It may load the icon asynchronously (in which case the initial icon
129 // returned by the factory will be transparent), so we have to observe it for
130 // updates to the icon.
131 ExtensionActionIconFactory icon_factory_;
132
133 // An additional observer that we need to notify when the icon of the button
134 // has been updated.
135 ExtensionActionIconFactory::Observer* icon_observer_;
136
rdevlin.cronin651153652014-11-15 00:34:48137 // The associated ExtensionRegistry; cached for quick checking.
138 extensions::ExtensionRegistry* extension_registry_;
139
rdevlin.cronin09530742014-11-03 19:23:28140 DISALLOW_COPY_AND_ASSIGN(ExtensionActionViewController);
141};
142
143#endif // CHROME_BROWSER_UI_EXTENSIONS_EXTENSION_ACTION_VIEW_CONTROLLER_H_