Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: chrome/browser/ui/extensions/shell_window.cc

Issue 10825240: Refactor ShellWindow to separate platform-specific code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comments Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/extensions/shell_window.h" 5 #include "chrome/browser/ui/extensions/shell_window.h"
6 6
7 #include "base/utf_string_conversions.h" 7 #include "base/utf_string_conversions.h"
8 #include "chrome/browser/extensions/extension_process_manager.h" 8 #include "chrome/browser/extensions/extension_process_manager.h"
9 #include "chrome/browser/extensions/shell_window_registry.h" 9 #include "chrome/browser/extensions/shell_window_registry.h"
10 #include "chrome/browser/file_select_helper.h" 10 #include "chrome/browser/file_select_helper.h"
11 #include "chrome/browser/infobars/infobar_tab_helper.h" 11 #include "chrome/browser/infobars/infobar_tab_helper.h"
12 #include "chrome/browser/intents/web_intents_util.h" 12 #include "chrome/browser/intents/web_intents_util.h"
13 #include "chrome/browser/lifetime/application_lifetime.h" 13 #include "chrome/browser/lifetime/application_lifetime.h"
14 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/sessions/session_id.h" 15 #include "chrome/browser/sessions/session_id.h"
16 #include "chrome/browser/ui/browser.h" 16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/browser_finder.h" 17 #include "chrome/browser/ui/browser_finder.h"
18 #include "chrome/browser/ui/browser_tabstrip.h" 18 #include "chrome/browser/ui/browser_tabstrip.h"
19 #include "chrome/browser/ui/browser_window.h" 19 #include "chrome/browser/ui/browser_window.h"
20 #include "chrome/browser/ui/extensions/native_shell_window.h"
20 #include "chrome/browser/ui/intents/web_intent_picker_controller.h" 21 #include "chrome/browser/ui/intents/web_intent_picker_controller.h"
21 #include "chrome/browser/ui/tab_contents/tab_contents.h" 22 #include "chrome/browser/ui/tab_contents/tab_contents.h"
22 #include "chrome/browser/view_type_utils.h" 23 #include "chrome/browser/view_type_utils.h"
23 #include "chrome/common/chrome_notification_types.h" 24 #include "chrome/common/chrome_notification_types.h"
24 #include "chrome/common/extensions/extension.h" 25 #include "chrome/common/extensions/extension.h"
25 #include "chrome/common/extensions/extension_messages.h" 26 #include "chrome/common/extensions/extension_messages.h"
26 #include "content/public/browser/browser_thread.h" 27 #include "content/public/browser/browser_thread.h"
27 #include "content/public/browser/invalidate_type.h" 28 #include "content/public/browser/invalidate_type.h"
28 #include "content/public/browser/navigation_entry.h" 29 #include "content/public/browser/navigation_entry.h"
29 #include "content/public/browser/notification_details.h" 30 #include "content/public/browser/notification_details.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 ShellWindow::CreateParams::CreateParams() 64 ShellWindow::CreateParams::CreateParams()
64 : frame(ShellWindow::CreateParams::FRAME_CHROME), 65 : frame(ShellWindow::CreateParams::FRAME_CHROME),
65 bounds(10, 10, kDefaultWidth, kDefaultHeight) { 66 bounds(10, 10, kDefaultWidth, kDefaultHeight) {
66 } 67 }
67 68
68 ShellWindow* ShellWindow::Create(Profile* profile, 69 ShellWindow* ShellWindow::Create(Profile* profile,
69 const extensions::Extension* extension, 70 const extensions::Extension* extension,
70 const GURL& url, 71 const GURL& url,
71 const ShellWindow::CreateParams& params) { 72 const ShellWindow::CreateParams& params) {
72 // This object will delete itself when the window is closed. 73 // This object will delete itself when the window is closed.
73 ShellWindow* window = 74 ShellWindow* window = new ShellWindow(profile, extension);
74 ShellWindow::CreateImpl(profile, extension, url, params); 75 window->Init(url, params);
75 ShellWindowRegistry::Get(profile)->AddShellWindow(window); 76 ShellWindowRegistry::Get(profile)->AddShellWindow(window);
76 return window; 77 return window;
77 } 78 }
78 79
79 ShellWindow::ShellWindow(Profile* profile, 80 ShellWindow::ShellWindow(Profile* profile,
80 const extensions::Extension* extension, 81 const extensions::Extension* extension)
81 const GURL& url)
82 : profile_(profile), 82 : profile_(profile),
83 extension_(extension), 83 extension_(extension),
84 web_contents_(NULL),
84 ALLOW_THIS_IN_INITIALIZER_LIST( 85 ALLOW_THIS_IN_INITIALIZER_LIST(
85 extension_function_dispatcher_(profile, this)) { 86 extension_function_dispatcher_(profile, this)) {
86 // TODO(jeremya) this should all be done in an Init() method, not in the 87 }
87 // constructor. During this code, WebContents will be calling 88
88 // WebContentsDelegate methods, but at this point the vftables for the 89 void ShellWindow::Init(const GURL& url,
89 // subclass are not yet in place, since it's still halfway through its 90 const ShellWindow::CreateParams& params) {
90 // constructor. As a result, overridden virtual methods won't be called.
91 web_contents_ = WebContents::Create( 91 web_contents_ = WebContents::Create(
92 profile, SiteInstance::CreateForURL(profile, url), MSG_ROUTING_NONE, 92 profile(), SiteInstance::CreateForURL(profile(), url), MSG_ROUTING_NONE,
93 NULL); 93 NULL);
94 contents_.reset(new TabContents(web_contents_)); 94 contents_.reset(new TabContents(web_contents_));
95 content::WebContentsObserver::Observe(web_contents_); 95 content::WebContentsObserver::Observe(web_contents_);
96 web_contents_->SetDelegate(this); 96 web_contents_->SetDelegate(this);
97 chrome::SetViewType(web_contents_, chrome::VIEW_TYPE_APP_SHELL); 97 chrome::SetViewType(web_contents_, chrome::VIEW_TYPE_APP_SHELL);
98 web_contents_->GetMutableRendererPrefs()-> 98 web_contents_->GetMutableRendererPrefs()->
99 browser_handles_all_top_level_requests = true; 99 browser_handles_all_top_level_requests = true;
100 web_contents_->GetRenderViewHost()->SyncRendererPrefs(); 100 web_contents_->GetRenderViewHost()->SyncRendererPrefs();
101 101
102 native_window_.reset(NativeShellWindow::Create(this, params));
103
102 // Block the created RVH from loading anything until the background page 104 // Block the created RVH from loading anything until the background page
103 // has had a chance to do any initialization it wants. 105 // has had a chance to do any initialization it wants.
104 SuspendRenderViewHost(web_contents_->GetRenderViewHost()); 106 SuspendRenderViewHost(web_contents_->GetRenderViewHost());
105 107
106 // TODO(jeremya): there's a bug where navigating a web contents to an 108 // TODO(jeremya): there's a bug where navigating a web contents to an
107 // extension URL causes it to create a new RVH and discard the old (perfectly 109 // extension URL causes it to create a new RVH and discard the old (perfectly
108 // usable) one. To work around this, we watch for a RVH_CHANGED message from 110 // usable) one. To work around this, we watch for a RVH_CHANGED message from
109 // the web contents (which will be sent during LoadURL) and suspend resource 111 // the web contents (which will be sent during LoadURL) and suspend resource
110 // requests on the new RVH to ensure that we block the new RVH from loading 112 // requests on the new RVH to ensure that we block the new RVH from loading
111 // anything. It should be okay to remove the NOTIFICATION_RVH_CHANGED 113 // anything. It should be okay to remove the NOTIFICATION_RVH_CHANGED
(...skipping 25 matching lines...) Expand all
137 139
138 ShellWindow::~ShellWindow() { 140 ShellWindow::~ShellWindow() {
139 // Unregister now to prevent getting NOTIFICATION_APP_TERMINATING if we're the 141 // Unregister now to prevent getting NOTIFICATION_APP_TERMINATING if we're the
140 // last window open. 142 // last window open.
141 registrar_.RemoveAll(); 143 registrar_.RemoveAll();
142 144
143 // Remove shutdown prevention. 145 // Remove shutdown prevention.
144 browser::EndKeepAlive(); 146 browser::EndKeepAlive();
145 } 147 }
146 148
147 bool ShellWindow::IsFullscreenOrPending() const {
148 return false;
149 }
150
151 void ShellWindow::RequestMediaAccessPermission( 149 void ShellWindow::RequestMediaAccessPermission(
152 content::WebContents* web_contents, 150 content::WebContents* web_contents,
153 const content::MediaStreamRequest* request, 151 const content::MediaStreamRequest* request,
154 const content::MediaResponseCallback& callback) { 152 const content::MediaResponseCallback& callback) {
155 content::MediaStreamDevices devices; 153 content::MediaStreamDevices devices;
156 154
157 content::MediaStreamDeviceMap::const_iterator iter = 155 content::MediaStreamDeviceMap::const_iterator iter =
158 request->devices.find(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE); 156 request->devices.find(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE);
159 if (iter != request->devices.end() && 157 if (iter != request->devices.end() &&
160 extension()->HasAPIPermission(APIPermission::kAudioCapture) && 158 extension()->HasAPIPermission(APIPermission::kAudioCapture) &&
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 disposition == NEW_BACKGROUND_TAB ? disposition : NEW_FOREGROUND_TAB; 230 disposition == NEW_BACKGROUND_TAB ? disposition : NEW_FOREGROUND_TAB;
233 chrome::AddWebContents(browser, NULL, new_contents, disposition, initial_pos, 231 chrome::AddWebContents(browser, NULL, new_contents, disposition, initial_pos,
234 user_gesture); 232 user_gesture);
235 } 233 }
236 234
237 void ShellWindow::OnNativeClose() { 235 void ShellWindow::OnNativeClose() {
238 ShellWindowRegistry::Get(profile_)->RemoveShellWindow(this); 236 ShellWindowRegistry::Get(profile_)->RemoveShellWindow(this);
239 delete this; 237 delete this;
240 } 238 }
241 239
240 BaseWindow* ShellWindow::GetBaseWindow() {
241 return native_window_.get();
242 }
243
242 string16 ShellWindow::GetTitle() const { 244 string16 ShellWindow::GetTitle() const {
243 // WebContents::GetTitle() will return the page's URL if there's no <title> 245 // WebContents::GetTitle() will return the page's URL if there's no <title>
244 // specified. However, we'd prefer to show the name of the extension in that 246 // specified. However, we'd prefer to show the name of the extension in that
245 // case, so we directly inspect the NavigationEntry's title. 247 // case, so we directly inspect the NavigationEntry's title.
246 if (!web_contents()->GetController().GetActiveEntry() || 248 if (!web_contents()->GetController().GetActiveEntry() ||
247 web_contents()->GetController().GetActiveEntry()->GetTitle().empty()) 249 web_contents()->GetController().GetActiveEntry()->GetTitle().empty())
248 return UTF8ToUTF16(extension()->name()); 250 return UTF8ToUTF16(extension()->name());
249 return web_contents()->GetTitle(); 251 return web_contents()->GetTitle();
250 } 252 }
251 253
252 bool ShellWindow::OnMessageReceived(const IPC::Message& message) { 254 bool ShellWindow::OnMessageReceived(const IPC::Message& message) {
253 bool handled = true; 255 bool handled = true;
254 IPC_BEGIN_MESSAGE_MAP(ShellWindow, message) 256 IPC_BEGIN_MESSAGE_MAP(ShellWindow, message)
255 IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest) 257 IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest)
256 IPC_MESSAGE_HANDLER(ExtensionHostMsg_UpdateDraggableRegions, 258 IPC_MESSAGE_HANDLER(ExtensionHostMsg_UpdateDraggableRegions,
257 UpdateDraggableRegions) 259 UpdateDraggableRegions)
258 IPC_MESSAGE_UNHANDLED(handled = false) 260 IPC_MESSAGE_UNHANDLED(handled = false)
259 IPC_END_MESSAGE_MAP() 261 IPC_END_MESSAGE_MAP()
260 return handled; 262 return handled;
261 } 263 }
262 264
265 void ShellWindow::UpdateDraggableRegions(
266 const std::vector<extensions::DraggableRegion>& regions) {
267 native_window_->UpdateDraggableRegions(regions);
268 }
269
263 void ShellWindow::CloseContents(WebContents* contents) { 270 void ShellWindow::CloseContents(WebContents* contents) {
264 Close(); 271 DCHECK(contents == web_contents_);
272 native_window_->Close();
265 } 273 }
266 274
267 bool ShellWindow::ShouldSuppressDialogs() { 275 bool ShellWindow::ShouldSuppressDialogs() {
268 return true; 276 return true;
269 } 277 }
270 278
271 void ShellWindow::WebIntentDispatch( 279 void ShellWindow::WebIntentDispatch(
272 content::WebContents* web_contents, 280 content::WebContents* web_contents,
273 content::WebIntentsDispatcher* intents_dispatcher) { 281 content::WebIntentsDispatcher* intents_dispatcher) {
274 if (!web_intents::IsWebIntentsEnabledForProfile(profile_)) 282 if (!web_intents::IsWebIntentsEnabledForProfile(profile_))
(...skipping 11 matching lines...) Expand all
286 FileSelectHelper::RunFileChooser(tab, params); 294 FileSelectHelper::RunFileChooser(tab, params);
287 } 295 }
288 296
289 bool ShellWindow::IsPopupOrPanel(const WebContents* source) const { 297 bool ShellWindow::IsPopupOrPanel(const WebContents* source) const {
290 DCHECK(source == web_contents_); 298 DCHECK(source == web_contents_);
291 return true; 299 return true;
292 } 300 }
293 301
294 void ShellWindow::MoveContents(WebContents* source, const gfx::Rect& pos) { 302 void ShellWindow::MoveContents(WebContents* source, const gfx::Rect& pos) {
295 DCHECK(source == web_contents_); 303 DCHECK(source == web_contents_);
296 SetBounds(pos); 304 native_window_->SetBounds(pos);
297 } 305 }
298 306
299 void ShellWindow::NavigationStateChanged( 307 void ShellWindow::NavigationStateChanged(
300 const content::WebContents* source, unsigned changed_flags) { 308 const content::WebContents* source, unsigned changed_flags) {
301 DCHECK(source == web_contents_); 309 DCHECK(source == web_contents_);
302 if (changed_flags & content::INVALIDATE_TYPE_TITLE) 310 if (changed_flags & content::INVALIDATE_TYPE_TITLE)
303 UpdateWindowTitle(); 311 native_window_->UpdateWindowTitle();
304 } 312 }
305 313
306 void ShellWindow::ToggleFullscreenModeForTab(content::WebContents* source, 314 void ShellWindow::ToggleFullscreenModeForTab(content::WebContents* source,
307 bool enter_fullscreen) { 315 bool enter_fullscreen) {
308 DCHECK(source == web_contents_); 316 DCHECK(source == web_contents_);
309 SetFullscreen(enter_fullscreen); 317 native_window_->SetFullscreen(enter_fullscreen);
310 } 318 }
311 319
312 bool ShellWindow::IsFullscreenForTabOrPending( 320 bool ShellWindow::IsFullscreenForTabOrPending(
313 const content::WebContents* source) const { 321 const content::WebContents* source) const {
314 DCHECK(source == web_contents_); 322 DCHECK(source == web_contents_);
315 return IsFullscreenOrPending(); 323 return native_window_->IsFullscreenOrPending();
316 } 324 }
317 325
318 void ShellWindow::Observe(int type, 326 void ShellWindow::Observe(int type,
319 const content::NotificationSource& source, 327 const content::NotificationSource& source,
320 const content::NotificationDetails& details) { 328 const content::NotificationDetails& details) {
321 switch (type) { 329 switch (type) {
322 case content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED: { 330 case content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED: {
323 // TODO(jeremya): once http://crbug.com/123007 is fixed, we'll no longer 331 // TODO(jeremya): once http://crbug.com/123007 is fixed, we'll no longer
324 // need to suspend resource requests here (the call in the constructor 332 // need to suspend resource requests here (the call in the constructor
325 // should be enough). 333 // should be enough).
326 content::Details<std::pair<RenderViewHost*, RenderViewHost*> > 334 content::Details<std::pair<RenderViewHost*, RenderViewHost*> >
327 host_details(details); 335 host_details(details);
328 if (host_details->first) 336 if (host_details->first)
329 SuspendRenderViewHost(host_details->second); 337 SuspendRenderViewHost(host_details->second);
330 break; 338 break;
331 } 339 }
332 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { 340 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
333 const extensions::Extension* unloaded_extension = 341 const extensions::Extension* unloaded_extension =
334 content::Details<extensions::UnloadedExtensionInfo>( 342 content::Details<extensions::UnloadedExtensionInfo>(
335 details)->extension; 343 details)->extension;
336 if (extension_ == unloaded_extension) 344 if (extension_ == unloaded_extension)
337 Close(); 345 native_window_->Close();
338 break; 346 break;
339 } 347 }
340 case content::NOTIFICATION_APP_TERMINATING: 348 case content::NOTIFICATION_APP_TERMINATING:
341 Close(); 349 native_window_->Close();
342 break; 350 break;
343 default: 351 default:
344 NOTREACHED() << "Received unexpected notification"; 352 NOTREACHED() << "Received unexpected notification";
345 } 353 }
346 } 354 }
347 355
348 extensions::WindowController* 356 extensions::WindowController*
349 ShellWindow::GetExtensionWindowController() const { 357 ShellWindow::GetExtensionWindowController() const {
350 return NULL; 358 return NULL;
351 } 359 }
352 360
353 void ShellWindow::OnRequest(const ExtensionHostMsg_Request_Params& params) { 361 void ShellWindow::OnRequest(const ExtensionHostMsg_Request_Params& params) {
354 extension_function_dispatcher_.Dispatch(params, 362 extension_function_dispatcher_.Dispatch(params,
355 web_contents_->GetRenderViewHost()); 363 web_contents_->GetRenderViewHost());
356 } 364 }
357 365
358 void ShellWindow::AddMessageToDevToolsConsole(ConsoleMessageLevel level, 366 void ShellWindow::AddMessageToDevToolsConsole(ConsoleMessageLevel level,
359 const std::string& message) { 367 const std::string& message) {
360 content::RenderViewHost* rvh = web_contents_->GetRenderViewHost(); 368 content::RenderViewHost* rvh = web_contents_->GetRenderViewHost();
361 rvh->Send(new ExtensionMsg_AddMessageToConsole( 369 rvh->Send(new ExtensionMsg_AddMessageToConsole(
362 rvh->GetRoutingID(), level, message)); 370 rvh->GetRoutingID(), level, message));
363 } 371 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698