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 | 4 |
5 #include "chrome/browser/android/data_usage/data_use_tab_model.h" | 5 #include "chrome/browser/android/data_usage/data_use_tab_model.h" |
6 | 6 |
7 #include "base/time/time.h" | 7 #include "base/metrics/histogram_macros.h" |
8 #include "chrome/browser/android/data_usage/external_data_use_observer.h" | 8 #include "chrome/browser/android/data_usage/external_data_use_observer.h" |
9 #include "chrome/browser/android/data_usage/tab_data_use_entry.h" | 9 #include "chrome/browser/android/data_usage/tab_data_use_entry.h" |
10 | 10 |
11 namespace { | 11 namespace { |
12 | 12 |
13 // TODO(rajendrant): To be changeable via field trial. | 13 // TODO(rajendrant): To be changeable via field trial. |
14 // Indicates the maximum number of tabs to maintain session information about. | 14 // Indicates the maximum number of tabs to maintain session information about. |
15 const size_t kMaxTabEntries = 200; | 15 const size_t kMaxTabEntries = 200; |
16 | 16 |
17 // Returns true if |tab_id| is a valid tab ID. | 17 // Returns true if |tab_id| is a valid tab ID. |
18 bool IsValidTabID(int32_t tab_id) { | 18 bool IsValidTabID(int32_t tab_id) { |
19 return tab_id >= 0; | 19 return tab_id >= 0; |
20 } | 20 } |
21 | 21 |
| 22 const char kUMAExpiredInactiveTabEntryRemovalDurationSecondsHistogram[] = |
| 23 "DataUse.TabModel.ExpiredInactiveTabEntryRemovalDuration"; |
| 24 const char kUMAExpiredActiveTabEntryRemovalDurationHoursHistogram[] = |
| 25 "DataUse.TabModel.ExpiredActiveTabEntryRemovalDuration"; |
| 26 const char kUMAUnexpiredTabEntryRemovalDurationMinutesHistogram[] = |
| 27 "DataUse.TabModel.UnexpiredTabEntryRemovalDuration"; |
| 28 |
22 } // namespace | 29 } // namespace |
23 | 30 |
24 namespace chrome { | 31 namespace chrome { |
25 | 32 |
26 namespace android { | 33 namespace android { |
27 | 34 |
28 size_t DataUseTabModel::GetMaxTabEntriesForTests() { | |
29 return kMaxTabEntries; | |
30 } | |
31 | |
32 DataUseTabModel::DataUseTabModel( | 35 DataUseTabModel::DataUseTabModel( |
33 const ExternalDataUseObserver* data_use_observer, | 36 const ExternalDataUseObserver* data_use_observer, |
34 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) | 37 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) |
35 : data_use_observer_(data_use_observer), | 38 : data_use_observer_(data_use_observer), |
36 observer_list_(new base::ObserverListThreadSafe<TabDataUseObserver>), | 39 observer_list_(new base::ObserverListThreadSafe<TabDataUseObserver>), |
37 weak_factory_(this) {} | 40 weak_factory_(this) {} |
38 | 41 |
39 DataUseTabModel::~DataUseTabModel() { | 42 DataUseTabModel::~DataUseTabModel() { |
40 DCHECK(thread_checker_.CalledOnValidThread()); | 43 DCHECK(thread_checker_.CalledOnValidThread()); |
41 } | 44 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 } | 121 } |
119 | 122 |
120 void DataUseTabModel::AddObserver(TabDataUseObserver* observer) { | 123 void DataUseTabModel::AddObserver(TabDataUseObserver* observer) { |
121 observer_list_->AddObserver(observer); | 124 observer_list_->AddObserver(observer); |
122 } | 125 } |
123 | 126 |
124 void DataUseTabModel::RemoveObserver(TabDataUseObserver* observer) { | 127 void DataUseTabModel::RemoveObserver(TabDataUseObserver* observer) { |
125 observer_list_->RemoveObserver(observer); | 128 observer_list_->RemoveObserver(observer); |
126 } | 129 } |
127 | 130 |
| 131 base::TimeTicks DataUseTabModel::Now() const { |
| 132 return base::TimeTicks::Now(); |
| 133 } |
| 134 |
| 135 size_t DataUseTabModel::GetMaxTabEntriesForTests() { |
| 136 return kMaxTabEntries; |
| 137 } |
| 138 |
128 void DataUseTabModel::NotifyObserversOfTrackingStarting(int32_t tab_id) { | 139 void DataUseTabModel::NotifyObserversOfTrackingStarting(int32_t tab_id) { |
129 observer_list_->Notify(FROM_HERE, &TabDataUseObserver::NotifyTrackingStarting, | 140 observer_list_->Notify(FROM_HERE, &TabDataUseObserver::NotifyTrackingStarting, |
130 tab_id); | 141 tab_id); |
131 } | 142 } |
132 | 143 |
133 void DataUseTabModel::NotifyObserversOfTrackingEnding(int32_t tab_id) { | 144 void DataUseTabModel::NotifyObserversOfTrackingEnding(int32_t tab_id) { |
134 observer_list_->Notify(FROM_HERE, &TabDataUseObserver::NotifyTrackingEnding, | 145 observer_list_->Notify(FROM_HERE, &TabDataUseObserver::NotifyTrackingEnding, |
135 tab_id); | 146 tab_id); |
136 } | 147 } |
137 | 148 |
(...skipping 23 matching lines...) Expand all Loading... |
161 if (tab_entry_iterator != active_tabs_.end() && | 172 if (tab_entry_iterator != active_tabs_.end() && |
162 tab_entry_iterator->second.EndTracking()) { | 173 tab_entry_iterator->second.EndTracking()) { |
163 NotifyObserversOfTrackingEnding(tab_id); | 174 NotifyObserversOfTrackingEnding(tab_id); |
164 } | 175 } |
165 } | 176 } |
166 | 177 |
167 void DataUseTabModel::CompactTabEntries() { | 178 void DataUseTabModel::CompactTabEntries() { |
168 // Remove expired tab entries. | 179 // Remove expired tab entries. |
169 for (TabEntryMap::iterator tab_entry_iterator = active_tabs_.begin(); | 180 for (TabEntryMap::iterator tab_entry_iterator = active_tabs_.begin(); |
170 tab_entry_iterator != active_tabs_.end();) { | 181 tab_entry_iterator != active_tabs_.end();) { |
171 if (tab_entry_iterator->second.IsExpired()) | 182 const auto& tab_entry = tab_entry_iterator->second; |
| 183 if (tab_entry.IsExpired()) { |
| 184 // Track the lifetime of expired tab entry. |
| 185 const base::TimeDelta removal_time = |
| 186 Now() - tab_entry.GetLatestStartOrEndTime(); |
| 187 if (!tab_entry.IsTrackingDataUse()) { |
| 188 UMA_HISTOGRAM_CUSTOM_TIMES( |
| 189 kUMAExpiredInactiveTabEntryRemovalDurationSecondsHistogram, |
| 190 removal_time, base::TimeDelta::FromSeconds(1), |
| 191 base::TimeDelta::FromHours(1), 50); |
| 192 } else { |
| 193 UMA_HISTOGRAM_CUSTOM_TIMES( |
| 194 kUMAExpiredActiveTabEntryRemovalDurationHoursHistogram, |
| 195 removal_time, base::TimeDelta::FromHours(1), |
| 196 base::TimeDelta::FromDays(5), 50); |
| 197 } |
172 active_tabs_.erase(tab_entry_iterator++); | 198 active_tabs_.erase(tab_entry_iterator++); |
173 else | 199 } else { |
174 ++tab_entry_iterator; | 200 ++tab_entry_iterator; |
| 201 } |
175 } | 202 } |
176 | 203 |
177 if (active_tabs_.size() <= kMaxTabEntries) | 204 if (active_tabs_.size() <= kMaxTabEntries) |
178 return; | 205 return; |
179 | 206 |
180 // Remove oldest unexpired tab entries. | 207 // Remove oldest unexpired tab entries. |
181 while (active_tabs_.size() > kMaxTabEntries) { | 208 while (active_tabs_.size() > kMaxTabEntries) { |
182 // Find oldest tab entry. | 209 // Find oldest tab entry. |
183 TabEntryMap::iterator oldest_tab_entry_iterator = active_tabs_.begin(); | 210 TabEntryMap::iterator oldest_tab_entry_iterator = active_tabs_.begin(); |
184 for (TabEntryMap::iterator tab_entry_iterator = active_tabs_.begin(); | 211 for (TabEntryMap::iterator tab_entry_iterator = active_tabs_.begin(); |
185 tab_entry_iterator != active_tabs_.end(); ++tab_entry_iterator) { | 212 tab_entry_iterator != active_tabs_.end(); ++tab_entry_iterator) { |
186 if (oldest_tab_entry_iterator->second.GetLatestStartOrEndTime() > | 213 if (oldest_tab_entry_iterator->second.GetLatestStartOrEndTime() > |
187 tab_entry_iterator->second.GetLatestStartOrEndTime()) { | 214 tab_entry_iterator->second.GetLatestStartOrEndTime()) { |
188 oldest_tab_entry_iterator = tab_entry_iterator; | 215 oldest_tab_entry_iterator = tab_entry_iterator; |
189 } | 216 } |
190 } | 217 } |
191 DCHECK(oldest_tab_entry_iterator != active_tabs_.end()); | 218 DCHECK(oldest_tab_entry_iterator != active_tabs_.end()); |
| 219 UMA_HISTOGRAM_CUSTOM_TIMES( |
| 220 kUMAUnexpiredTabEntryRemovalDurationMinutesHistogram, |
| 221 Now() - oldest_tab_entry_iterator->second.GetLatestStartOrEndTime(), |
| 222 base::TimeDelta::FromMinutes(1), base::TimeDelta::FromHours(1), 50); |
192 active_tabs_.erase(oldest_tab_entry_iterator); | 223 active_tabs_.erase(oldest_tab_entry_iterator); |
193 } | 224 } |
194 } | 225 } |
195 | 226 |
196 } // namespace android | 227 } // namespace android |
197 | 228 |
198 } // namespace chrome | 229 } // namespace chrome |
OLD | NEW |