| 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/background/background_contents.h" | 5 #include "chrome/browser/background/background_contents.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" |
| 10 #include "base/callback.h" |
| 11 #include "base/metrics/histogram_macros.h" |
| 9 #include "base/profiler/scoped_tracker.h" | 12 #include "base/profiler/scoped_tracker.h" |
| 10 #include "chrome/browser/background/background_contents_service.h" | 13 #include "chrome/browser/background/background_contents_service.h" |
| 11 #include "chrome/browser/chrome_notification_types.h" | 14 #include "chrome/browser/chrome_notification_types.h" |
| 12 #include "chrome/browser/data_use_measurement/data_use_web_contents_observer.h" | 15 #include "chrome/browser/data_use_measurement/data_use_web_contents_observer.h" |
| 13 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" | 16 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" |
| 14 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
| 15 #include "chrome/browser/renderer_preferences_util.h" | 18 #include "chrome/browser/renderer_preferences_util.h" |
| 16 #include "chrome/browser/task_manager/web_contents_tags.h" | 19 #include "chrome/browser/task_manager/web_contents_tags.h" |
| 17 #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h" | 20 #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h" |
| 18 #include "chrome/common/url_constants.h" | 21 #include "chrome/common/url_constants.h" |
| 19 #include "content/public/browser/notification_service.h" | 22 #include "content/public/browser/notification_service.h" |
| 20 #include "content/public/browser/render_frame_host.h" | 23 #include "content/public/browser/render_frame_host.h" |
| 21 #include "content/public/browser/render_process_host.h" | 24 #include "content/public/browser/render_process_host.h" |
| 22 #include "content/public/browser/render_view_host.h" | 25 #include "content/public/browser/render_view_host.h" |
| 23 #include "content/public/browser/session_storage_namespace.h" | 26 #include "content/public/browser/session_storage_namespace.h" |
| 24 #include "content/public/browser/site_instance.h" | 27 #include "content/public/browser/site_instance.h" |
| 25 #include "content/public/browser/web_contents.h" | 28 #include "content/public/browser/web_contents.h" |
| 26 #include "extensions/browser/deferred_start_render_host_observer.h" | 29 #include "extensions/browser/deferred_start_render_host_observer.h" |
| 27 #include "extensions/browser/extension_host_delegate.h" | 30 #include "extensions/browser/extension_host_delegate.h" |
| 28 #include "extensions/browser/extension_host_queue.h" | 31 #include "extensions/browser/extension_host_queue.h" |
| 32 #include "extensions/browser/extension_registry.h" |
| 29 #include "extensions/browser/extensions_browser_client.h" | 33 #include "extensions/browser/extensions_browser_client.h" |
| 30 #include "extensions/browser/view_type_utils.h" | 34 #include "extensions/browser/view_type_utils.h" |
| 31 #include "ui/gfx/geometry/rect.h" | 35 #include "ui/gfx/geometry/rect.h" |
| 32 | 36 |
| 33 using content::SiteInstance; | 37 using content::SiteInstance; |
| 34 using content::WebContents; | 38 using content::WebContents; |
| 35 | 39 |
| 36 BackgroundContents::BackgroundContents( | 40 BackgroundContents::BackgroundContents( |
| 37 scoped_refptr<SiteInstance> site_instance, | 41 scoped_refptr<SiteInstance> site_instance, |
| 38 content::RenderFrameHost* opener, | 42 content::RenderFrameHost* opener, |
| 39 int32_t routing_id, | 43 int32_t routing_id, |
| 40 int32_t main_frame_routing_id, | 44 int32_t main_frame_routing_id, |
| 41 int32_t main_frame_widget_routing_id, | 45 int32_t main_frame_widget_routing_id, |
| 42 Delegate* delegate, | 46 Delegate* delegate, |
| 43 const std::string& partition_id, | 47 const std::string& partition_id, |
| 44 content::SessionStorageNamespace* session_storage_namespace) | 48 content::SessionStorageNamespace* session_storage_namespace) |
| 45 : delegate_(delegate), | 49 : delegate_(delegate), |
| 46 extension_host_delegate_(extensions::ExtensionsBrowserClient::Get() | 50 extension_host_delegate_(extensions::ExtensionsBrowserClient::Get() |
| 47 ->CreateExtensionHostDelegate()) { | 51 ->CreateExtensionHostDelegate()), |
| 52 weak_factory_(this) { |
| 48 profile_ = Profile::FromBrowserContext( | 53 profile_ = Profile::FromBrowserContext( |
| 49 site_instance->GetBrowserContext()); | 54 site_instance->GetBrowserContext()); |
| 50 | 55 |
| 51 WebContents::CreateParams create_params(profile_, std::move(site_instance)); | 56 WebContents::CreateParams create_params(profile_, std::move(site_instance)); |
| 52 create_params.opener_render_process_id = | 57 create_params.opener_render_process_id = |
| 53 opener ? opener->GetProcess()->GetID() : MSG_ROUTING_NONE; | 58 opener ? opener->GetProcess()->GetID() : MSG_ROUTING_NONE; |
| 54 create_params.opener_render_frame_id = | 59 create_params.opener_render_frame_id = |
| 55 opener ? opener->GetRoutingID() : MSG_ROUTING_NONE; | 60 opener ? opener->GetRoutingID() : MSG_ROUTING_NONE; |
| 56 create_params.routing_id = routing_id; | 61 create_params.routing_id = routing_id; |
| 57 create_params.main_frame_routing_id = main_frame_routing_id; | 62 create_params.main_frame_routing_id = main_frame_routing_id; |
| 58 create_params.main_frame_widget_routing_id = main_frame_widget_routing_id; | 63 create_params.main_frame_widget_routing_id = main_frame_widget_routing_id; |
| 59 create_params.renderer_initiated_creation = routing_id != MSG_ROUTING_NONE; | 64 create_params.renderer_initiated_creation = routing_id != MSG_ROUTING_NONE; |
| 60 if (session_storage_namespace) { | 65 if (session_storage_namespace) { |
| 61 content::SessionStorageNamespaceMap session_storage_namespace_map; | 66 content::SessionStorageNamespaceMap session_storage_namespace_map; |
| 62 session_storage_namespace_map.insert( | 67 session_storage_namespace_map.insert( |
| 63 std::make_pair(partition_id, session_storage_namespace)); | 68 std::make_pair(partition_id, session_storage_namespace)); |
| 64 web_contents_.reset(WebContents::CreateWithSessionStorage( | 69 web_contents_.reset(WebContents::CreateWithSessionStorage( |
| 65 create_params, session_storage_namespace_map)); | 70 create_params, session_storage_namespace_map)); |
| 66 } else { | 71 } else { |
| 67 web_contents_.reset(WebContents::Create(create_params)); | 72 web_contents_.reset(WebContents::Create(create_params)); |
| 68 } | 73 } |
| 74 TrackPreviousOpener(); |
| 69 extensions::SetViewType( | 75 extensions::SetViewType( |
| 70 web_contents_.get(), extensions::VIEW_TYPE_BACKGROUND_CONTENTS); | 76 web_contents_.get(), extensions::VIEW_TYPE_BACKGROUND_CONTENTS); |
| 71 web_contents_->SetDelegate(this); | 77 web_contents_->SetDelegate(this); |
| 72 content::WebContentsObserver::Observe(web_contents_.get()); | 78 content::WebContentsObserver::Observe(web_contents_.get()); |
| 73 data_use_measurement::DataUseWebContentsObserver::CreateForWebContents( | 79 data_use_measurement::DataUseWebContentsObserver::CreateForWebContents( |
| 74 web_contents_.get()); | 80 web_contents_.get()); |
| 75 extensions::ChromeExtensionWebContentsObserver::CreateForWebContents( | 81 extensions::ChromeExtensionWebContentsObserver::CreateForWebContents( |
| 76 web_contents_.get()); | 82 web_contents_.get()); |
| 77 | 83 |
| 78 // Add the TaskManager-specific tag for the BackgroundContents. | 84 // Add the TaskManager-specific tag for the BackgroundContents. |
| 79 task_manager::WebContentsTags::CreateForBackgroundContents( | 85 task_manager::WebContentsTags::CreateForBackgroundContents( |
| 80 web_contents_.get(), this); | 86 web_contents_.get(), this); |
| 81 | 87 |
| 82 // Close ourselves when the application is shutting down. | 88 // Close ourselves when the application is shutting down. |
| 83 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, | 89 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, |
| 84 content::NotificationService::AllSources()); | 90 content::NotificationService::AllSources()); |
| 85 | 91 |
| 86 // Register for our parent profile to shutdown, so we can shut ourselves down | 92 // Register for our parent profile to shutdown, so we can shut ourselves down |
| 87 // as well (should only be called for OTR profiles, as we should receive | 93 // as well (should only be called for OTR profiles, as we should receive |
| 88 // APP_TERMINATING before non-OTR profiles are destroyed). | 94 // APP_TERMINATING before non-OTR profiles are destroyed). |
| 89 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, | 95 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, |
| 90 content::Source<Profile>(profile_)); | 96 content::Source<Profile>(profile_)); |
| 91 } | 97 } |
| 92 | 98 |
| 93 // Exposed to allow creating mocks. | 99 // Exposed to allow creating mocks. |
| 94 BackgroundContents::BackgroundContents() | 100 BackgroundContents::BackgroundContents() |
| 95 : delegate_(NULL), | 101 : delegate_(NULL), profile_(NULL), weak_factory_(this) {} |
| 96 profile_(NULL) { | |
| 97 } | |
| 98 | 102 |
| 99 BackgroundContents::~BackgroundContents() { | 103 BackgroundContents::~BackgroundContents() { |
| 100 if (!web_contents_.get()) // Will be null for unit tests. | 104 if (!web_contents_.get()) // Will be null for unit tests. |
| 101 return; | 105 return; |
| 102 | 106 |
| 103 // Unregister for any notifications before notifying observers that we are | 107 // Unregister for any notifications before notifying observers that we are |
| 104 // going away - this prevents any re-entrancy due to chained notifications | 108 // going away - this prevents any re-entrancy due to chained notifications |
| 105 // (http://crbug.com/237781). | 109 // (http://crbug.com/237781). |
| 106 registrar_.RemoveAll(); | 110 registrar_.RemoveAll(); |
| 107 | 111 |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 | 227 |
| 224 void BackgroundContents::AddDeferredStartRenderHostObserver( | 228 void BackgroundContents::AddDeferredStartRenderHostObserver( |
| 225 extensions::DeferredStartRenderHostObserver* observer) { | 229 extensions::DeferredStartRenderHostObserver* observer) { |
| 226 deferred_start_render_host_observer_list_.AddObserver(observer); | 230 deferred_start_render_host_observer_list_.AddObserver(observer); |
| 227 } | 231 } |
| 228 | 232 |
| 229 void BackgroundContents::RemoveDeferredStartRenderHostObserver( | 233 void BackgroundContents::RemoveDeferredStartRenderHostObserver( |
| 230 extensions::DeferredStartRenderHostObserver* observer) { | 234 extensions::DeferredStartRenderHostObserver* observer) { |
| 231 deferred_start_render_host_observer_list_.RemoveObserver(observer); | 235 deferred_start_render_host_observer_list_.RemoveObserver(observer); |
| 232 } | 236 } |
| 237 |
| 238 namespace { |
| 239 |
| 240 class OpenerDestroyedObserver : public content::WebContentsObserver { |
| 241 public: |
| 242 OpenerDestroyedObserver(content::RenderFrameHost* opener, |
| 243 base::OnceClosure callback) |
| 244 : WebContentsObserver(WebContents::FromRenderFrameHost(opener)), |
| 245 opener_(opener), |
| 246 callback_(std::move(callback)) { |
| 247 DCHECK(!callback_.is_null()); |
| 248 } |
| 249 |
| 250 // WebContentsObserver override: |
| 251 void RenderFrameDeleted(content::RenderFrameHost* deleted_frame) override { |
| 252 if (deleted_frame == opener_) { |
| 253 std::move(callback_).Run(); |
| 254 delete this; |
| 255 } |
| 256 } |
| 257 |
| 258 private: |
| 259 content::RenderFrameHost* opener_; |
| 260 base::OnceClosure callback_; |
| 261 DISALLOW_COPY_AND_ASSIGN(OpenerDestroyedObserver); |
| 262 }; |
| 263 |
| 264 } // namespace |
| 265 |
| 266 void BackgroundContents::TrackPreviousOpener() { |
| 267 // Do we already have a still-alive previous opener that is a hosted app? |
| 268 if (previous_opener_) |
| 269 return; |
| 270 |
| 271 if (!IsCurrentOpenerHostedApp()) |
| 272 return; |
| 273 |
| 274 previous_opener_ = web_contents()->GetOpener(); |
| 275 DCHECK(previous_opener_); |
| 276 new OpenerDestroyedObserver( |
| 277 previous_opener_, |
| 278 base::Bind(&BackgroundContents::OnPreviousOpenerDestroyed, |
| 279 weak_factory_.GetWeakPtr())); |
| 280 } |
| 281 |
| 282 void BackgroundContents::OnPreviousOpenerDestroyed() { |
| 283 previous_opener_ = nullptr; |
| 284 } |
| 285 |
| 286 bool BackgroundContents::IsCurrentOpenerHostedApp() { |
| 287 content::RenderFrameHost* current_opener = web_contents()->GetOpener(); |
| 288 if (!current_opener) |
| 289 return false; |
| 290 |
| 291 const extensions::Extension* opener_extension = |
| 292 extensions::ExtensionRegistry::Get(web_contents()->GetBrowserContext()) |
| 293 ->enabled_extensions() |
| 294 .GetExtensionOrAppByURL(current_opener->GetLastCommittedURL()); |
| 295 return opener_extension && opener_extension->is_hosted_app(); |
| 296 } |
| 297 |
| 298 void BackgroundContents::DidChangeOpener() { |
| 299 if (previous_opener_ && IsCurrentOpenerHostedApp() && |
| 300 (web_contents()->GetOpener() != previous_opener_)) { |
| 301 UMA_HISTOGRAM_BOOLEAN( |
| 302 "Extensions.HostedAppOpenedBackgroundContentsFromTwoOpeners", true); |
| 303 } |
| 304 |
| 305 TrackPreviousOpener(); |
| 306 } |
| OLD | NEW |