| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "extensions/browser/app_window/app_window.h" | 5 #include "extensions/browser/app_window/app_window.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <string> | 10 #include <string> |
| 11 #include <utility> | 11 #include <utility> |
| 12 #include <vector> | 12 #include <vector> |
| 13 | 13 |
| 14 #include "base/callback_helpers.h" | 14 #include "base/callback_helpers.h" |
| 15 #include "base/command_line.h" | |
| 16 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
| 17 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
| 18 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
| 19 #include "base/task_runner.h" | 18 #include "base/task_runner.h" |
| 20 #include "base/threading/thread_task_runner_handle.h" | 19 #include "base/threading/thread_task_runner_handle.h" |
| 21 #include "base/values.h" | 20 #include "base/values.h" |
| 22 #include "build/build_config.h" | 21 #include "build/build_config.h" |
| 23 #include "components/web_modal/web_contents_modal_dialog_manager.h" | 22 #include "components/web_modal/web_contents_modal_dialog_manager.h" |
| 24 #include "content/public/browser/browser_context.h" | 23 #include "content/public/browser/browser_context.h" |
| 25 #include "content/public/browser/invalidate_type.h" | 24 #include "content/public/browser/invalidate_type.h" |
| 26 #include "content/public/browser/navigation_entry.h" | 25 #include "content/public/browser/navigation_entry.h" |
| 27 #include "content/public/browser/render_view_host.h" | 26 #include "content/public/browser/render_view_host.h" |
| 28 #include "content/public/browser/render_widget_host.h" | 27 #include "content/public/browser/render_widget_host.h" |
| 29 #include "content/public/browser/resource_dispatcher_host.h" | 28 #include "content/public/browser/resource_dispatcher_host.h" |
| 30 #include "content/public/browser/web_contents.h" | 29 #include "content/public/browser/web_contents.h" |
| 31 #include "content/public/common/browser_side_navigation_policy.h" | 30 #include "content/public/common/browser_side_navigation_policy.h" |
| 32 #include "content/public/common/content_switches.h" | |
| 33 #include "content/public/common/media_stream_request.h" | 31 #include "content/public/common/media_stream_request.h" |
| 34 #include "extensions/browser/app_window/app_delegate.h" | 32 #include "extensions/browser/app_window/app_delegate.h" |
| 35 #include "extensions/browser/app_window/app_web_contents_helper.h" | 33 #include "extensions/browser/app_window/app_web_contents_helper.h" |
| 36 #include "extensions/browser/app_window/app_window_client.h" | 34 #include "extensions/browser/app_window/app_window_client.h" |
| 37 #include "extensions/browser/app_window/app_window_geometry_cache.h" | 35 #include "extensions/browser/app_window/app_window_geometry_cache.h" |
| 38 #include "extensions/browser/app_window/app_window_registry.h" | 36 #include "extensions/browser/app_window/app_window_registry.h" |
| 39 #include "extensions/browser/app_window/native_app_window.h" | 37 #include "extensions/browser/app_window/native_app_window.h" |
| 40 #include "extensions/browser/app_window/size_constraints.h" | 38 #include "extensions/browser/app_window/size_constraints.h" |
| 41 #include "extensions/browser/extension_registry.h" | 39 #include "extensions/browser/extension_registry.h" |
| 42 #include "extensions/browser/extension_system.h" | 40 #include "extensions/browser/extension_system.h" |
| 43 #include "extensions/browser/extension_web_contents_observer.h" | 41 #include "extensions/browser/extension_web_contents_observer.h" |
| 44 #include "extensions/browser/extensions_browser_client.h" | 42 #include "extensions/browser/extensions_browser_client.h" |
| 45 #include "extensions/browser/notification_types.h" | 43 #include "extensions/browser/notification_types.h" |
| 46 #include "extensions/browser/process_manager.h" | 44 #include "extensions/browser/process_manager.h" |
| 47 #include "extensions/browser/suggest_permission_util.h" | 45 #include "extensions/browser/suggest_permission_util.h" |
| 48 #include "extensions/browser/view_type_utils.h" | 46 #include "extensions/browser/view_type_utils.h" |
| 49 #include "extensions/common/draggable_region.h" | 47 #include "extensions/common/draggable_region.h" |
| 50 #include "extensions/common/extension.h" | 48 #include "extensions/common/extension.h" |
| 51 #include "extensions/common/manifest_handlers/icons_handler.h" | 49 #include "extensions/common/manifest_handlers/icons_handler.h" |
| 52 #include "extensions/common/permissions/permissions_data.h" | 50 #include "extensions/common/permissions/permissions_data.h" |
| 53 #include "extensions/common/switches.h" | |
| 54 #include "extensions/grit/extensions_browser_resources.h" | 51 #include "extensions/grit/extensions_browser_resources.h" |
| 55 #include "third_party/skia/include/core/SkRegion.h" | 52 #include "third_party/skia/include/core/SkRegion.h" |
| 56 #include "ui/base/resource/resource_bundle.h" | 53 #include "ui/base/resource/resource_bundle.h" |
| 57 #include "ui/display/display.h" | 54 #include "ui/display/display.h" |
| 58 #include "ui/display/screen.h" | 55 #include "ui/display/screen.h" |
| 59 #include "ui/events/keycodes/keyboard_codes.h" | 56 #include "ui/events/keycodes/keyboard_codes.h" |
| 60 #include "ui/gfx/image/image_skia_operations.h" | 57 #include "ui/gfx/image/image_skia_operations.h" |
| 61 | 58 |
| 62 #if !defined(OS_MACOSX) | 59 #if !defined(OS_MACOSX) |
| 63 #include "components/prefs/pref_service.h" | 60 #include "components/prefs/pref_service.h" |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 // AppWindow | 237 // AppWindow |
| 241 | 238 |
| 242 AppWindow::AppWindow(BrowserContext* context, | 239 AppWindow::AppWindow(BrowserContext* context, |
| 243 AppDelegate* app_delegate, | 240 AppDelegate* app_delegate, |
| 244 const Extension* extension) | 241 const Extension* extension) |
| 245 : browser_context_(context), | 242 : browser_context_(context), |
| 246 extension_id_(extension->id()), | 243 extension_id_(extension->id()), |
| 247 window_type_(WINDOW_TYPE_DEFAULT), | 244 window_type_(WINDOW_TYPE_DEFAULT), |
| 248 app_delegate_(app_delegate), | 245 app_delegate_(app_delegate), |
| 249 fullscreen_types_(FULLSCREEN_TYPE_NONE), | 246 fullscreen_types_(FULLSCREEN_TYPE_NONE), |
| 250 show_on_first_paint_(false), | |
| 251 first_paint_complete_(false), | |
| 252 has_been_shown_(false), | 247 has_been_shown_(false), |
| 253 can_send_events_(false), | |
| 254 is_hidden_(false), | 248 is_hidden_(false), |
| 255 delayed_show_type_(SHOW_ACTIVE), | |
| 256 cached_always_on_top_(false), | 249 cached_always_on_top_(false), |
| 257 requested_alpha_enabled_(false), | 250 requested_alpha_enabled_(false), |
| 258 is_ime_window_(false), | 251 is_ime_window_(false), |
| 259 show_in_shelf_(false), | 252 show_in_shelf_(false), |
| 260 image_loader_ptr_factory_(this) { | 253 image_loader_ptr_factory_(this) { |
| 261 ExtensionsBrowserClient* client = ExtensionsBrowserClient::Get(); | 254 ExtensionsBrowserClient* client = ExtensionsBrowserClient::Get(); |
| 262 CHECK(!client->IsGuestSession(context) || context->IsOffTheRecord()) | 255 CHECK(!client->IsGuestSession(context) || context->IsOffTheRecord()) |
| 263 << "Only off the record window may be opened in the guest mode."; | 256 << "Only off the record window may be opened in the guest mode."; |
| 264 } | 257 } |
| 265 | 258 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 OnNativeWindowChanged(); | 337 OnNativeWindowChanged(); |
| 345 | 338 |
| 346 ExtensionRegistry::Get(browser_context_)->AddObserver(this); | 339 ExtensionRegistry::Get(browser_context_)->AddObserver(this); |
| 347 | 340 |
| 348 // Close when the browser process is exiting. | 341 // Close when the browser process is exiting. |
| 349 app_delegate_->SetTerminatingCallback( | 342 app_delegate_->SetTerminatingCallback( |
| 350 base::Bind(&NativeAppWindow::Close, | 343 base::Bind(&NativeAppWindow::Close, |
| 351 base::Unretained(native_app_window_.get()))); | 344 base::Unretained(native_app_window_.get()))); |
| 352 | 345 |
| 353 app_window_contents_->LoadContents(new_params.creator_process_id); | 346 app_window_contents_->LoadContents(new_params.creator_process_id); |
| 354 | |
| 355 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 356 extensions::switches::kEnableAppsShowOnFirstPaint)) { | |
| 357 // We want to show the window only when the content has been painted. For | |
| 358 // that to happen, we need to define a size for the content, otherwise the | |
| 359 // layout will happen in a 0x0 area. | |
| 360 gfx::Insets frame_insets = native_app_window_->GetFrameInsets(); | |
| 361 gfx::Rect initial_bounds = new_params.GetInitialWindowBounds(frame_insets); | |
| 362 initial_bounds.Inset(frame_insets); | |
| 363 app_delegate_->ResizeWebContents(web_contents(), initial_bounds.size()); | |
| 364 } | |
| 365 } | 347 } |
| 366 | 348 |
| 367 AppWindow::~AppWindow() { | 349 AppWindow::~AppWindow() { |
| 368 ExtensionRegistry::Get(browser_context_)->RemoveObserver(this); | 350 ExtensionRegistry::Get(browser_context_)->RemoveObserver(this); |
| 369 } | 351 } |
| 370 | 352 |
| 371 void AppWindow::RequestMediaAccessPermission( | 353 void AppWindow::RequestMediaAccessPermission( |
| 372 content::WebContents* web_contents, | 354 content::WebContents* web_contents, |
| 373 const content::MediaStreamRequest& request, | 355 const content::MediaStreamRequest& request, |
| 374 const content::MediaResponseCallback& callback) { | 356 const content::MediaResponseCallback& callback) { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 content::RenderFrameHost* frame, | 444 content::RenderFrameHost* frame, |
| 463 const content::BluetoothChooser::EventHandler& event_handler) { | 445 const content::BluetoothChooser::EventHandler& event_handler) { |
| 464 return ExtensionsBrowserClient::Get()->CreateBluetoothChooser(frame, | 446 return ExtensionsBrowserClient::Get()->CreateBluetoothChooser(frame, |
| 465 event_handler); | 447 event_handler); |
| 466 } | 448 } |
| 467 | 449 |
| 468 void AppWindow::RenderViewCreated(content::RenderViewHost* render_view_host) { | 450 void AppWindow::RenderViewCreated(content::RenderViewHost* render_view_host) { |
| 469 app_delegate_->RenderViewCreated(render_view_host); | 451 app_delegate_->RenderViewCreated(render_view_host); |
| 470 } | 452 } |
| 471 | 453 |
| 472 void AppWindow::DidFirstVisuallyNonEmptyPaint() { | |
| 473 first_paint_complete_ = true; | |
| 474 if (show_on_first_paint_) { | |
| 475 DCHECK(delayed_show_type_ == SHOW_ACTIVE || | |
| 476 delayed_show_type_ == SHOW_INACTIVE); | |
| 477 Show(delayed_show_type_); | |
| 478 } | |
| 479 } | |
| 480 | |
| 481 void AppWindow::SetOnFirstCommitCallback(const base::Closure& callback) { | 454 void AppWindow::SetOnFirstCommitCallback(const base::Closure& callback) { |
| 482 DCHECK(on_first_commit_callback_.is_null()); | 455 DCHECK(on_first_commit_callback_.is_null()); |
| 483 on_first_commit_callback_ = callback; | 456 on_first_commit_callback_ = callback; |
| 484 } | 457 } |
| 485 | 458 |
| 486 void AppWindow::OnReadyToCommitFirstNavigation() { | 459 void AppWindow::OnReadyToCommitFirstNavigation() { |
| 487 if (!content::IsBrowserSideNavigationEnabled()) | 460 if (!content::IsBrowserSideNavigationEnabled()) |
| 488 return; | 461 return; |
| 489 | 462 |
| 490 // PlzNavigate: execute renderer-side setup now that there is a renderer | 463 // PlzNavigate: execute renderer-side setup now that there is a renderer |
| 491 // process assigned to the navigation. With renderer-side navigation, this | 464 // process assigned to the navigation. With renderer-side navigation, this |
| 492 // would happen before the navigation starts, but PlzNavigate must wait until | 465 // would happen before the navigation starts, but PlzNavigate must wait until |
| 493 // this point in time in the navigation. | 466 // this point in time in the navigation. |
| 494 | 467 |
| 495 WindowEventsReady(); | |
| 496 if (on_first_commit_callback_.is_null()) | 468 if (on_first_commit_callback_.is_null()) |
| 497 return; | 469 return; |
| 498 // It is important that the callback executes after the calls to | 470 // It is important that the callback executes after the calls to |
| 499 // WebContentsObserver::ReadyToCommitNavigation have been processed. The | 471 // WebContentsObserver::ReadyToCommitNavigation have been processed. The |
| 500 // CommitNavigation IPC that will properly set up the renderer will only be | 472 // CommitNavigation IPC that will properly set up the renderer will only be |
| 501 // sent after these, and it must be sent before the callback gets to run, | 473 // sent after these, and it must be sent before the callback gets to run, |
| 502 // hence the use of PostTask. | 474 // hence the use of PostTask. |
| 503 base::ThreadTaskRunnerHandle::Get()->PostTask( | 475 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 504 FROM_HERE, base::ResetAndReturn(&on_first_commit_callback_)); | 476 FROM_HERE, base::ResetAndReturn(&on_first_commit_callback_)); |
| 505 } | 477 } |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 native_app_window_->SetBounds(bounds); | 690 native_app_window_->SetBounds(bounds); |
| 719 } | 691 } |
| 720 OnNativeWindowChanged(); | 692 OnNativeWindowChanged(); |
| 721 } | 693 } |
| 722 | 694 |
| 723 void AppWindow::Show(ShowType show_type) { | 695 void AppWindow::Show(ShowType show_type) { |
| 724 app_delegate_->OnShow(); | 696 app_delegate_->OnShow(); |
| 725 bool was_hidden = is_hidden_ || !has_been_shown_; | 697 bool was_hidden = is_hidden_ || !has_been_shown_; |
| 726 is_hidden_ = false; | 698 is_hidden_ = false; |
| 727 | 699 |
| 728 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 729 switches::kEnableAppsShowOnFirstPaint)) { | |
| 730 show_on_first_paint_ = true; | |
| 731 | |
| 732 if (!first_paint_complete_) { | |
| 733 delayed_show_type_ = show_type; | |
| 734 return; | |
| 735 } | |
| 736 } | |
| 737 | |
| 738 switch (show_type) { | 700 switch (show_type) { |
| 739 case SHOW_ACTIVE: | 701 case SHOW_ACTIVE: |
| 740 GetBaseWindow()->Show(); | 702 GetBaseWindow()->Show(); |
| 741 break; | 703 break; |
| 742 case SHOW_INACTIVE: | 704 case SHOW_INACTIVE: |
| 743 GetBaseWindow()->ShowInactive(); | 705 GetBaseWindow()->ShowInactive(); |
| 744 break; | 706 break; |
| 745 } | 707 } |
| 746 AppWindowRegistry::Get(browser_context_)->AppWindowShown(this, was_hidden); | 708 AppWindowRegistry::Get(browser_context_)->AppWindowShown(this, was_hidden); |
| 747 | |
| 748 has_been_shown_ = true; | 709 has_been_shown_ = true; |
| 749 SendOnWindowShownIfShown(); | |
| 750 } | 710 } |
| 751 | 711 |
| 752 void AppWindow::Hide() { | 712 void AppWindow::Hide() { |
| 753 // This is there to prevent race conditions with Hide() being called before | |
| 754 // there was a non-empty paint. It should have no effect in a non-racy | |
| 755 // scenario where the application is hiding then showing a window: the second | |
| 756 // show will not be delayed. | |
| 757 is_hidden_ = true; | 713 is_hidden_ = true; |
| 758 show_on_first_paint_ = false; | |
| 759 GetBaseWindow()->Hide(); | 714 GetBaseWindow()->Hide(); |
| 760 AppWindowRegistry::Get(browser_context_)->AppWindowHidden(this); | 715 AppWindowRegistry::Get(browser_context_)->AppWindowHidden(this); |
| 761 app_delegate_->OnHide(); | 716 app_delegate_->OnHide(); |
| 762 } | 717 } |
| 763 | 718 |
| 764 void AppWindow::SetAlwaysOnTop(bool always_on_top) { | 719 void AppWindow::SetAlwaysOnTop(bool always_on_top) { |
| 765 if (cached_always_on_top_ == always_on_top) | 720 if (cached_always_on_top_ == always_on_top) |
| 766 return; | 721 return; |
| 767 | 722 |
| 768 cached_always_on_top_ = always_on_top; | 723 cached_always_on_top_ = always_on_top; |
| 769 | 724 |
| 770 // As a security measure, do not allow fullscreen windows or windows that | 725 // As a security measure, do not allow fullscreen windows or windows that |
| 771 // overlap the taskbar to be on top. The property will be applied when the | 726 // overlap the taskbar to be on top. The property will be applied when the |
| 772 // window exits fullscreen and moves away from the taskbar. | 727 // window exits fullscreen and moves away from the taskbar. |
| 773 if (!IsFullscreen() && !IntersectsWithTaskbar()) | 728 if (!IsFullscreen() && !IntersectsWithTaskbar()) |
| 774 native_app_window_->SetAlwaysOnTop(always_on_top); | 729 native_app_window_->SetAlwaysOnTop(always_on_top); |
| 775 | 730 |
| 776 OnNativeWindowChanged(); | 731 OnNativeWindowChanged(); |
| 777 } | 732 } |
| 778 | 733 |
| 779 bool AppWindow::IsAlwaysOnTop() const { return cached_always_on_top_; } | 734 bool AppWindow::IsAlwaysOnTop() const { return cached_always_on_top_; } |
| 780 | 735 |
| 781 void AppWindow::RestoreAlwaysOnTop() { | 736 void AppWindow::RestoreAlwaysOnTop() { |
| 782 if (cached_always_on_top_) | 737 if (cached_always_on_top_) |
| 783 UpdateNativeAlwaysOnTop(); | 738 UpdateNativeAlwaysOnTop(); |
| 784 } | 739 } |
| 785 | 740 |
| 786 void AppWindow::WindowEventsReady() { | |
| 787 can_send_events_ = true; | |
| 788 SendOnWindowShownIfShown(); | |
| 789 } | |
| 790 | |
| 791 void AppWindow::NotifyRenderViewReady() { | 741 void AppWindow::NotifyRenderViewReady() { |
| 792 if (app_window_contents_) | 742 if (app_window_contents_) |
| 793 app_window_contents_->OnWindowReady(); | 743 app_window_contents_->OnWindowReady(); |
| 794 } | 744 } |
| 795 | 745 |
| 796 void AppWindow::GetSerializedState(base::DictionaryValue* properties) const { | 746 void AppWindow::GetSerializedState(base::DictionaryValue* properties) const { |
| 797 DCHECK(properties); | 747 DCHECK(properties); |
| 798 | 748 |
| 799 properties->SetBoolean("fullscreen", | 749 properties->SetBoolean("fullscreen", |
| 800 native_app_window_->IsFullscreenOrPending()); | 750 native_app_window_->IsFullscreenOrPending()); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 932 // When entering fullscreen or overlapping the taskbar, ensure windows are | 882 // When entering fullscreen or overlapping the taskbar, ensure windows are |
| 933 // not always-on-top. | 883 // not always-on-top. |
| 934 native_app_window_->SetAlwaysOnTop(false); | 884 native_app_window_->SetAlwaysOnTop(false); |
| 935 } else if (!is_on_top && !fullscreen && !intersects_taskbar) { | 885 } else if (!is_on_top && !fullscreen && !intersects_taskbar) { |
| 936 // When exiting fullscreen and moving away from the taskbar, reinstate | 886 // When exiting fullscreen and moving away from the taskbar, reinstate |
| 937 // always-on-top. | 887 // always-on-top. |
| 938 native_app_window_->SetAlwaysOnTop(true); | 888 native_app_window_->SetAlwaysOnTop(true); |
| 939 } | 889 } |
| 940 } | 890 } |
| 941 | 891 |
| 942 void AppWindow::SendOnWindowShownIfShown() { | |
| 943 if (!can_send_events_ || !has_been_shown_) | |
| 944 return; | |
| 945 | |
| 946 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 947 ::switches::kTestType)) { | |
| 948 app_window_contents_->DispatchWindowShownForTests(); | |
| 949 } | |
| 950 } | |
| 951 | |
| 952 void AppWindow::CloseContents(WebContents* contents) { | 892 void AppWindow::CloseContents(WebContents* contents) { |
| 953 native_app_window_->Close(); | 893 native_app_window_->Close(); |
| 954 } | 894 } |
| 955 | 895 |
| 956 bool AppWindow::ShouldSuppressDialogs(WebContents* source) { | 896 bool AppWindow::ShouldSuppressDialogs(WebContents* source) { |
| 957 return true; | 897 return true; |
| 958 } | 898 } |
| 959 | 899 |
| 960 content::ColorChooser* AppWindow::OpenColorChooser( | 900 content::ColorChooser* AppWindow::OpenColorChooser( |
| 961 WebContents* web_contents, | 901 WebContents* web_contents, |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1162 region.bounds.x(), | 1102 region.bounds.x(), |
| 1163 region.bounds.y(), | 1103 region.bounds.y(), |
| 1164 region.bounds.right(), | 1104 region.bounds.right(), |
| 1165 region.bounds.bottom(), | 1105 region.bounds.bottom(), |
| 1166 region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); | 1106 region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); |
| 1167 } | 1107 } |
| 1168 return sk_region; | 1108 return sk_region; |
| 1169 } | 1109 } |
| 1170 | 1110 |
| 1171 } // namespace extensions | 1111 } // namespace extensions |
| OLD | NEW |