Index: ios/chrome/browser/metrics/tab_usage_recorder.h |
diff --git a/ios/chrome/browser/metrics/tab_usage_recorder.h b/ios/chrome/browser/metrics/tab_usage_recorder.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..8b99125161c1c9eb2b05b5cef16c5232b26e2d96 |
--- /dev/null |
+++ b/ios/chrome/browser/metrics/tab_usage_recorder.h |
@@ -0,0 +1,222 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef IOS_CHROME_BROWSER_METRICS_TAB_USAGE_RECORDER_H_ |
+#define IOS_CHROME_BROWSER_METRICS_TAB_USAGE_RECORDER_H_ |
+ |
+#import <Foundation/Foundation.h> |
+#include <deque> |
+#include <map> |
+ |
+#include "base/ios/weak_nsobject.h" |
+#include "base/macros.h" |
+#include "base/time/time.h" |
+#import "ios/chrome/browser/metrics/tab_usage_recorder_delegate.h" |
+ |
+@class Tab; |
+ |
+// Histogram names (visible for testing only). |
+ |
+// The prefix of the histogram names. Used to create a HistogramRecorder. |
+extern const char kTabUsageHistogramPrefix[]; |
+ |
+// The name of the histogram that records the state of the selected tab |
+// (i.e. the tab being switched to). |
+extern const char kSelectedTabHistogramName[]; |
+ |
+// The name of the histogram that records the number of page loads before an |
+// evicted tab is selected. |
+extern const char kPageLoadsBeforeEvictedTabSelected[]; |
+ |
+// The name of the histogram tracking the reload time for a previously-evicted |
+// tab. |
+extern const char kEvictedTabReloadTime[]; |
+ |
+// The name of the histogram for whether or not the reload of a |
+// previously-evicted tab completed successfully. |
+extern const char kEvictedTabReloadSuccessRate[]; |
+ |
+// The name of the histogram for whether or not the user switched tabs before an |
+// evicted tab completed reloading. |
+extern const char kDidUserWaitForEvictedTabReload[]; |
+ |
+// The name of the histogram that records time intervals between restores of |
+// previously-evicted tabs. The first restore seen in a session will record the |
+// time since the session started. |
+extern const char kTimeBetweenRestores[]; |
+ |
+// The name of the histogram that records time intervals between the last |
+// restore of a previously-evicted tab and the end of the session. |
+extern const char kTimeAfterLastRestore[]; |
+ |
+// Name of histogram to record whether a memory warning had been recently |
+// received when a renderer termination occurred. |
+extern const char kRendererTerminationSawMemoryWarning[]; |
+ |
+// Name of histogram to record the number of alive renderers when a renderer |
+// termination is received. |
+extern const char kRendererTerminationAliveRenderers[]; |
+ |
+// Name of histogram to record the number of renderers that were alive shortly |
+// before a renderer termination. This metric is being recorded in case the OS |
+// kills renderers in batches. |
+extern const char kRendererTerminationRecentlyAliveRenderers[]; |
+ |
+// The recently alive renderer count metric counts all renderers that were alive |
+// x seconds before a renderer termination. |kSecondsBeforeRendererTermination| |
+// specifies x. |
+extern const int kSecondsBeforeRendererTermination; |
+ |
+// Reports usage about the lifecycle of a single TabModel's tabs. |
+class TabUsageRecorder { |
+ public: |
+ enum TabStateWhenSelected { |
+ IN_MEMORY = 0, |
+ EVICTED, |
+ EVICTED_DUE_TO_COLD_START, |
+ PARTIALLY_EVICTED, // Currently, used only by Android. |
+ EVICTED_DUE_TO_BACKGROUNDING, // Deprecated |
+ EVICTED_DUE_TO_INCOGNITO, |
+ RELOADED_DUE_TO_COLD_START_FG_TAB_ON_START, // Android. |
+ RELOADED_DUE_TO_COLD_START_BG_TAB_ON_SWITCH, // Android. |
+ LAZY_LOAD_FOR_OPEN_IN_NEW_TAB, // Android |
+ STOPPED_DUE_TO_LOADING_WHEN_BACKGROUNDING, // Deprecated. |
+ EVICTED_DUE_TO_LOADING_WHEN_BACKGROUNDING, // Deprecated. |
+ EVICTED_DUE_TO_RENDERER_TERMINATION, |
+ TAB_STATE_COUNT, |
+ }; |
+ |
+ enum LoadDoneState { |
+ LOAD_FAILURE, |
+ LOAD_SUCCESS, |
+ LOAD_DONE_STATE_COUNT, |
+ }; |
+ |
+ enum EvictedTabUserBehavior { |
+ USER_WAITED, |
+ USER_DID_NOT_WAIT, |
+ USER_LEFT_CHROME, |
+ USER_BEHAVIOR_COUNT, |
+ }; |
+ |
+ // |delegate| is the TabUsageRecorderDelegate which provides access to the |
+ // Tabs which this TabUsageRecorder is monitoring. |delegate| can be nil. |
+ explicit TabUsageRecorder(id<TabUsageRecorderDelegate> delegate); |
+ virtual ~TabUsageRecorder(); |
+ |
+ // Called during startup when the tab model is created, or shortly after a |
+ // post-crash launch if the tabs are restored. |tabs| is an array containing |
+ // the tabs being restored in the current tab model. |active_tab| is the tab |
+ // currently in the foreground. |
+ void InitialRestoredTabs(Tab* active_tab, NSArray* tabs); |
+ |
+ // Called when a tab is created for immediate selection. |
+ void TabCreatedForSelection(Tab* tab); |
+ |
+ // Called when a tab switch is made. Determines what value to record, and |
+ // when to reset the page load counter. |
+ void RecordTabSwitched(Tab* old_tab, Tab* new_tab); |
+ |
+ // Called when the tab model which the user is primarily interacting with has |
+ // changed. The |active_tab| is the current tab of the tab model. If the user |
+ // began interacting with |active_tab|, |primary| should be true. If the user |
+ // stopped interacting with |active_tab|, |primary| should be false. |
+ void RecordPrimaryTabModelChange(BOOL primary, Tab* active_tab); |
+ |
+ // Called when a page load begins, to keep track of how many page loads |
+ // happen before an evicted tab is seen. |
+ void RecordPageLoadStart(Tab* tab); |
+ |
+ // Called when a page load finishes, to track the load time for evicted tabs. |
+ void RecordPageLoadDone(Tab* tab, bool success); |
+ |
+ // Called when there is a user-initiated reload. |
+ void RecordReload(Tab* tab); |
+ |
+ // Called when WKWebView's renderer is terminated. |tab| contains the tab |
+ // whose renderer was terminated, and |visible| indicates whether or not the |
+ // tab was visible when the renderer terminated. |
+ void RendererTerminated(Tab* tab, bool visible); |
+ |
+ // Called when the app has been backgrounded. |
+ void AppDidEnterBackground(); |
+ |
+ // Called when the app has been foregrounded. |
+ void AppWillEnterForeground(); |
+ |
+ // Resets the page load count. |
+ void ResetPageLoads(); |
+ |
+ // Size of |evicted_tabs_|. Used for testing. |
+ int EvictedTabsMapSize(); |
+ |
+ // Resets all tracked data. Used for testing. |
+ void ResetAll(); |
+ |
+ // Sets the delegate for the TabUsageRecorder. |
+ void SetDelegate(id<TabUsageRecorderDelegate> delegate); |
+ |
+ protected: |
+ // Keep track of when the most recent tab restore begins, to record the time |
+ // between evicted-tab-reloads. |
+ base::TimeTicks restore_start_time_; |
+ |
+ // Keep track of the timestamps of renderer terminations in order to find the |
+ // number of recently alive tabs when a renderer termination occurs. |
+ std::deque<base::TimeTicks> termination_timestamps_; |
+ |
+ private: |
+ // Clear out all state regarding a current evicted tab. |
+ void ResetEvictedTab(); |
+ |
+ // Whether or not a tab can be disregarded by the metrics. |
+ bool ShouldIgnoreTab(Tab* tab); |
+ |
+ // Whether or not the tab has already been evicted. |
+ bool TabAlreadyEvicted(Tab* tab); |
+ |
+ // Returns the state of the given tab. Call only once per tab, as it removes |
+ // the tab from |evicted_tabs_|. |
+ TabStateWhenSelected ExtractTabState(Tab* tab); |
+ |
+ // Records various time metrics when a restore of an evicted tab begins. |
+ void RecordRestoreStartTime(); |
+ |
+ // Clears deleted tabs from |evicted_tabs_|. |
+ void ClearDeletedTabs(); |
+ |
+ // Number of page loads since the last evicted tab was seen. |
+ unsigned int page_loads_; |
+ |
+ // Keep track of the current tab, but only if it has been evicted. |
+ // This is kept as a pointer value only - it should never be dereferenced. |
+ void* evicted_tab_; |
+ |
+ // State of |evicted_tab_| at the time it became the current tab. |
+ TabStateWhenSelected evicted_tab_state_; |
+ |
+ // Keep track of the tab last selected when this tab model was switched |
+ // away from to another mode (e.g. to incognito). |
+ // Kept as a pointer value only - it should never be dereferenced. |
+ void* mode_switch_tab_; |
+ |
+ // Keep track of a tab that was created to be immediately selected. It should |
+ // not contribute to the "StatusWhenSwitchedBackToForeground" metric. |
+ void* tab_created_selected_; |
+ |
+ // Keep track of when the evicted tab starts to reload, so that the total |
+ // time it takes to reload can be recorded. |
+ base::TimeTicks evicted_tab_reload_start_time_; |
+ |
+ // Keep track of the tabs that have a known eviction cause. |
+ std::map<base::WeakNSObject<Tab>, TabStateWhenSelected> evicted_tabs_; |
+ |
+ // Reference to TabUsageRecorderDelegate which provides access to the count of |
+ // live tabs monitored by this recorder. |
+ base::WeakNSProtocol<id<TabUsageRecorderDelegate>> recorder_delegate_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(TabUsageRecorder); |
+}; |
+ |
+#endif // IOS_CHROME_BROWSER_METRICS_TAB_USAGE_RECORDER_H_ |