1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ANDROID_DATA_USAGE_DATA_USE_MATCHER_H_
#define CHROME_BROWSER_ANDROID_DATA_USAGE_DATA_USE_MATCHER_H_
#include <string>
#include <vector>
#include "base/compiler_specific.h"
#include "base/containers/hash_tables.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "chrome/browser/android/data_usage/data_use_tab_model.h"
namespace base {
class TickClock;
}
namespace re2 {
class RE2;
}
class GURL;
namespace chrome {
namespace android {
class ExternalDataUseObserverBridge;
// DataUseMatcher stores the matching URL patterns and package names along with
// the labels. It also provides functionality to get the matching label for a
// given URL or package. DataUseMatcher is not thread safe.
class DataUseMatcher {
public:
DataUseMatcher(
const base::WeakPtr<DataUseTabModel>& data_use_tab_model,
const ExternalDataUseObserverBridge* external_data_use_observer_bridge,
const base::TimeDelta& default_matching_rule_expiration_duration);
~DataUseMatcher();
// Called by FetchMatchingRulesDoneOnIOThread to register multiple
// case-insensitive regular expressions. If the url of the data use request
// matches any of the regular expression, the observation is passed to the
// Java listener.
void RegisterURLRegexes(const std::vector<std::string>& app_package_names,
const std::vector<std::string>& domain_path_regexes,
const std::vector<std::string>& labels);
// Returns true if the |url| matches the registered regular expressions.
// |label| must not be null. If a match is found, the |label| is set to the
// matching rule's label.
bool MatchesURL(const GURL& url, std::string* label) const WARN_UNUSED_RESULT;
// Returns true if the |app_package_name| matches the registered package
// names. |label| must not be null. If a match is found, the |label| is set
// to the matching rule's label.
bool MatchesAppPackageName(const std::string& app_package_name,
std::string* label) const WARN_UNUSED_RESULT;
// Fetches the matching rules asynchronously from
// |external_data_use_observer_bridge_|.
void FetchMatchingRules();
// Returns true if there is any valid matching rule.
bool HasValidRules() const;
private:
friend class DataUseMatcherTest;
FRIEND_TEST_ALL_PREFIXES(DataUseMatcherTest,
EncodeExpirationTimeInPackageName);
FRIEND_TEST_ALL_PREFIXES(DataUseMatcherTest,
EncodeJavaExpirationTimeInPackageName);
FRIEND_TEST_ALL_PREFIXES(DataUseMatcherTest, MatchesIgnoresExpiredRules);
FRIEND_TEST_ALL_PREFIXES(DataUseMatcherTest, ParsePackageField);
// Stores the matching rules.
class MatchingRule {
public:
MatchingRule(const std::string& app_package_name,
scoped_ptr<re2::RE2> pattern,
const std::string& label,
const base::TimeTicks& expiration);
~MatchingRule();
const re2::RE2* pattern() const;
const std::string& app_package_name() const;
const std::string& label() const;
const base::TimeTicks& expiration() const;
private:
// Package name of the app that should be matched.
const std::string app_package_name_;
// RE2 pattern to match against URLs.
scoped_ptr<re2::RE2> pattern_;
// Opaque label that uniquely identifies this matching rule.
const std::string label_;
// Expiration time of this matching rule.
const base::TimeTicks expiration_;
DISALLOW_COPY_AND_ASSIGN(MatchingRule);
};
// Parses the app package name and expiration time of the matching rule
// encoded in the format "app_package_name|milliseconds_since_epoch" in
// |app_package_name|. |new_app_package_name| and |expiration| should not be
// null. Parsed expiration time is set in |expiration| and app package name
// is set in |new_app_package_name|. If |app_package_name| is not in the
// expected format, |expiration| will be set to default expiration duration
// from now, and |new_app_package_name| will be set to the |app_package_name|.
void ParsePackageField(const std::string& app_package_name,
std::string* new_app_package_name,
base::TimeTicks* expiration) const;
base::ThreadChecker thread_checker_;
std::vector<scoped_ptr<MatchingRule>> matching_rules_;
// |data_use_tab_model_| is notified if a label is removed from the set of
// matching labels.
base::WeakPtr<DataUseTabModel> data_use_tab_model_;
// Default expiration duration of a matching rule, if expiration is not
// specified in the rule.
const base::TimeDelta default_matching_rule_expiration_duration_;
// TickClock used for obtaining the current time.
scoped_ptr<base::TickClock> tick_clock_;
// Pointer to the ExternalDataUseObserverBridge owned by
// ExternalDataUseObserver. DataUseTabModel (owner of |this|) and
// ExternalDataUseObserverBridge are owned by ExternalDataUseObserver, and are
// destroyed in that order. So |external_data_use_observer_bridge_| is
// guaranteed to be non-null.
const ExternalDataUseObserverBridge* external_data_use_observer_bridge_;
DISALLOW_COPY_AND_ASSIGN(DataUseMatcher);
};
} // namespace android
} // namespace chrome
#endif // CHROME_BROWSER_ANDROID_DATA_USAGE_DATA_USE_MATCHER_H_
|