url_param_classifications_loader.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // Copyright 2022 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. #ifndef COMPONENTS_URL_PARAM_FILTER_CORE_URL_PARAM_CLASSIFICATIONS_LOADER_H_
  5. #define COMPONENTS_URL_PARAM_FILTER_CORE_URL_PARAM_CLASSIFICATIONS_LOADER_H_
  6. #include <functional>
  7. #include <string>
  8. #include <unordered_map>
  9. #include "base/no_destructor.h"
  10. #include "base/sequence_checker.h"
  11. #include "components/url_param_filter/core/url_param_filter_classification.pb.h"
  12. #include "third_party/abseil-cpp/absl/types/optional.h"
  13. namespace url_param_filter {
  14. enum ClassificationExperimentStatus { EXPERIMENTAL, NON_EXPERIMENTAL };
  15. // Struct used as key in map of classifications.
  16. // Pair of a site's role and and the site name, e.g. (SOURCE, source.xyz).
  17. struct ClassificationMapKey {
  18. FilterClassification::SiteRole site_role;
  19. FilterClassification::SiteMatchType site_match_type;
  20. std::string site;
  21. };
  22. bool operator==(const ClassificationMapKey& lhs,
  23. const ClassificationMapKey& rhs);
  24. // Defined so that this can be used to key `std::map` as well as
  25. // `std::unordered_map`
  26. bool operator<(const ClassificationMapKey& lhs,
  27. const ClassificationMapKey& rhs);
  28. struct ClassificationMapKeyHash {
  29. size_t operator()(const ClassificationMapKey& key) const {
  30. return std::hash<int>()(key.site_role) ^
  31. std::hash<std::string>()(key.site) ^
  32. std::hash<int>()(key.site_match_type);
  33. }
  34. };
  35. inline ClassificationMapKey SourceKey(std::string site) {
  36. return {
  37. .site_role =
  38. FilterClassification::SiteRole::FilterClassification_SiteRole_SOURCE,
  39. .site_match_type = FilterClassification::SiteMatchType::
  40. FilterClassification_SiteMatchType_EXACT_ETLD_PLUS_ONE,
  41. .site = site};
  42. }
  43. inline ClassificationMapKey DestinationKey(std::string site) {
  44. return {.site_role = FilterClassification::SiteRole::
  45. FilterClassification_SiteRole_DESTINATION,
  46. .site_match_type = FilterClassification::SiteMatchType::
  47. FilterClassification_SiteMatchType_EXACT_ETLD_PLUS_ONE,
  48. .site = site};
  49. }
  50. inline ClassificationMapKey SourceWildcardKey(std::string site_no_etld) {
  51. return {
  52. .site_role =
  53. FilterClassification::SiteRole::FilterClassification_SiteRole_SOURCE,
  54. .site_match_type = FilterClassification::SiteMatchType::
  55. FilterClassification_SiteMatchType_ETLD_WILDCARD,
  56. .site = site_no_etld};
  57. }
  58. // `unordered_map` is used for the outer map of (role, domain) pairs, which
  59. // is likely to have hundreds. `map` is used for the inner map of `UseCase`,
  60. // which will have a single digit number of keys.
  61. using ClassificationMap = std::unordered_map<
  62. ClassificationMapKey,
  63. std::map<FilterClassification::UseCase,
  64. std::map<std::string, ClassificationExperimentStatus>>,
  65. ClassificationMapKeyHash>;
  66. class ClassificationsLoader {
  67. public:
  68. static ClassificationsLoader* GetInstance();
  69. ClassificationsLoader(const ClassificationsLoader&) = delete;
  70. ClassificationsLoader& operator=(const ClassificationsLoader&) = delete;
  71. // Returns a mapping from site to all of its classifications.
  72. ClassificationMap GetClassifications();
  73. // Deserializes the proto from |raw_classifications|. The classifications that
  74. // are being read will have already been validated in the VerifyInstallation
  75. // method in our ComponentInstaller, so we can assume this input is valid.
  76. //
  77. // The component_source_classifications_ and
  78. // component_destination_classifications_ data members are populated by this
  79. // method if the proto is deserialized successfully.
  80. void ReadClassifications(const std::string& raw_classifications);
  81. // Resets the stored classification lists for testing.
  82. void ResetListsForTesting();
  83. private:
  84. friend class base::NoDestructor<ClassificationsLoader>;
  85. ClassificationsLoader();
  86. ~ClassificationsLoader();
  87. // Creates a mapping from a site to its `role` classifications by retrieving
  88. // classifications from either the Component Updater or the feature flag.
  89. // If classifications from both are provided, then the feature flag
  90. // classifications take precedence.
  91. ClassificationMap GetClassificationsInternal();
  92. absl::optional<ClassificationMap> component_classifications_
  93. GUARDED_BY_CONTEXT(sequence_checker_) = absl::nullopt;
  94. SEQUENCE_CHECKER(sequence_checker_);
  95. };
  96. } // namespace url_param_filter
  97. #endif // COMPONENTS_URL_PARAM_FILTER_CORE_URL_PARAM_CLASSIFICATIONS_LOADER_H_