tab_helper.h revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
1// Copyright (c) 2012 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_EXTENSIONS_TAB_HELPER_H_ 6#define CHROME_BROWSER_EXTENSIONS_TAB_HELPER_H_ 7 8#include <map> 9#include <string> 10#include <vector> 11 12#include "base/memory/ref_counted.h" 13#include "base/memory/weak_ptr.h" 14#include "base/observer_list.h" 15#include "chrome/browser/extensions/active_tab_permission_granter.h" 16#include "chrome/browser/extensions/extension_function_dispatcher.h" 17#include "chrome/common/web_application_info.h" 18#include "content/public/browser/notification_observer.h" 19#include "content/public/browser/notification_registrar.h" 20#include "content/public/browser/web_contents_observer.h" 21#include "content/public/browser/web_contents_user_data.h" 22#include "third_party/skia/include/core/SkBitmap.h" 23 24namespace content { 25struct LoadCommittedDetails; 26} 27 28namespace gfx { 29class Image; 30} 31 32namespace extensions { 33class Extension; 34class LocationBarController; 35class RulesRegistryService; 36class ScriptBadgeController; 37class ScriptBubbleController; 38class ScriptExecutor; 39 40// Per-tab extension helper. Also handles non-extension apps. 41class TabHelper : public content::WebContentsObserver, 42 public ExtensionFunctionDispatcher::Delegate, 43 public base::SupportsWeakPtr<TabHelper>, 44 public content::NotificationObserver, 45 public content::WebContentsUserData<TabHelper> { 46 public: 47 // Different types of action when web app info is available. 48 // OnDidGetApplicationInfo uses this to dispatch calls. 49 enum WebAppAction { 50 NONE, // No action at all. 51 CREATE_SHORTCUT, // Bring up create application shortcut dialog. 52 UPDATE_SHORTCUT // Update icon for app shortcut. 53 }; 54 55 // Observer base class for classes that need to be notified when content 56 // scripts and/or tabs.executeScript calls run on a page. 57 class ScriptExecutionObserver { 58 public: 59 // Map of extensions IDs to the executing script paths. 60 typedef std::map<std::string, std::set<std::string> > ExecutingScriptsMap; 61 62 // Automatically observes and unobserves |tab_helper| on construction 63 // and destruction. |tab_helper| must outlive |this|. 64 explicit ScriptExecutionObserver(TabHelper* tab_helper); 65 ScriptExecutionObserver(); 66 67 // Called when script(s) have executed on a page. 68 // 69 // |executing_scripts_map| contains all extensions that are executing 70 // scripts, mapped to the paths for those scripts. This may be an empty set 71 // if the script has no path associated with it (e.g. in the case of 72 // tabs.executeScript). 73 virtual void OnScriptsExecuted( 74 const content::WebContents* web_contents, 75 const ExecutingScriptsMap& executing_scripts_map, 76 int32 on_page_id, 77 const GURL& on_url) = 0; 78 79 protected: 80 virtual ~ScriptExecutionObserver(); 81 82 TabHelper* tab_helper_; 83 }; 84 85 virtual ~TabHelper(); 86 87 void AddScriptExecutionObserver(ScriptExecutionObserver* observer) { 88 script_execution_observers_.AddObserver(observer); 89 } 90 91 void RemoveScriptExecutionObserver(ScriptExecutionObserver* observer) { 92 script_execution_observers_.RemoveObserver(observer); 93 } 94 95 void CreateApplicationShortcuts(); 96 bool CanCreateApplicationShortcuts() const; 97 98 void set_pending_web_app_action(WebAppAction action) { 99 pending_web_app_action_ = action; 100 } 101 102 // App extensions ------------------------------------------------------------ 103 104 // Sets the extension denoting this as an app. If |extension| is non-null this 105 // tab becomes an app-tab. WebContents does not listen for unload events for 106 // the extension. It's up to consumers of WebContents to do that. 107 // 108 // NOTE: this should only be manipulated before the tab is added to a browser. 109 // TODO(sky): resolve if this is the right way to identify an app tab. If it 110 // is, than this should be passed in the constructor. 111 void SetExtensionApp(const Extension* extension); 112 113 // Convenience for setting the app extension by id. This does nothing if 114 // |extension_app_id| is empty, or an extension can't be found given the 115 // specified id. 116 void SetExtensionAppById(const std::string& extension_app_id); 117 118 // Set just the app icon, used by panels created by an extension. 119 void SetExtensionAppIconById(const std::string& extension_app_id); 120 121 const Extension* extension_app() const { return extension_app_; } 122 bool is_app() const { return extension_app_ != NULL; } 123 const WebApplicationInfo& web_app_info() const { 124 return web_app_info_; 125 } 126 127 // If an app extension has been explicitly set for this WebContents its icon 128 // is returned. 129 // 130 // NOTE: the returned icon is larger than 16x16 (its size is 131 // extension_misc::EXTENSION_ICON_SMALLISH). 132 SkBitmap* GetExtensionAppIcon(); 133 134 content::WebContents* web_contents() const { 135 return content::WebContentsObserver::web_contents(); 136 } 137 138 ScriptExecutor* script_executor() { 139 return script_executor_.get(); 140 } 141 142 LocationBarController* location_bar_controller() { 143 return location_bar_controller_.get(); 144 } 145 146 ActiveTabPermissionGranter* active_tab_permission_granter() { 147 return active_tab_permission_granter_.get(); 148 } 149 150 ScriptBubbleController* script_bubble_controller() { 151 return script_bubble_controller_.get(); 152 } 153 154 // Sets a non-extension app icon associated with WebContents and fires an 155 // INVALIDATE_TYPE_TITLE navigation state change to trigger repaint of title. 156 void SetAppIcon(const SkBitmap& app_icon); 157 158 private: 159 explicit TabHelper(content::WebContents* web_contents); 160 friend class content::WebContentsUserData<TabHelper>; 161 162 // content::WebContentsObserver overrides. 163 virtual void RenderViewCreated( 164 content::RenderViewHost* render_view_host) OVERRIDE; 165 virtual void DidNavigateMainFrame( 166 const content::LoadCommittedDetails& details, 167 const content::FrameNavigateParams& params) OVERRIDE; 168 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 169 virtual void DidCloneToNewWebContents( 170 content::WebContents* old_web_contents, 171 content::WebContents* new_web_contents) OVERRIDE; 172 173 // ExtensionFunctionDispatcher::Delegate overrides. 174 virtual extensions::WindowController* GetExtensionWindowController() 175 const OVERRIDE; 176 virtual content::WebContents* GetAssociatedWebContents() const OVERRIDE; 177 178 // Message handlers. 179 void OnDidGetApplicationInfo(int32 page_id, const WebApplicationInfo& info); 180 void OnInlineWebstoreInstall(int install_id, 181 int return_route_id, 182 const std::string& webstore_item_id, 183 const GURL& requestor_url); 184 void OnGetAppInstallState(const GURL& requestor_url, 185 int return_route_id, 186 int callback_id); 187 void OnRequest(const ExtensionHostMsg_Request_Params& params); 188 void OnContentScriptsExecuting( 189 const ScriptExecutionObserver::ExecutingScriptsMap& extension_ids, 190 int32 page_id, 191 const GURL& on_url); 192 void OnWatchedPageChange(const std::vector<std::string>& css_selectors); 193 194 // App extensions related methods: 195 196 // Resets app_icon_ and if |extension| is non-null uses ImageLoader to load 197 // the extension's image asynchronously. 198 void UpdateExtensionAppIcon(const Extension* extension); 199 200 const Extension* GetExtension(const std::string& extension_app_id); 201 202 void OnImageLoaded(const gfx::Image& image); 203 204 // WebstoreStandaloneInstaller::Callback. 205 virtual void OnInlineInstallComplete(int install_id, 206 int return_route_id, 207 bool success, 208 const std::string& error); 209 210 // content::NotificationObserver. 211 virtual void Observe(int type, 212 const content::NotificationSource& source, 213 const content::NotificationDetails& details) OVERRIDE; 214 215 // Requests application info for the specified page. This is an asynchronous 216 // request. The delegate is notified by way of OnDidGetApplicationInfo when 217 // the data is available. 218 void GetApplicationInfo(int32 page_id); 219 220 // Sends our tab ID to |render_view_host|. 221 void SetTabId(content::RenderViewHost* render_view_host); 222 223 // Data for app extensions --------------------------------------------------- 224 225 // Our content script observers. Declare at top so that it will outlive all 226 // other members, since they might add themselves as observers. 227 ObserverList<ScriptExecutionObserver> script_execution_observers_; 228 229 // If non-null this tab is an app tab and this is the extension the tab was 230 // created for. 231 const Extension* extension_app_; 232 233 // Icon for extension_app_ (if non-null) or a manually-set icon for 234 // non-extension apps. 235 SkBitmap extension_app_icon_; 236 237 // Process any extension messages coming from the tab. 238 ExtensionFunctionDispatcher extension_function_dispatcher_; 239 240 // Cached web app info data. 241 WebApplicationInfo web_app_info_; 242 243 // Which deferred action to perform when OnDidGetApplicationInfo is notified 244 // from a WebContents. 245 WebAppAction pending_web_app_action_; 246 247 content::NotificationRegistrar registrar_; 248 249 scoped_ptr<ScriptExecutor> script_executor_; 250 251 scoped_ptr<LocationBarController> location_bar_controller_; 252 253 scoped_ptr<ActiveTabPermissionGranter> active_tab_permission_granter_; 254 255 scoped_ptr<ScriptBubbleController> script_bubble_controller_; 256 257 RulesRegistryService* rules_registry_service_; 258 259 Profile* profile_; 260 261 // Vend weak pointers that can be invalidated to stop in-progress loads. 262 base::WeakPtrFactory<TabHelper> image_loader_ptr_factory_; 263 264 DISALLOW_COPY_AND_ASSIGN(TabHelper); 265}; 266 267} // namespace extensions 268 269#endif // CHROME_BROWSER_EXTENSIONS_TAB_HELPER_H_ 270