| 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 |