Chromium Code Reviews| 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 number of UI navigation events that are buffered initially | |
| 44 // until they are processed later. | |
| 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 ui_navigation_buffer(new std::vector<DataUseUINavigationBuffer>()), | |
| 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 |
| 146 base::WeakPtr<DataUseTabModel> DataUseTabModel::GetWeakPtr() { | 151 base::WeakPtr<DataUseTabModel> DataUseTabModel::GetWeakPtr() { |
| 147 DCHECK(thread_checker_.CalledOnValidThread()); | 152 DCHECK(thread_checker_.CalledOnValidThread()); |
| 148 return weak_factory_.GetWeakPtr(); | 153 return weak_factory_.GetWeakPtr(); |
| 149 } | 154 } |
| 150 | 155 |
| 151 void DataUseTabModel::InitOnUIThread( | 156 void DataUseTabModel::InitOnUIThread( |
| 152 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, | 157 const ExternalDataUseObserverBridge* external_data_use_observer_bridge) { |
| 153 const base::WeakPtr<ExternalDataUseObserver>& external_data_use_observer) { | |
| 154 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 158 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 155 DCHECK(thread_checker_.CalledOnValidThread()); | 159 DCHECK(thread_checker_.CalledOnValidThread()); |
| 156 DCHECK(io_task_runner); | 160 DCHECK(external_data_use_observer_bridge); |
| 157 | 161 |
| 158 tick_clock_.reset(new base::DefaultTickClock()); | 162 tick_clock_.reset(new base::DefaultTickClock()); |
| 159 data_use_matcher_.reset(new DataUseMatcher( | 163 data_use_matcher_.reset( |
| 160 GetWeakPtr(), io_task_runner, external_data_use_observer, | 164 new DataUseMatcher(GetWeakPtr(), external_data_use_observer_bridge, |
| 161 GetDefaultMatchingRuleExpirationDuration())); | 165 GetDefaultMatchingRuleExpirationDuration())); |
| 162 } | 166 } |
| 163 | 167 |
| 164 void DataUseTabModel::OnNavigationEvent(SessionID::id_type tab_id, | 168 void DataUseTabModel::OnNavigationEvent(SessionID::id_type tab_id, |
| 165 TransitionType transition, | 169 TransitionType transition, |
| 166 const GURL& url, | 170 const GURL& url, |
| 167 const std::string& package) { | 171 const std::string& package) { |
| 168 DCHECK(thread_checker_.CalledOnValidThread()); | 172 DCHECK(thread_checker_.CalledOnValidThread()); |
| 169 DCHECK(IsValidTabID(tab_id)); | 173 DCHECK(IsValidTabID(tab_id)); |
| 170 std::string current_label, new_label; | 174 std::string current_label, new_label; |
| 171 bool is_package_match; | 175 bool is_package_match; |
|
tbansal1
2016/03/08 18:15:00
May be declare these variables after the if-block
| |
| 172 | 176 |
| 177 if (ui_navigation_buffer) { | |
| 178 // Buffer the navigation event for later processing. | |
| 179 DataUseUINavigationBuffer ui_event; | |
|
tbansal1
2016/03/08 18:15:00
If you want to force callers to fill all the field
| |
| 180 ui_event.tab_id = tab_id; | |
| 181 ui_event.transition = transition; | |
| 182 ui_event.url = url; | |
| 183 ui_event.package = package; | |
| 184 ui_navigation_buffer->push_back(ui_event); | |
| 185 | |
| 186 if (ui_navigation_buffer->size() >= kDefaultMaxNavigationEventsBuffered) { | |
|
tbansal1
2016/03/08 18:15:00
If the matching rules have not been fetched, what
| |
| 187 ProcessBufferedNavigationEvents(); | |
| 188 } | |
| 189 return; | |
| 190 } | |
| 191 | |
| 173 if (is_control_app_installed_ && !data_use_matcher_->HasValidRules()) | 192 if (is_control_app_installed_ && !data_use_matcher_->HasValidRules()) |
| 174 data_use_matcher_->FetchMatchingRules(); | 193 data_use_matcher_->FetchMatchingRules(); |
| 175 | 194 |
| 176 GetCurrentAndNewLabelForNavigationEvent(tab_id, transition, url, package, | 195 GetCurrentAndNewLabelForNavigationEvent(tab_id, transition, url, package, |
| 177 ¤t_label, &new_label, | 196 ¤t_label, &new_label, |
| 178 &is_package_match); | 197 &is_package_match); |
| 179 if (!current_label.empty() && new_label.empty()) { | 198 if (!current_label.empty() && new_label.empty()) { |
| 180 EndTrackingDataUse(tab_id); | 199 EndTrackingDataUse(tab_id); |
| 181 } else if (current_label.empty() && !new_label.empty()) { | 200 } else if (current_label.empty() && !new_label.empty()) { |
| 182 StartTrackingDataUse( | 201 StartTrackingDataUse( |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 252 const std::vector<std::string>& label) { | 271 const std::vector<std::string>& label) { |
| 253 DCHECK(thread_checker_.CalledOnValidThread()); | 272 DCHECK(thread_checker_.CalledOnValidThread()); |
| 254 | 273 |
| 255 // Fetch rule requests could be started when control app was installed, and | 274 // Fetch rule requests could be started when control app was installed, and |
| 256 // the response could be received when control app was uninstalled. Ignore | 275 // the response could be received when control app was uninstalled. Ignore |
| 257 // these spurious rule fetch responses. | 276 // these spurious rule fetch responses. |
| 258 if (!is_control_app_installed_) | 277 if (!is_control_app_installed_) |
| 259 return; | 278 return; |
| 260 data_use_matcher_->RegisterURLRegexes(app_package_name, domain_path_regex, | 279 data_use_matcher_->RegisterURLRegexes(app_package_name, domain_path_regex, |
| 261 label); | 280 label); |
| 281 ProcessBufferedNavigationEvents(); | |
| 262 } | 282 } |
| 263 | 283 |
| 264 void DataUseTabModel::OnControlAppInstallStateChange( | 284 void DataUseTabModel::OnControlAppInstallStateChange( |
| 265 bool is_control_app_installed) { | 285 bool is_control_app_installed) { |
| 266 DCHECK(thread_checker_.CalledOnValidThread()); | 286 DCHECK(thread_checker_.CalledOnValidThread()); |
| 267 DCHECK_NE(is_control_app_installed_, is_control_app_installed); | 287 DCHECK_NE(is_control_app_installed_, is_control_app_installed); |
| 268 // If external control app is installed now, rules will be fetched on the next | 288 |
| 269 // navigation event. | |
| 270 is_control_app_installed_ = is_control_app_installed; | 289 is_control_app_installed_ = is_control_app_installed; |
| 271 std::vector<std::string> empty; | 290 std::vector<std::string> empty; |
| 272 if (!is_control_app_installed_) // Clear rules. | 291 if (!is_control_app_installed_) { // Clear rules. |
|
tbansal1
2016/03/08 18:15:00
nit: move the comment on next line?
Raj
2016/03/09 02:27:35
Done.
| |
| 273 data_use_matcher_->RegisterURLRegexes(empty, empty, empty); | 292 data_use_matcher_->RegisterURLRegexes(empty, empty, empty); |
| 293 ProcessBufferedNavigationEvents(); | |
| 294 } else { | |
| 295 data_use_matcher_->FetchMatchingRules(); | |
|
tbansal1
2016/03/08 18:15:00
Can we do this in a separate CL and merge it to M-
Raj
2016/03/09 02:27:35
Done.
| |
| 296 } | |
| 274 } | 297 } |
| 275 | 298 |
| 276 base::TimeTicks DataUseTabModel::NowTicks() const { | 299 base::TimeTicks DataUseTabModel::NowTicks() const { |
| 277 DCHECK(thread_checker_.CalledOnValidThread()); | 300 DCHECK(thread_checker_.CalledOnValidThread()); |
| 278 return tick_clock_->NowTicks(); | 301 return tick_clock_->NowTicks(); |
| 279 } | 302 } |
| 280 | 303 |
| 281 bool DataUseTabModel::IsCustomTabPackageMatch(SessionID::id_type tab_id) const { | 304 bool DataUseTabModel::IsCustomTabPackageMatch(SessionID::id_type tab_id) const { |
| 282 DCHECK(thread_checker_.CalledOnValidThread()); | 305 DCHECK(thread_checker_.CalledOnValidThread()); |
| 283 TabEntryMap::const_iterator tab_entry_iterator = active_tabs_.find(tab_id); | 306 TabEntryMap::const_iterator tab_entry_iterator = active_tabs_.find(tab_id); |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 448 DCHECK(oldest_tab_entry_iterator != active_tabs_.end()); | 471 DCHECK(oldest_tab_entry_iterator != active_tabs_.end()); |
| 449 UMA_HISTOGRAM_CUSTOM_TIMES( | 472 UMA_HISTOGRAM_CUSTOM_TIMES( |
| 450 kUMAUnexpiredTabEntryRemovalDurationHistogram, | 473 kUMAUnexpiredTabEntryRemovalDurationHistogram, |
| 451 NowTicks() - | 474 NowTicks() - |
| 452 oldest_tab_entry_iterator->second.GetLatestStartOrEndTime(), | 475 oldest_tab_entry_iterator->second.GetLatestStartOrEndTime(), |
| 453 base::TimeDelta::FromMinutes(1), base::TimeDelta::FromHours(1), 50); | 476 base::TimeDelta::FromMinutes(1), base::TimeDelta::FromHours(1), 50); |
| 454 active_tabs_.erase(oldest_tab_entry_iterator); | 477 active_tabs_.erase(oldest_tab_entry_iterator); |
| 455 } | 478 } |
| 456 } | 479 } |
| 457 | 480 |
| 481 void DataUseTabModel::ProcessBufferedNavigationEvents() { | |
| 482 if (!ui_navigation_buffer) | |
|
tbansal1
2016/03/08 18:15:00
DCHECK (thread_checker_...)
| |
| 483 return; | |
| 484 scoped_ptr<std::vector<DataUseUINavigationBuffer>> tmp_ui_navigation_buffer = | |
|
tbansal1
2016/03/08 18:15:00
Why move it to a tmp vector? Can we not iterate ov
| |
| 485 std::move(ui_navigation_buffer); | |
| 486 for (const auto& ui_event : *tmp_ui_navigation_buffer.get()) { | |
| 487 OnNavigationEvent(ui_event.tab_id, ui_event.transition, ui_event.url, | |
| 488 ui_event.package); | |
| 489 } | |
| 490 } | |
| 491 | |
| 458 } // namespace android | 492 } // namespace android |
| 459 | 493 |
| 460 } // namespace chrome | 494 } // namespace chrome |
| OLD | NEW |