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 |