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

Unified Diff: chrome/browser/ui/webui/sync_internals_message_handler.cc

Issue 2898723003: [Sync] Migrate SyncInternalsMessageHandler off CallJavascriptFunctionUnsafe. (Closed)
Patch Set: More updates for dbeam. Created 3 years, 7 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/sync_internals_message_handler.cc
diff --git a/chrome/browser/ui/webui/sync_internals_message_handler.cc b/chrome/browser/ui/webui/sync_internals_message_handler.cc
index 4e29f99aa8637096092f329813a2d08459577e35..3a68db41789f4ca9e129e3fed8c5468fd2d34065 100644
--- a/chrome/browser/ui/webui/sync_internals_message_handler.cc
+++ b/chrome/browser/ui/webui/sync_internals_message_handler.cc
@@ -4,6 +4,8 @@
#include "chrome/browser/ui/webui/sync_internals_message_handler.h"
+#include <stdint.h>
+
#include <utility>
#include <vector>
@@ -13,7 +15,6 @@
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/common/channel_info.h"
#include "components/browser_sync/profile_sync_service.h"
-#include "components/signin/core/browser/signin_manager_base.h"
#include "components/sync/base/weak_handle.h"
#include "components/sync/driver/about_sync_util.h"
#include "components/sync/driver/sync_service.h"
@@ -25,45 +26,41 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_ui.h"
+using base::DictionaryValue;
+using base::ListValue;
+using base::Value;
using browser_sync::ProfileSyncService;
using syncer::JsEventDetails;
using syncer::ModelTypeSet;
+using syncer::SyncService;
using syncer::WeakHandle;
-namespace {
-class UtilAboutSyncDataExtractor : public AboutSyncDataExtractor {
- public:
- std::unique_ptr<base::DictionaryValue> ConstructAboutInformation(
- syncer::SyncService* service,
- SigninManagerBase* signin) override {
- return syncer::sync_ui_util::ConstructAboutInformation(
- service, signin, chrome::GetChannel());
- }
-};
-} // namespace
-
SyncInternalsMessageHandler::SyncInternalsMessageHandler()
: SyncInternalsMessageHandler(
- base::MakeUnique<UtilAboutSyncDataExtractor>()) {}
+ base::BindRepeating(
+ &SyncInternalsMessageHandler::BindForSyncServiceProvider,
+ base::Unretained(this)),
+ base::BindRepeating(
+ &syncer::sync_ui_util::ConstructAboutInformation)) {}
SyncInternalsMessageHandler::SyncInternalsMessageHandler(
- std::unique_ptr<AboutSyncDataExtractor> about_sync_data_extractor)
- : about_sync_data_extractor_(std::move(about_sync_data_extractor)),
+ SyncServiceProvider sync_service_provider,
+ AboutSyncDataDelegate about_sync_data_delegate)
+ : sync_service_provider_(std::move(sync_service_provider)),
+ about_sync_data_delegate_(std::move(about_sync_data_delegate)),
weak_ptr_factory_(this) {}
SyncInternalsMessageHandler::~SyncInternalsMessageHandler() {
- if (js_controller_)
- js_controller_->RemoveJsEventHandler(this);
-
- ProfileSyncService* service = GetProfileSyncService();
- if (service && service->HasObserver(this)) {
- service->RemoveObserver(this);
- service->RemoveProtocolEventObserver(this);
- }
+ UnregisterModelNotifications();
+}
- if (service && is_registered_for_counters_) {
- service->RemoveTypeDebugInfoObserver(this);
- }
+void SyncInternalsMessageHandler::OnJavascriptDisallowed() {
+ // Invaliding weak ptrs works well here because the only weak ptr we vend is
+ // to the sync side to give us information that should be used to populate the
+ // javascript side. If javascript is disallowed, we don't care about updating
+ // the UI with data, so dropping those callbacks is fine.
+ weak_ptr_factory_.InvalidateWeakPtrs();
+ UnregisterModelNotifications();
}
void SyncInternalsMessageHandler::RegisterMessages() {
@@ -96,13 +93,14 @@ void SyncInternalsMessageHandler::RegisterMessages() {
}
void SyncInternalsMessageHandler::HandleRegisterForEvents(
- const base::ListValue* args) {
+ const ListValue* args) {
DCHECK(args->empty());
+ AllowJavascript();
// is_registered_ flag protects us from double-registering. This could
// happen on a page refresh, where the JavaScript gets re-run but the
// message handler remains unchanged.
- ProfileSyncService* service = GetProfileSyncService();
+ SyncService* service = sync_service_provider_.Run();
if (service && !is_registered_) {
service->AddObserver(this);
service->AddProtocolEventObserver(this);
@@ -113,52 +111,61 @@ void SyncInternalsMessageHandler::HandleRegisterForEvents(
}
void SyncInternalsMessageHandler::HandleRegisterForPerTypeCounters(
- const base::ListValue* args) {
+ const ListValue* args) {
DCHECK(args->empty());
+ AllowJavascript();
+
+ SyncService* service = sync_service_provider_.Run();
+ if (!service)
+ return;
- if (ProfileSyncService* service = GetProfileSyncService()) {
- if (!is_registered_for_counters_) {
- service->AddTypeDebugInfoObserver(this);
- is_registered_for_counters_ = true;
- } else {
- // Re-register to ensure counters get re-emitted.
- service->RemoveTypeDebugInfoObserver(this);
- service->AddTypeDebugInfoObserver(this);
- }
+ if (!is_registered_for_counters_) {
+ service->AddTypeDebugInfoObserver(this);
+ is_registered_for_counters_ = true;
+ } else {
+ // Re-register to ensure counters get re-emitted.
+ service->RemoveTypeDebugInfoObserver(this);
+ service->AddTypeDebugInfoObserver(this);
}
}
void SyncInternalsMessageHandler::HandleRequestUpdatedAboutInfo(
- const base::ListValue* args) {
+ const ListValue* args) {
DCHECK(args->empty());
+ AllowJavascript();
SendAboutInfo();
}
void SyncInternalsMessageHandler::HandleRequestListOfTypes(
- const base::ListValue* args) {
+ const ListValue* args) {
DCHECK(args->empty());
- base::DictionaryValue event_details;
- std::unique_ptr<base::ListValue> type_list(new base::ListValue());
+ AllowJavascript();
+
+ DictionaryValue event_details;
+ auto type_list = base::MakeUnique<ListValue>();
ModelTypeSet protocol_types = syncer::ProtocolTypes();
- for (ModelTypeSet::Iterator it = protocol_types.First();
- it.Good(); it.Inc()) {
+ for (ModelTypeSet::Iterator it = protocol_types.First(); it.Good();
+ it.Inc()) {
type_list->AppendString(ModelTypeToString(it.Get()));
}
event_details.Set(syncer::sync_ui_util::kTypes, std::move(type_list));
- web_ui()->CallJavascriptFunctionUnsafe(
- syncer::sync_ui_util::kDispatchEvent,
- base::Value(syncer::sync_ui_util::kOnReceivedListOfTypes), event_details);
+ DispatchEvent(syncer::sync_ui_util::kOnReceivedListOfTypes, event_details);
}
-void SyncInternalsMessageHandler::HandleGetAllNodes(
- const base::ListValue* args) {
+void SyncInternalsMessageHandler::HandleGetAllNodes(const ListValue* args) {
DCHECK_EQ(1U, args->GetSize());
+ AllowJavascript();
+
int request_id = 0;
bool success = ExtractIntegerValue(args, &request_id);
DCHECK(success);
- ProfileSyncService* service = GetProfileSyncService();
+ SyncService* service = sync_service_provider_.Run();
if (service) {
+ // This opens up the possibility of non-javascript code calling us
+ // asynchronously, and potentially at times we're not allowed to call into
+ // the javascript side. We guard against this by invalidating this weak ptr
+ // should javascript become disallowed.
service->GetAllNodes(
base::Bind(&SyncInternalsMessageHandler::OnReceivedAllNodes,
weak_ptr_factory_.GetWeakPtr(), request_id));
@@ -167,23 +174,19 @@ void SyncInternalsMessageHandler::HandleGetAllNodes(
void SyncInternalsMessageHandler::OnReceivedAllNodes(
int request_id,
- std::unique_ptr<base::ListValue> nodes) {
- base::Value id(request_id);
- web_ui()->CallJavascriptFunctionUnsafe(
- syncer::sync_ui_util::kGetAllNodesCallback, id, *nodes);
+ std::unique_ptr<ListValue> nodes) {
+ CallJavascriptFunction(syncer::sync_ui_util::kGetAllNodesCallback,
+ Value(request_id), *nodes);
}
-void SyncInternalsMessageHandler::OnStateChanged(syncer::SyncService* sync) {
+void SyncInternalsMessageHandler::OnStateChanged(SyncService* sync) {
SendAboutInfo();
}
void SyncInternalsMessageHandler::OnProtocolEvent(
const syncer::ProtocolEvent& event) {
- std::unique_ptr<base::DictionaryValue> value(
- syncer::ProtocolEvent::ToValue(event));
- web_ui()->CallJavascriptFunctionUnsafe(
- syncer::sync_ui_util::kDispatchEvent,
- base::Value(syncer::sync_ui_util::kOnProtocolEvent), *value);
+ std::unique_ptr<DictionaryValue> value(syncer::ProtocolEvent::ToValue(event));
+ DispatchEvent(syncer::sync_ui_util::kOnProtocolEvent, *value);
}
void SyncInternalsMessageHandler::OnCommitCountersUpdated(
@@ -207,14 +210,12 @@ void SyncInternalsMessageHandler::OnStatusCountersUpdated(
void SyncInternalsMessageHandler::EmitCounterUpdate(
syncer::ModelType type,
const std::string& counter_type,
- std::unique_ptr<base::DictionaryValue> value) {
- std::unique_ptr<base::DictionaryValue> details(new base::DictionaryValue());
+ std::unique_ptr<DictionaryValue> value) {
+ auto details = base::MakeUnique<DictionaryValue>();
details->SetString(syncer::sync_ui_util::kModelType, ModelTypeToString(type));
details->SetString(syncer::sync_ui_util::kCounterType, counter_type);
details->Set(syncer::sync_ui_util::kCounters, std::move(value));
- web_ui()->CallJavascriptFunctionUnsafe(
- syncer::sync_ui_util::kDispatchEvent,
- base::Value(syncer::sync_ui_util::kOnCountersUpdated), *details);
+ DispatchEvent(syncer::sync_ui_util::kOnCountersUpdated, *details);
}
void SyncInternalsMessageHandler::HandleJsEvent(
@@ -222,25 +223,44 @@ void SyncInternalsMessageHandler::HandleJsEvent(
const JsEventDetails& details) {
DVLOG(1) << "Handling event: " << name
<< " with details " << details.ToString();
- web_ui()->CallJavascriptFunctionUnsafe(syncer::sync_ui_util::kDispatchEvent,
- base::Value(name), details.Get());
+ DispatchEvent(name, details.Get());
}
void SyncInternalsMessageHandler::SendAboutInfo() {
- ProfileSyncService* sync_service = GetProfileSyncService();
- SigninManagerBase* signin = sync_service ? sync_service->signin() : nullptr;
- std::unique_ptr<base::DictionaryValue> value =
- about_sync_data_extractor_->ConstructAboutInformation(sync_service,
- signin);
- web_ui()->CallJavascriptFunctionUnsafe(
- syncer::sync_ui_util::kDispatchEvent,
- base::Value(syncer::sync_ui_util::kOnAboutInfoUpdated), *value);
-}
-
-// Gets the ProfileSyncService of the underlying original profile.
-// May return NULL (e.g., if sync is disabled on the command line).
-ProfileSyncService* SyncInternalsMessageHandler::GetProfileSyncService() {
- Profile* profile = Profile::FromWebUI(web_ui());
+ std::unique_ptr<DictionaryValue> value = about_sync_data_delegate_.Run(
+ sync_service_provider_.Run(), chrome::GetChannel());
+ DispatchEvent(syncer::sync_ui_util::kOnAboutInfoUpdated, *value);
+}
+
+SyncService* SyncInternalsMessageHandler::BindForSyncServiceProvider() {
return ProfileSyncServiceFactory::GetForProfile(
- profile->GetOriginalProfile());
+ Profile::FromWebUI(web_ui())->GetOriginalProfile());
+}
+
+void SyncInternalsMessageHandler::DispatchEvent(const std::string& name,
+ const Value& details_value) {
+ CallJavascriptFunction(syncer::sync_ui_util::kDispatchEvent, Value(name),
+ details_value);
+}
+
+void SyncInternalsMessageHandler::UnregisterModelNotifications() {
+ SyncService* service = sync_service_provider_.Run();
+ if (!service)
+ return;
+
+ // Cannot use ScopedObserver to do all the tracking because most don't follow
+ // AddObserver/RemoveObserver method naming style.
+ if (is_registered_) {
+ DCHECK(js_controller_);
+ service->RemoveObserver(this);
+ service->RemoveProtocolEventObserver(this);
+ js_controller_->RemoveJsEventHandler(this);
+ js_controller_ = nullptr;
+ is_registered_ = false;
+ }
+
+ if (is_registered_for_counters_) {
+ service->RemoveTypeDebugInfoObserver(this);
+ is_registered_for_counters_ = false;
+ }
}

Powered by Google App Engine
This is Rietveld 408576698