Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / webui / sync_internals_message_handler.cc
blobc6dc05aaadea34c2a82930e5620937d358d3a74b
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"
7 #include <vector>
9 #include "base/logging.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/sync/profile_sync_service.h"
12 #include "chrome/browser/sync/profile_sync_service_factory.h"
13 #include "chrome/common/channel_info.h"
14 #include "components/sync_driver/about_sync_util.h"
15 #include "components/sync_driver/about_sync_util.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/web_ui.h"
18 #include "sync/internal_api/public/events/protocol_event.h"
19 #include "sync/internal_api/public/sessions/commit_counters.h"
20 #include "sync/internal_api/public/sessions/status_counters.h"
21 #include "sync/internal_api/public/sessions/update_counters.h"
22 #include "sync/internal_api/public/util/weak_handle.h"
23 #include "sync/js/js_event_details.h"
25 using syncer::JsEventDetails;
26 using syncer::ModelTypeSet;
27 using syncer::WeakHandle;
29 SyncInternalsMessageHandler::SyncInternalsMessageHandler()
30 : is_registered_(false),
31 is_registered_for_counters_(false),
32 weak_ptr_factory_(this) {
35 SyncInternalsMessageHandler::~SyncInternalsMessageHandler() {
36 if (js_controller_)
37 js_controller_->RemoveJsEventHandler(this);
39 ProfileSyncService* service = GetProfileSyncService();
40 if (service && service->HasObserver(this)) {
41 service->RemoveObserver(this);
42 service->RemoveProtocolEventObserver(this);
45 if (service && is_registered_for_counters_) {
46 service->RemoveTypeDebugInfoObserver(this);
50 void SyncInternalsMessageHandler::RegisterMessages() {
51 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
53 web_ui()->RegisterMessageCallback(
54 sync_driver::sync_ui_util::kRegisterForEvents,
55 base::Bind(&SyncInternalsMessageHandler::HandleRegisterForEvents,
56 base::Unretained(this)));
58 web_ui()->RegisterMessageCallback(
59 sync_driver::sync_ui_util::kRegisterForPerTypeCounters,
60 base::Bind(&SyncInternalsMessageHandler::HandleRegisterForPerTypeCounters,
61 base::Unretained(this)));
63 web_ui()->RegisterMessageCallback(
64 sync_driver::sync_ui_util::kRequestUpdatedAboutInfo,
65 base::Bind(&SyncInternalsMessageHandler::HandleRequestUpdatedAboutInfo,
66 base::Unretained(this)));
68 web_ui()->RegisterMessageCallback(
69 sync_driver::sync_ui_util::kRequestListOfTypes,
70 base::Bind(&SyncInternalsMessageHandler::HandleRequestListOfTypes,
71 base::Unretained(this)));
73 web_ui()->RegisterMessageCallback(
74 sync_driver::sync_ui_util::kGetAllNodes,
75 base::Bind(&SyncInternalsMessageHandler::HandleGetAllNodes,
76 base::Unretained(this)));
79 void SyncInternalsMessageHandler::HandleRegisterForEvents(
80 const base::ListValue* args) {
81 DCHECK(args->empty());
83 // is_registered_ flag protects us from double-registering. This could
84 // happen on a page refresh, where the JavaScript gets re-run but the
85 // message handler remains unchanged.
86 ProfileSyncService* service = GetProfileSyncService();
87 if (service && !is_registered_) {
88 service->AddObserver(this);
89 service->AddProtocolEventObserver(this);
90 js_controller_ = service->GetJsController();
91 js_controller_->AddJsEventHandler(this);
92 is_registered_ = true;
96 void SyncInternalsMessageHandler::HandleRegisterForPerTypeCounters(
97 const base::ListValue* args) {
98 DCHECK(args->empty());
100 if (ProfileSyncService* service = GetProfileSyncService()) {
101 if (!is_registered_for_counters_) {
102 service->AddTypeDebugInfoObserver(this);
103 is_registered_for_counters_ = true;
104 } else {
105 // Re-register to ensure counters get re-emitted.
106 service->RemoveTypeDebugInfoObserver(this);
107 service->AddTypeDebugInfoObserver(this);
112 void SyncInternalsMessageHandler::HandleRequestUpdatedAboutInfo(
113 const base::ListValue* args) {
114 DCHECK(args->empty());
115 SendAboutInfo();
118 void SyncInternalsMessageHandler::HandleRequestListOfTypes(
119 const base::ListValue* args) {
120 DCHECK(args->empty());
121 base::DictionaryValue event_details;
122 scoped_ptr<base::ListValue> type_list(new base::ListValue());
123 ModelTypeSet protocol_types = syncer::ProtocolTypes();
124 for (ModelTypeSet::Iterator it = protocol_types.First();
125 it.Good(); it.Inc()) {
126 type_list->Append(new base::StringValue(ModelTypeToString(it.Get())));
128 event_details.Set(sync_driver::sync_ui_util::kTypes, type_list.release());
129 web_ui()->CallJavascriptFunction(
130 sync_driver::sync_ui_util::kDispatchEvent,
131 base::StringValue(sync_driver::sync_ui_util::kOnReceivedListOfTypes),
132 event_details);
135 void SyncInternalsMessageHandler::HandleGetAllNodes(
136 const base::ListValue* args) {
137 DCHECK_EQ(1U, args->GetSize());
138 int request_id = 0;
139 bool success = args->GetInteger(0, &request_id);
140 DCHECK(success);
142 ProfileSyncService* service = GetProfileSyncService();
143 if (service) {
144 service->GetAllNodes(
145 base::Bind(&SyncInternalsMessageHandler::OnReceivedAllNodes,
146 weak_ptr_factory_.GetWeakPtr(), request_id));
150 void SyncInternalsMessageHandler::OnReceivedAllNodes(
151 int request_id,
152 scoped_ptr<base::ListValue> nodes) {
153 base::FundamentalValue id(request_id);
154 web_ui()->CallJavascriptFunction(
155 sync_driver::sync_ui_util::kGetAllNodesCallback, id, *nodes);
158 void SyncInternalsMessageHandler::OnStateChanged() {
159 SendAboutInfo();
162 void SyncInternalsMessageHandler::OnProtocolEvent(
163 const syncer::ProtocolEvent& event) {
164 scoped_ptr<base::DictionaryValue> value(
165 syncer::ProtocolEvent::ToValue(event));
166 web_ui()->CallJavascriptFunction(
167 sync_driver::sync_ui_util::kDispatchEvent,
168 base::StringValue(sync_driver::sync_ui_util::kOnProtocolEvent), *value);
171 void SyncInternalsMessageHandler::OnCommitCountersUpdated(
172 syncer::ModelType type,
173 const syncer::CommitCounters& counters) {
174 EmitCounterUpdate(type, sync_driver::sync_ui_util::kCommit,
175 counters.ToValue());
178 void SyncInternalsMessageHandler::OnUpdateCountersUpdated(
179 syncer::ModelType type,
180 const syncer::UpdateCounters& counters) {
181 EmitCounterUpdate(type, sync_driver::sync_ui_util::kUpdate,
182 counters.ToValue());
185 void SyncInternalsMessageHandler::OnStatusCountersUpdated(
186 syncer::ModelType type,
187 const syncer::StatusCounters& counters) {
188 EmitCounterUpdate(type, sync_driver::sync_ui_util::kStatus,
189 counters.ToValue());
192 void SyncInternalsMessageHandler::EmitCounterUpdate(
193 syncer::ModelType type,
194 const std::string& counter_type,
195 scoped_ptr<base::DictionaryValue> value) {
196 scoped_ptr<base::DictionaryValue> details(new base::DictionaryValue());
197 details->SetString(sync_driver::sync_ui_util::kModelType,
198 ModelTypeToString(type));
199 details->SetString(sync_driver::sync_ui_util::kCounterType, counter_type);
200 details->Set(sync_driver::sync_ui_util::kCounters, value.release());
201 web_ui()->CallJavascriptFunction(
202 sync_driver::sync_ui_util::kDispatchEvent,
203 base::StringValue(sync_driver::sync_ui_util::kOnCountersUpdated),
204 *details);
207 void SyncInternalsMessageHandler::HandleJsEvent(
208 const std::string& name,
209 const JsEventDetails& details) {
210 DVLOG(1) << "Handling event: " << name
211 << " with details " << details.ToString();
212 web_ui()->CallJavascriptFunction(sync_driver::sync_ui_util::kDispatchEvent,
213 base::StringValue(name), details.Get());
216 void SyncInternalsMessageHandler::SendAboutInfo() {
217 ProfileSyncService* sync_service = GetProfileSyncService();
218 scoped_ptr<base::DictionaryValue> value =
219 sync_driver::sync_ui_util::ConstructAboutInformation(
220 sync_service, sync_service->signin(), chrome::GetChannel());
221 web_ui()->CallJavascriptFunction(
222 sync_driver::sync_ui_util::kDispatchEvent,
223 base::StringValue(sync_driver::sync_ui_util::kOnAboutInfoUpdated),
224 *value);
227 // Gets the ProfileSyncService of the underlying original profile.
228 // May return NULL (e.g., if sync is disabled on the command line).
229 ProfileSyncService* SyncInternalsMessageHandler::GetProfileSyncService() {
230 Profile* profile = Profile::FromWebUI(web_ui());
231 return ProfileSyncServiceFactory::GetForProfile(
232 profile->GetOriginalProfile());