OLD | NEW |
(Empty) | |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef IOS_CHROME_BROWSER_METRICS_TAB_USAGE_RECORDER_H_ |
| 6 #define IOS_CHROME_BROWSER_METRICS_TAB_USAGE_RECORDER_H_ |
| 7 |
| 8 #import <Foundation/Foundation.h> |
| 9 #include <deque> |
| 10 #include <map> |
| 11 |
| 12 #include "base/ios/weak_nsobject.h" |
| 13 #include "base/macros.h" |
| 14 #include "base/time/time.h" |
| 15 #import "ios/chrome/browser/metrics/tab_usage_recorder_delegate.h" |
| 16 |
| 17 @class Tab; |
| 18 |
| 19 // Histogram names (visible for testing only). |
| 20 |
| 21 // The prefix of the histogram names. Used to create a HistogramRecorder. |
| 22 extern const char kTabUsageHistogramPrefix[]; |
| 23 |
| 24 // The name of the histogram that records the state of the selected tab |
| 25 // (i.e. the tab being switched to). |
| 26 extern const char kSelectedTabHistogramName[]; |
| 27 |
| 28 // The name of the histogram that records the number of page loads before an |
| 29 // evicted tab is selected. |
| 30 extern const char kPageLoadsBeforeEvictedTabSelected[]; |
| 31 |
| 32 // The name of the histogram tracking the reload time for a previously-evicted |
| 33 // tab. |
| 34 extern const char kEvictedTabReloadTime[]; |
| 35 |
| 36 // The name of the histogram for whether or not the reload of a |
| 37 // previously-evicted tab completed successfully. |
| 38 extern const char kEvictedTabReloadSuccessRate[]; |
| 39 |
| 40 // The name of the histogram for whether or not the user switched tabs before an |
| 41 // evicted tab completed reloading. |
| 42 extern const char kDidUserWaitForEvictedTabReload[]; |
| 43 |
| 44 // The name of the histogram that records time intervals between restores of |
| 45 // previously-evicted tabs. The first restore seen in a session will record the |
| 46 // time since the session started. |
| 47 extern const char kTimeBetweenRestores[]; |
| 48 |
| 49 // The name of the histogram that records time intervals between the last |
| 50 // restore of a previously-evicted tab and the end of the session. |
| 51 extern const char kTimeAfterLastRestore[]; |
| 52 |
| 53 // Name of histogram to record whether a memory warning had been recently |
| 54 // received when a renderer termination occurred. |
| 55 extern const char kRendererTerminationSawMemoryWarning[]; |
| 56 |
| 57 // Name of histogram to record the number of alive renderers when a renderer |
| 58 // termination is received. |
| 59 extern const char kRendererTerminationAliveRenderers[]; |
| 60 |
| 61 // Name of histogram to record the number of renderers that were alive shortly |
| 62 // before a renderer termination. This metric is being recorded in case the OS |
| 63 // kills renderers in batches. |
| 64 extern const char kRendererTerminationRecentlyAliveRenderers[]; |
| 65 |
| 66 // The recently alive renderer count metric counts all renderers that were alive |
| 67 // x seconds before a renderer termination. |kSecondsBeforeRendererTermination| |
| 68 // specifies x. |
| 69 extern const int kSecondsBeforeRendererTermination; |
| 70 |
| 71 // Reports usage about the lifecycle of a single TabModel's tabs. |
| 72 class TabUsageRecorder { |
| 73 public: |
| 74 enum TabStateWhenSelected { |
| 75 IN_MEMORY = 0, |
| 76 EVICTED, |
| 77 EVICTED_DUE_TO_COLD_START, |
| 78 PARTIALLY_EVICTED, // Currently, used only by Android. |
| 79 EVICTED_DUE_TO_BACKGROUNDING, // Deprecated |
| 80 EVICTED_DUE_TO_INCOGNITO, |
| 81 RELOADED_DUE_TO_COLD_START_FG_TAB_ON_START, // Android. |
| 82 RELOADED_DUE_TO_COLD_START_BG_TAB_ON_SWITCH, // Android. |
| 83 LAZY_LOAD_FOR_OPEN_IN_NEW_TAB, // Android |
| 84 STOPPED_DUE_TO_LOADING_WHEN_BACKGROUNDING, // Deprecated. |
| 85 EVICTED_DUE_TO_LOADING_WHEN_BACKGROUNDING, // Deprecated. |
| 86 EVICTED_DUE_TO_RENDERER_TERMINATION, |
| 87 TAB_STATE_COUNT, |
| 88 }; |
| 89 |
| 90 enum LoadDoneState { |
| 91 LOAD_FAILURE, |
| 92 LOAD_SUCCESS, |
| 93 LOAD_DONE_STATE_COUNT, |
| 94 }; |
| 95 |
| 96 enum EvictedTabUserBehavior { |
| 97 USER_WAITED, |
| 98 USER_DID_NOT_WAIT, |
| 99 USER_LEFT_CHROME, |
| 100 USER_BEHAVIOR_COUNT, |
| 101 }; |
| 102 |
| 103 // |delegate| is the TabUsageRecorderDelegate which provides access to the |
| 104 // Tabs which this TabUsageRecorder is monitoring. |delegate| can be nil. |
| 105 explicit TabUsageRecorder(id<TabUsageRecorderDelegate> delegate); |
| 106 virtual ~TabUsageRecorder(); |
| 107 |
| 108 // Called during startup when the tab model is created, or shortly after a |
| 109 // post-crash launch if the tabs are restored. |tabs| is an array containing |
| 110 // the tabs being restored in the current tab model. |active_tab| is the tab |
| 111 // currently in the foreground. |
| 112 void InitialRestoredTabs(Tab* active_tab, NSArray* tabs); |
| 113 |
| 114 // Called when a tab is created for immediate selection. |
| 115 void TabCreatedForSelection(Tab* tab); |
| 116 |
| 117 // Called when a tab switch is made. Determines what value to record, and |
| 118 // when to reset the page load counter. |
| 119 void RecordTabSwitched(Tab* old_tab, Tab* new_tab); |
| 120 |
| 121 // Called when the tab model which the user is primarily interacting with has |
| 122 // changed. The |active_tab| is the current tab of the tab model. If the user |
| 123 // began interacting with |active_tab|, |primary| should be true. If the user |
| 124 // stopped interacting with |active_tab|, |primary| should be false. |
| 125 void RecordPrimaryTabModelChange(BOOL primary, Tab* active_tab); |
| 126 |
| 127 // Called when a page load begins, to keep track of how many page loads |
| 128 // happen before an evicted tab is seen. |
| 129 void RecordPageLoadStart(Tab* tab); |
| 130 |
| 131 // Called when a page load finishes, to track the load time for evicted tabs. |
| 132 void RecordPageLoadDone(Tab* tab, bool success); |
| 133 |
| 134 // Called when there is a user-initiated reload. |
| 135 void RecordReload(Tab* tab); |
| 136 |
| 137 // Called when WKWebView's renderer is terminated. |tab| contains the tab |
| 138 // whose renderer was terminated, and |visible| indicates whether or not the |
| 139 // tab was visible when the renderer terminated. |
| 140 void RendererTerminated(Tab* tab, bool visible); |
| 141 |
| 142 // Called when the app has been backgrounded. |
| 143 void AppDidEnterBackground(); |
| 144 |
| 145 // Called when the app has been foregrounded. |
| 146 void AppWillEnterForeground(); |
| 147 |
| 148 // Resets the page load count. |
| 149 void ResetPageLoads(); |
| 150 |
| 151 // Size of |evicted_tabs_|. Used for testing. |
| 152 int EvictedTabsMapSize(); |
| 153 |
| 154 // Resets all tracked data. Used for testing. |
| 155 void ResetAll(); |
| 156 |
| 157 // Sets the delegate for the TabUsageRecorder. |
| 158 void SetDelegate(id<TabUsageRecorderDelegate> delegate); |
| 159 |
| 160 protected: |
| 161 // Keep track of when the most recent tab restore begins, to record the time |
| 162 // between evicted-tab-reloads. |
| 163 base::TimeTicks restore_start_time_; |
| 164 |
| 165 // Keep track of the timestamps of renderer terminations in order to find the |
| 166 // number of recently alive tabs when a renderer termination occurs. |
| 167 std::deque<base::TimeTicks> termination_timestamps_; |
| 168 |
| 169 private: |
| 170 // Clear out all state regarding a current evicted tab. |
| 171 void ResetEvictedTab(); |
| 172 |
| 173 // Whether or not a tab can be disregarded by the metrics. |
| 174 bool ShouldIgnoreTab(Tab* tab); |
| 175 |
| 176 // Whether or not the tab has already been evicted. |
| 177 bool TabAlreadyEvicted(Tab* tab); |
| 178 |
| 179 // Returns the state of the given tab. Call only once per tab, as it removes |
| 180 // the tab from |evicted_tabs_|. |
| 181 TabStateWhenSelected ExtractTabState(Tab* tab); |
| 182 |
| 183 // Records various time metrics when a restore of an evicted tab begins. |
| 184 void RecordRestoreStartTime(); |
| 185 |
| 186 // Clears deleted tabs from |evicted_tabs_|. |
| 187 void ClearDeletedTabs(); |
| 188 |
| 189 // Number of page loads since the last evicted tab was seen. |
| 190 unsigned int page_loads_; |
| 191 |
| 192 // Keep track of the current tab, but only if it has been evicted. |
| 193 // This is kept as a pointer value only - it should never be dereferenced. |
| 194 void* evicted_tab_; |
| 195 |
| 196 // State of |evicted_tab_| at the time it became the current tab. |
| 197 TabStateWhenSelected evicted_tab_state_; |
| 198 |
| 199 // Keep track of the tab last selected when this tab model was switched |
| 200 // away from to another mode (e.g. to incognito). |
| 201 // Kept as a pointer value only - it should never be dereferenced. |
| 202 void* mode_switch_tab_; |
| 203 |
| 204 // Keep track of a tab that was created to be immediately selected. It should |
| 205 // not contribute to the "StatusWhenSwitchedBackToForeground" metric. |
| 206 void* tab_created_selected_; |
| 207 |
| 208 // Keep track of when the evicted tab starts to reload, so that the total |
| 209 // time it takes to reload can be recorded. |
| 210 base::TimeTicks evicted_tab_reload_start_time_; |
| 211 |
| 212 // Keep track of the tabs that have a known eviction cause. |
| 213 std::map<base::WeakNSObject<Tab>, TabStateWhenSelected> evicted_tabs_; |
| 214 |
| 215 // Reference to TabUsageRecorderDelegate which provides access to the count of |
| 216 // live tabs monitored by this recorder. |
| 217 base::WeakNSProtocol<id<TabUsageRecorderDelegate>> recorder_delegate_; |
| 218 |
| 219 DISALLOW_COPY_AND_ASSIGN(TabUsageRecorder); |
| 220 }; |
| 221 |
| 222 #endif // IOS_CHROME_BROWSER_METRICS_TAB_USAGE_RECORDER_H_ |
OLD | NEW |