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