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 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_PREVIEWS_CORE_PREVIEWS_BLOCK_LIST_H_ 6 #define COMPONENTS_PREVIEWS_CORE_PREVIEWS_BLOCK_LIST_H_ 7 8 #include <stdint.h> 9 10 #include <map> 11 #include <memory> 12 #include <string> 13 #include <vector> 14 15 #include "base/callback.h" 16 #include "base/macros.h" 17 #include "base/optional.h" 18 #include "base/time/time.h" 19 #include "components/blocklist/opt_out_blocklist/opt_out_blocklist.h" 20 #include "components/blocklist/opt_out_blocklist/opt_out_blocklist_delegate.h" 21 #include "components/blocklist/opt_out_blocklist/opt_out_store.h" 22 #include "components/previews/core/previews_experiments.h" 23 24 class GURL; 25 26 namespace base { 27 class Clock; 28 } 29 30 namespace previews { 31 32 // Must remain synchronized with |PreviewsEligibilityReason| in 33 // //tools/metrics/histograms/enums.xml. 34 enum class PreviewsEligibilityReason { 35 // The preview navigation was allowed. 36 ALLOWED = 0, 37 // The block list was not initialized. 38 BLOCKLIST_UNAVAILABLE = 1, 39 // The block list has not loaded from disk yet. 40 BLOCKLIST_DATA_NOT_LOADED = 2, 41 // The user has opted out of a preview recently. 42 USER_RECENTLY_OPTED_OUT = 3, 43 // The user has opted out of previews often, and is no longer shown previews 44 // on any host. 45 USER_BLOCKLISTED = 4, 46 // The user has opted out of previews on a specific host often, and was not 47 // not shown a previews on that host. 48 HOST_BLOCKLISTED = 5, 49 // The network quality estimate is not available. 50 NETWORK_QUALITY_UNAVAILABLE = 6, 51 // The network was fast enough to not warrant previews. 52 NETWORK_NOT_SLOW = 7, 53 // If the page was reloaded, the user should not be shown a stale preview. 54 RELOAD_DISALLOWED = 8, 55 // DEPRECATED: The host is explicitly blocklisted by the server, so the user 56 // was not shown 57 // a preview. 58 // Replaced by NOT_ALLOWED_BY_OPTIMIZATION_GUIDE. 59 DEPRECATED_HOST_BLOCKLISTED_BY_SERVER = 9, 60 // DEPRECATED: The host is not allowlisted by the server for a preview 61 // decision that uses 62 // server optimization hints. 63 // Replaced by NOT_ALLOWED_BY_OPTIMIZATION_GUIDE. 64 DEPRECATED_HOST_NOT_ALLOWLISTED_BY_SERVER = 10, 65 // The preview is allowed but without an expected check of server optimization 66 // hints because they are not enabled (features::kOptimizationHints). 67 ALLOWED_WITHOUT_OPTIMIZATION_HINTS = 11, 68 // The preview type chosen as the committed preview. 69 COMMITTED = 12, 70 // Previews blocked by a Cache-Control:no-transform directive. 71 CACHE_CONTROL_NO_TRANSFORM = 13, 72 // The network is faster than the max slow page triggering threshold for the 73 // session. No longer used as of M80. 74 DEPRECATED_NETWORK_NOT_SLOW_FOR_SESSION = 14, 75 // Device is offline. 76 DEVICE_OFFLINE = 15, 77 // URL contained Basic Authentication, i.e.: a username or password. 78 URL_HAS_BASIC_AUTH = 16, 79 // Optimization hints needed to be checked for this preview type, but were not 80 // available. Common on first navigations. 81 OPTIMIZATION_HINTS_NOT_AVAILABLE = 17, 82 // The navigation URL has a media suffix which is excluded from previews. 83 EXCLUDED_BY_MEDIA_SUFFIX = 18, 84 // The Optimization Guide was checked for this preview type and the 85 // optimization guide did not allow this preview type. 86 NOT_ALLOWED_BY_OPTIMIZATION_GUIDE = 19, 87 // The preview was not performed due to a coinflip experiment holdback. 88 COINFLIP_HOLDBACK = 20, 89 // A redirect loop was detected. 90 REDIRECT_LOOP_DETECTED = 21, 91 // URL matched the deny list. 92 DENY_LIST_MATCHED = 22, 93 // The page load was not predicted to be painful. 94 PAGE_LOAD_PREDICTION_NOT_PAINFUL = 23, 95 LAST, 96 }; 97 98 // Manages the state of block listed domains for the previews experiment. Loads 99 // the stored block list from |opt_out_store| and manages an in memory block 100 // list on the IO thread. Updates to the block list are stored in memory and 101 // pushed to the store. Asynchronous modifications are stored in a queue and 102 // executed in order. Reading from the block list is always synchronous, and if 103 // the block list is not currently loaded (e.g., at startup, after clearing 104 // browsing history), domains are reported as block listed. The list stores no 105 // more than previews::params::MaxInMemoryHostsInBlockList hosts in-memory, 106 // which defaults to 100. 107 class PreviewsBlockList : public blocklist::OptOutBlocklist { 108 public: 109 PreviewsBlockList( 110 std::unique_ptr<blocklist::OptOutStore> opt_out_store, 111 base::Clock* clock, 112 blocklist::OptOutBlocklistDelegate* blocklist_delegate, 113 blocklist::BlocklistData::AllowedTypesAndVersions allowed_types); 114 ~PreviewsBlockList() override; 115 116 // Asynchronously adds a new navigation to to the in-memory block list and 117 // backing store. |opt_out| is whether the user opted out of the preview or 118 // navigated away from the page without opting out. |type| is only passed to 119 // the backing store. If the in memory map has reached the max number of hosts 120 // allowed, and |url| is a new host, a host will be evicted based on recency 121 // of the hosts most recent opt out. It returns the time used for recording 122 // the moment when the navigation is added for logging. 123 base::Time AddPreviewNavigation(const GURL& url, 124 bool opt_out, 125 PreviewsType type); 126 127 // Synchronously determines if |host_name| should be allowed to show previews. 128 // Returns the reason the blocklist disallowed the preview, or 129 // PreviewsEligibilityReason::ALLOWED if the preview is allowed. Record 130 // checked reasons in |passed_reasons|. Virtualized in testing. 131 virtual PreviewsEligibilityReason IsLoadedAndAllowed( 132 const GURL& url, 133 PreviewsType type, 134 std::vector<PreviewsEligibilityReason>* passed_reasons) const; 135 136 protected: 137 // blocklist::OptOutBlocklist (virtual for testing): 138 bool ShouldUseSessionPolicy(base::TimeDelta* duration, 139 size_t* history, 140 int* threshold) const override; 141 bool ShouldUsePersistentPolicy(base::TimeDelta* duration, 142 size_t* history, 143 int* threshold) const override; 144 bool ShouldUseHostPolicy(base::TimeDelta* duration, 145 size_t* history, 146 int* threshold, 147 size_t* max_hosts) const override; 148 bool ShouldUseTypePolicy(base::TimeDelta* duration, 149 size_t* history, 150 int* threshold) const override; 151 blocklist::BlocklistData::AllowedTypesAndVersions GetAllowedTypes() 152 const override; 153 154 private: 155 const blocklist::BlocklistData::AllowedTypesAndVersions allowed_types_; 156 157 DISALLOW_COPY_AND_ASSIGN(PreviewsBlockList); 158 }; 159 160 } // namespace previews 161 162 #endif // COMPONENTS_PREVIEWS_CORE_PREVIEWS_BLOCK_LIST_H_ 163