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/metrics/histogram_macros.h" |
| 8 #include "base/single_thread_task_runner.h" |
8 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
9 #include "base/time/time.h" | 10 #include "base/time/time.h" |
10 #include "chrome/browser/android/data_usage/external_data_use_observer.h" | 11 #include "chrome/browser/android/data_usage/external_data_use_observer.h" |
11 #include "chrome/browser/android/data_usage/tab_data_use_entry.h" | 12 #include "chrome/browser/android/data_usage/tab_data_use_entry.h" |
| 13 #include "components/data_usage/core/data_use.h" |
12 #include "components/variations/variations_associated_data.h" | 14 #include "components/variations/variations_associated_data.h" |
13 | 15 |
14 namespace { | 16 namespace { |
15 | 17 |
16 // Indicates the default maximum number of tabs to maintain session information | 18 // Indicates the default maximum number of tabs to maintain session information |
17 // about. May be overridden by the field trial. | 19 // about. May be overridden by the field trial. |
18 const size_t kDefaultMaxTabEntries = 200; | 20 const size_t kDefaultMaxTabEntries = 200; |
19 | 21 |
20 const char kUMAExpiredInactiveTabEntryRemovalDurationSecondsHistogram[] = | 22 const char kUMAExpiredInactiveTabEntryRemovalDurationSecondsHistogram[] = |
21 "DataUse.TabModel.ExpiredInactiveTabEntryRemovalDuration"; | 23 "DataUse.TabModel.ExpiredInactiveTabEntryRemovalDuration"; |
(...skipping 24 matching lines...) Expand all Loading... |
46 } // namespace | 48 } // namespace |
47 | 49 |
48 namespace chrome { | 50 namespace chrome { |
49 | 51 |
50 namespace android { | 52 namespace android { |
51 | 53 |
52 DataUseTabModel::DataUseTabModel( | 54 DataUseTabModel::DataUseTabModel( |
53 const ExternalDataUseObserver* data_use_observer, | 55 const ExternalDataUseObserver* data_use_observer, |
54 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) | 56 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) |
55 : data_use_observer_(data_use_observer), | 57 : data_use_observer_(data_use_observer), |
56 observer_list_(new base::ObserverListThreadSafe<TabDataUseObserver>), | |
57 max_tab_entries_(GetMaxTabEntries()), | 58 max_tab_entries_(GetMaxTabEntries()), |
58 weak_factory_(this) {} | 59 ui_task_runner_(ui_task_runner), |
| 60 weak_factory_(this) { |
| 61 DCHECK(ui_task_runner_); |
| 62 } |
59 | 63 |
60 DataUseTabModel::~DataUseTabModel() { | 64 DataUseTabModel::~DataUseTabModel() { |
61 DCHECK(thread_checker_.CalledOnValidThread()); | 65 DCHECK(thread_checker_.CalledOnValidThread()); |
62 } | 66 } |
63 | 67 |
64 base::WeakPtr<DataUseTabModel> DataUseTabModel::GetWeakPtr() { | 68 base::WeakPtr<DataUseTabModel> DataUseTabModel::GetWeakPtr() { |
65 DCHECK(thread_checker_.CalledOnValidThread()); | 69 DCHECK(thread_checker_.CalledOnValidThread()); |
66 return weak_factory_.GetWeakPtr(); | 70 return weak_factory_.GetWeakPtr(); |
67 } | 71 } |
68 | 72 |
69 void DataUseTabModel::OnNavigationEvent(int32_t tab_id, | 73 void DataUseTabModel::OnNavigationEvent(int32_t tab_id, |
70 TransitionType transition, | 74 TransitionType transition, |
71 const GURL& url, | 75 const GURL& url, |
72 const std::string& package) { | 76 const std::string& package) { |
73 DCHECK(thread_checker_.CalledOnValidThread()); | 77 DCHECK(thread_checker_.CalledOnValidThread()); |
74 DCHECK(IsValidTabID(tab_id)); | 78 DCHECK(IsValidTabID(tab_id)); |
75 | 79 |
76 switch (transition) { | 80 switch (transition) { |
77 case TRANSITION_OMNIBOX_SEARCH: | 81 case TRANSITION_OMNIBOX_SEARCH: |
| 82 case TRANSITION_OMNIBOX_NAVIGATION: |
78 case TRANSITION_FROM_EXTERNAL_APP: { | 83 case TRANSITION_FROM_EXTERNAL_APP: { |
79 // Enter events. | 84 // Enter events. |
80 bool start_tracking = false; | 85 bool start_tracking = false; |
81 std::string label; | 86 std::string label; |
82 TabEntryMap::const_iterator tab_entry_iterator = | 87 TabEntryMap::const_iterator tab_entry_iterator = |
83 active_tabs_.find(tab_id); | 88 active_tabs_.find(tab_id); |
84 if (tab_entry_iterator != active_tabs_.end() && | 89 if (tab_entry_iterator != active_tabs_.end() && |
85 tab_entry_iterator->second.IsTrackingDataUse()) { | 90 tab_entry_iterator->second.IsTrackingDataUse()) { |
86 break; | 91 break; |
87 } | 92 } |
88 if (transition == TRANSITION_FROM_EXTERNAL_APP) { | 93 if (transition == TRANSITION_FROM_EXTERNAL_APP) { |
89 // Package name should match, for transitions from external app. | 94 // Package name should match, for transitions from external app. |
90 if (!package.empty() && | 95 if (!package.empty() && |
91 data_use_observer_->MatchesAppPackageName(package, &label)) { | 96 data_use_observer_->MatchesAppPackageName(package, &label)) { |
92 DCHECK(!label.empty()); | 97 DCHECK(!label.empty()); |
93 start_tracking = true; | 98 start_tracking = true; |
94 } | 99 } |
95 } | 100 } |
96 if (!start_tracking && !url.is_empty() && | 101 if (!start_tracking && !url.is_empty() && |
97 data_use_observer_->Matches(url, &label)) { | 102 data_use_observer_->Matches(url, &label)) { |
98 DCHECK(!label.empty()); | 103 DCHECK(!label.empty()); |
99 start_tracking = true; | 104 start_tracking = true; |
100 } | 105 } |
101 if (start_tracking) | 106 if (start_tracking) |
102 StartTrackingDataUse(tab_id, label); | 107 StartTrackingDataUse(tab_id, label); |
103 break; | 108 break; |
104 } | 109 } |
105 | 110 |
106 case TRANSITION_FROM_NAVSUGGEST: | |
107 case TRANSITION_OMNIBOX_NAVIGATION: | |
108 case TRANSITION_BOOKMARK: | 111 case TRANSITION_BOOKMARK: |
109 case TRANSITION_HISTORY_ITEM: | 112 case TRANSITION_HISTORY_ITEM: |
110 case TRANSITION_TO_EXTERNAL_APP: | |
111 // Exit events. | 113 // Exit events. |
112 EndTrackingDataUse(tab_id); | 114 EndTrackingDataUse(tab_id); |
113 break; | 115 break; |
114 | 116 |
115 default: | 117 default: |
116 NOTREACHED(); | 118 NOTREACHED(); |
117 break; | 119 break; |
118 } | 120 } |
119 } | 121 } |
120 | 122 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 TabEntryMap::const_iterator tab_entry_iterator = | 154 TabEntryMap::const_iterator tab_entry_iterator = |
153 active_tabs_.find(data_use.tab_id); | 155 active_tabs_.find(data_use.tab_id); |
154 if (tab_entry_iterator != active_tabs_.end()) { | 156 if (tab_entry_iterator != active_tabs_.end()) { |
155 return tab_entry_iterator->second.GetLabel(data_use.request_start, | 157 return tab_entry_iterator->second.GetLabel(data_use.request_start, |
156 output_label); | 158 output_label); |
157 } | 159 } |
158 | 160 |
159 return false; // Tab session not found. | 161 return false; // Tab session not found. |
160 } | 162 } |
161 | 163 |
162 void DataUseTabModel::AddObserver(TabDataUseObserver* observer) { | 164 void DataUseTabModel::AddObserver( |
163 observer_list_->AddObserver(observer); | 165 const TabDataUseObserver* observer, |
| 166 const base::WeakPtr<TabDataUseObserver> weak_ptr_observer) { |
| 167 DCHECK(thread_checker_.CalledOnValidThread()); |
| 168 observers_.insert(ObserverMap::value_type(observer, weak_ptr_observer)); |
| 169 DCHECK_LT(0U, observers_.size()); |
164 } | 170 } |
165 | 171 |
166 void DataUseTabModel::RemoveObserver(TabDataUseObserver* observer) { | 172 void DataUseTabModel::RemoveObserver(const TabDataUseObserver* observer) { |
167 observer_list_->RemoveObserver(observer); | 173 DCHECK(thread_checker_.CalledOnValidThread()); |
| 174 observers_.erase(observer); |
168 } | 175 } |
169 | 176 |
170 base::TimeTicks DataUseTabModel::Now() const { | 177 base::TimeTicks DataUseTabModel::Now() const { |
171 return base::TimeTicks::Now(); | 178 return base::TimeTicks::Now(); |
172 } | 179 } |
173 | 180 |
174 void DataUseTabModel::NotifyObserversOfTrackingStarting(int32_t tab_id) { | 181 void DataUseTabModel::NotifyObserversOfTrackingStarting(int32_t tab_id) { |
175 observer_list_->Notify(FROM_HERE, &TabDataUseObserver::NotifyTrackingStarting, | 182 DCHECK(thread_checker_.CalledOnValidThread()); |
176 tab_id); | 183 DCHECK(ui_task_runner_); |
| 184 for (const auto& it : observers_) { |
| 185 ui_task_runner_->PostTask( |
| 186 FROM_HERE, base::Bind(&TabDataUseObserver::NotifyTrackingStarting, |
| 187 it.second, tab_id)); |
| 188 } |
177 } | 189 } |
178 | 190 |
179 void DataUseTabModel::NotifyObserversOfTrackingEnding(int32_t tab_id) { | 191 void DataUseTabModel::NotifyObserversOfTrackingEnding(int32_t tab_id) { |
180 observer_list_->Notify(FROM_HERE, &TabDataUseObserver::NotifyTrackingEnding, | 192 DCHECK(thread_checker_.CalledOnValidThread()); |
181 tab_id); | 193 DCHECK(ui_task_runner_); |
| 194 for (const auto& it : observers_) { |
| 195 ui_task_runner_->PostTask( |
| 196 FROM_HERE, base::Bind(&TabDataUseObserver::NotifyTrackingEnding, |
| 197 it.second, tab_id)); |
| 198 } |
182 } | 199 } |
183 | 200 |
184 void DataUseTabModel::StartTrackingDataUse(int32_t tab_id, | 201 void DataUseTabModel::StartTrackingDataUse(int32_t tab_id, |
185 const std::string& label) { | 202 const std::string& label) { |
186 // TODO(rajendrant): Explore ability to handle changes in label for current | 203 // TODO(rajendrant): Explore ability to handle changes in label for current |
187 // session. | 204 // session. |
188 bool new_tab_entry_added = false; | 205 bool new_tab_entry_added = false; |
189 TabEntryMap::iterator tab_entry_iterator = active_tabs_.find(tab_id); | 206 TabEntryMap::iterator tab_entry_iterator = active_tabs_.find(tab_id); |
190 if (tab_entry_iterator == active_tabs_.end()) { | 207 if (tab_entry_iterator == active_tabs_.end()) { |
191 auto new_entry = | 208 auto new_entry = |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 kUMAUnexpiredTabEntryRemovalDurationMinutesHistogram, | 272 kUMAUnexpiredTabEntryRemovalDurationMinutesHistogram, |
256 Now() - oldest_tab_entry_iterator->second.GetLatestStartOrEndTime(), | 273 Now() - oldest_tab_entry_iterator->second.GetLatestStartOrEndTime(), |
257 base::TimeDelta::FromMinutes(1), base::TimeDelta::FromHours(1), 50); | 274 base::TimeDelta::FromMinutes(1), base::TimeDelta::FromHours(1), 50); |
258 active_tabs_.erase(oldest_tab_entry_iterator); | 275 active_tabs_.erase(oldest_tab_entry_iterator); |
259 } | 276 } |
260 } | 277 } |
261 | 278 |
262 } // namespace android | 279 } // namespace android |
263 | 280 |
264 } // namespace chrome | 281 } // namespace chrome |
OLD | NEW |