1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
|
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_SESSIONS_SESSION_RESTORE_STATS_COLLECTOR_H_
#define CHROME_BROWSER_SESSIONS_SESSION_RESTORE_STATS_COLLECTOR_H_
#include <stddef.h>
#include <map>
#include <memory>
#include <utility>
#include <vector>
#include "base/memory/weak_ptr.h"
#include "base/scoped_multi_source_observation.h"
#include "base/time/time.h"
#include "chrome/browser/sessions/session_restore.h"
#include "chrome/browser/sessions/session_restore_delegate.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_observer.h"
namespace content {
class WebContents;
}
// SessionRestoreStatsCollector observes SessionRestore events ands records UMA
// accordingly.
//
// TODO(chrisha): Many of these metrics don't make sense to collect in the
// presence of an unavailable network, or when tabs are closed during loading.
// Rethink the collection in these cases.
class SessionRestoreStatsCollector : public content::RenderWidgetHostObserver {
public:
// Recorded in SessionRestore.ForegroundTabFirstPaint4.FinishReason metric.
// Values other than PAINT_FINISHED_UMA_DONE indicate why FirstPaint time
// was not recorded.
enum SessionRestorePaintFinishReasonUma {
// SessionRestore.ForegroundTabFirstPaint4 successfully recorded.
PAINT_FINISHED_UMA_DONE = 0,
// No tabs were visible the whole time before first paint.
PAINT_FINISHED_UMA_NO_COMPLETELY_VISIBLE_TABS = 1,
// No restored tabs were painted.
PAINT_FINISHED_UMA_NO_PAINT = 2,
// A non-restored tab was painted first.
PAINT_FINISHED_NON_RESTORED_TAB_PAINTED_FIRST = 3,
// The size of this enum. Must be the last entry.
PAINT_FINISHED_UMA_MAX = 4,
};
// Houses all of the statistics gathered by the SessionRestoreStatsCollector
// while the underlying TabLoader is active. These statistics are all reported
// at once via the reporting delegate.
struct TabLoaderStats {
// Constructor that initializes everything to zero.
TabLoaderStats();
// The number of tabs involved in all overlapping session restores being
// tracked by this SessionRestoreStatsCollector. This is used as suffix for
// the "SessionRestore.ForegroundTabFirstPaint4" histogram.
size_t tab_count;
// The time elapsed between |restore_started| and reception of the first
// NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_VISUAL_PROPERTIES event for
// any of the tabs involved in the session restore. If this is zero it is
// because it has not been recorded (all restored tabs were closed or
// hidden before they were painted, or were never painted). Corresponds to
// "SessionRestore.ForegroundTabFirstPaint4" and its ".NTabs" variants.
base::TimeDelta foreground_tab_first_paint;
// Whether we recorded |foreground_tab_first_paint| and if not, why.
SessionRestorePaintFinishReasonUma tab_first_paint_reason;
// Count of tabs in a session with various properties tracked in
// SessionRestoreDelegate::RestoredTab.
size_t active_tab_count = 0;
size_t app_tab_count = 0;
size_t internal_page_tab_count = 0;
size_t pinned_tab_count = 0;
size_t grouped_tab_count = 0;
// Count of tabs in a session whose site engagement score is below the
// minimum to load.
size_t low_site_engagement_tab_count = 0;
// Count of tabs included in `low_site_engagement_tab_count` that use
// background communications (notification permission or update
// title/favicon in background.)
size_t low_site_engagement_with_background_communication_tab_count = 0;
// Count of tabs in a session with notification permission.
size_t notification_permission_tab_count = 0;
// Count of tabs in a session that update title or favicon in background.
size_t updates_in_background_tab_count = 0;
};
// The StatsReportingDelegate is responsible for delivering statistics
// reported by the SessionRestoreStatsCollector.
class StatsReportingDelegate;
// An implementation of StatsReportingDelegate for reporting via UMA.
class UmaStatsReportingDelegate;
// Gets or creates an instance of SessionRestoreStatsCollector. An instance
// self-deletes once it has reported all stats. If an existing instance is
// returned, |restored_started| and |reporting_delegate| are ignored.
static SessionRestoreStatsCollector* GetOrCreateInstance(
base::TimeTicks restore_started,
std::unique_ptr<StatsReportingDelegate> reporting_delegate);
SessionRestoreStatsCollector(const SessionRestoreStatsCollector&) = delete;
SessionRestoreStatsCollector& operator=(const SessionRestoreStatsCollector&) =
delete;
// Tracks stats for restored tabs. Tabs from overlapping session restores can
// be tracked by the same SessionRestoreStatsCollector.
void TrackTabs(const std::vector<SessionRestoreDelegate::RestoredTab>& tabs);
private:
friend class SessionRestoreStatsCollectorTest;
// Constructs a SessionRestoreStatsCollector.
SessionRestoreStatsCollector(
const base::TimeTicks& restore_started,
std::unique_ptr<StatsReportingDelegate> reporting_delegate);
~SessionRestoreStatsCollector() override;
// content::RenderWidgetHostObserver:
void RenderWidgetHostVisibilityChanged(content::RenderWidgetHost* widget_host,
bool became_visible) override;
void RenderWidgetHostDidUpdateVisualProperties(
content::RenderWidgetHost* widget_host) override;
void RenderWidgetHostDestroyed(
content::RenderWidgetHost* widget_host) override;
// Registers observers for a tab and inserts the tab into
// |tracked_tabs_occluded_maps| map.
void RegisterObserverForTab(content::WebContents* tab);
// Report stats and self-deletes.
void ReportStatsAndSelfDestroy();
// Updates counts that depend on async lookup of UpdatesFaviconInBackground()
// and UpdatesTitleInBackground() in SiteDataReader.
void OnTabUpdatesInBackground(bool low_site_engagement,
bool notification_permission,
bool updates_in_background);
// Won't record time for foreground tab paint because a non-restored
// tab was painted first.
bool non_restored_tab_painted_first_;
// Got first paint of tab that was hidden or occluded before being painted.
bool hidden_or_occluded_tab_ignored_;
// The time the restore process started.
const base::TimeTicks restore_started_;
// Tabs we are tracking paints in, keyed by their RenderWidgetHost and mapped
// to a bool indicating whether the tab was ever hidden or occluded.
std::map<content::RenderWidgetHost*, bool> tracked_tabs_occluded_map_;
// Statistics gathered regarding the TabLoader.
TabLoaderStats tab_loader_stats_;
// The reporting delegate used to report gathered statistics.
std::unique_ptr<StatsReportingDelegate> reporting_delegate_;
base::ScopedMultiSourceObservation<content::RenderWidgetHost,
content::RenderWidgetHostObserver>
render_widget_host_observations_{this};
base::WeakPtrFactory<SessionRestoreStatsCollector> weak_factory_{this};
};
// An abstract reporting delegate is used as a testing seam.
class SessionRestoreStatsCollector::StatsReportingDelegate {
public:
StatsReportingDelegate() = default;
StatsReportingDelegate(const StatsReportingDelegate&) = delete;
StatsReportingDelegate& operator=(const StatsReportingDelegate&) = delete;
virtual ~StatsReportingDelegate() = default;
// Called when TabLoader has completed its work.
virtual void ReportTabLoaderStats(const TabLoaderStats& tab_loader_stats) = 0;
};
// The default reporting delegate, which reports statistics via UMA.
class SessionRestoreStatsCollector::UmaStatsReportingDelegate
: public StatsReportingDelegate {
public:
UmaStatsReportingDelegate();
UmaStatsReportingDelegate(const UmaStatsReportingDelegate&) = delete;
UmaStatsReportingDelegate& operator=(const UmaStatsReportingDelegate&) =
delete;
~UmaStatsReportingDelegate() override = default;
// StatsReportingDelegate:
void ReportTabLoaderStats(const TabLoaderStats& tab_loader_stats) override;
};
#endif // CHROME_BROWSER_SESSIONS_SESSION_RESTORE_STATS_COLLECTOR_H_
|