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