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/metrics/histogram_macros.h" |
7 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
8 #include "base/time/time.h" | 9 #include "base/time/time.h" |
9 #include "chrome/browser/android/data_usage/external_data_use_observer.h" | 10 #include "chrome/browser/android/data_usage/external_data_use_observer.h" |
10 #include "chrome/browser/android/data_usage/tab_data_use_entry.h" | 11 #include "chrome/browser/android/data_usage/tab_data_use_entry.h" |
11 #include "components/variations/variations_associated_data.h" | 12 #include "components/variations/variations_associated_data.h" |
12 | 13 |
13 namespace { | 14 namespace { |
14 | 15 |
15 // Indicates the default maximum number of tabs to maintain session information | 16 // Indicates the default maximum number of tabs to maintain session information |
16 // about. May be overridden by the field trial. | 17 // about. May be overridden by the field trial. |
17 const size_t kDefaultMaxTabEntries = 200; | 18 const size_t kDefaultMaxTabEntries = 200; |
18 | 19 |
| 20 const char kUMAExpiredInactiveTabEntryRemovalDurationSecondsHistogram[] = |
| 21 "DataUse.TabModel.ExpiredInactiveTabEntryRemovalDuration"; |
| 22 const char kUMAExpiredActiveTabEntryRemovalDurationHoursHistogram[] = |
| 23 "DataUse.TabModel.ExpiredActiveTabEntryRemovalDuration"; |
| 24 const char kUMAUnexpiredTabEntryRemovalDurationMinutesHistogram[] = |
| 25 "DataUse.TabModel.UnexpiredTabEntryRemovalDuration"; |
| 26 |
19 // Returns true if |tab_id| is a valid tab ID. | 27 // Returns true if |tab_id| is a valid tab ID. |
20 bool IsValidTabID(int32_t tab_id) { | 28 bool IsValidTabID(int32_t tab_id) { |
21 return tab_id >= 0; | 29 return tab_id >= 0; |
22 } | 30 } |
23 | 31 |
24 // Returns various parameters from the values specified in the field trial. | 32 // Returns various parameters from the values specified in the field trial. |
25 size_t GetMaxTabEntries() { | 33 size_t GetMaxTabEntries() { |
26 size_t max_tab_entries = -1; | 34 size_t max_tab_entries = -1; |
27 std::string variation_value = variations::GetVariationParamValue( | 35 std::string variation_value = variations::GetVariationParamValue( |
28 chrome::android::ExternalDataUseObserver:: | 36 chrome::android::ExternalDataUseObserver:: |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 } | 152 } |
145 | 153 |
146 void DataUseTabModel::AddObserver(TabDataUseObserver* observer) { | 154 void DataUseTabModel::AddObserver(TabDataUseObserver* observer) { |
147 observer_list_->AddObserver(observer); | 155 observer_list_->AddObserver(observer); |
148 } | 156 } |
149 | 157 |
150 void DataUseTabModel::RemoveObserver(TabDataUseObserver* observer) { | 158 void DataUseTabModel::RemoveObserver(TabDataUseObserver* observer) { |
151 observer_list_->RemoveObserver(observer); | 159 observer_list_->RemoveObserver(observer); |
152 } | 160 } |
153 | 161 |
| 162 base::TimeTicks DataUseTabModel::Now() const { |
| 163 return base::TimeTicks::Now(); |
| 164 } |
| 165 |
154 void DataUseTabModel::NotifyObserversOfTrackingStarting(int32_t tab_id) { | 166 void DataUseTabModel::NotifyObserversOfTrackingStarting(int32_t tab_id) { |
155 observer_list_->Notify(FROM_HERE, &TabDataUseObserver::NotifyTrackingStarting, | 167 observer_list_->Notify(FROM_HERE, &TabDataUseObserver::NotifyTrackingStarting, |
156 tab_id); | 168 tab_id); |
157 } | 169 } |
158 | 170 |
159 void DataUseTabModel::NotifyObserversOfTrackingEnding(int32_t tab_id) { | 171 void DataUseTabModel::NotifyObserversOfTrackingEnding(int32_t tab_id) { |
160 observer_list_->Notify(FROM_HERE, &TabDataUseObserver::NotifyTrackingEnding, | 172 observer_list_->Notify(FROM_HERE, &TabDataUseObserver::NotifyTrackingEnding, |
161 tab_id); | 173 tab_id); |
162 } | 174 } |
163 | 175 |
(...skipping 23 matching lines...) Expand all Loading... |
187 if (tab_entry_iterator != active_tabs_.end() && | 199 if (tab_entry_iterator != active_tabs_.end() && |
188 tab_entry_iterator->second.EndTracking()) { | 200 tab_entry_iterator->second.EndTracking()) { |
189 NotifyObserversOfTrackingEnding(tab_id); | 201 NotifyObserversOfTrackingEnding(tab_id); |
190 } | 202 } |
191 } | 203 } |
192 | 204 |
193 void DataUseTabModel::CompactTabEntries() { | 205 void DataUseTabModel::CompactTabEntries() { |
194 // Remove expired tab entries. | 206 // Remove expired tab entries. |
195 for (TabEntryMap::iterator tab_entry_iterator = active_tabs_.begin(); | 207 for (TabEntryMap::iterator tab_entry_iterator = active_tabs_.begin(); |
196 tab_entry_iterator != active_tabs_.end();) { | 208 tab_entry_iterator != active_tabs_.end();) { |
197 if (tab_entry_iterator->second.IsExpired()) | 209 const auto& tab_entry = tab_entry_iterator->second; |
| 210 if (tab_entry.IsExpired()) { |
| 211 // Track the lifetime of expired tab entry. |
| 212 const base::TimeDelta removal_time = |
| 213 Now() - tab_entry.GetLatestStartOrEndTime(); |
| 214 if (!tab_entry.IsTrackingDataUse()) { |
| 215 UMA_HISTOGRAM_CUSTOM_TIMES( |
| 216 kUMAExpiredInactiveTabEntryRemovalDurationSecondsHistogram, |
| 217 removal_time, base::TimeDelta::FromSeconds(1), |
| 218 base::TimeDelta::FromHours(1), 50); |
| 219 } else { |
| 220 UMA_HISTOGRAM_CUSTOM_TIMES( |
| 221 kUMAExpiredActiveTabEntryRemovalDurationHoursHistogram, |
| 222 removal_time, base::TimeDelta::FromHours(1), |
| 223 base::TimeDelta::FromDays(5), 50); |
| 224 } |
198 active_tabs_.erase(tab_entry_iterator++); | 225 active_tabs_.erase(tab_entry_iterator++); |
199 else | 226 } else { |
200 ++tab_entry_iterator; | 227 ++tab_entry_iterator; |
| 228 } |
201 } | 229 } |
202 | 230 |
203 if (active_tabs_.size() <= max_tab_entries_) | 231 if (active_tabs_.size() <= max_tab_entries_) |
204 return; | 232 return; |
205 | 233 |
206 // Remove oldest unexpired tab entries. | 234 // Remove oldest unexpired tab entries. |
207 while (active_tabs_.size() > max_tab_entries_) { | 235 while (active_tabs_.size() > max_tab_entries_) { |
208 // Find oldest tab entry. | 236 // Find oldest tab entry. |
209 TabEntryMap::iterator oldest_tab_entry_iterator = active_tabs_.begin(); | 237 TabEntryMap::iterator oldest_tab_entry_iterator = active_tabs_.begin(); |
210 for (TabEntryMap::iterator tab_entry_iterator = active_tabs_.begin(); | 238 for (TabEntryMap::iterator tab_entry_iterator = active_tabs_.begin(); |
211 tab_entry_iterator != active_tabs_.end(); ++tab_entry_iterator) { | 239 tab_entry_iterator != active_tabs_.end(); ++tab_entry_iterator) { |
212 if (oldest_tab_entry_iterator->second.GetLatestStartOrEndTime() > | 240 if (oldest_tab_entry_iterator->second.GetLatestStartOrEndTime() > |
213 tab_entry_iterator->second.GetLatestStartOrEndTime()) { | 241 tab_entry_iterator->second.GetLatestStartOrEndTime()) { |
214 oldest_tab_entry_iterator = tab_entry_iterator; | 242 oldest_tab_entry_iterator = tab_entry_iterator; |
215 } | 243 } |
216 } | 244 } |
217 DCHECK(oldest_tab_entry_iterator != active_tabs_.end()); | 245 DCHECK(oldest_tab_entry_iterator != active_tabs_.end()); |
| 246 UMA_HISTOGRAM_CUSTOM_TIMES( |
| 247 kUMAUnexpiredTabEntryRemovalDurationMinutesHistogram, |
| 248 Now() - oldest_tab_entry_iterator->second.GetLatestStartOrEndTime(), |
| 249 base::TimeDelta::FromMinutes(1), base::TimeDelta::FromHours(1), 50); |
218 active_tabs_.erase(oldest_tab_entry_iterator); | 250 active_tabs_.erase(oldest_tab_entry_iterator); |
219 } | 251 } |
220 } | 252 } |
221 | 253 |
222 } // namespace android | 254 } // namespace android |
223 | 255 |
224 } // namespace chrome | 256 } // namespace chrome |
OLD | NEW |