Remove the old signature of NotificationManager::closePersistent().
[chromium-blink-merge.git] / chrome / browser / supervised_user / supervised_user_resource_throttle.cc
blob479556b389b52831017c07154581c946f7c1b9d6
1 // Copyright 2014 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.
5 #include "chrome/browser/supervised_user/supervised_user_resource_throttle.h"
7 #include "base/bind.h"
8 #include "base/metrics/histogram.h"
9 #include "chrome/browser/supervised_user/supervised_user_interstitial.h"
10 #include "chrome/browser/supervised_user/supervised_user_navigation_observer.h"
11 #include "chrome/browser/supervised_user/supervised_user_url_filter.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/resource_controller.h"
14 #include "content/public/browser/resource_request_info.h"
15 #include "net/url_request/redirect_info.h"
16 #include "net/url_request/url_request.h"
17 #include "ui/base/page_transition_types.h"
19 using content::BrowserThread;
21 namespace {
23 // These values corresponds to SupervisedUserSafetyFilterResult in
24 // tools/metrics/histograms/histograms.xml. If you change anything here, make
25 // sure to also update histograms.xml accordingly.
26 enum {
27 FILTERING_BEHAVIOR_ALLOW = 1,
28 FILTERING_BEHAVIOR_ALLOW_UNCERTAIN,
29 FILTERING_BEHAVIOR_BLOCK_BLACKLIST,
30 FILTERING_BEHAVIOR_BLOCK_SAFESITES,
31 FILTERING_BEHAVIOR_MAX = FILTERING_BEHAVIOR_BLOCK_SAFESITES
33 const int kHistogramFilteringBehaviorSpacing = 100;
34 const int kHistogramPageTransitionMaxKnownValue =
35 static_cast<int>(ui::PAGE_TRANSITION_KEYWORD_GENERATED);
36 const int kHistogramPageTransitionFallbackValue =
37 kHistogramFilteringBehaviorSpacing - 1;
38 const int kHistogramMax = 500;
40 static_assert(kHistogramPageTransitionMaxKnownValue <
41 kHistogramPageTransitionFallbackValue,
42 "HistogramPageTransition MaxKnownValue must be < FallbackValue");
43 static_assert(FILTERING_BEHAVIOR_MAX * kHistogramFilteringBehaviorSpacing +
44 kHistogramPageTransitionFallbackValue < kHistogramMax,
45 "Invalid HistogramMax value");
47 int GetHistogramValueForFilteringBehavior(
48 SupervisedUserURLFilter::FilteringBehavior behavior,
49 SupervisedUserURLFilter::FilteringBehaviorReason reason,
50 bool uncertain) {
51 // Since we're only interested in statistics about the blacklist and
52 // SafeSites, count everything that got through to the default fallback
53 // behavior as ALLOW (made it through all the filters!).
54 if (reason == SupervisedUserURLFilter::DEFAULT)
55 behavior = SupervisedUserURLFilter::ALLOW;
57 switch (behavior) {
58 case SupervisedUserURLFilter::ALLOW:
59 return uncertain ? FILTERING_BEHAVIOR_ALLOW_UNCERTAIN
60 : FILTERING_BEHAVIOR_ALLOW;
61 case SupervisedUserURLFilter::BLOCK:
62 if (reason == SupervisedUserURLFilter::BLACKLIST)
63 return FILTERING_BEHAVIOR_BLOCK_BLACKLIST;
64 else if (reason == SupervisedUserURLFilter::ASYNC_CHECKER)
65 return FILTERING_BEHAVIOR_BLOCK_SAFESITES;
66 // Fall through.
67 default:
68 NOTREACHED();
70 return 0;
73 int GetHistogramValueForTransitionType(ui::PageTransition transition_type) {
74 int value =
75 static_cast<int>(ui::PageTransitionStripQualifier(transition_type));
76 if (0 <= value && value <= kHistogramPageTransitionMaxKnownValue)
77 return value;
78 NOTREACHED();
79 return kHistogramPageTransitionFallbackValue;
82 void RecordFilterResultEvent(
83 SupervisedUserURLFilter::FilteringBehavior behavior,
84 SupervisedUserURLFilter::FilteringBehaviorReason reason,
85 bool uncertain,
86 ui::PageTransition transition_type) {
87 DCHECK(reason != SupervisedUserURLFilter::MANUAL);
88 int value =
89 GetHistogramValueForFilteringBehavior(behavior, reason, uncertain) *
90 kHistogramFilteringBehaviorSpacing +
91 GetHistogramValueForTransitionType(transition_type);
92 DCHECK_LT(value, kHistogramMax);
93 UMA_HISTOGRAM_ENUMERATION("ManagedUsers.SafetyFilter",
94 value, kHistogramMax);
97 } // namespace
99 SupervisedUserResourceThrottle::SupervisedUserResourceThrottle(
100 const net::URLRequest* request,
101 bool is_main_frame,
102 const SupervisedUserURLFilter* url_filter)
103 : request_(request),
104 is_main_frame_(is_main_frame),
105 url_filter_(url_filter),
106 deferred_(false),
107 behavior_(SupervisedUserURLFilter::HISTOGRAM_BOUNDING_VALUE),
108 weak_ptr_factory_(this) {}
110 SupervisedUserResourceThrottle::~SupervisedUserResourceThrottle() {}
112 void SupervisedUserResourceThrottle::ShowInterstitialIfNeeded(bool is_redirect,
113 const GURL& url,
114 bool* defer) {
115 // Only treat main frame requests for now (ignoring subresources).
116 if (!is_main_frame_)
117 return;
119 deferred_ = false;
120 DCHECK_EQ(SupervisedUserURLFilter::HISTOGRAM_BOUNDING_VALUE, behavior_);
121 bool got_result = url_filter_->GetFilteringBehaviorForURLWithAsyncChecks(
122 url,
123 base::Bind(&SupervisedUserResourceThrottle::OnCheckDone,
124 weak_ptr_factory_.GetWeakPtr(), url));
125 DCHECK_EQ(got_result,
126 (behavior_ != SupervisedUserURLFilter::HISTOGRAM_BOUNDING_VALUE));
127 // If we got a "not blocked" result synchronously, don't defer.
128 *defer = deferred_ = !got_result ||
129 (behavior_ == SupervisedUserURLFilter::BLOCK);
130 if (got_result)
131 behavior_ = SupervisedUserURLFilter::HISTOGRAM_BOUNDING_VALUE;
134 void SupervisedUserResourceThrottle::ShowInterstitial(
135 const GURL& url,
136 SupervisedUserURLFilter::FilteringBehaviorReason reason) {
137 const content::ResourceRequestInfo* info =
138 content::ResourceRequestInfo::ForRequest(request_);
139 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
140 base::Bind(&SupervisedUserNavigationObserver::OnRequestBlocked,
141 info->GetChildID(), info->GetRouteID(), url, reason,
142 base::Bind(
143 &SupervisedUserResourceThrottle::OnInterstitialResult,
144 weak_ptr_factory_.GetWeakPtr())));
147 void SupervisedUserResourceThrottle::WillStartRequest(bool* defer) {
148 ShowInterstitialIfNeeded(false, request_->url(), defer);
151 void SupervisedUserResourceThrottle::WillRedirectRequest(
152 const net::RedirectInfo& redirect_info,
153 bool* defer) {
154 ShowInterstitialIfNeeded(true, redirect_info.new_url, defer);
157 const char* SupervisedUserResourceThrottle::GetNameForLogging() const {
158 return "SupervisedUserResourceThrottle";
161 void SupervisedUserResourceThrottle::OnCheckDone(
162 const GURL& url,
163 SupervisedUserURLFilter::FilteringBehavior behavior,
164 SupervisedUserURLFilter::FilteringBehaviorReason reason,
165 bool uncertain) {
166 DCHECK_EQ(SupervisedUserURLFilter::HISTOGRAM_BOUNDING_VALUE, behavior_);
167 // If we got a result synchronously, pass it back to ShowInterstitialIfNeeded.
168 if (!deferred_)
169 behavior_ = behavior;
171 // If both the static blacklist and SafeSites are enabled, record UMA events.
172 if (url_filter_->HasBlacklist() && url_filter_->HasAsyncURLChecker() &&
173 reason < SupervisedUserURLFilter::MANUAL) {
174 const content::ResourceRequestInfo* info =
175 content::ResourceRequestInfo::ForRequest(request_);
176 RecordFilterResultEvent(behavior, reason, uncertain,
177 info->GetPageTransition());
180 if (behavior == SupervisedUserURLFilter::BLOCK)
181 ShowInterstitial(url, reason);
182 else if (deferred_)
183 controller()->Resume();
186 void SupervisedUserResourceThrottle::OnInterstitialResult(
187 bool continue_request) {
188 if (continue_request)
189 controller()->Resume();
190 else
191 controller()->Cancel();