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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/webui/snippets_internals_message_handler.cc
diff --git a/chrome/browser/ui/webui/snippets_internals_message_handler.cc b/chrome/browser/ui/webui/snippets_internals_message_handler.cc
new file mode 100644
index 0000000000000000000000000000000000000000..46210af24b9edeadd8aea3dbbf0557963497e710
--- /dev/null
+++ b/chrome/browser/ui/webui/snippets_internals_message_handler.cc
@@ -0,0 +1,230 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "snippets_internals_message_handler.h"
+
+#include <set>
+#include <sstream>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/command_line.h"
+#include "base/feature_list.h"
+#include "base/i18n/time_formatting.h"
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_split.h"
+#include "base/values.h"
+#include "chrome/browser/android/chrome_feature_list.h"
+#include "chrome/browser/ntp_snippets/ntp_snippets_service_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/ntp_snippets/ntp_snippet.h"
+#include "components/ntp_snippets/switches.h"
+#include "content/public/browser/web_ui.h"
+
+namespace {
+
+scoped_ptr<base::DictionaryValue> PrepareSnippet(
+ const ntp_snippets::NTPSnippet& snippet,
+ int index,
+ bool discarded) {
+ scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
+ entry->SetString("title", snippet.title());
+ entry->SetString("siteTitle", snippet.site_title());
+ entry->SetString("snippet", snippet.snippet());
+ entry->SetString("published",
+ TimeFormatShortDateAndTime(snippet.publish_date()));
+ entry->SetString("expires",
+ TimeFormatShortDateAndTime(snippet.expiry_date()));
+ entry->SetString("url", snippet.url().spec());
+ entry->SetString("faviconUrl", snippet.favicon_url().spec());
+ entry->SetString("salientImageUrl", snippet.salient_image_url().spec());
+
+ if (discarded)
+ entry->SetString("id", "discarded-snippet-" + base::IntToString(index));
+ else
+ entry->SetString("id", "snippet-" + base::IntToString(index));
+
+ return entry;
+}
+
+} // namespace
+
+SnippetsInternalsMessageHandler::SnippetsInternalsMessageHandler() {}
+
+SnippetsInternalsMessageHandler::~SnippetsInternalsMessageHandler() {}
+
+void SnippetsInternalsMessageHandler::NTPSnippetsServiceShutdown() {}
+
+void SnippetsInternalsMessageHandler::NTPSnippetsServiceLoaded() {
+ ntp_snippets::NTPSnippetsService* ntp_snippets_service =
+ NTPSnippetsServiceFactory::GetInstance()->GetForProfile(
+ Profile::FromWebUI(web_ui()));
+
+ SendSnippets(ntp_snippets_service);
+ SendDiscardedSnippets(ntp_snippets_service);
+}
+
+void SnippetsInternalsMessageHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "loaded",
+ base::Bind(&SnippetsInternalsMessageHandler::HandleLoaded,
+ base::Unretained(this)));
+
+ web_ui()->RegisterMessageCallback(
+ "clear", base::Bind(&SnippetsInternalsMessageHandler::HandleClear,
+ base::Unretained(this)));
+
+ web_ui()->RegisterMessageCallback(
+ "download", base::Bind(&SnippetsInternalsMessageHandler::HandleDownload,
+ base::Unretained(this)));
+
+ web_ui()->RegisterMessageCallback(
+ "clearDiscarded",
+ base::Bind(&SnippetsInternalsMessageHandler::HandleClearDiscarded,
+ base::Unretained(this)));
+}
+
+void SnippetsInternalsMessageHandler::HandleLoaded(
+ const base::ListValue* args) {
+ DCHECK(args->empty());
+
+ ntp_snippets::NTPSnippetsService* ntp_snippets_service =
+ NTPSnippetsServiceFactory::GetInstance()->GetForProfile(
+ Profile::FromWebUI(web_ui()));
+
+ // 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
+ ntp_snippets_service->RemoveObserver(this);
+ ntp_snippets_service->AddObserver(this);
+
+ ntp_snippets_service->FetchSnippets();
+
+ SendInitialData(ntp_snippets_service);
+}
+
+void SnippetsInternalsMessageHandler::HandleClear(const base::ListValue* args) {
+ DCHECK_EQ(0u, args->GetSize());
+
+ ntp_snippets::NTPSnippetsService* ntp_snippets_service =
+ NTPSnippetsServiceFactory::GetInstance()->GetForProfile(
+ Profile::FromWebUI(web_ui()));
+
+ ntp_snippets_service->ClearSnippets();
+}
+
+void SnippetsInternalsMessageHandler::HandleClearDiscarded(
+ const base::ListValue* args) {
+ DCHECK_EQ(0u, args->GetSize());
+
+ ntp_snippets::NTPSnippetsService* ntp_snippets_service =
+ NTPSnippetsServiceFactory::GetInstance()->GetForProfile(
+ Profile::FromWebUI(web_ui()));
+
+ ntp_snippets_service->ClearDiscardedSnippets();
+ SendDiscardedSnippets(ntp_snippets_service);
+}
+
+void SnippetsInternalsMessageHandler::HandleDownload(
+ const base::ListValue* args) {
+ DCHECK_EQ(1u, args->GetSize());
+
+ std::string hosts_string;
+ args->GetString(0, &hosts_string);
+ 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.
+
+ std::vector<std::string> hosts_vector = base::SplitString(
+ hosts_piece, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ std::set<std::string> hosts(hosts_vector.begin(), hosts_vector.end());
+
+ ntp_snippets::NTPSnippetsService* ntp_snippets_service =
+ NTPSnippetsServiceFactory::GetInstance()->GetForProfile(
+ Profile::FromWebUI(web_ui()));
+
+ ntp_snippets_service->FetchSnippetsFromHosts(hosts);
+}
+
+void SnippetsInternalsMessageHandler::SendInitialData(
+ ntp_snippets::NTPSnippetsService* service){
+ SendHosts(service);
+
+ SendBoolean("flag-snippets", base::FeatureList::IsEnabled(
+ chrome::android::kNTPSnippetsFeature));
+
+ bool restricted = !base::CommandLine::ForCurrentProcess()->HasSwitch(
+ ntp_snippets::switches::kDontRestrict);
+ SendBoolean("switch-restrict-to-hosts", restricted);
+ const std::string help(restricted ? "cannot be empty"
+ : "unrestricted if empty");
+ SendString("hosts-help", help);
+}
+
+void SnippetsInternalsMessageHandler::SendSnippets(
+ ntp_snippets::NTPSnippetsService* service) {
+ scoped_ptr<base::ListValue> snippets_list(new base::ListValue);
+
+ int index = 0;
+ for (auto& snippet : *service)
+ snippets_list->Append(PrepareSnippet(snippet, index++, false));
+
+ base::DictionaryValue result;
+ result.Set("list", std::move(snippets_list));
+ web_ui()->CallJavascriptFunction("chrome.snippets_internals.receiveSnippets",
+ result);
+}
+
+void SnippetsInternalsMessageHandler::SendDiscardedSnippets(
+ ntp_snippets::NTPSnippetsService* service) {
+ scoped_ptr<base::ListValue> snippets_list(new base::ListValue);
+
+ int index = 0;
+ for (auto& snippet : service->GetDiscardedSnippets())
+ snippets_list->Append(PrepareSnippet(*snippet, index++, true));
+
+ base::DictionaryValue result;
+ result.Set("list", std::move(snippets_list));
+ web_ui()->CallJavascriptFunction(
+ "chrome.snippets_internals.receiveDiscardedSnippets", result);
+}
+
+void SnippetsInternalsMessageHandler::SendHosts(
+ ntp_snippets::NTPSnippetsService* service) {
+ scoped_ptr<base::ListValue> hosts_list(new base::ListValue);
+
+ std::set<std::string> hosts = service->GetSuggestionsHosts();
+ std::ostringstream hosts_imploded;
+
+ for (const std::string& host : hosts) {
+ scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
+ entry->SetString("url", host);
+
+ hosts_list->Append(std::move(entry));
+ hosts_imploded << host << " ";
+ }
+
+ base::DictionaryValue result;
+ result.Set("list", std::move(hosts_list));
+ web_ui()->CallJavascriptFunction("chrome.snippets_internals.receiveHosts",
+ result);
+
+ base::StringValue hosts_value(hosts_imploded.str());
+ web_ui()->CallJavascriptFunction(
+ "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.
+}
+
+void SnippetsInternalsMessageHandler::SendBoolean(const std::string& name,
+ bool value) {
+ 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.
+ SendString(name, string_value);
+}
+
+void SnippetsInternalsMessageHandler::SendString(const std::string& name,
+ const std::string& value) {
+ base::StringValue string_name(name);
+ base::StringValue string_value(value);
+
+ web_ui()->CallJavascriptFunction("chrome.snippets_internals.receiveProperty",
+ string_name, string_value);
+}

Powered by Google App Engine
This is Rietveld 408576698