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