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

Side by Side Diff: chrome/browser/android/data_usage/external_data_use_observer.h

Issue 2145863002: Separate data use reporting logic in ExternalDataUseObserver (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed nits Created 4 years, 5 months 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 #ifndef CHROME_BROWSER_ANDROID_DATA_USAGE_EXTERNAL_DATA_USE_OBSERVER_H_ 5 #ifndef CHROME_BROWSER_ANDROID_DATA_USAGE_EXTERNAL_DATA_USE_OBSERVER_H_
6 #define CHROME_BROWSER_ANDROID_DATA_USAGE_EXTERNAL_DATA_USE_OBSERVER_H_ 6 #define CHROME_BROWSER_ANDROID_DATA_USAGE_EXTERNAL_DATA_USE_OBSERVER_H_
7 7
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <memory>
12 #include <string>
13 #include <vector>
14
15 #include "base/containers/hash_tables.h"
16 #include "base/gtest_prod_util.h" 8 #include "base/gtest_prod_util.h"
17 #include "base/macros.h" 9 #include "base/macros.h"
18 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
19 #include "base/memory/weak_ptr.h" 11 #include "base/memory/weak_ptr.h"
20 #include "base/threading/thread_checker.h" 12 #include "base/threading/thread_checker.h"
21 #include "base/time/time.h" 13 #include "base/time/time.h"
22 #include "chrome/browser/android/data_usage/data_use_tab_model.h"
23 #include "components/data_usage/core/data_use_aggregator.h" 14 #include "components/data_usage/core/data_use_aggregator.h"
24 #include "net/base/network_change_notifier.h"
25
26 #if defined(OS_ANDROID)
27 #include "base/android/application_status_listener.h"
28 #endif
29 15
30 namespace base { 16 namespace base {
31 class SingleThreadTaskRunner; 17 class SingleThreadTaskRunner;
32 } 18 }
33 19
34 namespace data_usage { 20 namespace data_usage {
35 struct DataUse; 21 struct DataUse;
36 } 22 }
37 23
38 namespace chrome { 24 namespace chrome {
39 25
40 namespace android { 26 namespace android {
41 27
28 class DataUseTabModel;
42 class ExternalDataUseObserverBridge; 29 class ExternalDataUseObserverBridge;
30 class ExternalDataUseReporter;
43 31
44 // This class allows platform APIs that are external to Chromium to observe how 32 // This class allows platform APIs that are external to Chromium to observe how
45 // much data is used by Chromium on the current Android device. This class 33 // much data is used by Chromium on the current Android device. This class
46 // registers as a data use observer with DataUseAggregator (as long as there is 34 // registers as a data use observer with DataUseAggregator (as long as there is
47 // at least one valid matching rule is present), filters the received 35 // at least one valid matching rule is present), collects a batch of data
48 // observations by applying the regex matching to the URLs of the requests, and 36 // use observations and passes them to ExternalDataUseReporter for labeling the
49 // notifies the filtered data use to the platform. This class is not thread 37 // data usage and reporting to the platform. This class also fetches the
50 // safe, and must only be accessed on IO thread. 38 // matching rules from external platform APIs, on demand and periodically. This
39 // class is not thread safe, and must only be accessed on IO thread.
51 class ExternalDataUseObserver : public data_usage::DataUseAggregator::Observer { 40 class ExternalDataUseObserver : public data_usage::DataUseAggregator::Observer {
52 public: 41 public:
53 // Result of data usage report submission. This enum must remain synchronized
54 // with the enum of the same name in metrics/histograms/histograms.xml.
55 enum DataUsageReportSubmissionResult {
56 // Submission of data use report to the external observer was successful.
57 DATAUSAGE_REPORT_SUBMISSION_SUCCESSFUL = 0,
58 // Submission of data use report to the external observer returned error.
59 DATAUSAGE_REPORT_SUBMISSION_FAILED = 1,
60 // Submission of data use report to the external observer timed out.
61 DATAUSAGE_REPORT_SUBMISSION_TIMED_OUT = 2,
62 // Data use report was lost before an attempt was made to submit it.
63 DATAUSAGE_REPORT_SUBMISSION_LOST = 3,
64 DATAUSAGE_REPORT_SUBMISSION_MAX = 4
65 };
66
67 // External data use observer field trial name. 42 // External data use observer field trial name.
68 static const char kExternalDataUseObserverFieldTrial[]; 43 static const char kExternalDataUseObserverFieldTrial[];
69 44
70 ExternalDataUseObserver( 45 ExternalDataUseObserver(
71 data_usage::DataUseAggregator* data_use_aggregator, 46 data_usage::DataUseAggregator* data_use_aggregator,
72 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, 47 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
73 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner); 48 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner);
74 ~ExternalDataUseObserver() override; 49 ~ExternalDataUseObserver() override;
75 50
76 // Returns the pointer to the DataUseTabModel object owned by |this|. The 51 // Returns the pointer to the DataUseTabModel object owned by |this|. The
77 // caller does not owns the returned pointer. 52 // caller does not owns the returned pointer.
78 DataUseTabModel* GetDataUseTabModel() const; 53 DataUseTabModel* GetDataUseTabModel() const;
79 54
80 // Called by ExternalDataUseObserverBridge::OnReportDataUseDone when a data
81 // use report has been submitted. |success| is true if the request was
82 // successfully submitted to the external data use observer by Java.
83 void OnReportDataUseDone(bool success);
84
85 // Called by ExternalDataUseObserverBridge. |should_register| is true if 55 // Called by ExternalDataUseObserverBridge. |should_register| is true if
86 // |this| should register as a data use observer. 56 // |this| should register as a data use observer.
87 void ShouldRegisterAsDataUseObserver(bool should_register); 57 void ShouldRegisterAsDataUseObserver(bool should_register);
88 58
89 // Fetches the matching rules asynchronously. 59 // Fetches the matching rules asynchronously.
90 void FetchMatchingRules(); 60 void FetchMatchingRules();
91 61
92 base::WeakPtr<ExternalDataUseObserver> GetWeakPtr(); 62 base::WeakPtr<ExternalDataUseObserver> GetWeakPtr();
93 63
64 // Called by ExternalDataUseObserverBridge::OnReportDataUseDone when a data
65 // use report has been submitted. |success| is true if the request was
66 // successfully submitted to the external data use observer by Java.
67 // TODO(rajendrant): Move this callback to ExternalDataUseReporter. In order
68 // to move this, ExternalDataUseObserverBridge needs to hold a pointer to
69 // ExternalDataUseReporter. This is currently not doable, since this creates
70 // a circular dependency between ExternalDataUseReporter, DataUseTabModel and
71 // ExternalDataUseObserverBridge, which creates issues during desctruction.
72 void OnReportDataUseDone(bool success);
73
74 ExternalDataUseReporter* GetExternalDataUseReporterForTesting() const {
75 return external_data_use_reporter_;
76 }
77
94 private: 78 private:
95 friend class DataUseTabModelTest; 79 friend class DataUseTabModelTest;
96 friend class DataUseUITabModelTest; 80 friend class DataUseUITabModelTest;
97 friend class ExternalDataUseObserverTest; 81 friend class ExternalDataUseObserverTest;
98 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, BufferDataUseReports);
99 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, BufferSize);
100 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, DataUseReportTimedOut);
101 #if defined(OS_ANDROID)
102 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest,
103 DataUseReportingOnApplicationStatusChange);
104 #endif
105 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, HashFunction);
106 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, 82 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest,
107 MatchingRuleFetchOnControlAppInstall); 83 MatchingRuleFetchOnControlAppInstall);
108 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, MultipleMatchingRules);
109 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, 84 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest,
110 PeriodicFetchMatchingRules); 85 PeriodicFetchMatchingRules);
111 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, 86 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest,
112 RegisteredAsDataUseObserver); 87 RegisteredAsDataUseObserver);
113 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, ReportsMergedCorrectly); 88 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, Variations);
114 FRIEND_TEST_ALL_PREFIXES(DataUseUITabModelTest, ReportTabEventsTest); 89 FRIEND_TEST_ALL_PREFIXES(DataUseUITabModelTest, ReportTabEventsTest);
115 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest,
116 TimestampsMergedCorrectly);
117 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, Variations);
118
119 // DataUseReportKey is a unique identifier for a data use report.
120 struct DataUseReportKey {
121 DataUseReportKey(const std::string& label,
122 const std::string& tag,
123 net::NetworkChangeNotifier::ConnectionType connection_type,
124 const std::string& mcc_mnc);
125
126 DataUseReportKey(const DataUseReportKey& other);
127
128 bool operator==(const DataUseReportKey& other) const;
129
130 // Label provided by the matching rules.
131 const std::string label;
132
133 // Tag to report for the data usage.
134 const std::string tag;
135
136 // Type of network used by the request.
137 const net::NetworkChangeNotifier::ConnectionType connection_type;
138
139 // mcc_mnc operator of the provider of the SIM as obtained from
140 // TelephonyManager#getNetworkOperator() Java API in Android.
141 const std::string mcc_mnc;
142 };
143
144 // DataUseReport is paired with a DataUseReportKey object. DataUseReport
145 // contains the bytes send/received during a specific interval. Only the bytes
146 // from the data use reports that have the |label|, |connection_type|, and
147 // |mcc_mnc| specified in the corresponding DataUseReportKey object are
148 // counted in the DataUseReport.
149 struct DataUseReport {
150 // |start_time| and |end_time| are the start and end timestamps (in UTC
151 // since the standard Java epoch of 1970-01-01 00:00:00) of the interval
152 // that this data report covers. |bytes_downloaded| and |bytes_uploaded| are
153 // the total bytes received and send during this interval.
154 DataUseReport(const base::Time& start_time,
155 const base::Time& end_time,
156 int64_t bytes_downloaded,
157 int64_t bytes_uploaded);
158
159 // Start time of |this| data report (in UTC since the standard Java epoch of
160 // 1970-01-01 00:00:00).
161 const base::Time start_time;
162
163 // End time of |this| data report (in UTC since the standard Java epoch of
164 // 1970-01-01 00:00:00)
165 const base::Time end_time;
166
167 // Number of bytes downloaded and uploaded by Chromium from |start_time| to
168 // |end_time|.
169 const int64_t bytes_downloaded;
170 const int64_t bytes_uploaded;
171 };
172
173 // Class that implements hash operator on DataUseReportKey.
174 class DataUseReportKeyHash {
175 public:
176 // A simple heuristical hash function that satisifes the property that two
177 // equal data structures have the same hash value.
178 size_t operator()(const DataUseReportKey& k) const;
179 };
180
181 typedef base::hash_map<DataUseReportKey, DataUseReport, DataUseReportKeyHash>
182 DataUseReports;
183
184 // Maximum buffer size. If an entry needs to be added to the buffer that has
185 // size |kMaxBufferSize|, then the oldest entry will be removed.
186 static const size_t kMaxBufferSize;
187 90
188 // data_usage::DataUseAggregator::Observer implementation: 91 // data_usage::DataUseAggregator::Observer implementation:
189 void OnDataUse(const data_usage::DataUse& data_use) override; 92 void OnDataUse(const data_usage::DataUse& data_use) override;
190 93
191 // Called by DataUseTabModel when tracking info has been retrieved for the
192 // |data_use| object. |tracking_info_valid| is true if |tracking_info| is
193 // populated that applies to the |data_use| object. |tracking_info| is owned
194 // by the caller.
195 void DataUseTrackingInfoRetrieved(
196 const data_usage::DataUse& data_use,
197 const base::Time& start_time,
198 const base::Time& end_time,
199 const DataUseTabModel::TrackingInfo* tracking_info,
200 bool tracking_info_valid);
201
202 // Adds |data_use| to buffered reports. |data_use| is the data use report
203 // received from DataUseAggregator. |label| is a non-empty label that applies
204 // to |data_use|. |tag| is the tag to be applied for this data use.
205 // |start_time| and |end_time| are the start, and end times of the interval
206 // during which bytes reported in |data_use| went over the network.
207 void BufferDataUseReport(const data_usage::DataUse& data_use,
208 const std::string& label,
209 const std::string& tag,
210 const base::Time& start_time,
211 const base::Time& end_time);
212
213 // Submits the first data report among the buffered data reports in
214 // |buffered_data_reports_|. Since an unordered map is used to buffer the
215 // reports, the order of reports may change. The reports are buffered in an
216 // arbitrary order and there are no guarantees that the next report to be
217 // submitted is the oldest one buffered. |immediate| indicates whether to
218 // submit the report immediately or to wait until |data_use_report_min_bytes_|
219 // unreported bytes are buffered.
220 void SubmitBufferedDataUseReport(bool immediate);
221
222 #if defined(OS_ANDROID)
223 // Called whenever the application transitions from foreground to background
224 // or vice versa.
225 void OnApplicationStateChange(base::android::ApplicationState new_state);
226 #endif
227
228 // Aggregator that sends data use observations to |this|. 94 // Aggregator that sends data use observations to |this|.
229 data_usage::DataUseAggregator* data_use_aggregator_; 95 data_usage::DataUseAggregator* data_use_aggregator_;
230 96
231 // |external_data_use_observer_bridge_| is owned by |this|, and interacts with 97 // |external_data_use_observer_bridge_| is owned by |this|, and interacts with
232 // the Java code. It is created on IO thread but afterwards, should only be 98 // the Java code. It is created on IO thread but afterwards, should only be
233 // accessed on UI thread. 99 // accessed on UI thread.
234 ExternalDataUseObserverBridge* external_data_use_observer_bridge_; 100 ExternalDataUseObserverBridge* external_data_use_observer_bridge_;
235 101
236 // Maintains tab sessions and is owned by |this|. It is created on IO thread 102 // Maintains tab sessions and is owned by |this|. It is created on IO thread
237 // but afterwards, should only be accessed on UI thread. 103 // but afterwards, should only be accessed on UI thread.
238 DataUseTabModel* data_use_tab_model_; 104 DataUseTabModel* data_use_tab_model_;
239 105
240 // Time when the currently pending data use report was submitted. 106 // Labels, buffers and reports the data usage. It is owned by |this|. It is
241 // |last_data_report_submitted_ticks_| is null if no data use report is 107 // created on IO thread but afterwards, should only be accessed on UI thread.
242 // currently pending. 108 ExternalDataUseReporter* external_data_use_reporter_;
243 base::TimeTicks last_data_report_submitted_ticks_;
244
245 // |pending_report_bytes_| is the total byte count in the data use report that
246 // is currently pending.
247 int64_t pending_report_bytes_;
248
249 // Buffered data reports that need to be submitted to the
250 // |external_data_use_observer_bridge_|.
251 DataUseReports buffered_data_reports_;
252 109
253 // |ui_task_runner_| is used to call methods on UI thread. 110 // |ui_task_runner_| is used to call methods on UI thread.
254 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; 111 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
255 112
256 // Time when the data use reports were last received from DataUseAggregator.
257 base::Time previous_report_time_;
258
259 // Time when the matching rules were last fetched. 113 // Time when the matching rules were last fetched.
260 base::TimeTicks last_matching_rules_fetch_time_; 114 base::TimeTicks last_matching_rules_fetch_time_;
261 115
262 // Total number of bytes transmitted or received across all the buffered
263 // reports.
264 int64_t total_bytes_buffered_;
265
266 // Duration after which matching rules are periodically fetched. 116 // Duration after which matching rules are periodically fetched.
267 const base::TimeDelta fetch_matching_rules_duration_; 117 const base::TimeDelta fetch_matching_rules_duration_;
268 118
269 // Minimum number of bytes that should be buffered before a data use report is
270 // submitted.
271 const int64_t data_use_report_min_bytes_;
272
273 // If a data use report is pending for more than |data_report_submit_timeout_|
274 // duration, it is considered as timed out.
275 const base::TimeDelta data_report_submit_timeout_;
276
277 #if defined(OS_ANDROID)
278 // Listens to when Chromium gets backgrounded and submits buffered data use
279 // reports.
280 std::unique_ptr<base::android::ApplicationStatusListener> app_state_listener_;
281 #endif
282
283 // True if |this| is currently registered as a data use observer. 119 // True if |this| is currently registered as a data use observer.
284 bool registered_as_data_use_observer_; 120 bool registered_as_data_use_observer_;
285 121
286 base::ThreadChecker thread_checker_; 122 base::ThreadChecker thread_checker_;
287 123
288 base::WeakPtrFactory<ExternalDataUseObserver> weak_factory_; 124 base::WeakPtrFactory<ExternalDataUseObserver> weak_factory_;
289 125
290 DISALLOW_COPY_AND_ASSIGN(ExternalDataUseObserver); 126 DISALLOW_COPY_AND_ASSIGN(ExternalDataUseObserver);
291 }; 127 };
292 128
293 } // namespace android 129 } // namespace android
294 130
295 } // namespace chrome 131 } // namespace chrome
296 132
297 #endif // CHROME_BROWSER_ANDROID_DATA_USAGE_EXTERNAL_DATA_USE_OBSERVER_H_ 133 #endif // CHROME_BROWSER_ANDROID_DATA_USAGE_EXTERNAL_DATA_USE_OBSERVER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698