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