Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(197)

Side by Side Diff: chrome/browser/android/data_usage/data_use_tab_model.cc

Issue 1443683002: Notify DataUseTabModel of navigations and tab closures (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed bengr comments Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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";
22 const char kUMAExpiredActiveTabEntryRemovalDurationHoursHistogram[] = 24 const char kUMAExpiredActiveTabEntryRemovalDurationHoursHistogram[] =
23 "DataUse.TabModel.ExpiredActiveTabEntryRemovalDuration"; 25 "DataUse.TabModel.ExpiredActiveTabEntryRemovalDuration";
24 const char kUMAUnexpiredTabEntryRemovalDurationMinutesHistogram[] = 26 const char kUMAUnexpiredTabEntryRemovalDurationMinutesHistogram[] =
25 "DataUse.TabModel.UnexpiredTabEntryRemovalDuration"; 27 "DataUse.TabModel.UnexpiredTabEntryRemovalDuration";
26 28
27 // Returns true if |tab_id| is a valid tab ID. 29 // Returns true if |tab_id| is a valid tab ID.
28 bool IsValidTabID(int32_t tab_id) { 30 bool IsValidTabID(int32_t tab_id) {
sclittle 2015/11/23 23:06:16 nit: either use SessionID::id_type everywhere, or
tbansal1 2015/11/24 00:42:02 Done.
29 return tab_id >= 0; 31 return tab_id >= 0;
30 } 32 }
31 33
32 // Returns various parameters from the values specified in the field trial. 34 // Returns various parameters from the values specified in the field trial.
33 size_t GetMaxTabEntries() { 35 size_t GetMaxTabEntries() {
34 size_t max_tab_entries = -1; 36 size_t max_tab_entries = -1;
35 std::string variation_value = variations::GetVariationParamValue( 37 std::string variation_value = variations::GetVariationParamValue(
36 chrome::android::ExternalDataUseObserver:: 38 chrome::android::ExternalDataUseObserver::
37 kExternalDataUseObserverFieldTrial, 39 kExternalDataUseObserverFieldTrial,
38 "max_tab_entries"); 40 "max_tab_entries");
39 if (!variation_value.empty() && 41 if (!variation_value.empty() &&
40 base::StringToSizeT(variation_value, &max_tab_entries)) { 42 base::StringToSizeT(variation_value, &max_tab_entries)) {
41 return max_tab_entries; 43 return max_tab_entries;
42 } 44 }
43 return kDefaultMaxTabEntries; 45 return kDefaultMaxTabEntries;
44 } 46 }
45 47
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(SessionID::id_type 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
121 void DataUseTabModel::OnTabCloseEvent(int32_t tab_id) { 123 void DataUseTabModel::OnTabCloseEvent(SessionID::id_type tab_id) {
122 DCHECK(thread_checker_.CalledOnValidThread()); 124 DCHECK(thread_checker_.CalledOnValidThread());
123 DCHECK(IsValidTabID(tab_id)); 125 DCHECK(IsValidTabID(tab_id));
124 126
125 TabEntryMap::iterator tab_entry_iterator = active_tabs_.find(tab_id); 127 TabEntryMap::iterator tab_entry_iterator = active_tabs_.find(tab_id);
126 if (tab_entry_iterator == active_tabs_.end()) 128 if (tab_entry_iterator == active_tabs_.end())
127 return; 129 return;
128 130
129 TabDataUseEntry& tab_entry = tab_entry_iterator->second; 131 TabDataUseEntry& tab_entry = tab_entry_iterator->second;
130 if (tab_entry.IsTrackingDataUse()) 132 if (tab_entry.IsTrackingDataUse())
131 tab_entry.EndTracking(); 133 tab_entry.EndTracking();
(...skipping 20 matching lines...) Expand all
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(
175 observer_list_->Notify(FROM_HERE, &TabDataUseObserver::NotifyTrackingStarting, 182 SessionID::id_type tab_id) {
176 tab_id); 183 DCHECK(thread_checker_.CalledOnValidThread());
184 DCHECK(ui_task_runner_);
185 for (const auto& it : observers_) {
186 ui_task_runner_->PostTask(
187 FROM_HERE, base::Bind(&TabDataUseObserver::NotifyTrackingStarting,
188 it.second, tab_id));
189 }
177 } 190 }
178 191
179 void DataUseTabModel::NotifyObserversOfTrackingEnding(int32_t tab_id) { 192 void DataUseTabModel::NotifyObserversOfTrackingEnding(
180 observer_list_->Notify(FROM_HERE, &TabDataUseObserver::NotifyTrackingEnding, 193 SessionID::id_type tab_id) {
181 tab_id); 194 DCHECK(thread_checker_.CalledOnValidThread());
195 DCHECK(ui_task_runner_);
196 for (const auto& it : observers_) {
197 ui_task_runner_->PostTask(
198 FROM_HERE, base::Bind(&TabDataUseObserver::NotifyTrackingEnding,
199 it.second, tab_id));
200 }
182 } 201 }
183 202
184 void DataUseTabModel::StartTrackingDataUse(int32_t tab_id, 203 void DataUseTabModel::StartTrackingDataUse(SessionID::id_type tab_id,
185 const std::string& label) { 204 const std::string& label) {
186 // TODO(rajendrant): Explore ability to handle changes in label for current 205 // TODO(rajendrant): Explore ability to handle changes in label for current
187 // session. 206 // session.
188 bool new_tab_entry_added = false; 207 bool new_tab_entry_added = false;
189 TabEntryMap::iterator tab_entry_iterator = active_tabs_.find(tab_id); 208 TabEntryMap::iterator tab_entry_iterator = active_tabs_.find(tab_id);
190 if (tab_entry_iterator == active_tabs_.end()) { 209 if (tab_entry_iterator == active_tabs_.end()) {
191 auto new_entry = 210 auto new_entry =
192 active_tabs_.insert(TabEntryMap::value_type(tab_id, TabDataUseEntry())); 211 active_tabs_.insert(TabEntryMap::value_type(tab_id, TabDataUseEntry()));
193 tab_entry_iterator = new_entry.first; 212 tab_entry_iterator = new_entry.first;
194 DCHECK(tab_entry_iterator != active_tabs_.end()); 213 DCHECK(tab_entry_iterator != active_tabs_.end());
195 DCHECK(!tab_entry_iterator->second.IsTrackingDataUse()); 214 DCHECK(!tab_entry_iterator->second.IsTrackingDataUse());
196 new_tab_entry_added = true; 215 new_tab_entry_added = true;
197 } 216 }
198 if (tab_entry_iterator->second.StartTracking(label)) 217 if (tab_entry_iterator->second.StartTracking(label))
199 NotifyObserversOfTrackingStarting(tab_id); 218 NotifyObserversOfTrackingStarting(tab_id);
200 219
201 if (new_tab_entry_added) 220 if (new_tab_entry_added)
202 CompactTabEntries(); // Keep total number of tab entries within limit. 221 CompactTabEntries(); // Keep total number of tab entries within limit.
203 } 222 }
204 223
205 void DataUseTabModel::EndTrackingDataUse(int32_t tab_id) { 224 void DataUseTabModel::EndTrackingDataUse(SessionID::id_type tab_id) {
206 TabEntryMap::iterator tab_entry_iterator = active_tabs_.find(tab_id); 225 TabEntryMap::iterator tab_entry_iterator = active_tabs_.find(tab_id);
207 if (tab_entry_iterator != active_tabs_.end() && 226 if (tab_entry_iterator != active_tabs_.end() &&
208 tab_entry_iterator->second.EndTracking()) { 227 tab_entry_iterator->second.EndTracking()) {
209 NotifyObserversOfTrackingEnding(tab_id); 228 NotifyObserversOfTrackingEnding(tab_id);
210 } 229 }
211 } 230 }
212 231
213 void DataUseTabModel::CompactTabEntries() { 232 void DataUseTabModel::CompactTabEntries() {
214 // Remove expired tab entries. 233 // Remove expired tab entries.
215 for (TabEntryMap::iterator tab_entry_iterator = active_tabs_.begin(); 234 for (TabEntryMap::iterator tab_entry_iterator = active_tabs_.begin();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 kUMAUnexpiredTabEntryRemovalDurationMinutesHistogram, 274 kUMAUnexpiredTabEntryRemovalDurationMinutesHistogram,
256 Now() - oldest_tab_entry_iterator->second.GetLatestStartOrEndTime(), 275 Now() - oldest_tab_entry_iterator->second.GetLatestStartOrEndTime(),
257 base::TimeDelta::FromMinutes(1), base::TimeDelta::FromHours(1), 50); 276 base::TimeDelta::FromMinutes(1), base::TimeDelta::FromHours(1), 50);
258 active_tabs_.erase(oldest_tab_entry_iterator); 277 active_tabs_.erase(oldest_tab_entry_iterator);
259 } 278 }
260 } 279 }
261 280
262 } // namespace android 281 } // namespace android
263 282
264 } // namespace chrome 283 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698