render_view_host_delegate_helper.cc revision 513209b27ff55e2841eac0e4120199c23acce758
1// Copyright (c) 2010 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#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h" 6 7#include "base/command_line.h" 8#include "base/string_util.h" 9#include "base/utf_string_conversions.h" 10#include "chrome/browser/background_contents_service.h" 11#include "chrome/browser/character_encoding.h" 12#include "chrome/browser/extensions/extensions_service.h" 13#include "chrome/browser/prefs/pref_service.h" 14#include "chrome/browser/profile.h" 15#include "chrome/browser/renderer_host/render_view_host.h" 16#include "chrome/browser/renderer_host/render_process_host.h" 17#include "chrome/browser/renderer_host/render_widget_fullscreen_host.h" 18#include "chrome/browser/renderer_host/render_widget_host.h" 19#include "chrome/browser/renderer_host/render_widget_host_view.h" 20#include "chrome/browser/renderer_host/site_instance.h" 21#include "chrome/browser/tab_contents/background_contents.h" 22#include "chrome/browser/tab_contents/tab_contents.h" 23#include "chrome/browser/tab_contents/tab_contents_view.h" 24#include "chrome/browser/user_style_sheet_watcher.h" 25#include "chrome/common/chrome_switches.h" 26#include "chrome/common/notification_service.h" 27#include "chrome/common/pref_names.h" 28 29RenderViewHostDelegateViewHelper::RenderViewHostDelegateViewHelper() {} 30 31RenderViewHostDelegateViewHelper::~RenderViewHostDelegateViewHelper() {} 32 33BackgroundContents* 34RenderViewHostDelegateViewHelper::MaybeCreateBackgroundContents( 35 int route_id, 36 Profile* profile, 37 SiteInstance* site, 38 const GURL& opener_url, 39 const string16& frame_name) { 40 ExtensionsService* extensions_service = profile->GetExtensionsService(); 41 42 if (!opener_url.is_valid() || 43 frame_name.empty() || 44 !extensions_service || 45 !extensions_service->is_ready()) 46 return NULL; 47 48 const Extension* extension = 49 extensions_service->GetExtensionByURL(opener_url); 50 if (!extension) 51 extension = extensions_service->GetExtensionByWebExtent(opener_url); 52 if (!extension || 53 !extension->HasApiPermission(Extension::kBackgroundPermission)) 54 return NULL; 55 56 // Only allow a single background contents per app. 57 if (!profile->GetBackgroundContentsService() || 58 profile->GetBackgroundContentsService()->GetAppBackgroundContents( 59 ASCIIToUTF16(extension->id()))) 60 return NULL; 61 62 // Ensure that we're trying to open this from the extension's process. 63 ExtensionProcessManager* process_manager = 64 profile->GetExtensionProcessManager(); 65 if (!site->GetProcess() || !process_manager || 66 site->GetProcess() != process_manager->GetExtensionProcess(opener_url)) 67 return NULL; 68 69 // Passed all the checks, so this should be created as a BackgroundContents. 70 BackgroundContents* contents = new BackgroundContents( 71 site, 72 route_id, 73 profile->GetBackgroundContentsService()); 74 string16 appid = ASCIIToUTF16(extension->id()); 75 BackgroundContentsOpenedDetails details = { contents, frame_name, appid }; 76 NotificationService::current()->Notify( 77 NotificationType::BACKGROUND_CONTENTS_OPENED, 78 Source<Profile>(profile), 79 Details<BackgroundContentsOpenedDetails>(&details)); 80 81 return contents; 82} 83 84TabContents* RenderViewHostDelegateViewHelper::CreateNewWindow( 85 int route_id, 86 Profile* profile, 87 SiteInstance* site, 88 DOMUITypeID domui_type, 89 RenderViewHostDelegate* opener, 90 WindowContainerType window_container_type, 91 const string16& frame_name) { 92 if (window_container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) { 93 BackgroundContents* contents = MaybeCreateBackgroundContents( 94 route_id, 95 profile, 96 site, 97 opener->GetURL(), 98 frame_name); 99 if (contents) { 100 pending_contents_[route_id] = contents->render_view_host(); 101 return NULL; 102 } 103 } 104 105 // Create the new web contents. This will automatically create the new 106 // TabContentsView. In the future, we may want to create the view separately. 107 TabContents* new_contents = 108 new TabContents(profile, 109 site, 110 route_id, 111 opener->GetAsTabContents(), 112 NULL); 113 new_contents->set_opener_dom_ui_type(domui_type); 114 TabContentsView* new_view = new_contents->view(); 115 116 // TODO(brettw) it seems bogus that we have to call this function on the 117 // newly created object and give it one of its own member variables. 118 new_view->CreateViewForWidget(new_contents->render_view_host()); 119 120 // Save the created window associated with the route so we can show it later. 121 pending_contents_[route_id] = new_contents->render_view_host(); 122 return new_contents; 123} 124 125RenderWidgetHostView* RenderViewHostDelegateViewHelper::CreateNewWidget( 126 int route_id, WebKit::WebPopupType popup_type, RenderProcessHost* process) { 127 RenderWidgetHost* widget_host = 128 new RenderWidgetHost(process, route_id); 129 RenderWidgetHostView* widget_view = 130 RenderWidgetHostView::CreateViewForWidget(widget_host); 131 // Popups should not get activated. 132 widget_view->set_popup_type(popup_type); 133 // Save the created widget associated with the route so we can show it later. 134 pending_widget_views_[route_id] = widget_view; 135 return widget_view; 136} 137 138RenderWidgetHostView* 139RenderViewHostDelegateViewHelper::CreateNewFullscreenWidget( 140 int route_id, WebKit::WebPopupType popup_type, RenderProcessHost* process) { 141 RenderWidgetFullscreenHost* fullscreen_widget_host = 142 new RenderWidgetFullscreenHost(process, route_id); 143 RenderWidgetHostView* widget_view = 144 RenderWidgetHostView::CreateViewForWidget(fullscreen_widget_host); 145 widget_view->set_popup_type(popup_type); 146 pending_widget_views_[route_id] = widget_view; 147 return widget_view; 148} 149 150TabContents* RenderViewHostDelegateViewHelper::GetCreatedWindow(int route_id) { 151 PendingContents::iterator iter = pending_contents_.find(route_id); 152 if (iter == pending_contents_.end()) { 153 DCHECK(false); 154 return NULL; 155 } 156 157 RenderViewHost* new_rvh = iter->second; 158 pending_contents_.erase(route_id); 159 160 // The renderer crashed or it is a TabContents and has no view. 161 if (!new_rvh->process()->HasConnection() || 162 (new_rvh->delegate()->GetAsTabContents() && !new_rvh->view())) 163 return NULL; 164 165 // TODO(brettw) this seems bogus to reach into here and initialize the host. 166 new_rvh->Init(); 167 return new_rvh->delegate()->GetAsTabContents(); 168} 169 170RenderWidgetHostView* RenderViewHostDelegateViewHelper::GetCreatedWidget( 171 int route_id) { 172 PendingWidgetViews::iterator iter = pending_widget_views_.find(route_id); 173 if (iter == pending_widget_views_.end()) { 174 DCHECK(false); 175 return NULL; 176 } 177 178 RenderWidgetHostView* widget_host_view = iter->second; 179 pending_widget_views_.erase(route_id); 180 181 RenderWidgetHost* widget_host = widget_host_view->GetRenderWidgetHost(); 182 if (!widget_host->process()->HasConnection()) { 183 // The view has gone away or the renderer crashed. Nothing to do. 184 return NULL; 185 } 186 187 return widget_host_view; 188} 189 190void RenderViewHostDelegateViewHelper::RenderWidgetHostDestroyed( 191 RenderWidgetHost* host) { 192 for (PendingWidgetViews::iterator i = pending_widget_views_.begin(); 193 i != pending_widget_views_.end(); ++i) { 194 if (host->view() == i->second) { 195 pending_widget_views_.erase(i); 196 return; 197 } 198 } 199} 200 201// static 202WebPreferences RenderViewHostDelegateHelper::GetWebkitPrefs( 203 Profile* profile, bool is_dom_ui) { 204 PrefService* prefs = profile->GetPrefs(); 205 WebPreferences web_prefs; 206 207 web_prefs.fixed_font_family = 208 UTF8ToWide(prefs->GetString(prefs::kWebKitFixedFontFamily)); 209 web_prefs.serif_font_family = 210 UTF8ToWide(prefs->GetString(prefs::kWebKitSerifFontFamily)); 211 web_prefs.sans_serif_font_family = 212 UTF8ToWide(prefs->GetString(prefs::kWebKitSansSerifFontFamily)); 213 if (prefs->GetBoolean(prefs::kWebKitStandardFontIsSerif)) 214 web_prefs.standard_font_family = web_prefs.serif_font_family; 215 else 216 web_prefs.standard_font_family = web_prefs.sans_serif_font_family; 217 web_prefs.cursive_font_family = 218 UTF8ToWide(prefs->GetString(prefs::kWebKitCursiveFontFamily)); 219 web_prefs.fantasy_font_family = 220 UTF8ToWide(prefs->GetString(prefs::kWebKitFantasyFontFamily)); 221 222 web_prefs.default_font_size = 223 prefs->GetInteger(prefs::kWebKitDefaultFontSize); 224 web_prefs.default_fixed_font_size = 225 prefs->GetInteger(prefs::kWebKitDefaultFixedFontSize); 226 web_prefs.minimum_font_size = 227 prefs->GetInteger(prefs::kWebKitMinimumFontSize); 228 web_prefs.minimum_logical_font_size = 229 prefs->GetInteger(prefs::kWebKitMinimumLogicalFontSize); 230 231 web_prefs.default_encoding = prefs->GetString(prefs::kDefaultCharset); 232 233 web_prefs.javascript_can_open_windows_automatically = 234 prefs->GetBoolean(prefs::kWebKitJavascriptCanOpenWindowsAutomatically); 235 web_prefs.dom_paste_enabled = 236 prefs->GetBoolean(prefs::kWebKitDomPasteEnabled); 237 web_prefs.shrinks_standalone_images_to_fit = 238 prefs->GetBoolean(prefs::kWebKitShrinksStandaloneImagesToFit); 239 const DictionaryValue* inspector_settings = 240 prefs->GetDictionary(prefs::kWebKitInspectorSettings); 241 if (inspector_settings) { 242 for (DictionaryValue::key_iterator iter(inspector_settings->begin_keys()); 243 iter != inspector_settings->end_keys(); ++iter) { 244 std::string value; 245 if (inspector_settings->GetStringWithoutPathExpansion(*iter, &value)) 246 web_prefs.inspector_settings.push_back( 247 std::make_pair(*iter, value)); 248 } 249 } 250 web_prefs.tabs_to_links = prefs->GetBoolean(prefs::kWebkitTabsToLinks); 251 252 { // Command line switches are used for preferences with no user interface. 253 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 254 web_prefs.developer_extras_enabled = 255 !command_line.HasSwitch(switches::kDisableDevTools); 256 web_prefs.javascript_enabled = 257 !command_line.HasSwitch(switches::kDisableJavaScript) && 258 prefs->GetBoolean(prefs::kWebKitJavascriptEnabled); 259 web_prefs.web_security_enabled = 260 !command_line.HasSwitch(switches::kDisableWebSecurity) && 261 prefs->GetBoolean(prefs::kWebKitWebSecurityEnabled); 262 web_prefs.plugins_enabled = 263 !command_line.HasSwitch(switches::kDisablePlugins) && 264 prefs->GetBoolean(prefs::kWebKitPluginsEnabled); 265 web_prefs.java_enabled = 266 !command_line.HasSwitch(switches::kDisableJava) && 267 prefs->GetBoolean(prefs::kWebKitJavaEnabled); 268 web_prefs.loads_images_automatically = 269 prefs->GetBoolean(prefs::kWebKitLoadsImagesAutomatically); 270 web_prefs.uses_page_cache = 271 command_line.HasSwitch(switches::kEnableFastback); 272 web_prefs.remote_fonts_enabled = 273 !command_line.HasSwitch(switches::kDisableRemoteFonts); 274 web_prefs.xss_auditor_enabled = 275 command_line.HasSwitch(switches::kEnableXSSAuditor); 276 web_prefs.application_cache_enabled = 277 !command_line.HasSwitch(switches::kDisableApplicationCache); 278 279 web_prefs.local_storage_enabled = 280 !command_line.HasSwitch(switches::kDisableLocalStorage); 281 web_prefs.databases_enabled = 282 !command_line.HasSwitch(switches::kDisableDatabases); 283 web_prefs.experimental_webgl_enabled = 284 !command_line.HasSwitch(switches::kDisableExperimentalWebGL); 285 web_prefs.site_specific_quirks_enabled = 286 !command_line.HasSwitch(switches::kDisableSiteSpecificQuirks); 287 web_prefs.allow_file_access_from_file_urls = 288 command_line.HasSwitch(switches::kAllowFileAccessFromFiles); 289 web_prefs.show_composited_layer_borders = 290 command_line.HasSwitch(switches::kShowCompositedLayerBorders); 291 web_prefs.accelerated_compositing_enabled = 292 !command_line.HasSwitch(switches::kDisableAcceleratedCompositing); 293 web_prefs.accelerated_2d_canvas_enabled = 294 command_line.HasSwitch(switches::kEnableAccelerated2dCanvas); 295 web_prefs.memory_info_enabled = 296 command_line.HasSwitch(switches::kEnableMemoryInfo); 297 web_prefs.hyperlink_auditing_enabled = 298 !command_line.HasSwitch(switches::kNoPings); 299 // The user stylesheet watcher may not exist in a testing profile. 300 if (profile->GetUserStyleSheetWatcher()) { 301 web_prefs.user_style_sheet_enabled = true; 302 web_prefs.user_style_sheet_location = 303 profile->GetUserStyleSheetWatcher()->user_style_sheet(); 304 } else { 305 web_prefs.user_style_sheet_enabled = false; 306 } 307 } 308 309 web_prefs.uses_universal_detector = 310 prefs->GetBoolean(prefs::kWebKitUsesUniversalDetector); 311 web_prefs.text_areas_are_resizable = 312 prefs->GetBoolean(prefs::kWebKitTextAreasAreResizable); 313 314 // Make sure we will set the default_encoding with canonical encoding name. 315 web_prefs.default_encoding = 316 CharacterEncoding::GetCanonicalEncodingNameByAliasName( 317 web_prefs.default_encoding); 318 if (web_prefs.default_encoding.empty()) { 319 prefs->ClearPref(prefs::kDefaultCharset); 320 web_prefs.default_encoding = prefs->GetString(prefs::kDefaultCharset); 321 } 322 DCHECK(!web_prefs.default_encoding.empty()); 323 324 if (is_dom_ui) { 325 web_prefs.loads_images_automatically = true; 326 web_prefs.javascript_enabled = true; 327 } 328 329 return web_prefs; 330} 331 332void RenderViewHostDelegateHelper::UpdateInspectorSetting( 333 Profile* profile, const std::string& key, const std::string& value) { 334 DictionaryValue* inspector_settings = 335 profile->GetPrefs()->GetMutableDictionary( 336 prefs::kWebKitInspectorSettings); 337 inspector_settings->SetWithoutPathExpansion(key, 338 Value::CreateStringValue(value)); 339} 340 341void RenderViewHostDelegateHelper::ClearInspectorSettings(Profile* profile) { 342 DictionaryValue* inspector_settings = 343 profile->GetPrefs()->GetMutableDictionary( 344 prefs::kWebKitInspectorSettings); 345 inspector_settings->Clear(); 346} 347