Create an initial chrome://supervised-user-internals page
[chromium-blink-merge.git] / chrome / browser / ui / webui / supervised_user_internals_message_handler.cc
blob234c79964382074cf0532bbd7c42005fd1b2bdd5
1 // Copyright 2015 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/ui/webui/supervised_user_internals_message_handler.h"
7 #include "base/bind.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/values.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/supervised_user/supervised_user_service.h"
12 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
13 #include "components/url_formatter/url_fixer.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/web_ui.h"
17 using content::BrowserThread;
19 namespace {
21 // Creates a 'section' for display on about:supervised-user-internals,
22 // consisting of a title and a list of fields. Returns a pointer to the new
23 // section's contents, for use with |AddSectionEntry| below. Note that
24 // |parent_list|, not the caller, owns the newly added section.
25 base::ListValue* AddSection(base::ListValue* parent_list,
26 const std::string& title) {
27 scoped_ptr<base::DictionaryValue> section(new base::DictionaryValue);
28 scoped_ptr<base::ListValue> section_contents(new base::ListValue);
29 section->SetString("title", title);
30 // Grab a raw pointer to the result before |Pass()|ing it on.
31 base::ListValue* result = section_contents.get();
32 section->Set("data", section_contents.Pass());
33 parent_list->Append(section.Pass());
34 return result;
37 // Adds a bool entry to a section (created with |AddSection| above).
38 void AddSectionEntry(base::ListValue* section_list,
39 const std::string& name,
40 bool value) {
41 scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
42 entry->SetString("stat_name", name);
43 entry->SetBoolean("stat_value", value);
44 entry->SetBoolean("is_valid", true);
45 section_list->Append(entry.Pass());
48 // Adds a string entry to a section (created with |AddSection| above).
49 void AddSectionEntry(base::ListValue* section_list,
50 const std::string& name,
51 const std::string& value) {
52 scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
53 entry->SetString("stat_name", name);
54 entry->SetString("stat_value", value);
55 entry->SetBoolean("is_valid", true);
56 section_list->Append(entry.Pass());
59 std::string FilteringBehaviorToString(
60 SupervisedUserURLFilter::FilteringBehavior behavior) {
61 switch (behavior) {
62 case SupervisedUserURLFilter::ALLOW:
63 return "Allow";
64 case SupervisedUserURLFilter::WARN:
65 return "Warn";
66 case SupervisedUserURLFilter::BLOCK:
67 return "Block";
68 case SupervisedUserURLFilter::INVALID:
69 return "Invalid";
71 return "Unknown";
74 std::string FilteringBehaviorToString(
75 SupervisedUserURLFilter::FilteringBehavior behavior, bool uncertain) {
76 std::string result = FilteringBehaviorToString(behavior);
77 if (uncertain)
78 result += " (Uncertain)";
79 return result;
82 std::string FilteringBehaviorReasonToString(
83 SupervisedUserURLFilter::FilteringBehaviorReason reason) {
84 switch (reason) {
85 case SupervisedUserURLFilter::DEFAULT:
86 return "Default";
87 case SupervisedUserURLFilter::ASYNC_CHECKER:
88 return "AsyncChecker";
89 case SupervisedUserURLFilter::BLACKLIST:
90 return "Blacklist";
91 case SupervisedUserURLFilter::MANUAL:
92 return "Manual";
94 return "Unknown/invalid";
97 } // namespace
99 // Helper class that lives on the IO thread, listens to the
100 // SupervisedUserURLFilter there, and posts results back to the UI thread.
101 class SupervisedUserInternalsMessageHandler::IOThreadHelper
102 : public base::RefCountedThreadSafe<IOThreadHelper,
103 BrowserThread::DeleteOnIOThread>,
104 public SupervisedUserURLFilter::Observer {
105 public:
106 using OnURLCheckedCallback =
107 base::Callback<void(const GURL&,
108 SupervisedUserURLFilter::FilteringBehavior,
109 SupervisedUserURLFilter::FilteringBehaviorReason,
110 bool uncertain)>;
112 IOThreadHelper(scoped_refptr<const SupervisedUserURLFilter> filter,
113 const OnURLCheckedCallback& callback)
114 : filter_(filter), callback_(callback) {
115 BrowserThread::PostTask(BrowserThread::IO,
116 FROM_HERE,
117 base::Bind(&IOThreadHelper::InitOnIOThread, this));
120 private:
121 friend class base::DeleteHelper<IOThreadHelper>;
122 friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
123 virtual ~IOThreadHelper() {
124 DCHECK_CURRENTLY_ON(BrowserThread::IO);
125 filter_->RemoveObserver(this);
128 // SupervisedUserURLFilter::Observer:
129 void OnSiteListUpdated() override {}
130 void OnURLChecked(const GURL& url,
131 SupervisedUserURLFilter::FilteringBehavior behavior,
132 SupervisedUserURLFilter::FilteringBehaviorReason reason,
133 bool uncertain) override {
134 BrowserThread::PostTask(BrowserThread::UI,
135 FROM_HERE,
136 base::Bind(callback_,
137 url, behavior, reason, uncertain));
140 void InitOnIOThread() {
141 DCHECK_CURRENTLY_ON(BrowserThread::IO);
142 filter_->AddObserver(this);
145 scoped_refptr<const SupervisedUserURLFilter> filter_;
146 OnURLCheckedCallback callback_;
148 DISALLOW_COPY_AND_ASSIGN(IOThreadHelper);
151 SupervisedUserInternalsMessageHandler::SupervisedUserInternalsMessageHandler()
152 : weak_factory_(this) {
155 SupervisedUserInternalsMessageHandler::
156 ~SupervisedUserInternalsMessageHandler() {
159 void SupervisedUserInternalsMessageHandler::RegisterMessages() {
160 DCHECK_CURRENTLY_ON(BrowserThread::UI);
162 web_ui()->RegisterMessageCallback("registerForEvents",
163 base::Bind(&SupervisedUserInternalsMessageHandler::
164 HandleRegisterForEvents,
165 base::Unretained(this)));
167 web_ui()->RegisterMessageCallback("getBasicInfo",
168 base::Bind(&SupervisedUserInternalsMessageHandler::HandleGetBasicInfo,
169 base::Unretained(this)));
171 web_ui()->RegisterMessageCallback("tryURL",
172 base::Bind(&SupervisedUserInternalsMessageHandler::HandleTryURL,
173 base::Unretained(this)));
176 void SupervisedUserInternalsMessageHandler::OnURLFilterChanged() {
177 SendBasicInfo();
180 SupervisedUserService*
181 SupervisedUserInternalsMessageHandler::GetSupervisedUserService() {
182 Profile* profile = Profile::FromWebUI(web_ui());
183 return SupervisedUserServiceFactory::GetForProfile(
184 profile->GetOriginalProfile());
187 void SupervisedUserInternalsMessageHandler::HandleRegisterForEvents(
188 const base::ListValue* args) {
189 DCHECK(args->empty());
191 if (!io_thread_helper_.get()) {
192 io_thread_helper_ = new IOThreadHelper(
193 GetSupervisedUserService()->GetURLFilterForIOThread(),
194 base::Bind(&SupervisedUserInternalsMessageHandler::OnURLChecked,
195 weak_factory_.GetWeakPtr()));
199 void SupervisedUserInternalsMessageHandler::HandleGetBasicInfo(
200 const base::ListValue* args) {
201 SendBasicInfo();
204 void SupervisedUserInternalsMessageHandler::HandleTryURL(
205 const base::ListValue* args) {
206 DCHECK_EQ(1u, args->GetSize());
207 std::string url_str;
208 if (!args->GetString(0, &url_str))
209 return;
211 GURL url = url_formatter::FixupURL(url_str, std::string());
212 if (!url.is_valid())
213 return;
215 SupervisedUserURLFilter* filter =
216 GetSupervisedUserService()->GetURLFilterForUIThread();
217 filter->GetFilteringBehaviorForURLWithAsyncChecks(
218 url,
219 base::Bind(&SupervisedUserInternalsMessageHandler::OnTryURLResult,
220 weak_factory_.GetWeakPtr()));
223 void SupervisedUserInternalsMessageHandler::SendBasicInfo() {
224 scoped_ptr<base::ListValue> section_list(new base::ListValue);
226 Profile* profile = Profile::FromWebUI(web_ui());
228 base::ListValue* section_profile = AddSection(section_list.get(), "Profile");
229 AddSectionEntry(section_profile, "Account", profile->GetProfileUserName());
230 AddSectionEntry(section_profile, "Legacy Supervised",
231 profile->IsLegacySupervised());
232 AddSectionEntry(section_profile, "Child", profile->IsChild());
234 SupervisedUserURLFilter* filter =
235 GetSupervisedUserService()->GetURLFilterForUIThread();
237 base::ListValue* section_filter = AddSection(section_list.get(), "Filter");
238 AddSectionEntry(section_filter, "Blacklist active", filter->HasBlacklist());
239 AddSectionEntry(section_filter, "Online checks active",
240 filter->HasAsyncURLChecker());
241 AddSectionEntry(section_filter, "Default behavior",
242 FilteringBehaviorToString(
243 filter->GetDefaultFilteringBehavior()));
245 base::DictionaryValue result;
246 result.Set("sections", section_list.Pass());
247 web_ui()->CallJavascriptFunction(
248 "chrome.supervised_user_internals.receiveBasicInfo", result);
251 void SupervisedUserInternalsMessageHandler::OnTryURLResult(
252 SupervisedUserURLFilter::FilteringBehavior behavior,
253 SupervisedUserURLFilter::FilteringBehaviorReason reason,
254 bool uncertain) {
255 web_ui()->CallJavascriptFunction(
256 "chrome.supervised_user_internals.receiveTryURLResult",
257 base::StringValue(FilteringBehaviorToString(behavior, uncertain)));
260 void SupervisedUserInternalsMessageHandler::OnURLChecked(
261 const GURL& url,
262 SupervisedUserURLFilter::FilteringBehavior behavior,
263 SupervisedUserURLFilter::FilteringBehaviorReason reason,
264 bool uncertain) {
265 DCHECK_CURRENTLY_ON(BrowserThread::UI);
266 base::DictionaryValue result;
267 result.SetString("url", url.possibly_invalid_spec());
268 result.SetString("result", FilteringBehaviorToString(behavior, uncertain));
269 result.SetString("reason", FilteringBehaviorReasonToString(reason));
270 web_ui()->CallJavascriptFunction(
271 "chrome.supervised_user_internals.receiveFilteringResult", result);