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