blob: f454270fc5eda64be3308ab39ae60d47728a07b4 [file] [log] [blame]
// Copyright 2014 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 "chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.h"
#include "base/values.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/url_constants.h"
#include "components/autofill/core/browser/logging/log_receiver.h"
#include "components/grit/components_resources.h"
#include "components/password_manager/content/browser/password_manager_internals_service_factory.h"
#include "components/password_manager/core/browser/password_manager_internals_service.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "content/public/browser/web_ui_message_handler.h"
#include "net/base/escape.h"
using password_manager::PasswordManagerInternalsService;
using password_manager::PasswordManagerInternalsServiceFactory;
namespace {
content::WebUIDataSource* CreatePasswordManagerInternalsHTMLSource() {
content::WebUIDataSource* source = content::WebUIDataSource::Create(
chrome::kChromeUIPasswordManagerInternalsHost);
source->AddResourcePath("autofill_and_password_manager_internals.js",
IDR_AUTOFILL_AND_PASSWORD_MANAGER_INTERNALS_JS);
source->AddResourcePath("autofill_and_password_manager_internals.css",
IDR_AUTOFILL_AND_PASSWORD_MANAGER_INTERNALS_CSS);
source->SetDefaultResource(IDR_AUTOFILL_AND_PASSWORD_MANAGER_INTERNALS_HTML);
return source;
}
// chrome://password-manager-internals specific UI handler that takes care of
// subscribing to the autofill logging instance.
class PasswordManagerInternalsUIHandler : public content::WebUIMessageHandler,
public autofill::LogReceiver {
public:
PasswordManagerInternalsUIHandler() = default;
~PasswordManagerInternalsUIHandler() override;
private:
// content::WebUIMessageHandler:
void RegisterMessages() override;
// Implements content::WebUIMessageHandler.
void OnJavascriptAllowed() override;
void OnJavascriptDisallowed() override;
// LogReceiver implementation.
void LogSavePasswordProgress(const std::string& text) override;
void StartSubscription();
void EndSubscription();
// JavaScript call handler.
void OnLoaded(const base::ListValue* args);
// Whether |this| is registered as a log receiver with the
// PasswordManagerInternalsService.
bool registered_with_logging_service_ = false;
DISALLOW_COPY_AND_ASSIGN(PasswordManagerInternalsUIHandler);
};
PasswordManagerInternalsUIHandler::~PasswordManagerInternalsUIHandler() {
EndSubscription();
}
void PasswordManagerInternalsUIHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
"loaded",
base::BindRepeating(&PasswordManagerInternalsUIHandler::OnLoaded,
base::Unretained(this)));
}
void PasswordManagerInternalsUIHandler::OnJavascriptAllowed() {
StartSubscription();
}
void PasswordManagerInternalsUIHandler::OnJavascriptDisallowed() {
EndSubscription();
}
void PasswordManagerInternalsUIHandler::OnLoaded(const base::ListValue* args) {
AllowJavascript();
CallJavascriptFunction("setUpPasswordManagerInternals");
CallJavascriptFunction(
"notifyAboutIncognito",
base::Value(Profile::FromWebUI(web_ui())->IsIncognitoProfile()));
}
void PasswordManagerInternalsUIHandler::StartSubscription() {
PasswordManagerInternalsService* service =
PasswordManagerInternalsServiceFactory::GetForBrowserContext(
Profile::FromWebUI(web_ui()));
if (!service)
return;
registered_with_logging_service_ = true;
std::string past_logs(service->RegisterReceiver(this));
LogSavePasswordProgress(past_logs);
}
void PasswordManagerInternalsUIHandler::EndSubscription() {
if (!registered_with_logging_service_)
return;
registered_with_logging_service_ = false;
PasswordManagerInternalsService* service =
PasswordManagerInternalsServiceFactory::GetForBrowserContext(
Profile::FromWebUI(web_ui()));
if (service)
service->UnregisterReceiver(this);
}
void PasswordManagerInternalsUIHandler::LogSavePasswordProgress(
const std::string& text) {
if (!registered_with_logging_service_ || text.empty())
return;
std::string no_quotes(text);
std::replace(no_quotes.begin(), no_quotes.end(), '"', ' ');
base::Value text_string_value(net::EscapeForHTML(no_quotes));
CallJavascriptFunction("addLog", text_string_value);
}
} // namespace
PasswordManagerInternalsUI::PasswordManagerInternalsUI(content::WebUI* web_ui)
: WebUIController(web_ui) {
Profile* profile = Profile::FromWebUI(web_ui);
content::WebUIDataSource::Add(profile,
CreatePasswordManagerInternalsHTMLSource());
web_ui->AddMessageHandler(
std::make_unique<PasswordManagerInternalsUIHandler>());
}
PasswordManagerInternalsUI::~PasswordManagerInternalsUI() = default;