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

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

Issue 1406003005: Rename chrome/browser/android/datausage to data_usage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #ifndef CHROME_BROWSER_ANDROID_DATAUSAGE_EXTERNAL_DATA_USE_OBSERVER_H_
6 #define CHROME_BROWSER_ANDROID_DATAUSAGE_EXTERNAL_DATA_USE_OBSERVER_H_
7
8 #include <jni.h>
9 #include <stdint.h>
10
11 #include <string>
12 #include <unordered_map>
13 #include <vector>
14
15 #include "base/android/jni_array.h"
16 #include "base/android/scoped_java_ref.h"
17 #include "base/gtest_prod_util.h"
18 #include "base/macros.h"
19 #include "base/memory/ref_counted.h"
20 #include "base/memory/scoped_vector.h"
21 #include "base/memory/weak_ptr.h"
22 #include "base/single_thread_task_runner.h"
23 #include "base/thread_task_runner_handle.h"
24 #include "base/threading/thread_checker.h"
25 #include "base/time/time.h"
26 #include "components/data_usage/core/data_use_aggregator.h"
27 #include "net/base/network_change_notifier.h"
28
29 class GURL;
30
31 namespace data_usage {
32 struct DataUse;
33 }
34
35 namespace re2 {
36 class RE2;
37 }
38
39 namespace chrome {
40
41 namespace android {
42
43 // This class allows platform APIs that are external to Chromium to observe how
44 // much data is used by Chromium on the current Android device. It creates and
45 // owns a Java listener object that is notified of the data usage observations
46 // of Chromium. This class receives regular expressions from the Java listener
47 // object. It also registers as a data use observer with DataUseAggregator,
48 // filters the received observations by applying the regex matching to the URLs
49 // of the requests, and notifies the filtered data use to the Java listener. The
50 // Java object in turn may notify the platform APIs of the data usage
51 // observations.
52 // TODO(tbansal): Create an inner class that manages the UI and IO threads.
53 class ExternalDataUseObserver : public data_usage::DataUseAggregator::Observer {
54 public:
55 ExternalDataUseObserver(
56 data_usage::DataUseAggregator* data_use_aggregator,
57 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
58 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner);
59 ~ExternalDataUseObserver() override;
60
61 // Called by Java when new matching rules have been fetched. This may be
62 // called on a different thread. |app_package_name| is the package name of
63 // the app that should be matched. |domain_path_regex| is the regex to be used
64 // for matching URLs. |label| is the label that must be applied to data
65 // reports corresponding to the matching rule, and must
66 // uniquely identify the matching rule. Each element in |label| must have
67 // non-zero length. The three vectors should have equal length. The vectors
68 // may be empty which implies that no matching rules are active. Must be
69 // called on UI thread.
70 void FetchMatchingRulesCallback(
71 JNIEnv* env,
72 jobject obj,
73 const base::android::JavaParamRef<jobjectArray>& app_package_name,
74 const base::android::JavaParamRef<jobjectArray>& domain_path_regex,
75 const base::android::JavaParamRef<jobjectArray>& label);
76
77 // Called by Java when the reporting of data usage has finished. This may be
78 // called on a different thread. |success| is true if the request was
79 // successfully submitted to the external data use observer by Java. Must be
80 // called on UI thread.
81 void OnReportDataUseDone(JNIEnv* env, jobject obj, bool success);
82
83 private:
84 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, SingleRegex);
85 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, TwoRegex);
86 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, MultipleRegex);
87 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, ChangeRegex);
88 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest,
89 AtMostOneDataUseSubmitRequest);
90 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, MultipleMatchingRules);
91 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, ReportsMergedCorrectly);
92 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest,
93 TimestampsMergedCorrectly);
94 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, HashFunction);
95 FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, BufferSize);
96
97 // DataUseReportKey is a unique identifier for a data use report.
98 struct DataUseReportKey {
99 DataUseReportKey(const std::string& label,
100 net::NetworkChangeNotifier::ConnectionType connection_type,
101 const std::string& mcc_mnc)
102 : label(label), connection_type(connection_type), mcc_mnc(mcc_mnc) {}
103
104 DataUseReportKey(const DataUseReportKey& other)
105 : label(other.label),
106 connection_type(other.connection_type),
107 mcc_mnc(other.mcc_mnc) {}
108
109 bool operator==(const DataUseReportKey& other) const {
110 return (label == other.label &&
111 connection_type == other.connection_type &&
112 mcc_mnc == other.mcc_mnc);
113 }
114
115 virtual ~DataUseReportKey() {}
116
117 // Label provided by the matching rules.
118 const std::string label;
119
120 // Type of network used by the request.
121 const net::NetworkChangeNotifier::ConnectionType connection_type;
122
123 // mcc_mnc operator of the provider of the SIM as obtained from
124 // TelephonyManager#getNetworkOperator() Java API in Android.
125 const std::string mcc_mnc;
126 };
127
128 // DataUseReport is paired with a DataUseReportKey object. DataUseReport
129 // contains the bytes send/received during a specific interval. Only the bytes
130 // from the data use reports that have the |label|, |connection_type|, and
131 // |mcc_mnc| specified in the corresponding DataUseReportKey object are
132 // counted in the DataUseReport.
133 struct DataUseReport {
134 // |start_time| and |end_time| are the start and end timestamps (in UTC
135 // since the standard Java epoch of 1970-01-01 00:00:00) of the interval
136 // that this data report covers. |bytes_downloaded| and |bytes_uploaded| are
137 // the total bytes received and send during this interval.
138 DataUseReport(const base::Time& start_time,
139 const base::Time& end_time,
140 int64_t bytes_downloaded,
141 int64_t bytes_uploaded)
142 : start_time(start_time),
143 end_time(end_time),
144 bytes_downloaded(bytes_downloaded),
145 bytes_uploaded(bytes_uploaded) {}
146
147 virtual ~DataUseReport() {}
148
149 // Start time of |this| data report (in UTC since the standard Java epoch of
150 // 1970-01-01 00:00:00).
151 const base::Time start_time;
152
153 // End time of |this| data report (in UTC since the standard Java epoch of
154 // 1970-01-01 00:00:00)
155 const base::Time end_time;
156
157 // Number of bytes downloaded and uploaded by Chromium from |start_time| to
158 // |end_time|.
159 const int64_t bytes_downloaded;
160 const int64_t bytes_uploaded;
161 };
162
163 // Class that implements hash operator on DataUseReportKey.
164 class DataUseReportKeyHash {
165 public:
166 // A simple heuristical hash function that satisifes the property that two
167 // equal data structures have the same hash value. The hash is computed by
168 // hashing individual variables and combining them using prime numbers.
169 // Prime numbers are used for multiplication because the number of buckets
170 // used by map is always an even number. Using a prime number ensures that
171 // for two different DataUseReportKey objects (say |j| and |k|), if the
172 // hash value of |k.label| is equal to hash value of |j.mcc_mnc|, then |j|
173 // and |k| map to different buckets. Large prime numbers are used so that
174 // hash value is spread over a larger range.
175 size_t operator()(const DataUseReportKey& k) const {
176 std::hash<std::string> hash_function;
177 size_t hash = 1;
178 hash = hash * 23 + hash_function(k.label);
179 hash = hash * 43 + k.connection_type;
180 hash = hash * 83 + hash_function(k.mcc_mnc);
181 return hash;
182 }
183 };
184
185 typedef std::unordered_map<DataUseReportKey,
186 DataUseReport,
187 DataUseReportKeyHash> DataUseReports;
188
189 // Stores the matching rules.
190 class MatchingRule {
191 public:
192 MatchingRule(const std::string& app_package_name,
193 scoped_ptr<re2::RE2> pattern,
194 const std::string& label);
195 ~MatchingRule();
196
197 const re2::RE2* pattern() const;
198 const std::string& label() const;
199
200 private:
201 // Package name of the app that should be matched.
202 const std::string app_package_name_;
203
204 // RE2 pattern to match against URLs.
205 scoped_ptr<re2::RE2> pattern_;
206
207 // Opaque label that uniquely identifies this matching rule.
208 const std::string label_;
209
210 DISALLOW_COPY_AND_ASSIGN(MatchingRule);
211 };
212
213 // Maximum buffer size. If an entry needs to be added to the buffer that has
214 // size |kMaxBufferSize|, then the oldest entry will be removed.
215 static const size_t kMaxBufferSize = 100;
216
217 // Creates Java object. Must be called on the UI thread.
218 void CreateJavaObjectOnUIThread();
219
220 // data_usage::DataUseAggregator::Observer implementation:
221 void OnDataUse(const std::vector<const data_usage::DataUse*>&
222 data_use_sequence) override;
223
224 // Fetches matching rules from Java. Must be called on the UI thread. Returns
225 // result asynchronously on UI thread via FetchMatchingRulesCallback.
226 void FetchMatchingRulesOnUIThread() const;
227
228 // Called by FetchMatchingRulesCallback on IO thread when new matching rules
229 // Adds |data_use| to buffered reports. |data_use| is the data use report
230 // received from DataUseAggregator. |data_use| should not be null. |label| is
231 // a non-empty label that applies to |data_use|. |start_time| and |end_time|
232 // are the start, and end times of the interval during which bytes reported in
233 // |data_use| went over the network.
234 void BufferDataUseReport(const data_usage::DataUse* data_use,
235 const std::string& label,
236 const base::Time& start_time,
237 const base::Time& end_time);
238
239 // Submits the first data report among the buffered data reports in
240 // |buffered_data_reports_|. Since an unordered_map is used to buffer the
241 // reports, the order of reports may change. The reports are buffered in an
242 // arbitrary order and there are no guarantees that the next report to be
243 // submitted is the oldest one buffered.
244 void SubmitBufferedDataUseReport();
245
246 // Called by |FetchMatchingRulesCallback| on IO thread when new matching rules
247 // have been fetched.
248 void FetchMatchingRulesCallbackOnIOThread(
249 const std::vector<std::string>& app_package_name,
250 const std::vector<std::string>& domain_path_regex,
251 const std::vector<std::string>& label);
252
253 // Reports data use to Java. Must be called on the UI thread. Returns
254 // result asynchronously on UI thread via OnReportDataUseDone.
255 void ReportDataUseOnUIThread(const DataUseReportKey& key,
256 const DataUseReport& report) const;
257
258 // Called by OnReportDataUseDone on IO thread when a data use report has
259 // been submitted.
260 void OnReportDataUseDoneOnIOThread(bool success);
261
262 // Called by FetchMatchingRulesCallbackIO to register multiple
263 // case-insensitive regular expressions. If the url of the data use request
264 // matches any of the regular expression, the observation is passed to the
265 // Java listener.
266 void RegisterURLRegexes(const std::vector<std::string>& app_package_name,
267 const std::vector<std::string>& domain_path_regex,
268 const std::vector<std::string>& label);
269
270 // Returns true if the |gurl| matches the registered regular expressions.
271 // |label| must not be null. If a match is found, the |label| is set to the
272 // matching rule's label.
273 bool Matches(const GURL& gurl, std::string* label) const;
274
275 // Return the weak pointer to |this| to be used on IO and UI thread,
276 // respectively.
277 base::WeakPtr<ExternalDataUseObserver> GetIOWeakPtr();
278 base::WeakPtr<ExternalDataUseObserver> GetUIWeakPtr();
279
280 // Aggregator that sends data use observations to |this|.
281 data_usage::DataUseAggregator* data_use_aggregator_;
282
283 // Java listener that provides regular expressions to |this|. The regular
284 // expressions are applied to the request URLs, and filtered data use is
285 // notified to |j_external_data_use_observer_|.
286 base::android::ScopedJavaGlobalRef<jobject> j_external_data_use_observer_;
287
288 // True if callback from |FetchMatchingRulesCallback| is currently pending.
289 bool matching_rules_fetch_pending_;
290
291 // True if callback from |SubmitDataUseReportCallback| is currently pending.
292 bool submit_data_report_pending_;
293
294 // Contains matching rules.
295 ScopedVector<MatchingRule> matching_rules_;
296
297 // Buffered data reports that need to be submitted to the Java data use
298 // observer.
299 DataUseReports buffered_data_reports_;
300
301 // True if |this| is currently registered as a data use observer.
302 bool registered_as_observer_;
303
304 // |io_task_runner_| accesses ExternalDataUseObserver members on IO thread.
305 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
306
307 // |ui_task_runner_| is used to call Java code on UI thread. This ensures
308 // that Java code is safely called only on a single thread, and eliminates
309 // the need for locks in Java.
310 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
311
312 // Time when the data use reports were last received from DataUseAggregator.
313 base::Time previous_report_time_;
314
315 base::ThreadChecker thread_checker_;
316
317 // |io_weak_factory_| and |ui_weak_factory_| are used for posting tasks on the
318 // IO and UI thread, respectively.
319 base::WeakPtrFactory<ExternalDataUseObserver> io_weak_factory_;
320 base::WeakPtrFactory<ExternalDataUseObserver> ui_weak_factory_;
321
322 DISALLOW_COPY_AND_ASSIGN(ExternalDataUseObserver);
323 };
324
325 bool RegisterExternalDataUseObserver(JNIEnv* env);
326
327 } // namespace android
328
329 } // namespace chrome
330
331 #endif // CHROME_BROWSER_ANDROID_DATAUSAGE_EXTERNAL_DATA_USE_OBSERVER_H_
OLDNEW
« no previous file with comments | « chrome/browser/android/datausage/OWNERS ('k') | chrome/browser/android/datausage/external_data_use_observer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698