OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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_REPORTER_H_ |
6 #define CHROME_BROWSER_ANDROID_DATA_USAGE_EXTERNAL_DATA_USE_OBSERVER_H_ | 6 #define CHROME_BROWSER_ANDROID_DATA_USAGE_EXTERNAL_DATA_USE_REPORTER_H_ |
7 | 7 |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
11 #include <memory> | 11 #include <memory> |
12 #include <string> | 12 #include <string> |
13 #include <vector> | |
14 | 13 |
15 #include "base/containers/hash_tables.h" | 14 #include "base/containers/hash_tables.h" |
16 #include "base/gtest_prod_util.h" | |
17 #include "base/macros.h" | 15 #include "base/macros.h" |
18 #include "base/memory/ref_counted.h" | |
19 #include "base/memory/weak_ptr.h" | |
20 #include "base/threading/thread_checker.h" | 16 #include "base/threading/thread_checker.h" |
21 #include "base/time/time.h" | 17 #include "base/time/time.h" |
22 #include "chrome/browser/android/data_usage/data_use_tab_model.h" | 18 #include "chrome/browser/android/data_usage/data_use_tab_model.h" |
tbansal1
2016/07/15 16:26:30
You should only need to forward declare this, and
Raj
2016/07/15 18:54:41
Done.
| |
23 #include "components/data_usage/core/data_use_aggregator.h" | |
24 #include "net/base/network_change_notifier.h" | 19 #include "net/base/network_change_notifier.h" |
25 | 20 |
26 #if defined(OS_ANDROID) | 21 #if defined(OS_ANDROID) |
27 #include "base/android/application_status_listener.h" | 22 #include "base/android/application_status_listener.h" |
28 #endif | 23 #endif |
29 | 24 |
30 namespace base { | |
31 class SingleThreadTaskRunner; | |
32 } | |
33 | |
34 namespace data_usage { | 25 namespace data_usage { |
35 struct DataUse; | 26 struct DataUse; |
36 } | 27 } |
37 | 28 |
38 namespace chrome { | 29 namespace chrome { |
39 | 30 |
40 namespace android { | 31 namespace android { |
41 | 32 |
42 class ExternalDataUseObserverBridge; | 33 class ExternalDataUseObserverBridge; |
43 | 34 |
44 // This class allows platform APIs that are external to Chromium to observe how | 35 // This class receives data use observations from ExternalDataUseObserver, |
45 // much data is used by Chromium on the current Android device. This class | 36 // labels the data use using DataUseTabModel, and buffers the data use report. |
46 // registers as a data use observer with DataUseAggregator (as long as there is | 37 // The buffered reports are submitted to the platform when a minimum number of |
47 // at least one valid matching rule is present), filters the received | 38 // data usage bytes is reached, or when Chromium goes into background, or when |
48 // observations by applying the regex matching to the URLs of the requests, and | 39 // the previous report submission times out. This class is not thread safe, and |
49 // notifies the filtered data use to the platform. This class is not thread | 40 // must only be accessed on UI thread. |
50 // safe, and must only be accessed on IO thread. | 41 class ExternalDataUseReporter { |
51 class ExternalDataUseObserver : public data_usage::DataUseAggregator::Observer { | |
52 public: | 42 public: |
53 // Result of data usage report submission. This enum must remain synchronized | 43 // Result of data usage report submission. This enum must remain synchronized |
54 // with the enum of the same name in metrics/histograms/histograms.xml. | 44 // with the enum of the same name in metrics/histograms/histograms.xml. |
55 enum DataUsageReportSubmissionResult { | 45 enum DataUsageReportSubmissionResult { |
56 // Submission of data use report to the external observer was successful. | 46 // Submission of data use report to the external observer was successful. |
57 DATAUSAGE_REPORT_SUBMISSION_SUCCESSFUL = 0, | 47 DATAUSAGE_REPORT_SUBMISSION_SUCCESSFUL = 0, |
58 // Submission of data use report to the external observer returned error. | 48 // Submission of data use report to the external observer returned error. |
59 DATAUSAGE_REPORT_SUBMISSION_FAILED = 1, | 49 DATAUSAGE_REPORT_SUBMISSION_FAILED = 1, |
60 // Submission of data use report to the external observer timed out. | 50 // Submission of data use report to the external observer timed out. |
61 DATAUSAGE_REPORT_SUBMISSION_TIMED_OUT = 2, | 51 DATAUSAGE_REPORT_SUBMISSION_TIMED_OUT = 2, |
62 // Data use report was lost before an attempt was made to submit it. | 52 // Data use report was lost before an attempt was made to submit it. |
63 DATAUSAGE_REPORT_SUBMISSION_LOST = 3, | 53 DATAUSAGE_REPORT_SUBMISSION_LOST = 3, |
64 DATAUSAGE_REPORT_SUBMISSION_MAX = 4 | 54 DATAUSAGE_REPORT_SUBMISSION_MAX = 4 |
65 }; | 55 }; |
66 | 56 |
67 // External data use observer field trial name. | 57 // The caller should guarantee that |data_use_tab_model| and |
68 static const char kExternalDataUseObserverFieldTrial[]; | 58 // |external_data_use_observer_bridge| to be non-null during the lifetime of |
59 // |this|. | |
60 ExternalDataUseReporter( | |
61 DataUseTabModel* data_use_tab_model, | |
62 ExternalDataUseObserverBridge* external_data_use_observer_bridge); | |
63 virtual ~ExternalDataUseReporter(); | |
69 | 64 |
70 ExternalDataUseObserver( | 65 // Notifies the ExternalDataUseReporter of data usage. The data use is |
71 data_usage::DataUseAggregator* data_use_aggregator, | 66 // labeled using |data_use_tab_model_|, buffered and then reported to |
72 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, | 67 // |external_data_use_observer_bridge_| later. |
73 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner); | 68 void OnDataUse(const data_usage::DataUse& data_use); |
74 ~ExternalDataUseObserver() override; | |
75 | 69 |
76 // Returns the pointer to the DataUseTabModel object owned by |this|. The | |
77 // caller does not owns the returned pointer. | |
78 DataUseTabModel* GetDataUseTabModel() const; | |
79 | |
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); | 70 void OnReportDataUseDone(bool success); |
84 | 71 |
85 // Called by ExternalDataUseObserverBridge. |should_register| is true if | |
86 // |this| should register as a data use observer. | |
87 void ShouldRegisterAsDataUseObserver(bool should_register); | |
88 | |
89 // Fetches the matching rules asynchronously. | |
90 void FetchMatchingRules(); | |
91 | |
92 base::WeakPtr<ExternalDataUseObserver> GetWeakPtr(); | |
93 | |
94 private: | 72 private: |
95 friend class DataUseTabModelTest; | 73 friend class ExternalDataUseReporterTest; |
96 friend class DataUseUITabModelTest; | 74 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, Variations); |
tbansal1
2016/07/15 16:26:30
Can the relevant part of the unittest be moved to
Raj
2016/07/15 18:54:41
Done.
| |
97 friend class ExternalDataUseObserverTest; | 75 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseReporterTest, BufferDataUseReports); |
98 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, BufferDataUseReports); | 76 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseReporterTest, BufferSize); |
99 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, BufferSize); | 77 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseReporterTest, DataUseReportTimedOut); |
100 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, DataUseReportTimedOut); | |
101 #if defined(OS_ANDROID) | 78 #if defined(OS_ANDROID) |
102 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, | 79 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseReporterTest, |
103 DataUseReportingOnApplicationStatusChange); | 80 DataUseReportingOnApplicationStatusChange); |
104 #endif | 81 #endif |
105 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, HashFunction); | 82 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseReporterTest, HashFunction); |
106 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, | 83 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseReporterTest, |
107 MatchingRuleFetchOnControlAppInstall); | 84 MatchingRuleFetchOnControlAppInstall); |
108 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, MultipleMatchingRules); | 85 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseReporterTest, ReportsMergedCorrectly); |
109 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, | 86 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseReporterTest, |
110 PeriodicFetchMatchingRules); | |
111 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, | |
112 RegisteredAsDataUseObserver); | |
113 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, ReportsMergedCorrectly); | |
114 FRIEND_TEST_ALL_PREFIXES(DataUseUITabModelTest, ReportTabEventsTest); | |
115 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, | |
116 TimestampsMergedCorrectly); | 87 TimestampsMergedCorrectly); |
117 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, Variations); | 88 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseReporterTest, MultipleMatchingRules); |
118 | 89 |
119 // DataUseReportKey is a unique identifier for a data use report. | 90 // DataUseReportKey is a unique identifier for a data use report. |
120 struct DataUseReportKey { | 91 struct DataUseReportKey { |
121 DataUseReportKey(const std::string& label, | 92 DataUseReportKey(const std::string& label, |
122 const std::string& tag, | 93 const std::string& tag, |
123 net::NetworkChangeNotifier::ConnectionType connection_type, | 94 net::NetworkChangeNotifier::ConnectionType connection_type, |
124 const std::string& mcc_mnc); | 95 const std::string& mcc_mnc); |
125 | 96 |
126 DataUseReportKey(const DataUseReportKey& other); | 97 DataUseReportKey(const DataUseReportKey& other); |
127 | 98 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
174 class DataUseReportKeyHash { | 145 class DataUseReportKeyHash { |
175 public: | 146 public: |
176 // A simple heuristical hash function that satisifes the property that two | 147 // A simple heuristical hash function that satisifes the property that two |
177 // equal data structures have the same hash value. | 148 // equal data structures have the same hash value. |
178 size_t operator()(const DataUseReportKey& k) const; | 149 size_t operator()(const DataUseReportKey& k) const; |
179 }; | 150 }; |
180 | 151 |
181 typedef base::hash_map<DataUseReportKey, DataUseReport, DataUseReportKeyHash> | 152 typedef base::hash_map<DataUseReportKey, DataUseReport, DataUseReportKeyHash> |
182 DataUseReports; | 153 DataUseReports; |
183 | 154 |
184 // Maximum buffer size. If an entry needs to be added to the buffer that has | 155 // Maximum size of the data use report buffer. Once this limit is reached, new |
185 // size |kMaxBufferSize|, then the oldest entry will be removed. | 156 // reports will be ignored. |
157 // TODO(rajendrant): Instead of the ignoring the new data use report, remove | |
158 // the oldest report entry. | |
186 static const size_t kMaxBufferSize; | 159 static const size_t kMaxBufferSize; |
187 | 160 |
188 // data_usage::DataUseAggregator::Observer implementation: | 161 // Adds |data_use| to buffered reports. |data_use| is the received data use |
189 void OnDataUse(const data_usage::DataUse& data_use) override; | 162 // report. |label| is a non-empty label that applies to |data_use|. |tag| is |
190 | 163 // the tag to be applied for this data use. |start_time| and |end_time| are |
191 // Called by DataUseTabModel when tracking info has been retrieved for the | 164 // the start, and end times of the interval during which bytes reported in |
192 // |data_use| object. |tracking_info_valid| is true if |tracking_info| is | 165 // |data_use| went over the network. |
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, | 166 void BufferDataUseReport(const data_usage::DataUse& data_use, |
208 const std::string& label, | 167 const std::string& label, |
209 const std::string& tag, | 168 const std::string& tag, |
210 const base::Time& start_time, | 169 const base::Time& start_time, |
211 const base::Time& end_time); | 170 const base::Time& end_time); |
212 | 171 |
213 // Submits the first data report among the buffered data reports in | 172 // Submits the first data report among the buffered data reports in |
214 // |buffered_data_reports_|. Since an unordered map is used to buffer the | 173 // |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 | 174 // 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 | 175 // arbitrary order and there are no guarantees that the next report to be |
217 // submitted is the oldest one buffered. |immediate| indicates whether to | 176 // submitted is the oldest one buffered. |immediate| indicates whether to |
218 // submit the report immediately or to wait until |data_use_report_min_bytes_| | 177 // submit the report immediately or to wait until |data_use_report_min_bytes_| |
219 // unreported bytes are buffered. | 178 // unreported bytes are buffered. |
220 void SubmitBufferedDataUseReport(bool immediate); | 179 void SubmitBufferedDataUseReport(bool immediate); |
221 | 180 |
222 #if defined(OS_ANDROID) | 181 #if defined(OS_ANDROID) |
223 // Called whenever the application transitions from foreground to background | 182 // Called whenever the application transitions from foreground to background |
224 // or vice versa. | 183 // or vice versa. |
225 void OnApplicationStateChange(base::android::ApplicationState new_state); | 184 void OnApplicationStateChange(base::android::ApplicationState new_state); |
226 #endif | 185 #endif |
227 | 186 |
228 // Aggregator that sends data use observations to |this|. | 187 // Pointer to the ExternalDataUseObserverBridge in UI thread. Not owned by |
229 data_usage::DataUseAggregator* data_use_aggregator_; | 188 // |this|. |
230 | |
231 // |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 | |
233 // accessed on UI thread. | |
234 ExternalDataUseObserverBridge* external_data_use_observer_bridge_; | 189 ExternalDataUseObserverBridge* external_data_use_observer_bridge_; |
235 | 190 |
236 // Maintains tab sessions and is owned by |this|. It is created on IO thread | 191 // Pointer to the DataUseTabModel in UI thread, Not owned by |this|. |
237 // but afterwards, should only be accessed on UI thread. | |
238 DataUseTabModel* data_use_tab_model_; | 192 DataUseTabModel* data_use_tab_model_; |
239 | 193 |
194 #if defined(OS_ANDROID) | |
195 // Listens to when Chromium gets backgrounded and submits buffered data use | |
196 // reports. | |
197 std::unique_ptr<base::android::ApplicationStatusListener> app_state_listener_; | |
198 #endif | |
199 | |
240 // Time when the currently pending data use report was submitted. | 200 // Time when the currently pending data use report was submitted. |
241 // |last_data_report_submitted_ticks_| is null if no data use report is | 201 // |last_data_report_submitted_ticks_| is null if no data use report is |
242 // currently pending. | 202 // currently pending. |
243 base::TimeTicks last_data_report_submitted_ticks_; | 203 base::TimeTicks last_data_report_submitted_ticks_; |
244 | 204 |
245 // |pending_report_bytes_| is the total byte count in the data use report that | 205 // |pending_report_bytes_| is the total byte count in the data use report that |
246 // is currently pending. | 206 // is currently pending. |
247 int64_t pending_report_bytes_; | 207 int64_t pending_report_bytes_; |
248 | 208 |
209 // Time when the data use reports were last received. | |
210 base::Time previous_report_time_; | |
211 | |
212 // Total number of bytes transmitted or received across all the buffered | |
213 // reports. | |
214 int64_t total_bytes_buffered_; | |
215 | |
249 // Buffered data reports that need to be submitted to the | 216 // Buffered data reports that need to be submitted to the |
250 // |external_data_use_observer_bridge_|. | 217 // |external_data_use_observer_bridge_|. |
251 DataUseReports buffered_data_reports_; | 218 DataUseReports buffered_data_reports_; |
252 | 219 |
253 // |ui_task_runner_| is used to call methods on UI thread. | |
254 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; | |
255 | |
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. | |
260 base::TimeTicks last_matching_rules_fetch_time_; | |
261 | |
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. | |
267 const base::TimeDelta fetch_matching_rules_duration_; | |
268 | |
269 // Minimum number of bytes that should be buffered before a data use report is | 220 // Minimum number of bytes that should be buffered before a data use report is |
270 // submitted. | 221 // submitted. |
271 const int64_t data_use_report_min_bytes_; | 222 const int64_t data_use_report_min_bytes_; |
272 | 223 |
273 // If a data use report is pending for more than |data_report_submit_timeout_| | 224 // If a data use report is pending for more than |data_report_submit_timeout_| |
274 // duration, it is considered as timed out. | 225 // duration, it is considered as timed out. |
275 const base::TimeDelta data_report_submit_timeout_; | 226 const base::TimeDelta data_report_submit_timeout_; |
276 | 227 |
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. | |
284 bool registered_as_data_use_observer_; | |
285 | |
286 base::ThreadChecker thread_checker_; | 228 base::ThreadChecker thread_checker_; |
287 | 229 |
288 base::WeakPtrFactory<ExternalDataUseObserver> weak_factory_; | 230 DISALLOW_COPY_AND_ASSIGN(ExternalDataUseReporter); |
289 | |
290 DISALLOW_COPY_AND_ASSIGN(ExternalDataUseObserver); | |
291 }; | 231 }; |
292 | 232 |
293 } // namespace android | 233 } // namespace android |
294 | 234 |
295 } // namespace chrome | 235 } // namespace chrome |
296 | 236 |
297 #endif // CHROME_BROWSER_ANDROID_DATA_USAGE_EXTERNAL_DATA_USE_OBSERVER_H_ | 237 #endif // CHROME_BROWSER_ANDROID_DATA_USAGE_EXTERNAL_DATA_USE_REPORTER_H_ |
OLD | NEW |