Commit 5e033130 authored by Daniel Rubery's avatar Daniel Rubery Committed by Commit Bot

Allow CRSBLOG to be used on other threads

Javascript can only be invoked from the UI thread, so call over to the
UI thread before sending CRSBLOG messages to the WebUI. This also fixes
a bug where, if messages were sent before the WebUI had fully
initialized, we would fail to execute the Javascript, causing a CHECK
failure.

Bug: 952333
Change-Id: I0b3a5eb90f8993c6e19d52179b727e8784139bcc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1566618Reviewed-by: default avatarVarun Khaneja <vakh@chromium.org>
Commit-Queue: Daniel Rubery <drubery@chromium.org>
Cr-Commit-Position: refs/heads/master@{#650532}
parent 7dfbd68a
......@@ -21,6 +21,7 @@
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/time/time.h"
#include "base/values.h"
#include "components/grit/components_resources.h"
......@@ -33,6 +34,8 @@
#include "components/strings/grit/components_strings.h"
#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#if SAFE_BROWSING_DB_LOCAL
......@@ -163,14 +166,25 @@ void WebUIInfoSingleton::LogMessage(const std::string& message) {
base::Time timestamp = base::Time::Now();
log_messages_.push_back(std::make_pair(timestamp, message));
for (auto* webui_listener : webui_instances_)
webui_listener->NotifyLogMessageJsListener(timestamp, message);
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&WebUIInfoSingleton::NotifyLogMessageListeners, timestamp,
message));
}
void WebUIInfoSingleton::ClearLogMessages() {
std::vector<std::pair<base::Time, std::string>>().swap(log_messages_);
}
/* static */ void WebUIInfoSingleton::NotifyLogMessageListeners(
const base::Time& timestamp,
const std::string& message) {
WebUIInfoSingleton* web_ui_info = GetInstance();
for (auto* webui_listener : web_ui_info->webui_instances())
webui_listener->NotifyLogMessageJsListener(timestamp, message);
}
void WebUIInfoSingleton::RegisterWebUIInstance(SafeBrowsingUIHandler* webui) {
webui_instances_.push_back(webui);
}
......@@ -986,13 +1000,26 @@ SafeBrowsingUI::~SafeBrowsingUI() {}
SafeBrowsingUIHandler::SafeBrowsingUIHandler(content::BrowserContext* context)
: browser_context_(context) {
WebUIInfoSingleton::GetInstance()->RegisterWebUIInstance(this);
}
SafeBrowsingUIHandler::~SafeBrowsingUIHandler() {
WebUIInfoSingleton::GetInstance()->UnregisterWebUIInstance(this);
}
void SafeBrowsingUIHandler::OnJavascriptAllowed() {
// We don't want to register the SafeBrowsingUIHandler with the
// WebUIInfoSingleton at construction, since this can lead to
// messages being sent to the renderer before it's ready. So register it here.
WebUIInfoSingleton::GetInstance()->RegisterWebUIInstance(this);
}
void SafeBrowsingUIHandler::OnJavascriptDisallowed() {
// In certain situations, Javascript can become disallowed before the
// destructor is called (e.g. tab refresh/renderer crash). In these situation,
// we want to stop receiving JS messages.
WebUIInfoSingleton::GetInstance()->UnregisterWebUIInstance(this);
}
void SafeBrowsingUIHandler::GetExperiments(const base::ListValue* args) {
AllowJavascript();
std::string callback_id;
......
......@@ -28,6 +28,12 @@ class SafeBrowsingUIHandler : public content::WebUIMessageHandler {
SafeBrowsingUIHandler(content::BrowserContext* context);
~SafeBrowsingUIHandler() override;
// Callback when Javascript becomes allowed in the WebUI.
void OnJavascriptAllowed() override;
// Callback when Javascript becomes disallowed in the WebUI.
void OnJavascriptDisallowed() override;
// Get the experiments that are currently enabled per Chrome instance.
void GetExperiments(const base::ListValue* args);
......@@ -188,6 +194,11 @@ class WebUIInfoSingleton {
// Clear the log messages.
void ClearLogMessages();
// Notify listeners of changes to the log messages. Static to avoid this being
// called after the destruction of the WebUIInfoSingleton
static void NotifyLogMessageListeners(const base::Time& timestamp,
const std::string& message);
// Register the new WebUI listener object.
void RegisterWebUIInstance(SafeBrowsingUIHandler* webui);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment