// 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 #include #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& 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& app_package_names, const std::vector& domain_path_regexes, const std::vector& 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 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 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> matching_rules_; // |data_use_tab_model_| is notified if a label is removed from the set of // matching labels. base::WeakPtr 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 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_