1 // Copyright 2014 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.
5 #include "chrome/browser/ui/webui/sync_internals_message_handler.h"
9 #include "base/logging.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/sync/about_sync_util.h"
12 #include "chrome/browser/sync/profile_sync_service.h"
13 #include "chrome/browser/sync/profile_sync_service_factory.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/web_ui.h"
16 #include "sync/internal_api/public/events/protocol_event.h"
17 #include "sync/internal_api/public/util/weak_handle.h"
18 #include "sync/js/js_arg_list.h"
19 #include "sync/js/js_event_details.h"
21 using syncer::JsArgList;
22 using syncer::JsEventDetails;
23 using syncer::JsReplyHandler;
24 using syncer::ModelTypeSet;
25 using syncer::WeakHandle;
27 SyncInternalsMessageHandler::SyncInternalsMessageHandler()
28 : weak_ptr_factory_(this) {}
30 SyncInternalsMessageHandler::~SyncInternalsMessageHandler() {
32 js_controller_->RemoveJsEventHandler(this);
34 ProfileSyncService* service = GetProfileSyncService();
35 if (service && service->HasObserver(this)) {
36 service->RemoveObserver(this);
37 service->RemoveProtocolEventObserver(this);
41 void SyncInternalsMessageHandler::RegisterMessages() {
42 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
44 // Register for ProfileSyncService events.
45 ProfileSyncService* service = GetProfileSyncService();
47 service->AddObserver(this);
48 service->AddProtocolEventObserver(this);
49 js_controller_ = service->GetJsController();
50 js_controller_->AddJsEventHandler(this);
53 web_ui()->RegisterMessageCallback(
54 "requestUpdatedAboutInfo",
55 base::Bind(&SyncInternalsMessageHandler::HandleRequestUpdatedAboutInfo,
56 base::Unretained(this)));
58 web_ui()->RegisterMessageCallback(
60 base::Bind(&SyncInternalsMessageHandler::HandleRequestListOfTypes,
61 base::Unretained(this)));
63 RegisterJsControllerCallback("getAllNodes");
64 RegisterJsControllerCallback("getClientServerTraffic");
67 void SyncInternalsMessageHandler::HandleRequestUpdatedAboutInfo(
68 const base::ListValue* args) {
69 DCHECK(args->empty());
73 void SyncInternalsMessageHandler::HandleRequestListOfTypes(
74 const base::ListValue* args) {
75 DCHECK(args->empty());
76 base::DictionaryValue event_details;
77 scoped_ptr<base::ListValue> type_list(new base::ListValue());
78 ModelTypeSet protocol_types = syncer::ProtocolTypes();
79 for (ModelTypeSet::Iterator it = protocol_types.First();
80 it.Good(); it.Inc()) {
81 type_list->Append(new base::StringValue(ModelTypeToString(it.Get())));
83 event_details.Set("types", type_list.release());
84 web_ui()->CallJavascriptFunction(
85 "chrome.sync.dispatchEvent",
86 base::StringValue("onReceivedListOfTypes"),
90 void SyncInternalsMessageHandler::HandleJsReply(
91 const std::string& name, const JsArgList& args) {
92 DVLOG(1) << "Handling reply for " << name << " message"
93 << " with args " << args.ToString();
94 const std::string& reply_handler = "chrome.sync." + name + ".handleReply";
95 std::vector<const base::Value*> arg_list(args.Get().begin(),
97 web_ui()->CallJavascriptFunction(reply_handler, arg_list);
100 void SyncInternalsMessageHandler::OnStateChanged() {
104 void SyncInternalsMessageHandler::OnProtocolEvent(
105 const syncer::ProtocolEvent& event) {
106 scoped_ptr<base::DictionaryValue> value(
107 syncer::ProtocolEvent::ToValue(event));
108 web_ui()->CallJavascriptFunction(
109 "chrome.sync.dispatchEvent",
110 base::StringValue("onProtocolEvent"),
114 void SyncInternalsMessageHandler::HandleJsEvent(
115 const std::string& name,
116 const JsEventDetails& details) {
117 DVLOG(1) << "Handling event: " << name
118 << " with details " << details.ToString();
119 web_ui()->CallJavascriptFunction("chrome.sync.dispatchEvent",
120 base::StringValue(name),
124 void SyncInternalsMessageHandler::RegisterJsControllerCallback(
125 const std::string& name) {
126 web_ui()->RegisterMessageCallback(
128 base::Bind(&SyncInternalsMessageHandler::ForwardToJsController,
129 base::Unretained(this),
133 void SyncInternalsMessageHandler::SendAboutInfo() {
134 scoped_ptr<base::DictionaryValue> value =
135 sync_ui_util::ConstructAboutInformation(GetProfileSyncService());
136 web_ui()->CallJavascriptFunction(
137 "chrome.sync.dispatchEvent",
138 base::StringValue("onAboutInfoUpdated"),
142 void SyncInternalsMessageHandler::ForwardToJsController(
143 const std::string& name,
144 const base::ListValue* args) {
145 if (js_controller_) {
146 scoped_ptr<base::ListValue> args_copy(args->DeepCopy());
147 JsArgList js_arg_list(args_copy.get());
148 js_controller_->ProcessJsMessage(
150 MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()));
152 DLOG(WARNING) << "No sync service; dropping message " << name;
156 // Gets the ProfileSyncService of the underlying original profile.
157 // May return NULL (e.g., if sync is disabled on the command line).
158 ProfileSyncService* SyncInternalsMessageHandler::GetProfileSyncService() {
159 Profile* profile = Profile::FromWebUI(web_ui());
160 ProfileSyncServiceFactory* factory = ProfileSyncServiceFactory::GetInstance();
161 return factory->GetForProfile(profile->GetOriginalProfile());