Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 // | |
| 5 // Declares a utility class for tracking tabs involved in a session restore. | |
|
sky
2015/05/14 15:47:04
Move this description above class description.
chrisha
2015/05/26 20:00:18
Done.
| |
| 6 // If multiple session restores occur simultaneously (ie: multiple profiles) | |
| 7 // they will use the same instance session restore stats tracker, as they | |
| 8 // actually share a single TabLoader and are effectively visually | |
| 9 // indistinguishable. This is done by effectively enforcing a singleton | |
| 10 // pattern, with static entry points into the class allocating a collector if | |
| 11 // necessary and repeatedly reusing the same collector. | |
| 12 // | |
| 13 // Since loading of deferred tabs is necessary statistics collection can be a | |
| 14 // long term thing. To avoid having a stats collector that is only observing | |
| 15 // deferred tabs get reused for a new session restore instance, the stats | |
| 16 // collector will detach itself from being the current 'shared collector', and | |
| 17 // allow a new collector to be created. This means that multiple stats | |
| 18 // collectors may exist simultaneously, however at most one may be the active | |
|
sky
2015/05/14 15:47:04
It's not clear what 'active' means here.
chrisha
2015/05/26 20:00:19
Acknowledged.
| |
| 19 // shared collector. | |
| 20 // | |
| 21 // When all tabs involved in a session restore have loaded and painted, or been | |
| 22 // closed, the session restore will destroy itself. | |
|
sky
2015/05/14 15:47:04
'session restore' -> stats collector. But it appea
chrisha
2015/05/26 20:00:18
Done.
| |
| 4 | 23 |
| 5 #ifndef CHROME_BROWSER_SESSIONS_SESSION_RESTORE_STATS_COLLECTOR_H_ | 24 #ifndef CHROME_BROWSER_SESSIONS_SESSION_RESTORE_STATS_COLLECTOR_H_ |
| 6 #define CHROME_BROWSER_SESSIONS_SESSION_RESTORE_STATS_COLLECTOR_H_ | 25 #define CHROME_BROWSER_SESSIONS_SESSION_RESTORE_STATS_COLLECTOR_H_ |
| 7 | 26 |
| 27 #include <map> | |
| 8 #include <set> | 28 #include <set> |
| 9 | 29 |
| 10 #include "base/callback_list.h" | 30 #include "base/callback_list.h" |
| 11 #include "chrome/browser/sessions/session_restore.h" | 31 #include "chrome/browser/sessions/session_restore.h" |
| 12 #include "chrome/browser/sessions/session_restore_delegate.h" | 32 #include "chrome/browser/sessions/session_restore_delegate.h" |
| 13 #include "content/public/browser/notification_observer.h" | 33 #include "content/public/browser/notification_observer.h" |
| 14 #include "content/public/browser/notification_registrar.h" | 34 #include "content/public/browser/notification_registrar.h" |
| 15 #include "content/public/browser/render_widget_host.h" | 35 #include "content/public/browser/render_widget_host.h" |
| 16 | 36 |
| 17 namespace content { | 37 namespace content { |
| 18 class NavigationController; | 38 class NavigationController; |
| 19 } | 39 } |
| 20 | 40 |
| 21 // SessionRestoreStatsCollector observes SessionRestore events ands records UMA | 41 // SessionRestoreStatsCollector observes SessionRestore events ands records UMA |
| 22 // accordingly. | 42 // accordingly. |
| 23 class SessionRestoreStatsCollector | 43 class SessionRestoreStatsCollector |
| 24 : public content::NotificationObserver, | 44 : public content::NotificationObserver, |
| 25 public base::RefCounted<SessionRestoreStatsCollector> { | 45 public base::RefCounted<SessionRestoreStatsCollector> { |
|
sky
2015/05/14 15:47:04
There isn't a need for this class to be ref counte
chrisha
2015/05/26 20:00:18
Done.
| |
| 26 public: | 46 public: |
| 27 // Called to start tracking tabs. If a restore is already occuring, the tabs | 47 // Called to start tracking tabs. If a restore is already occuring, the tabs |
| 28 // are added to the existing list of tracked tabs. | 48 // are added to the existing list of tracked tabs. |
| 29 static void TrackTabs( | 49 static void TrackTabs( |
| 30 const std::vector<SessionRestoreDelegate::RestoredTab>& tabs, | 50 const std::vector<SessionRestoreDelegate::RestoredTab>& tabs, |
| 31 const base::TimeTicks& restore_started); | 51 const base::TimeTicks& restore_started); |
| 32 | 52 |
| 33 // Called to start tracking only active tabs. If a restore is already | 53 // Called to indicate that the loading of a tab has been deferred by session |
| 34 // occuring, the tabs are added to the existing list of tracked tabs. | 54 // restore. If the reason for the deferral was memory pressure this will be |
| 35 static void TrackActiveTabs( | 55 // recorded. |
| 36 const std::vector<SessionRestoreDelegate::RestoredTab>& tabs, | 56 static void DeferTab(content::NavigationController* tab); |
| 37 const base::TimeTicks& restore_started); | |
| 38 | 57 |
| 39 private: | 58 private: |
| 40 friend class base::RefCounted<SessionRestoreStatsCollector>; | 59 friend class base::RefCounted<SessionRestoreStatsCollector>; |
| 41 | 60 |
| 61 // Maps a RenderWidgetHost to its deferred state. | |
| 62 using RenderWidgetHostMap = std::map<content::RenderWidgetHost*, bool>; | |
|
sky
2015/05/14 15:47:04
Bools can be a bit mysterious, where as enums are
chrisha
2015/05/26 20:00:18
Done.
| |
| 42 using RenderWidgetHostSet = std::set<content::RenderWidgetHost*>; | 63 using RenderWidgetHostSet = std::set<content::RenderWidgetHost*>; |
| 43 | 64 |
| 44 explicit SessionRestoreStatsCollector(const base::TimeTicks& restore_started); | 65 explicit SessionRestoreStatsCollector(const base::TimeTicks& restore_started); |
| 45 ~SessionRestoreStatsCollector() override; | 66 ~SessionRestoreStatsCollector() override; |
| 46 | 67 |
| 47 // NotificationObserver method. | 68 // NotificationObserver method. |
| 48 void Observe(int type, | 69 void Observe(int type, |
| 49 const content::NotificationSource& source, | 70 const content::NotificationSource& source, |
| 50 const content::NotificationDetails& details) override; | 71 const content::NotificationDetails& details) override; |
| 51 | 72 |
| 52 // Adds new tabs to the list of tracked tabs. | 73 // Adds new tabs to the list of tracked tabs. |
| 53 void AddTabs(const std::vector<SessionRestoreDelegate::RestoredTab>& tabs); | 74 void AddTabs(const std::vector<SessionRestoreDelegate::RestoredTab>& tabs); |
| 54 | 75 |
| 55 // Called when a tab is no longer tracked. | 76 // Called to indicate that the loading of a tab has been deferred by session |
| 77 // restore. Called by the static DeferTab. | |
| 78 void DeferTabImpl(content::NavigationController* tab); | |
| 79 | |
| 80 // Called when a tab is no longer tracked. This is called by the 'Observe' | |
| 81 // notification callback. | |
| 56 void RemoveTab(content::NavigationController* tab); | 82 void RemoveTab(content::NavigationController* tab); |
| 57 | 83 |
| 58 // Registers for relevant notifications for a tab. | 84 // Registers for relevant notifications for a tab. |
| 59 void RegisterForNotifications(content::NavigationController* tab); | 85 void RegisterForNotifications(content::NavigationController* tab); |
| 60 | 86 |
| 61 // Returns the RenderWidgetHost of a tab. | 87 // Returns the RenderWidgetHost of a tab. |
| 62 content::RenderWidgetHost* GetRenderWidgetHost( | 88 content::RenderWidgetHost* GetRenderWidgetHost( |
| 63 content::NavigationController* tab); | 89 content::NavigationController* tab); |
| 64 | 90 |
| 65 // Have we recorded the times for a foreground tab load? | 91 // Returns true if the specified tab had it's loading deferred by an active |
| 92 // session restore. | |
| 93 bool IsDeferred(content::NavigationController* tab) const; | |
| 94 | |
| 95 // Returns true if done tracking non-deferred tabs. When this returns true | |
| 96 // the collector will detach itself from being the active shared collector | |
| 97 // and continue observing deferred tabs only. Called from Observe. | |
| 98 bool DoneTrackingNonDeferredTabs() const; | |
| 99 | |
| 100 // Returns true when no longer tracking any tabs. When this returns true the | |
| 101 // collector will destory itself. Called from Observe. | |
| 102 bool DoneTracking() const; | |
| 103 | |
| 104 // Has the the time for foreground tab load been recorded? | |
| 66 bool got_first_foreground_load_; | 105 bool got_first_foreground_load_; |
| 67 | 106 |
| 68 // Have we recorded the times for a foreground tab paint? | 107 // Has the time for foreground tab paint been recorded? |
| 69 bool got_first_paint_; | 108 bool got_first_paint_; |
| 70 | 109 |
| 71 // The time the restore process started. | 110 // The time the restore process started. |
| 72 base::TimeTicks restore_started_; | 111 base::TimeTicks restore_started_; |
| 73 | 112 |
| 74 // The renderers we have started loading into. | 113 // The following 3 maps are used to track tabs at different points in their |
|
sky
2015/05/14 15:47:04
Seems like you're tracking a bunch of state per ta
chrisha
2015/05/26 20:00:18
Unfortunately we need efficient lookup by 2 indice
| |
| 75 RenderWidgetHostSet render_widget_hosts_loading_; | 114 // lifetime: |
| 115 // 1. Tabs start in the tabs_tracked_ map. | |
| 116 // 2. When a tab starts loading it will be inserted into the | |
| 117 // render_widget_hosts_loading_ map, and also remain in the tabs_tracked_ | |
| 118 // map. | |
| 119 // 3. Once a tab stops loading it will be removed from both the tabs_tracked_ | |
| 120 // and render_widget_hosts_loading_ maps, and be placed into the | |
| 121 // render_widget_hosts_to_paint_ set. | |
| 122 // 4. When a tab has loaded and been painted it will be removed from the | |
| 123 // render_widget_hosts_to_paint_ set and no longer be explicitly tracked | |
| 124 // by the stats collector. | |
| 125 // Tabs are only tracked for paint events if got_first_paint_ is false. If | |
| 126 // first paint has already been observed then tabs no longer migrate into the | |
| 127 // render_widget_hosts_to_paint_ set. | |
| 76 | 128 |
| 77 // The renderers we have loaded and are waiting on to paint. | 129 // The renderers that have started loading, mapped to their deferred state |
| 130 // and the total number of deferred tabs in the map. Render widgets in this | |
| 131 // map will also have their corresponding tabs in the tabs_tracked_ map. | |
| 132 RenderWidgetHostMap render_widget_hosts_loading_; | |
| 133 size_t render_widget_hosts_loading_deferred_count_; | |
| 134 | |
| 135 // The renderers that have loaded and are waiting to paint A render widget in | |
| 136 // this map will not also be in the render_widget_hosts_loading_ map. The | |
| 137 // deferred state of a tab is not considered for paint events. | |
| 78 RenderWidgetHostSet render_widget_hosts_to_paint_; | 138 RenderWidgetHostSet render_widget_hosts_to_paint_; |
| 79 | 139 |
| 80 // List of tracked tabs. | 140 // List of tracked tabs, mapped to their deferred status, and the total |
| 81 std::set<content::NavigationController*> tabs_tracked_; | 141 // number of deferred tabs in the map. |
| 142 std::map<content::NavigationController*, bool> tabs_tracked_; | |
| 143 size_t tabs_tracked_deferred_count_; | |
| 82 | 144 |
| 83 // The number of tabs that have been restored. | 145 // The total number of tabs that have been restored. This may be greater than |
| 84 int tab_count_; | 146 // the number of currently tracked tabs as tabs migrate out of the |
| 147 // tabs_tracked_ map. | |
|
sky
2015/05/14 15:47:04
Generally we use | around variable and parameter n
chrisha
2015/05/26 20:00:19
Done.
| |
| 148 size_t tab_count_; | |
| 85 | 149 |
| 86 // Max number of tabs that were loaded in parallel (for metrics). | 150 // The total number of tabs that have been deferred. This may be greater than |
| 151 // the number of currently tracked tabs as tabs migrate out of the | |
| 152 // tabs_tracked_ map. | |
| 153 size_t tab_deferred_count_; | |
| 154 | |
| 155 // Max number of tabs that were observed to load in parallel (for metrics). | |
| 87 size_t max_parallel_tab_loads_; | 156 size_t max_parallel_tab_loads_; |
| 88 | 157 |
| 89 // Notification registrar. | 158 // Notification registrar. |
| 90 content::NotificationRegistrar registrar_; | 159 content::NotificationRegistrar registrar_; |
| 91 | 160 |
| 92 // To keep the collector alive as long as needed. | 161 // To keep the collector alive as long as needed. |
| 93 scoped_refptr<SessionRestoreStatsCollector> this_retainer_; | 162 scoped_refptr<SessionRestoreStatsCollector> this_retainer_; |
| 94 | 163 |
| 95 // The shared SessionRestoreNotifier instance for all SessionRestores running | 164 // The shared SessionRestoreNotifier instance for all SessionRestores running |
| 96 // at this time. | 165 // at this time. |
| 97 static SessionRestoreStatsCollector* shared_collector_; | 166 static SessionRestoreStatsCollector* shared_collector_; |
| 98 | 167 |
| 99 DISALLOW_COPY_AND_ASSIGN(SessionRestoreStatsCollector); | 168 DISALLOW_COPY_AND_ASSIGN(SessionRestoreStatsCollector); |
| 100 }; | 169 }; |
| 101 | 170 |
| 102 #endif // CHROME_BROWSER_SESSIONS_SESSION_RESTORE_STATS_COLLECTOR_H_ | 171 #endif // CHROME_BROWSER_SESSIONS_SESSION_RESTORE_STATS_COLLECTOR_H_ |
| OLD | NEW |