OLD | NEW |
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/extension_system.h" | 9 #include "chrome/browser/extensions/extension_system.h" |
10 #include "chrome/browser/extensions/shell_window_geometry_cache.h" | 10 #include "chrome/browser/extensions/shell_window_geometry_cache.h" |
11 #include "chrome/browser/extensions/shell_window_registry.h" | 11 #include "chrome/browser/extensions/shell_window_registry.h" |
12 #include "chrome/browser/extensions/tab_helper.h" | 12 #include "chrome/browser/extensions/tab_helper.h" |
13 #include "chrome/browser/favicon/favicon_tab_helper.h" | 13 #include "chrome/browser/favicon/favicon_tab_helper.h" |
14 #include "chrome/browser/file_select_helper.h" | 14 #include "chrome/browser/file_select_helper.h" |
15 #include "chrome/browser/intents/web_intents_util.h" | 15 #include "chrome/browser/intents/web_intents_util.h" |
16 #include "chrome/browser/lifetime/application_lifetime.h" | 16 #include "chrome/browser/lifetime/application_lifetime.h" |
17 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
18 #include "chrome/browser/sessions/session_id.h" | 18 #include "chrome/browser/sessions/session_id.h" |
19 #include "chrome/browser/ui/browser.h" | 19 #include "chrome/browser/ui/browser.h" |
20 #include "chrome/browser/ui/browser_finder.h" | 20 #include "chrome/browser/ui/browser_finder.h" |
21 #include "chrome/browser/ui/browser_tabstrip.h" | 21 #include "chrome/browser/ui/browser_tabstrip.h" |
22 #include "chrome/browser/ui/browser_window.h" | 22 #include "chrome/browser/ui/browser_window.h" |
23 #include "chrome/browser/ui/constrained_window_tab_helper.h" | 23 #include "chrome/browser/ui/constrained_window_tab_helper.h" |
24 #include "chrome/browser/ui/extensions/native_shell_window.h" | 24 #include "chrome/browser/ui/extensions/app_base_window.h" |
25 #include "chrome/browser/ui/intents/web_intent_picker_controller.h" | 25 #include "chrome/browser/ui/intents/web_intent_picker_controller.h" |
26 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 26 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
27 #include "chrome/browser/view_type_utils.h" | 27 #include "chrome/browser/view_type_utils.h" |
28 #include "chrome/common/chrome_notification_types.h" | 28 #include "chrome/common/chrome_notification_types.h" |
29 #include "chrome/common/extensions/api/app_window.h" | 29 #include "chrome/common/extensions/api/app_window.h" |
30 #include "chrome/common/extensions/extension.h" | 30 #include "chrome/common/extensions/extension.h" |
31 #include "chrome/common/extensions/extension_messages.h" | 31 #include "chrome/common/extensions/extension_messages.h" |
32 #include "chrome/common/extensions/request_media_access_permission_helper.h" | 32 #include "chrome/common/extensions/request_media_access_permission_helper.h" |
33 #include "content/public/browser/browser_thread.h" | 33 #include "content/public/browser/browser_thread.h" |
34 #include "content/public/browser/invalidate_type.h" | 34 #include "content/public/browser/invalidate_type.h" |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 shell_window_geometry_cache(); | 135 shell_window_geometry_cache(); |
136 gfx::Rect cached_bounds; | 136 gfx::Rect cached_bounds; |
137 if (cache->GetGeometry(extension()->id(), params.window_key, | 137 if (cache->GetGeometry(extension()->id(), params.window_key, |
138 &cached_bounds)) | 138 &cached_bounds)) |
139 bounds = cached_bounds; | 139 bounds = cached_bounds; |
140 } | 140 } |
141 | 141 |
142 ShellWindow::CreateParams new_params = params; | 142 ShellWindow::CreateParams new_params = params; |
143 new_params.bounds = bounds; | 143 new_params.bounds = bounds; |
144 | 144 |
145 native_window_.reset(NativeShellWindow::Create(this, new_params)); | 145 app_window_.reset(AppBaseWindow::Create(this, new_params)); |
146 SaveWindowPosition(); | 146 SaveWindowPosition(); |
147 | 147 |
148 if (!params.hidden) | 148 if (!params.hidden) |
149 GetBaseWindow()->Show(); | 149 GetBaseWindow()->Show(); |
150 | 150 |
151 // If the new view is in the same process as the creator, block the created | 151 // If the new view is in the same process as the creator, block the created |
152 // RVH from loading anything until the background page has had a chance to do | 152 // RVH from loading anything until the background page has had a chance to do |
153 // any initialization it wants. If it's a different process, the new RVH | 153 // any initialization it wants. If it's a different process, the new RVH |
154 // shouldn't communicate with the background page anyway (e.g. sandboxed). | 154 // shouldn't communicate with the background page anyway (e.g. sandboxed). |
155 if (web_contents_->GetRenderViewHost()->GetProcess()->GetID() == | 155 if (web_contents_->GetRenderViewHost()->GetProcess()->GetID() == |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 disposition = | 270 disposition = |
271 disposition == NEW_BACKGROUND_TAB ? disposition : NEW_FOREGROUND_TAB; | 271 disposition == NEW_BACKGROUND_TAB ? disposition : NEW_FOREGROUND_TAB; |
272 chrome::AddWebContents(browser, NULL, new_contents, disposition, initial_pos, | 272 chrome::AddWebContents(browser, NULL, new_contents, disposition, initial_pos, |
273 user_gesture, was_blocked); | 273 user_gesture, was_blocked); |
274 } | 274 } |
275 | 275 |
276 void ShellWindow::HandleKeyboardEvent( | 276 void ShellWindow::HandleKeyboardEvent( |
277 WebContents* source, | 277 WebContents* source, |
278 const content::NativeWebKeyboardEvent& event) { | 278 const content::NativeWebKeyboardEvent& event) { |
279 DCHECK_EQ(source, web_contents_); | 279 DCHECK_EQ(source, web_contents_); |
280 native_window_->HandleKeyboardEvent(event); | 280 app_window_->HandleKeyboardEvent(event); |
281 } | 281 } |
282 | 282 |
283 void ShellWindow::OnNativeClose() { | 283 void ShellWindow::OnNativeClose() { |
284 extensions::ShellWindowRegistry::Get(profile_)->RemoveShellWindow(this); | 284 extensions::ShellWindowRegistry::Get(profile_)->RemoveShellWindow(this); |
285 content::RenderViewHost* rvh = web_contents_->GetRenderViewHost(); | 285 content::RenderViewHost* rvh = web_contents_->GetRenderViewHost(); |
286 rvh->Send(new ExtensionMsg_AppWindowClosed(rvh->GetRoutingID())); | 286 rvh->Send(new ExtensionMsg_AppWindowClosed(rvh->GetRoutingID())); |
287 delete this; | 287 delete this; |
288 } | 288 } |
289 | 289 |
290 BaseWindow* ShellWindow::GetBaseWindow() { | 290 BaseWindow* ShellWindow::GetBaseWindow() { |
291 return native_window_.get(); | 291 return app_window_.get(); |
292 } | 292 } |
293 | 293 |
294 string16 ShellWindow::GetTitle() const { | 294 string16 ShellWindow::GetTitle() const { |
295 // WebContents::GetTitle() will return the page's URL if there's no <title> | 295 // WebContents::GetTitle() will return the page's URL if there's no <title> |
296 // specified. However, we'd prefer to show the name of the extension in that | 296 // specified. However, we'd prefer to show the name of the extension in that |
297 // case, so we directly inspect the NavigationEntry's title. | 297 // case, so we directly inspect the NavigationEntry's title. |
298 if (!web_contents()->GetController().GetActiveEntry() || | 298 if (!web_contents()->GetController().GetActiveEntry() || |
299 web_contents()->GetController().GetActiveEntry()->GetTitle().empty()) | 299 web_contents()->GetController().GetActiveEntry()->GetTitle().empty()) |
300 return UTF8ToUTF16(extension()->name()); | 300 return UTF8ToUTF16(extension()->name()); |
301 string16 title = web_contents()->GetTitle(); | 301 string16 title = web_contents()->GetTitle(); |
302 Browser::FormatTitleForDisplay(&title); | 302 Browser::FormatTitleForDisplay(&title); |
303 return title; | 303 return title; |
304 } | 304 } |
305 | 305 |
306 bool ShellWindow::OnMessageReceived(const IPC::Message& message) { | 306 bool ShellWindow::OnMessageReceived(const IPC::Message& message) { |
307 bool handled = true; | 307 bool handled = true; |
308 IPC_BEGIN_MESSAGE_MAP(ShellWindow, message) | 308 IPC_BEGIN_MESSAGE_MAP(ShellWindow, message) |
309 IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest) | 309 IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest) |
310 IPC_MESSAGE_HANDLER(ExtensionHostMsg_UpdateDraggableRegions, | 310 IPC_MESSAGE_HANDLER(ExtensionHostMsg_UpdateDraggableRegions, |
311 UpdateDraggableRegions) | 311 UpdateDraggableRegions) |
312 IPC_MESSAGE_UNHANDLED(handled = false) | 312 IPC_MESSAGE_UNHANDLED(handled = false) |
313 IPC_END_MESSAGE_MAP() | 313 IPC_END_MESSAGE_MAP() |
314 return handled; | 314 return handled; |
315 } | 315 } |
316 | 316 |
317 void ShellWindow::UpdateDraggableRegions( | 317 void ShellWindow::UpdateDraggableRegions( |
318 const std::vector<extensions::DraggableRegion>& regions) { | 318 const std::vector<extensions::DraggableRegion>& regions) { |
319 native_window_->UpdateDraggableRegions(regions); | 319 app_window_->UpdateDraggableRegions(regions); |
320 } | 320 } |
321 | 321 |
322 void ShellWindow::OnImageLoaded(const gfx::Image& image, | 322 void ShellWindow::OnImageLoaded(const gfx::Image& image, |
323 const std::string& extension_id, | 323 const std::string& extension_id, |
324 int index) { | 324 int index) { |
325 if (!image.IsEmpty()) { | 325 if (!image.IsEmpty()) { |
326 app_icon_ = image; | 326 app_icon_ = image; |
327 native_window_->UpdateWindowIcon(); | 327 app_window_->UpdateWindowIcon(); |
328 } | 328 } |
329 app_icon_loader_.reset(); | 329 app_icon_loader_.reset(); |
330 } | 330 } |
331 | 331 |
332 void ShellWindow::UpdateExtensionAppIcon() { | 332 void ShellWindow::UpdateExtensionAppIcon() { |
333 app_icon_loader_.reset(new ImageLoadingTracker(this)); | 333 app_icon_loader_.reset(new ImageLoadingTracker(this)); |
334 app_icon_loader_->LoadImage( | 334 app_icon_loader_->LoadImage( |
335 extension(), | 335 extension(), |
336 extension()->GetIconResource(extension_misc::EXTENSION_ICON_SMALL, | 336 extension()->GetIconResource(extension_misc::EXTENSION_ICON_SMALL, |
337 ExtensionIconSet::MATCH_BIGGER), | 337 ExtensionIconSet::MATCH_BIGGER), |
338 gfx::Size(extension_misc::EXTENSION_ICON_SMALL, | 338 gfx::Size(extension_misc::EXTENSION_ICON_SMALL, |
339 extension_misc::EXTENSION_ICON_SMALL), | 339 extension_misc::EXTENSION_ICON_SMALL), |
340 ImageLoadingTracker::CACHE); | 340 ImageLoadingTracker::CACHE); |
341 } | 341 } |
342 | 342 |
343 void ShellWindow::CloseContents(WebContents* contents) { | 343 void ShellWindow::CloseContents(WebContents* contents) { |
344 DCHECK(contents == web_contents_); | 344 DCHECK(contents == web_contents_); |
345 native_window_->Close(); | 345 app_window_->Close(); |
346 } | 346 } |
347 | 347 |
348 bool ShellWindow::ShouldSuppressDialogs() { | 348 bool ShellWindow::ShouldSuppressDialogs() { |
349 return true; | 349 return true; |
350 } | 350 } |
351 | 351 |
352 void ShellWindow::WebIntentDispatch( | 352 void ShellWindow::WebIntentDispatch( |
353 content::WebContents* web_contents, | 353 content::WebContents* web_contents, |
354 content::WebIntentsDispatcher* intents_dispatcher) { | 354 content::WebIntentsDispatcher* intents_dispatcher) { |
355 if (!web_intents::IsWebIntentsEnabledForProfile(profile_)) | 355 if (!web_intents::IsWebIntentsEnabledForProfile(profile_)) |
(...skipping 12 matching lines...) Expand all Loading... |
368 FileSelectHelper::RunFileChooser(tab, params); | 368 FileSelectHelper::RunFileChooser(tab, params); |
369 } | 369 } |
370 | 370 |
371 bool ShellWindow::IsPopupOrPanel(const WebContents* source) const { | 371 bool ShellWindow::IsPopupOrPanel(const WebContents* source) const { |
372 DCHECK(source == web_contents_.get()); | 372 DCHECK(source == web_contents_.get()); |
373 return true; | 373 return true; |
374 } | 374 } |
375 | 375 |
376 void ShellWindow::MoveContents(WebContents* source, const gfx::Rect& pos) { | 376 void ShellWindow::MoveContents(WebContents* source, const gfx::Rect& pos) { |
377 DCHECK(source == web_contents_.get()); | 377 DCHECK(source == web_contents_.get()); |
378 native_window_->SetBounds(pos); | 378 app_window_->SetBounds(pos); |
379 } | 379 } |
380 | 380 |
381 void ShellWindow::NavigationStateChanged( | 381 void ShellWindow::NavigationStateChanged( |
382 const content::WebContents* source, unsigned changed_flags) { | 382 const content::WebContents* source, unsigned changed_flags) { |
383 DCHECK(source == web_contents_.get()); | 383 DCHECK(source == web_contents_.get()); |
384 if (changed_flags & content::INVALIDATE_TYPE_TITLE) | 384 if (changed_flags & content::INVALIDATE_TYPE_TITLE) |
385 native_window_->UpdateWindowTitle(); | 385 app_window_->UpdateWindowTitle(); |
386 else if (changed_flags & content::INVALIDATE_TYPE_TAB) | 386 else if (changed_flags & content::INVALIDATE_TYPE_TAB) |
387 native_window_->UpdateWindowIcon(); | 387 app_window_->UpdateWindowIcon(); |
388 } | 388 } |
389 | 389 |
390 void ShellWindow::ToggleFullscreenModeForTab(content::WebContents* source, | 390 void ShellWindow::ToggleFullscreenModeForTab(content::WebContents* source, |
391 bool enter_fullscreen) { | 391 bool enter_fullscreen) { |
392 DCHECK(source == web_contents_.get()); | 392 DCHECK(source == web_contents_.get()); |
393 native_window_->SetFullscreen(enter_fullscreen); | 393 app_window_->SetFullscreen(enter_fullscreen); |
394 } | 394 } |
395 | 395 |
396 bool ShellWindow::IsFullscreenForTabOrPending( | 396 bool ShellWindow::IsFullscreenForTabOrPending( |
397 const content::WebContents* source) const { | 397 const content::WebContents* source) const { |
398 DCHECK(source == web_contents_.get()); | 398 DCHECK(source == web_contents_.get()); |
399 return native_window_->IsFullscreenOrPending(); | 399 return app_window_->IsFullscreenOrPending(); |
400 } | 400 } |
401 | 401 |
402 void ShellWindow::Observe(int type, | 402 void ShellWindow::Observe(int type, |
403 const content::NotificationSource& source, | 403 const content::NotificationSource& source, |
404 const content::NotificationDetails& details) { | 404 const content::NotificationDetails& details) { |
405 switch (type) { | 405 switch (type) { |
406 case content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED: { | 406 case content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED: { |
407 // TODO(jeremya): once http://crbug.com/123007 is fixed, we'll no longer | 407 // TODO(jeremya): once http://crbug.com/123007 is fixed, we'll no longer |
408 // need to suspend resource requests here (the call in the constructor | 408 // need to suspend resource requests here (the call in the constructor |
409 // should be enough). | 409 // should be enough). |
410 content::Details<std::pair<RenderViewHost*, RenderViewHost*> > | 410 content::Details<std::pair<RenderViewHost*, RenderViewHost*> > |
411 host_details(details); | 411 host_details(details); |
412 if (host_details->first) | 412 if (host_details->first) |
413 SuspendRenderViewHost(host_details->second); | 413 SuspendRenderViewHost(host_details->second); |
414 // TODO(jianli): once http://crbug.com/123007 is fixed, we'll no longer | 414 // TODO(jianli): once http://crbug.com/123007 is fixed, we'll no longer |
415 // need to make the native window (ShellWindowViews specially) update | 415 // need to make the native window (ShellWindowViews specially) update |
416 // the clickthrough region for the new RVH. | 416 // the clickthrough region for the new RVH. |
417 native_window_->RenderViewHostChanged(); | 417 app_window_->RenderViewHostChanged(); |
418 break; | 418 break; |
419 } | 419 } |
420 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { | 420 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { |
421 const extensions::Extension* unloaded_extension = | 421 const extensions::Extension* unloaded_extension = |
422 content::Details<extensions::UnloadedExtensionInfo>( | 422 content::Details<extensions::UnloadedExtensionInfo>( |
423 details)->extension; | 423 details)->extension; |
424 if (extension_ == unloaded_extension) | 424 if (extension_ == unloaded_extension) |
425 native_window_->Close(); | 425 app_window_->Close(); |
426 break; | 426 break; |
427 } | 427 } |
428 case chrome::NOTIFICATION_APP_TERMINATING: | 428 case chrome::NOTIFICATION_APP_TERMINATING: |
429 native_window_->Close(); | 429 app_window_->Close(); |
430 break; | 430 break; |
431 default: | 431 default: |
432 NOTREACHED() << "Received unexpected notification"; | 432 NOTREACHED() << "Received unexpected notification"; |
433 } | 433 } |
434 } | 434 } |
435 | 435 |
436 extensions::WindowController* | 436 extensions::WindowController* |
437 ShellWindow::GetExtensionWindowController() const { | 437 ShellWindow::GetExtensionWindowController() const { |
438 return NULL; | 438 return NULL; |
439 } | 439 } |
(...skipping 14 matching lines...) Expand all Loading... |
454 } | 454 } |
455 | 455 |
456 void ShellWindow::AddMessageToDevToolsConsole(ConsoleMessageLevel level, | 456 void ShellWindow::AddMessageToDevToolsConsole(ConsoleMessageLevel level, |
457 const std::string& message) { | 457 const std::string& message) { |
458 content::RenderViewHost* rvh = web_contents_->GetRenderViewHost(); | 458 content::RenderViewHost* rvh = web_contents_->GetRenderViewHost(); |
459 rvh->Send(new ExtensionMsg_AddMessageToConsole( | 459 rvh->Send(new ExtensionMsg_AddMessageToConsole( |
460 rvh->GetRoutingID(), level, message)); | 460 rvh->GetRoutingID(), level, message)); |
461 } | 461 } |
462 | 462 |
463 void ShellWindow::SendBoundsUpdate() { | 463 void ShellWindow::SendBoundsUpdate() { |
464 if (!native_window_ || !web_contents_) | 464 if (!app_window_ || !web_contents_) |
465 return; | 465 return; |
466 gfx::Rect bounds = native_window_->GetBounds(); | 466 gfx::Rect bounds = app_window_->GetBounds(); |
467 content::RenderViewHost* rvh = web_contents_->GetRenderViewHost(); | 467 content::RenderViewHost* rvh = web_contents_->GetRenderViewHost(); |
468 ListValue args; | 468 ListValue args; |
469 app_window::Bounds update; | 469 app_window::Bounds update; |
470 update.left.reset(new int(bounds.x())); | 470 update.left.reset(new int(bounds.x())); |
471 update.top.reset(new int(bounds.y())); | 471 update.top.reset(new int(bounds.y())); |
472 update.width.reset(new int(bounds.width())); | 472 update.width.reset(new int(bounds.width())); |
473 update.height.reset(new int(bounds.height())); | 473 update.height.reset(new int(bounds.height())); |
474 args.Append(update.ToValue().release()); | 474 args.Append(update.ToValue().release()); |
475 rvh->Send(new ExtensionMsg_MessageInvoke(rvh->GetRoutingID(), | 475 rvh->Send(new ExtensionMsg_MessageInvoke(rvh->GetRoutingID(), |
476 extension_->id(), | 476 extension_->id(), |
477 "updateAppWindowBounds", | 477 "updateAppWindowBounds", |
478 args, | 478 args, |
479 GURL(), | 479 GURL(), |
480 false)); | 480 false)); |
481 } | 481 } |
482 | 482 |
483 void ShellWindow::SaveWindowPosition() { | 483 void ShellWindow::SaveWindowPosition() { |
484 SendBoundsUpdate(); | 484 SendBoundsUpdate(); |
485 if (window_key_.empty()) | 485 if (window_key_.empty()) |
486 return; | 486 return; |
487 if (!native_window_) | 487 if (!app_window_) |
488 return; | 488 return; |
489 | 489 |
490 extensions::ShellWindowGeometryCache* cache = | 490 extensions::ShellWindowGeometryCache* cache = |
491 extensions::ExtensionSystem::Get(profile())-> | 491 extensions::ExtensionSystem::Get(profile())-> |
492 shell_window_geometry_cache(); | 492 shell_window_geometry_cache(); |
493 | 493 |
494 gfx::Rect bounds = native_window_->GetBounds(); | 494 gfx::Rect bounds = app_window_->GetBounds(); |
495 cache->SaveGeometry(extension()->id(), window_key_, bounds); | 495 cache->SaveGeometry(extension()->id(), window_key_, bounds); |
496 } | 496 } |
497 | 497 |
498 // static | 498 // static |
499 SkRegion* ShellWindow::RawDraggableRegionsToSkRegion( | 499 SkRegion* ShellWindow::RawDraggableRegionsToSkRegion( |
500 const std::vector<extensions::DraggableRegion>& regions) { | 500 const std::vector<extensions::DraggableRegion>& regions) { |
501 SkRegion* sk_region = new SkRegion; | 501 SkRegion* sk_region = new SkRegion; |
502 for (std::vector<extensions::DraggableRegion>::const_iterator iter = | 502 for (std::vector<extensions::DraggableRegion>::const_iterator iter = |
503 regions.begin(); | 503 regions.begin(); |
504 iter != regions.end(); ++iter) { | 504 iter != regions.end(); ++iter) { |
505 const extensions::DraggableRegion& region = *iter; | 505 const extensions::DraggableRegion& region = *iter; |
506 sk_region->op( | 506 sk_region->op( |
507 region.bounds.x(), | 507 region.bounds.x(), |
508 region.bounds.y(), | 508 region.bounds.y(), |
509 region.bounds.right(), | 509 region.bounds.right(), |
510 region.bounds.bottom(), | 510 region.bounds.bottom(), |
511 region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); | 511 region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); |
512 } | 512 } |
513 return sk_region; | 513 return sk_region; |
514 } | 514 } |
OLD | NEW |