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

Side by Side Diff: chrome/browser/sessions/session_restore_stats_collector.h

Issue 1136523004: [Sessions] Add detailed logging of SessionRestore events. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Sweeping refactor. Created 5 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 #ifndef CHROME_BROWSER_SESSIONS_SESSION_RESTORE_STATS_COLLECTOR_H_ 5 #ifndef CHROME_BROWSER_SESSIONS_SESSION_RESTORE_STATS_COLLECTOR_H_
6 #define CHROME_BROWSER_SESSIONS_SESSION_RESTORE_STATS_COLLECTOR_H_ 6 #define CHROME_BROWSER_SESSIONS_SESSION_RESTORE_STATS_COLLECTOR_H_
7 7
8 #include <set> 8 #include <map>
9 9
10 #include "base/callback_list.h" 10 #include "base/callback_list.h"
11 #include "chrome/browser/sessions/session_restore.h" 11 #include "chrome/browser/sessions/session_restore.h"
12 #include "chrome/browser/sessions/session_restore_delegate.h" 12 #include "chrome/browser/sessions/session_restore_delegate.h"
13 #include "content/public/browser/notification_observer.h" 13 #include "content/public/browser/notification_observer.h"
14 #include "content/public/browser/notification_registrar.h" 14 #include "content/public/browser/notification_registrar.h"
15 #include "content/public/browser/render_widget_host.h" 15 #include "content/public/browser/render_widget_host.h"
16 16
17 namespace content { 17 namespace content {
18 class NavigationController; 18 class NavigationController;
19 } 19 }
20 20
21 // SessionRestoreStatsCollector observes SessionRestore events ands records UMA 21 // SessionRestoreStatsCollector observes SessionRestore events ands records UMA
22 // accordingly. 22 // accordingly.
23 //
24 // A SessionRestoreStatsCollector is tied to an instance of a session restore,
25 // currently being instantianted and owned by the TabLoader. It has two main
26 // phases to its life:
27 //
28 // 1. The session restore is active and ongoing (the TabLoader is still
29 // scheduling tabs for loading). This phases ends when there are no
30 // non-deferred tabs left to be loaded. During this phases statistics are
31 // gathered in a structure before being emitted as UMA metrics at the end of
32 // this phase. At this point the TabLoader ceases to exist and destroys it's
33 // reference to the SessionRestoreStatsCollector.
34 // 2. If any tabs have been deferred the SessionRestoreStatsCollector continues
35 // tracking deferred tabs. This continues to observe the tabs to see which
36 // (if any) of the deferred tabs are subsequently forced to be loaded by the
37 // user. Since such tabs may exist until the end of the browsers life the
38 // statistics are emitted immediately, or risk being lost entirely. When
39 // there are no longer deferred tabs to track the
40 // SessionRestoreStatsCollector will destroy itself.
41 //
42 // TODO(chrisha): Many of these metrics don't make sense to collect in the
43 // presence of an unavailable network, or when tabs are closed during loading.
44 // Rethink the collection in these cases.
23 class SessionRestoreStatsCollector 45 class SessionRestoreStatsCollector
24 : public content::NotificationObserver, 46 : public content::NotificationObserver,
25 public base::RefCounted<SessionRestoreStatsCollector> { 47 public base::RefCounted<SessionRestoreStatsCollector> {
26 public: 48 public:
27 // Called to start tracking tabs. If a restore is already occuring, the tabs 49 // Houses all of the statistics gathered by the SessionRestoreStatsCollector
28 // are added to the existing list of tracked tabs. 50 // while the underlying TabLoader is active. These statistics are all reported
29 static void TrackTabs( 51 // at once via ReportTabLoaderStats.
30 const std::vector<SessionRestoreDelegate::RestoredTab>& tabs, 52 struct TabLoaderStats {
31 const base::TimeTicks& restore_started); 53 // Constructor that initializes everything to zero.
32 54 TabLoaderStats();
33 // Called to start tracking only active tabs. If a restore is already 55
34 // occuring, the tabs are added to the existing list of tracked tabs. 56 // The number of tabs involved in the session restore. This corresponds to
sky 2015/05/27 15:18:39 Using 'the session restore' is confusing here as t
chrisha 2015/06/03 21:16:36 Done.
35 static void TrackActiveTabs( 57 // the "SessionRestore.TabCount" metric and one bucket of the
36 const std::vector<SessionRestoreDelegate::RestoredTab>& tabs, 58 // "SessionRestore.TabActions" histogram.
37 const base::TimeTicks& restore_started); 59 size_t tab_count;
60
61 // The number of tabs automatically loaded by the TabLoader. This
sky 2015/05/27 15:18:40 It's not clear what automatically loaded means her
chrisha 2015/06/03 21:16:36 Done.
62 // corresponds to one bucket of the "SessionRestore.TabActions" histogram.
63 size_t tabs_loaded;
64
65 // The time taken to load the first foreground tab. If this is zero it is
sky 2015/05/27 15:18:40 Clarify what this is relative to and what 'load' c
chrisha 2015/06/03 21:16:36 Done.
66 // because it has not been recorded (tab was closed before loading).
67 // Corresponds to "SessionRestore.ForegroundTabFirstLoaded" and its _XX
68 // variants.
69 base::TimeDelta foreground_tab_first_loaded;
70
71 // The time taken to paint the first foreground tab. If this is zero it is
sky 2015/05/27 15:18:40 Same comment about what this is relative to. It's
chrisha 2015/06/03 21:16:36 Done.
72 // because it has not been recorded (tab was closed before painting or user
73 // switched to another tab). Corresponds to
74 // "SessionRestore.ForegroundTabFirstPaint" and
75 // "SessionRestore.ForegroundTabFirstPaint2" metrics and their _XX variants.
76 base::TimeDelta foreground_tab_first_paint;
77
78 // The time taken for all non-deferred tabs to be loaded. This corresponds
79 // to the "SessionRestore.AllTabsLoaded" metric and its _XX variants.
80 base::TimeDelta all_tabs_loaded;
sky 2015/05/27 15:18:40 all is too overloaded here. Maybe time_to_non_defe
chrisha 2015/06/03 21:16:36 Done.
81
82 // The maximum number of tabs loading in parallel. This corresponds to the
83 // "SessionRestore.ParallelTabLoads" metric.
84 size_t parallel_tab_loads;
85 };
86
87 explicit SessionRestoreStatsCollector(const base::TimeTicks& restore_started);
88
89 // Adds new tabs to the list of tracked tabs.
90 void TrackTabs(const std::vector<SessionRestoreDelegate::RestoredTab>& tabs);
91
92 // Called to indicate that the loading of a tab has been deferred by session
93 // restore.
94 void DeferTab(content::NavigationController* tab);
95
96 // Exposed for unittesting.
97 const TabLoaderStats& tab_loader_stats() const { return tab_loader_stats_; }
98
99 protected:
100 // Reporting functions that cause actual UMA metrics to be emitted. Exposed as
101 // a unittesting seams.
102 virtual void ReportTabLoaderStats();
sky 2015/05/27 15:18:40 I would prefer a delegate rather than subclassing.
chrisha 2015/06/03 21:16:36 Done.
103 virtual void ReportTabDeferred();
104 virtual void ReportDeferredTabLoaded();
38 105
39 private: 106 private:
40 friend class base::RefCounted<SessionRestoreStatsCollector>; 107 friend class base::RefCounted<SessionRestoreStatsCollector>;
41 108
42 using RenderWidgetHostSet = std::set<content::RenderWidgetHost*>; 109 // Indicates whether the loading state of a tab.
43 110 enum TabLoadingState {
44 explicit SessionRestoreStatsCollector(const base::TimeTicks& restore_started); 111 TAB_IS_NOT_LOADING,
112 TAB_IS_LOADING,
113 TAB_IS_LOADED
114 };
115
116 // State that is tracked for a tab while it is being observed.
117 struct TabState {
118 TabState(content::NavigationController* controller);
sky 2015/05/27 15:18:40 explicit
chrisha 2015/06/03 21:16:37 Done.
119
120 // The NavigationController associated with the tab. This is the primary
121 // index for it and is never null.
122 content::NavigationController* controller;
123
124 // The RenderWidgetHost associated with the tab. This is the secondary
125 // index and starts out being null. If it is not null it is because the tab
126 // is actively loading or waiting to be painted.
127 content::RenderWidgetHost* render_widget_host;
128
129 // Set to true if the tab has been deferred by the TabLoader.
130 bool is_deferred;
131
132 // The current loading state of the tab.
133 TabLoadingState loading_state;
134 };
135
136 // Maps a NavigationController to its state. This is the primary map and
137 // physically houses the state.
138 using NavigationControllerMap = std::map<content::NavigationController*,
139 TabState>;
140
141 // Maps a RenderWidgetHost to its state. This is a secondary index and maps
142 // the tab to a pointer to its state housed in the primary map.
143 using RenderWidgetHostMap = std::map<content::RenderWidgetHost*, TabState*>;
144
45 ~SessionRestoreStatsCollector() override; 145 ~SessionRestoreStatsCollector() override;
46 146
47 // NotificationObserver method. 147 // NotificationObserver method. This is the workhorse of the class and drives
148 // all state transitions.
48 void Observe(int type, 149 void Observe(int type,
49 const content::NotificationSource& source, 150 const content::NotificationSource& source,
50 const content::NotificationDetails& details) override; 151 const content::NotificationDetails& details) override;
51 152
52 // Adds new tabs to the list of tracked tabs. 153 // Called when a tab is no longer tracked. This is called by the 'Observe'
53 void AddTabs(const std::vector<SessionRestoreDelegate::RestoredTab>& tabs); 154 // notification callback. Takes care of unregistering all observers and
54 155 // removing the tab from all internal data structures.
55 // Called when a tab is no longer tracked.
56 void RemoveTab(content::NavigationController* tab); 156 void RemoveTab(content::NavigationController* tab);
57 157
58 // Registers for relevant notifications for a tab. 158 // Registers for relevant notifications for a tab and inserts the tab into
59 void RegisterForNotifications(content::NavigationController* tab); 159 // to tabs_tracked_ map. Return a pointer to the newly created TabState.
160 TabState* RegisterForNotifications(content::NavigationController* tab);
60 161
61 // Returns the RenderWidgetHost of a tab. 162 // Returns the RenderWidgetHost of a tab.
62 content::RenderWidgetHost* GetRenderWidgetHost( 163 content::RenderWidgetHost* GetRenderWidgetHost(
63 content::NavigationController* tab); 164 content::NavigationController* tab);
64 165
65 // Have we recorded the times for a foreground tab load? 166 // Returns the tab state, nullptr if not found.
167 TabState* GetTabState(content::NavigationController* tab);
168 TabState* GetTabState(content::RenderWidgetHost* tab);
169
170 // Marks a tab as loading.
171 void MarkTabAsLoading(TabState* tab_state);
172
173 // Returns true if done tracking non-deferred tabs. When this returns true
174 // the TabLoader will have finished its work and aggregate statistics will be
175 // emitted via Record
176 bool DoneTrackingNonDeferredTabs() const;
177
178 // Returns true when no longer tracking any tabs. When this returns true the
179 // collector will destory itself. Called from Observe.
180 bool DoneTracking() const;
181
182 // Has DoneTrackingNonDeferredTabs returned true?
183 bool got_done_tracking_non_deferred_tabs_;
184
185 // Has the time for foreground tab load been recorded?
66 bool got_first_foreground_load_; 186 bool got_first_foreground_load_;
67 187
68 // Have we recorded the times for a foreground tab paint? 188 // Has the time for foreground tab paint been recorded?
69 bool got_first_paint_; 189 bool got_first_paint_;
70 190
191 // Has ReportTabDeferred been called?
192 bool got_report_tab_deferred_;
193
71 // The time the restore process started. 194 // The time the restore process started.
72 base::TimeTicks restore_started_; 195 base::TimeTicks restore_started_;
sky 2015/05/27 15:18:39 const
chrisha 2015/06/03 21:16:36 Done.
73 196
74 // The renderers we have started loading into. 197 // List of tracked tabs, mapped to their TabState.
75 RenderWidgetHostSet render_widget_hosts_loading_; 198 NavigationControllerMap tabs_tracked_;
76 199
77 // The renderers we have loaded and are waiting on to paint. 200 // A secondary index of TabState by their RenderWidgetHosts.
78 RenderWidgetHostSet render_widget_hosts_to_paint_; 201 RenderWidgetHostMap render_widget_map_;
79 202
80 // List of tracked tabs. 203 // Counts the number of non-deferred tabs that the
81 std::set<content::NavigationController*> tabs_tracked_; 204 // SessionRestoreStatsCollector is waiting to see load.
82 205 size_t waiting_for_load_tab_count_;
83 // The number of tabs that have been restored. 206
84 int tab_count_; 207 // Counts the current number of actively loading tabs.
85 208 size_t loading_tab_count_;
86 // Max number of tabs that were loaded in parallel (for metrics).
87 size_t max_parallel_tab_loads_;
88 209
89 // Notification registrar. 210 // Notification registrar.
90 content::NotificationRegistrar registrar_; 211 content::NotificationRegistrar registrar_;
91 212
92 // To keep the collector alive as long as needed. 213 // Statistics gathered regarding the TabLoader.
214 TabLoaderStats tab_loader_stats_;
215
216 // For keeping SessionRestoreStatsCollector alive while it is still working
217 // even if no TabLoader references it. The object only lives on if it still
218 // has deferred tabs remaining from an interrupted session restore.
93 scoped_refptr<SessionRestoreStatsCollector> this_retainer_; 219 scoped_refptr<SessionRestoreStatsCollector> this_retainer_;
94 220
95 // The shared SessionRestoreNotifier instance for all SessionRestores running
96 // at this time.
97 static SessionRestoreStatsCollector* shared_collector_;
98
99 DISALLOW_COPY_AND_ASSIGN(SessionRestoreStatsCollector); 221 DISALLOW_COPY_AND_ASSIGN(SessionRestoreStatsCollector);
100 }; 222 };
101 223
102 #endif // CHROME_BROWSER_SESSIONS_SESSION_RESTORE_STATS_COLLECTOR_H_ 224 #endif // CHROME_BROWSER_SESSIONS_SESSION_RESTORE_STATS_COLLECTOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698