Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(750)

Side by Side Diff: chrome/browser/ui/webui/snippets_internals_message_handler.cc

Issue 1883523002: chrome://snippets-internals page for debugging NTP snippets. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Unit tests Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "snippets_internals_message_handler.h"
6
7 #include <set>
8 #include <sstream>
9 #include <vector>
10
11 #include "base/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/command_line.h"
14 #include "base/feature_list.h"
15 #include "base/i18n/time_formatting.h"
16 #include "base/logging.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_piece.h"
19 #include "base/strings/string_split.h"
20 #include "base/values.h"
21 #include "chrome/browser/android/chrome_feature_list.h"
22 #include "chrome/browser/ntp_snippets/ntp_snippets_service_factory.h"
23 #include "chrome/browser/profiles/profile.h"
24 #include "components/ntp_snippets/ntp_snippet.h"
25 #include "components/ntp_snippets/switches.h"
26 #include "content/public/browser/web_ui.h"
27
28 namespace {
29
30 scoped_ptr<base::DictionaryValue> PrepareSnippet(
31 const ntp_snippets::NTPSnippet& snippet,
32 int index,
33 bool discarded) {
34 scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
35 entry->SetString("title", snippet.title());
36 entry->SetString("siteTitle", snippet.site_title());
37 entry->SetString("snippet", snippet.snippet());
38 entry->SetString("published",
39 TimeFormatShortDateAndTime(snippet.publish_date()));
40 entry->SetString("expires",
41 TimeFormatShortDateAndTime(snippet.expiry_date()));
42 entry->SetString("url", snippet.url().spec());
43 entry->SetString("faviconUrl", snippet.favicon_url().spec());
44 entry->SetString("salientImageUrl", snippet.salient_image_url().spec());
45
46 if (discarded)
47 entry->SetString("id", "discarded-snippet-" + base::IntToString(index));
48 else
49 entry->SetString("id", "snippet-" + base::IntToString(index));
50
51 return entry;
52 }
53
54 } // namespace
55
56 SnippetsInternalsMessageHandler::SnippetsInternalsMessageHandler() {}
57
58 SnippetsInternalsMessageHandler::~SnippetsInternalsMessageHandler() {}
59
60 void SnippetsInternalsMessageHandler::NTPSnippetsServiceShutdown() {}
61
62 void SnippetsInternalsMessageHandler::NTPSnippetsServiceLoaded() {
63 ntp_snippets::NTPSnippetsService* ntp_snippets_service =
64 NTPSnippetsServiceFactory::GetInstance()->GetForProfile(
65 Profile::FromWebUI(web_ui()));
66
67 SendSnippets(ntp_snippets_service);
68 SendDiscardedSnippets(ntp_snippets_service);
69 }
70
71 void SnippetsInternalsMessageHandler::RegisterMessages() {
72 web_ui()->RegisterMessageCallback(
73 "loaded",
74 base::Bind(&SnippetsInternalsMessageHandler::HandleLoaded,
75 base::Unretained(this)));
76
77 web_ui()->RegisterMessageCallback(
78 "clear", base::Bind(&SnippetsInternalsMessageHandler::HandleClear,
79 base::Unretained(this)));
80
81 web_ui()->RegisterMessageCallback(
82 "download", base::Bind(&SnippetsInternalsMessageHandler::HandleDownload,
83 base::Unretained(this)));
84
85 web_ui()->RegisterMessageCallback(
86 "clearDiscarded",
87 base::Bind(&SnippetsInternalsMessageHandler::HandleClearDiscarded,
88 base::Unretained(this)));
89 }
90
91 void SnippetsInternalsMessageHandler::HandleLoaded(
92 const base::ListValue* args) {
93 DCHECK(args->empty());
94
95 ntp_snippets::NTPSnippetsService* ntp_snippets_service =
96 NTPSnippetsServiceFactory::GetInstance()->GetForProfile(
97 Profile::FromWebUI(web_ui()));
98
99 // On page reloads it is necessary to first remove the observer.
Marc Treib 2016/04/13 08:45:51 Why? Also: On the initial load, you're trying to r
jkrcal 2016/04/14 15:27:00 Done. On page reload, nothing is destroyed, Handl
Marc Treib 2016/04/14 15:43:44 IMO this class should handle not adding itself twi
100 ntp_snippets_service->RemoveObserver(this);
101 ntp_snippets_service->AddObserver(this);
102
103 ntp_snippets_service->FetchSnippets();
104
105 SendInitialData(ntp_snippets_service);
106 }
107
108 void SnippetsInternalsMessageHandler::HandleClear(const base::ListValue* args) {
109 DCHECK_EQ(0u, args->GetSize());
110
111 ntp_snippets::NTPSnippetsService* ntp_snippets_service =
112 NTPSnippetsServiceFactory::GetInstance()->GetForProfile(
113 Profile::FromWebUI(web_ui()));
114
115 ntp_snippets_service->ClearSnippets();
116 }
117
118 void SnippetsInternalsMessageHandler::HandleClearDiscarded(
119 const base::ListValue* args) {
120 DCHECK_EQ(0u, args->GetSize());
121
122 ntp_snippets::NTPSnippetsService* ntp_snippets_service =
123 NTPSnippetsServiceFactory::GetInstance()->GetForProfile(
124 Profile::FromWebUI(web_ui()));
125
126 ntp_snippets_service->ClearDiscardedSnippets();
127 SendDiscardedSnippets(ntp_snippets_service);
128 }
129
130 void SnippetsInternalsMessageHandler::HandleDownload(
131 const base::ListValue* args) {
132 DCHECK_EQ(1u, args->GetSize());
133
134 std::string hosts_string;
135 args->GetString(0, &hosts_string);
136 base::StringPiece hosts_piece(hosts_string);
Marc Treib 2016/04/13 08:45:51 I think this conversion happens automatically, i.e
jkrcal 2016/04/14 15:27:00 Done.
137
138 std::vector<std::string> hosts_vector = base::SplitString(
139 hosts_piece, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
140 std::set<std::string> hosts(hosts_vector.begin(), hosts_vector.end());
141
142 ntp_snippets::NTPSnippetsService* ntp_snippets_service =
143 NTPSnippetsServiceFactory::GetInstance()->GetForProfile(
144 Profile::FromWebUI(web_ui()));
145
146 ntp_snippets_service->FetchSnippetsFromHosts(hosts);
147 }
148
149 void SnippetsInternalsMessageHandler::SendInitialData(
150 ntp_snippets::NTPSnippetsService* service){
151 SendHosts(service);
152
153 SendBoolean("flag-snippets", base::FeatureList::IsEnabled(
154 chrome::android::kNTPSnippetsFeature));
155
156 bool restricted = !base::CommandLine::ForCurrentProcess()->HasSwitch(
157 ntp_snippets::switches::kDontRestrict);
158 SendBoolean("switch-restrict-to-hosts", restricted);
159 const std::string help(restricted ? "cannot be empty"
160 : "unrestricted if empty");
161 SendString("hosts-help", help);
162 }
163
164 void SnippetsInternalsMessageHandler::SendSnippets(
165 ntp_snippets::NTPSnippetsService* service) {
166 scoped_ptr<base::ListValue> snippets_list(new base::ListValue);
167
168 int index = 0;
169 for (auto& snippet : *service)
170 snippets_list->Append(PrepareSnippet(snippet, index++, false));
171
172 base::DictionaryValue result;
173 result.Set("list", std::move(snippets_list));
174 web_ui()->CallJavascriptFunction("chrome.snippets_internals.receiveSnippets",
175 result);
176 }
177
178 void SnippetsInternalsMessageHandler::SendDiscardedSnippets(
179 ntp_snippets::NTPSnippetsService* service) {
180 scoped_ptr<base::ListValue> snippets_list(new base::ListValue);
181
182 int index = 0;
183 for (auto& snippet : service->GetDiscardedSnippets())
184 snippets_list->Append(PrepareSnippet(*snippet, index++, true));
185
186 base::DictionaryValue result;
187 result.Set("list", std::move(snippets_list));
188 web_ui()->CallJavascriptFunction(
189 "chrome.snippets_internals.receiveDiscardedSnippets", result);
190 }
191
192 void SnippetsInternalsMessageHandler::SendHosts(
193 ntp_snippets::NTPSnippetsService* service) {
194 scoped_ptr<base::ListValue> hosts_list(new base::ListValue);
195
196 std::set<std::string> hosts = service->GetSuggestionsHosts();
197 std::ostringstream hosts_imploded;
198
199 for (const std::string& host : hosts) {
200 scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
201 entry->SetString("url", host);
202
203 hosts_list->Append(std::move(entry));
204 hosts_imploded << host << " ";
205 }
206
207 base::DictionaryValue result;
208 result.Set("list", std::move(hosts_list));
209 web_ui()->CallJavascriptFunction("chrome.snippets_internals.receiveHosts",
210 result);
211
212 base::StringValue hosts_value(hosts_imploded.str());
213 web_ui()->CallJavascriptFunction(
214 "chrome.snippets_internals.receiveHostsInput", hosts_value);
Marc Treib 2016/04/13 08:45:51 Any particular reason for sending this separately?
jkrcal 2016/04/14 15:27:00 Done.
215 }
216
217 void SnippetsInternalsMessageHandler::SendBoolean(const std::string& name,
218 bool value) {
219 const std::string string_value(value ? "True" : "False");
Marc Treib 2016/04/13 08:45:51 Might as well just inline this below.
jkrcal 2016/04/14 15:27:00 Done.
220 SendString(name, string_value);
221 }
222
223 void SnippetsInternalsMessageHandler::SendString(const std::string& name,
224 const std::string& value) {
225 base::StringValue string_name(name);
226 base::StringValue string_value(value);
227
228 web_ui()->CallJavascriptFunction("chrome.snippets_internals.receiveProperty",
229 string_name, string_value);
230 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698