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

Side by Side Diff: chrome/browser/background/background_contents.cc

Issue 2877333004: UMA for measuring how often 2 or more tabs script the same background contents.
Patch Set: No PostDelayedTask and checking if opener is a hosted app Created 3 years, 7 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
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/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
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 }
OLDNEW
« no previous file with comments | « chrome/browser/background/background_contents.h ('k') | content/browser/frame_host/render_frame_host_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698