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 <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
10 #include "base/single_thread_task_runner.h" | 10 #include "base/single_thread_task_runner.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 // overridden by the field trial. | 33 // overridden by the field trial. |
34 const uint32_t kDefaultClosedTabExpirationDurationSeconds = 30; // 30 seconds. | 34 const uint32_t kDefaultClosedTabExpirationDurationSeconds = 30; // 30 seconds. |
35 const uint32_t kDefaultOpenTabExpirationDurationSeconds = | 35 const uint32_t kDefaultOpenTabExpirationDurationSeconds = |
36 60 * 60 * 24 * 5; // 5 days. | 36 60 * 60 * 24 * 5; // 5 days. |
37 | 37 |
38 // Default expiration duration in seconds of a matching rule, used when | 38 // Default expiration duration in seconds of a matching rule, used when |
39 // expiration time is not specified. | 39 // expiration time is not specified. |
40 const uint32_t kDefaultMatchingRuleExpirationDurationSeconds = | 40 const uint32_t kDefaultMatchingRuleExpirationDurationSeconds = |
41 60 * 60 * 24; // 24 hours. | 41 60 * 60 * 24; // 24 hours. |
42 | 42 |
| 43 // Default maximum limit imposed for the initial UI navigation event buffer. |
| 44 // Once this limit is reached, the buffer will be cleared. |
| 45 const uint32_t kDefaultMaxNavigationEventsBuffered = 100; |
| 46 |
43 const char kUMAExpiredInactiveTabEntryRemovalDurationHistogram[] = | 47 const char kUMAExpiredInactiveTabEntryRemovalDurationHistogram[] = |
44 "DataUsage.TabModel.ExpiredInactiveTabEntryRemovalDuration"; | 48 "DataUsage.TabModel.ExpiredInactiveTabEntryRemovalDuration"; |
45 const char kUMAExpiredActiveTabEntryRemovalDurationHistogram[] = | 49 const char kUMAExpiredActiveTabEntryRemovalDurationHistogram[] = |
46 "DataUsage.TabModel.ExpiredActiveTabEntryRemovalDuration"; | 50 "DataUsage.TabModel.ExpiredActiveTabEntryRemovalDuration"; |
47 const char kUMAUnexpiredTabEntryRemovalDurationHistogram[] = | 51 const char kUMAUnexpiredTabEntryRemovalDurationHistogram[] = |
48 "DataUsage.TabModel.UnexpiredTabEntryRemovalDuration"; | 52 "DataUsage.TabModel.UnexpiredTabEntryRemovalDuration"; |
49 | 53 |
50 // Returns true if |tab_id| is a valid tab ID. | 54 // Returns true if |tab_id| is a valid tab ID. |
51 bool IsValidTabID(SessionID::id_type tab_id) { | 55 bool IsValidTabID(SessionID::id_type tab_id) { |
52 return tab_id >= 0; | 56 return tab_id >= 0; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 namespace chrome { | 130 namespace chrome { |
127 | 131 |
128 namespace android { | 132 namespace android { |
129 | 133 |
130 DataUseTabModel::DataUseTabModel() | 134 DataUseTabModel::DataUseTabModel() |
131 : max_tab_entries_(GetMaxTabEntries()), | 135 : max_tab_entries_(GetMaxTabEntries()), |
132 max_sessions_per_tab_(GetMaxSessionsPerTab()), | 136 max_sessions_per_tab_(GetMaxSessionsPerTab()), |
133 closed_tab_expiration_duration_(GetClosedTabExpirationDuration()), | 137 closed_tab_expiration_duration_(GetClosedTabExpirationDuration()), |
134 open_tab_expiration_duration_(GetOpenTabExpirationDuration()), | 138 open_tab_expiration_duration_(GetOpenTabExpirationDuration()), |
135 is_control_app_installed_(false), | 139 is_control_app_installed_(false), |
| 140 data_use_ui_navigations_(new std::vector<DataUseUINavigationEvent>()), |
136 weak_factory_(this) { | 141 weak_factory_(this) { |
137 // Detach from current thread since rest of DataUseTabModel lives on the UI | 142 // Detach from current thread since rest of DataUseTabModel lives on the UI |
138 // thread and the current thread may not be UI thread.. | 143 // thread and the current thread may not be UI thread.. |
139 thread_checker_.DetachFromThread(); | 144 thread_checker_.DetachFromThread(); |
140 } | 145 } |
141 | 146 |
142 DataUseTabModel::~DataUseTabModel() { | 147 DataUseTabModel::~DataUseTabModel() { |
143 DCHECK(thread_checker_.CalledOnValidThread()); | 148 DCHECK(thread_checker_.CalledOnValidThread()); |
144 } | 149 } |
145 | 150 |
(...skipping 13 matching lines...) Expand all Loading... |
159 new DataUseMatcher(GetWeakPtr(), external_data_use_observer_bridge, | 164 new DataUseMatcher(GetWeakPtr(), external_data_use_observer_bridge, |
160 GetDefaultMatchingRuleExpirationDuration())); | 165 GetDefaultMatchingRuleExpirationDuration())); |
161 } | 166 } |
162 | 167 |
163 void DataUseTabModel::OnNavigationEvent(SessionID::id_type tab_id, | 168 void DataUseTabModel::OnNavigationEvent(SessionID::id_type tab_id, |
164 TransitionType transition, | 169 TransitionType transition, |
165 const GURL& url, | 170 const GURL& url, |
166 const std::string& package) { | 171 const std::string& package) { |
167 DCHECK(thread_checker_.CalledOnValidThread()); | 172 DCHECK(thread_checker_.CalledOnValidThread()); |
168 DCHECK(IsValidTabID(tab_id)); | 173 DCHECK(IsValidTabID(tab_id)); |
| 174 |
| 175 if (data_use_ui_navigations_) { |
| 176 // Buffer the navigation event for later processing. |
| 177 data_use_ui_navigations_->push_back( |
| 178 DataUseUINavigationEvent(tab_id, transition, url, package)); |
| 179 |
| 180 if (data_use_ui_navigations_->size() >= |
| 181 kDefaultMaxNavigationEventsBuffered) { |
| 182 ProcessBufferedNavigationEvents(); |
| 183 } |
| 184 return; |
| 185 } |
| 186 |
169 std::string current_label, new_label; | 187 std::string current_label, new_label; |
170 bool is_package_match; | 188 bool is_package_match; |
171 | 189 |
172 if (is_control_app_installed_ && !data_use_matcher_->HasValidRules()) | 190 if (is_control_app_installed_ && !data_use_matcher_->HasValidRules()) |
173 data_use_matcher_->FetchMatchingRules(); | 191 data_use_matcher_->FetchMatchingRules(); |
174 | 192 |
175 GetCurrentAndNewLabelForNavigationEvent(tab_id, transition, url, package, | 193 GetCurrentAndNewLabelForNavigationEvent(tab_id, transition, url, package, |
176 ¤t_label, &new_label, | 194 ¤t_label, &new_label, |
177 &is_package_match); | 195 &is_package_match); |
178 if (!current_label.empty() && new_label.empty()) { | 196 if (!current_label.empty() && new_label.empty()) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 const std::vector<std::string>& label) { | 269 const std::vector<std::string>& label) { |
252 DCHECK(thread_checker_.CalledOnValidThread()); | 270 DCHECK(thread_checker_.CalledOnValidThread()); |
253 | 271 |
254 // Fetch rule requests could be started when control app was installed, and | 272 // Fetch rule requests could be started when control app was installed, and |
255 // the response could be received when control app was uninstalled. Ignore | 273 // the response could be received when control app was uninstalled. Ignore |
256 // these spurious rule fetch responses. | 274 // these spurious rule fetch responses. |
257 if (!is_control_app_installed_) | 275 if (!is_control_app_installed_) |
258 return; | 276 return; |
259 data_use_matcher_->RegisterURLRegexes(app_package_name, domain_path_regex, | 277 data_use_matcher_->RegisterURLRegexes(app_package_name, domain_path_regex, |
260 label); | 278 label); |
| 279 ProcessBufferedNavigationEvents(); |
261 } | 280 } |
262 | 281 |
263 void DataUseTabModel::OnControlAppInstallStateChange( | 282 void DataUseTabModel::OnControlAppInstallStateChange( |
264 bool is_control_app_installed) { | 283 bool is_control_app_installed) { |
265 DCHECK(thread_checker_.CalledOnValidThread()); | 284 DCHECK(thread_checker_.CalledOnValidThread()); |
266 DCHECK_NE(is_control_app_installed_, is_control_app_installed); | 285 DCHECK_NE(is_control_app_installed_, is_control_app_installed); |
267 DCHECK(data_use_matcher_); | 286 DCHECK(data_use_matcher_); |
268 | 287 |
269 is_control_app_installed_ = is_control_app_installed; | 288 is_control_app_installed_ = is_control_app_installed; |
270 std::vector<std::string> empty; | 289 std::vector<std::string> empty; |
271 if (!is_control_app_installed_) { | 290 if (!is_control_app_installed_) { |
272 // Clear rules. | 291 // Clear rules, and process the buffered UI navigation events. |
273 data_use_matcher_->RegisterURLRegexes(empty, empty, empty); | 292 data_use_matcher_->RegisterURLRegexes(empty, empty, empty); |
| 293 ProcessBufferedNavigationEvents(); |
274 } else { | 294 } else { |
275 // Fetch the matching rules when the app is installed. | 295 // Fetch the matching rules when the app is installed. |
276 data_use_matcher_->FetchMatchingRules(); | 296 data_use_matcher_->FetchMatchingRules(); |
277 } | 297 } |
278 } | 298 } |
279 | 299 |
280 base::TimeTicks DataUseTabModel::NowTicks() const { | 300 base::TimeTicks DataUseTabModel::NowTicks() const { |
281 DCHECK(thread_checker_.CalledOnValidThread()); | 301 DCHECK(thread_checker_.CalledOnValidThread()); |
282 return tick_clock_->NowTicks(); | 302 return tick_clock_->NowTicks(); |
283 } | 303 } |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 DCHECK(oldest_tab_entry_iterator != active_tabs_.end()); | 472 DCHECK(oldest_tab_entry_iterator != active_tabs_.end()); |
453 UMA_HISTOGRAM_CUSTOM_TIMES( | 473 UMA_HISTOGRAM_CUSTOM_TIMES( |
454 kUMAUnexpiredTabEntryRemovalDurationHistogram, | 474 kUMAUnexpiredTabEntryRemovalDurationHistogram, |
455 NowTicks() - | 475 NowTicks() - |
456 oldest_tab_entry_iterator->second.GetLatestStartOrEndTime(), | 476 oldest_tab_entry_iterator->second.GetLatestStartOrEndTime(), |
457 base::TimeDelta::FromMinutes(1), base::TimeDelta::FromHours(1), 50); | 477 base::TimeDelta::FromMinutes(1), base::TimeDelta::FromHours(1), 50); |
458 active_tabs_.erase(oldest_tab_entry_iterator); | 478 active_tabs_.erase(oldest_tab_entry_iterator); |
459 } | 479 } |
460 } | 480 } |
461 | 481 |
| 482 void DataUseTabModel::ProcessBufferedNavigationEvents() { |
| 483 DCHECK(thread_checker_.CalledOnValidThread()); |
| 484 if (!data_use_ui_navigations_) |
| 485 return; |
| 486 // Move the ownership of vector managed by |data_use_ui_navigations_| and |
| 487 // release it, so that navigation events will be processed immediately. |
| 488 const auto tmp_data_use_ui_navigations_ = std::move(data_use_ui_navigations_); |
| 489 for (const auto& ui_event : *tmp_data_use_ui_navigations_.get()) { |
| 490 OnNavigationEvent(ui_event.tab_id, ui_event.transition_type, ui_event.url, |
| 491 ui_event.package); |
| 492 } |
| 493 } |
| 494 |
462 } // namespace android | 495 } // namespace android |
463 | 496 |
464 } // namespace chrome | 497 } // namespace chrome |
OLD | NEW |