1 // Copyright (c) 2012 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 CHROME_BROWSER_NET_LOAD_TIME_STATS_H_ 6 #define CHROME_BROWSER_NET_LOAD_TIME_STATS_H_ 7 8 #include <map> 9 #include <vector> 10 11 #include "base/basictypes.h" 12 #include "base/compiler_specific.h" 13 #include "base/containers/hash_tables.h" 14 #include "base/memory/scoped_ptr.h" 15 #include "base/message_loop/message_loop.h" 16 #include "base/time/time.h" 17 #include "chrome/browser/net/chrome_url_request_context.h" 18 #include "content/public/browser/web_contents_observer.h" 19 #include "content/public/browser/web_contents_user_data.h" 20 #include "net/base/network_delegate.h" 21 22 namespace base { 23 class HistogramBase; 24 } 25 26 namespace net { 27 class URLRequest; 28 class URLRequestContext; 29 } 30 31 #if defined(COMPILER_GCC) 32 33 namespace BASE_HASH_NAMESPACE { 34 template <> 35 struct hash<const net::URLRequest*> { 36 std::size_t operator()(const net::URLRequest* value) const { 37 return reinterpret_cast<std::size_t>(value); 38 } 39 }; 40 template <> 41 struct hash<const net::URLRequestContext*> { 42 std::size_t operator()(const net::URLRequestContext* value) const { 43 return reinterpret_cast<std::size_t>(value); 44 } 45 }; 46 } 47 48 #endif 49 50 namespace chrome_browser_net { 51 52 // This class collects UMA stats about cache performance. 53 class LoadTimeStats { 54 public: 55 enum TabEvent { 56 SPINNER_START, 57 SPINNER_STOP 58 }; 59 enum RequestStatus { 60 REQUEST_STATUS_CACHE_WAIT, 61 REQUEST_STATUS_NETWORK_WAIT, 62 REQUEST_STATUS_ACTIVE, 63 REQUEST_STATUS_NONE, 64 REQUEST_STATUS_MAX 65 }; 66 enum HistogramType { 67 HISTOGRAM_FINAL_AGGREGATE, 68 HISTOGRAM_FINAL_CUMULATIVE_PERCENTAGE, 69 HISTOGRAM_INTERMEDIATE_AGGREGATE, 70 HISTOGRAM_INTERMEDIATE_CUMULATIVE_PERCENTAGE, 71 HISTOGRAM_MAX 72 }; 73 74 LoadTimeStats(); 75 ~LoadTimeStats(); 76 77 void OnRequestWaitStateChange(const net::URLRequest& request, 78 net::NetworkDelegate::RequestWaitState state); 79 void OnURLRequestDestroyed(const net::URLRequest& request); 80 void OnTabEvent(std::pair<int, int> render_view_id, TabEvent event); 81 void RegisterURLRequestContext(const net::URLRequestContext* context, 82 ChromeURLRequestContext::ContextType type); 83 void UnregisterURLRequestContext(const net::URLRequestContext* context); 84 85 private: 86 class TabLoadStats; 87 // A map mapping a renderer's process id and route id to a TabLoadStats, 88 // representing that renderer's load statistics. 89 typedef std::map<std::pair<int, int>, TabLoadStats*> TabLoadStatsMap; 90 91 class URLRequestStats; 92 typedef base::hash_map<const net::URLRequest*, 93 URLRequestStats*> RequestStatsMap; 94 95 // Gets RequestStats for a given request. 96 URLRequestStats* GetRequestStats(const net::URLRequest* request); 97 // Gets TabLoadStats for a given RenderView. 98 TabLoadStats* GetTabLoadStats(std::pair<int, int> render_view_id); 99 // Deletes TabLoadStats no longer needed for a render view. 100 void RemoveTabLoadStats(std::pair<int, int> render_view_id); 101 // Sets a timer for a given tab to collect stats. |timer_index| indicates 102 // how many times stats have been collected since the navigation has started 103 // for this tab. 104 void ScheduleTimer(TabLoadStats* stats); 105 // The callback when a timer fires to collect stats again. 106 void TimerCallback(TabLoadStats* stats); 107 // Helper function to put the current set of statistics into UMA histograms. 108 void RecordHistograms(base::TimeDelta elapsed, 109 TabLoadStats* stats, 110 bool is_load_done); 111 112 TabLoadStatsMap tab_load_stats_; 113 RequestStatsMap request_stats_; 114 std::vector<base::HistogramBase*> 115 histograms_[REQUEST_STATUS_MAX][HISTOGRAM_MAX]; 116 base::hash_set<const net::URLRequestContext*> main_request_contexts_; 117 118 DISALLOW_COPY_AND_ASSIGN(LoadTimeStats); 119 }; 120 121 // A WebContentsObserver watching a tab, notifying LoadTimeStats whenever the 122 // spinner starts or stops for it, and whenever a renderer is no longer used. 123 class LoadTimeStatsTabHelper 124 : public content::WebContentsObserver, 125 public content::WebContentsUserData<LoadTimeStatsTabHelper> { 126 public: 127 virtual ~LoadTimeStatsTabHelper(); 128 129 // content::WebContentsObserver implementation 130 virtual void DidStartProvisionalLoadForFrame( 131 int64 frame_id, 132 int64 parent_frame_id, 133 bool is_main_frame, 134 const GURL& validated_url, 135 bool is_error_page, 136 bool is_iframe_srcdoc, 137 content::RenderViewHost* render_view_host) OVERRIDE; 138 virtual void DidStopLoading( 139 content::RenderViewHost* render_view_host) OVERRIDE; 140 141 private: 142 explicit LoadTimeStatsTabHelper(content::WebContents* web_contents); 143 friend class content::WebContentsUserData<LoadTimeStatsTabHelper>; 144 145 // Calls into LoadTimeStats to notify that a reportable event has occurred 146 // for the tab being observed. 147 void NotifyLoadTimeStats(LoadTimeStats::TabEvent event, 148 content::RenderViewHost* render_view_host); 149 150 bool is_otr_profile_; 151 152 DISALLOW_COPY_AND_ASSIGN(LoadTimeStatsTabHelper); 153 }; 154 155 } // namespace chrome_browser_net 156 157 #endif // CHROME_BROWSER_NET_LOAD_TIME_STATS_H_ 158