• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/background_contents.h"
6 
7 #include "chrome/browser/background_contents_service.h"
8 #include "chrome/browser/extensions/extension_message_service.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/renderer_preferences_util.h"
11 #include "chrome/browser/ui/webui/chrome_web_ui_factory.h"
12 #include "chrome/common/extensions/extension_constants.h"
13 #include "chrome/common/extensions/extension_messages.h"
14 #include "chrome/common/url_constants.h"
15 #include "chrome/common/view_types.h"
16 #include "content/browser/browsing_instance.h"
17 #include "content/browser/renderer_host/render_view_host.h"
18 #include "content/browser/site_instance.h"
19 #include "content/common/notification_service.h"
20 #include "content/common/view_messages.h"
21 #include "ui/gfx/rect.h"
22 
23 ////////////////
24 // BackgroundContents
25 
BackgroundContents(SiteInstance * site_instance,int routing_id,Delegate * delegate)26 BackgroundContents::BackgroundContents(SiteInstance* site_instance,
27                                        int routing_id,
28                                        Delegate* delegate)
29     : delegate_(delegate) {
30   Profile* profile = site_instance->browsing_instance()->profile();
31 
32   // TODO(rafaelw): Implement correct session storage.
33   render_view_host_ = new RenderViewHost(site_instance, this, routing_id, NULL);
34 
35   // Close ourselves when the application is shutting down.
36   registrar_.Add(this, NotificationType::APP_TERMINATING,
37                  NotificationService::AllSources());
38 
39   // Register for our parent profile to shutdown, so we can shut ourselves down
40   // as well (should only be called for OTR profiles, as we should receive
41   // APP_TERMINATING before non-OTR profiles are destroyed).
42   registrar_.Add(this, NotificationType::PROFILE_DESTROYED,
43                  Source<Profile>(profile));
44 }
45 
46 // Exposed to allow creating mocks.
BackgroundContents()47 BackgroundContents::BackgroundContents()
48     : delegate_(NULL),
49       render_view_host_(NULL) {
50 }
51 
~BackgroundContents()52 BackgroundContents::~BackgroundContents() {
53   if (!render_view_host_)   // Will be null for unit tests.
54     return;
55   Profile* profile = render_view_host_->process()->profile();
56   NotificationService::current()->Notify(
57       NotificationType::BACKGROUND_CONTENTS_DELETED,
58       Source<Profile>(profile),
59       Details<BackgroundContents>(this));
60   render_view_host_->Shutdown();  // deletes render_view_host
61 }
62 
GetAsBackgroundContents()63 BackgroundContents* BackgroundContents::GetAsBackgroundContents() {
64   return this;
65 }
66 
GetViewDelegate()67 RenderViewHostDelegate::View* BackgroundContents::GetViewDelegate() {
68   return this;
69 }
70 
GetURL() const71 const GURL& BackgroundContents::GetURL() const {
72   return url_;
73 }
74 
GetRenderViewType() const75 ViewType::Type BackgroundContents::GetRenderViewType() const {
76   return ViewType::BACKGROUND_CONTENTS;
77 }
78 
GetBrowserWindowID() const79 int BackgroundContents::GetBrowserWindowID() const {
80   return extension_misc::kUnknownWindowId;
81 }
82 
DidNavigate(RenderViewHost * render_view_host,const ViewHostMsg_FrameNavigate_Params & params)83 void BackgroundContents::DidNavigate(
84     RenderViewHost* render_view_host,
85     const ViewHostMsg_FrameNavigate_Params& params) {
86   // We only care when the outer frame changes.
87   if (!PageTransition::IsMainFrame(params.transition))
88     return;
89 
90   // Note: because BackgroundContents are only available to extension apps,
91   // navigation is limited to urls within the app's extent. This is enforced in
92   // RenderView::decidePolicyForNaviation. If BackgroundContents become
93   // available as a part of the web platform, it probably makes sense to have
94   // some way to scope navigation of a background page to its opener's security
95   // origin. Note: if the first navigation is to a URL outside the app's
96   // extent a background page will be opened but will remain at about:blank.
97   url_ = params.url;
98 
99   Profile* profile = render_view_host->process()->profile();
100   NotificationService::current()->Notify(
101       NotificationType::BACKGROUND_CONTENTS_NAVIGATED,
102       Source<Profile>(profile),
103       Details<BackgroundContents>(this));
104 }
105 
RunJavaScriptMessage(const std::wstring & message,const std::wstring & default_prompt,const GURL & frame_url,const int flags,IPC::Message * reply_msg,bool * did_suppress_message)106 void BackgroundContents::RunJavaScriptMessage(
107     const std::wstring& message,
108     const std::wstring& default_prompt,
109     const GURL& frame_url,
110     const int flags,
111     IPC::Message* reply_msg,
112     bool* did_suppress_message) {
113   // TODO(rafaelw): Implement, The JavaScriptModalDialog needs to learn about
114   // BackgroundContents.
115   *did_suppress_message = true;
116 }
117 
PreHandleKeyboardEvent(const NativeWebKeyboardEvent & event,bool * is_keyboard_shortcut)118 bool BackgroundContents::PreHandleKeyboardEvent(
119     const NativeWebKeyboardEvent& event,
120     bool* is_keyboard_shortcut) {
121   return false;
122 }
123 
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)124 void BackgroundContents::Observe(NotificationType type,
125                                  const NotificationSource& source,
126                                  const NotificationDetails& details) {
127   // TODO(rafaelw): Implement pagegroup ref-counting so that non-persistent
128   // background pages are closed when the last referencing frame is closed.
129   switch (type.value) {
130     case NotificationType::PROFILE_DESTROYED:
131     case NotificationType::APP_TERMINATING: {
132       delete this;
133       break;
134     }
135     default:
136       NOTREACHED() << "Unexpected notification sent.";
137       break;
138   }
139 }
140 
OnMessageBoxClosed(IPC::Message * reply_msg,bool success,const std::wstring & prompt)141 void BackgroundContents::OnMessageBoxClosed(IPC::Message* reply_msg,
142                                             bool success,
143                                             const std::wstring& prompt) {
144   render_view_host_->JavaScriptMessageBoxClosed(reply_msg, success, prompt);
145 }
146 
GetMessageBoxRootWindow()147 gfx::NativeWindow BackgroundContents::GetMessageBoxRootWindow() {
148   NOTIMPLEMENTED();
149   return NULL;
150 }
151 
AsTabContents()152 TabContents* BackgroundContents::AsTabContents() {
153   return NULL;
154 }
155 
AsExtensionHost()156 ExtensionHost* BackgroundContents::AsExtensionHost() {
157   return NULL;
158 }
159 
UpdateInspectorSetting(const std::string & key,const std::string & value)160 void BackgroundContents::UpdateInspectorSetting(const std::string& key,
161                                          const std::string& value) {
162   Profile* profile = render_view_host_->process()->profile();
163   RenderViewHostDelegateHelper::UpdateInspectorSetting(profile, key, value);
164 }
165 
ClearInspectorSettings()166 void BackgroundContents::ClearInspectorSettings() {
167   Profile* profile = render_view_host_->process()->profile();
168   RenderViewHostDelegateHelper::ClearInspectorSettings(profile);
169 }
170 
Close(RenderViewHost * render_view_host)171 void BackgroundContents::Close(RenderViewHost* render_view_host) {
172   Profile* profile = render_view_host->process()->profile();
173   NotificationService::current()->Notify(
174       NotificationType::BACKGROUND_CONTENTS_CLOSED,
175       Source<Profile>(profile),
176       Details<BackgroundContents>(this));
177   delete this;
178 }
179 
RenderViewGone(RenderViewHost * rvh,base::TerminationStatus status,int error_code)180 void BackgroundContents::RenderViewGone(RenderViewHost* rvh,
181                                         base::TerminationStatus status,
182                                         int error_code) {
183   Profile* profile = rvh->process()->profile();
184   NotificationService::current()->Notify(
185       NotificationType::BACKGROUND_CONTENTS_TERMINATED,
186       Source<Profile>(profile),
187       Details<BackgroundContents>(this));
188 
189   // Our RenderView went away, so we should go away also, so killing the process
190   // via the TaskManager doesn't permanently leave a BackgroundContents hanging
191   // around the system, blocking future instances from being created
192   // (http://crbug.com/65189).
193   delete this;
194 }
195 
GetRendererPrefs(Profile * profile) const196 RendererPreferences BackgroundContents::GetRendererPrefs(
197     Profile* profile) const {
198   RendererPreferences preferences;
199   renderer_preferences_util::UpdateFromSystemSettings(&preferences, profile);
200   return preferences;
201 }
202 
GetWebkitPrefs()203 WebPreferences BackgroundContents::GetWebkitPrefs() {
204   // TODO(rafaelw): Consider enabling the webkit_prefs.dom_paste_enabled for
205   // apps.
206   Profile* profile = render_view_host_->process()->profile();
207   return RenderViewHostDelegateHelper::GetWebkitPrefs(profile,
208                                                       false);  // is_web_ui
209 }
210 
ProcessWebUIMessage(const ExtensionHostMsg_DomMessage_Params & params)211 void BackgroundContents::ProcessWebUIMessage(
212     const ExtensionHostMsg_DomMessage_Params& params) {
213   // TODO(rafaelw): It may make sense for extensions to be able to open
214   // BackgroundContents to chrome-extension://<id> pages. Consider implementing.
215   render_view_host_->Send(new ExtensionMsg_Response(
216       render_view_host_->routing_id(), params.request_id, false,
217       std::string(), "Access to extension API denied."));
218 }
219 
CreateNewWindow(int route_id,const ViewHostMsg_CreateWindow_Params & params)220 void BackgroundContents::CreateNewWindow(
221     int route_id,
222     const ViewHostMsg_CreateWindow_Params& params) {
223   delegate_view_helper_.CreateNewWindow(
224       route_id,
225       render_view_host_->process()->profile(),
226       render_view_host_->site_instance(),
227       ChromeWebUIFactory::GetInstance()->GetWebUIType(
228           render_view_host_->process()->profile(), url_),
229       this,
230       params.window_container_type,
231       params.frame_name);
232 }
233 
CreateNewWidget(int route_id,WebKit::WebPopupType popup_type)234 void BackgroundContents::CreateNewWidget(int route_id,
235                                          WebKit::WebPopupType popup_type) {
236   NOTREACHED();
237 }
238 
CreateNewFullscreenWidget(int route_id)239 void BackgroundContents::CreateNewFullscreenWidget(int route_id) {
240   NOTREACHED();
241 }
242 
ShowCreatedWindow(int route_id,WindowOpenDisposition disposition,const gfx::Rect & initial_pos,bool user_gesture)243 void BackgroundContents::ShowCreatedWindow(int route_id,
244                                            WindowOpenDisposition disposition,
245                                            const gfx::Rect& initial_pos,
246                                            bool user_gesture) {
247   TabContents* contents = delegate_view_helper_.GetCreatedWindow(route_id);
248   if (contents)
249     delegate_->AddTabContents(contents, disposition, initial_pos, user_gesture);
250 }
251 
ShowCreatedWidget(int route_id,const gfx::Rect & initial_pos)252 void BackgroundContents::ShowCreatedWidget(int route_id,
253                                            const gfx::Rect& initial_pos) {
254   NOTIMPLEMENTED();
255 }
256 
ShowCreatedFullscreenWidget(int route_id)257 void BackgroundContents::ShowCreatedFullscreenWidget(int route_id) {
258   NOTIMPLEMENTED();
259 }
260 
261 // static
262 BackgroundContents*
GetBackgroundContentsByID(int render_process_id,int render_view_id)263 BackgroundContents::GetBackgroundContentsByID(int render_process_id,
264                                               int render_view_id) {
265   RenderViewHost* render_view_host =
266       RenderViewHost::FromID(render_process_id, render_view_id);
267   if (!render_view_host)
268     return NULL;
269 
270   return render_view_host->delegate()->GetAsBackgroundContents();
271 }
272