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

Side by Side Diff: chrome/browser/ui/webui/sync_internals_message_handler.cc

Issue 2898723003: [Sync] Migrate SyncInternalsMessageHandler off CallJavascriptFunctionUnsafe. (Closed)
Patch Set: Fix Android compile. 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/webui/sync_internals_message_handler.h" 5 #include "chrome/browser/ui/webui/sync_internals_message_handler.h"
6 6
7 #include <stdint.h>
8
7 #include <utility> 9 #include <utility>
8 #include <vector> 10 #include <vector>
9 11
10 #include "base/logging.h" 12 #include "base/logging.h"
11 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
12 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/sync/profile_sync_service_factory.h" 15 #include "chrome/browser/sync/profile_sync_service_factory.h"
14 #include "chrome/common/channel_info.h" 16 #include "chrome/common/channel_info.h"
15 #include "components/browser_sync/profile_sync_service.h" 17 #include "components/browser_sync/profile_sync_service.h"
16 #include "components/signin/core/browser/signin_manager_base.h"
17 #include "components/sync/base/weak_handle.h" 18 #include "components/sync/base/weak_handle.h"
18 #include "components/sync/driver/about_sync_util.h" 19 #include "components/sync/driver/about_sync_util.h"
19 #include "components/sync/driver/sync_service.h" 20 #include "components/sync/driver/sync_service.h"
20 #include "components/sync/engine/cycle/commit_counters.h" 21 #include "components/sync/engine/cycle/commit_counters.h"
21 #include "components/sync/engine/cycle/status_counters.h" 22 #include "components/sync/engine/cycle/status_counters.h"
22 #include "components/sync/engine/cycle/update_counters.h" 23 #include "components/sync/engine/cycle/update_counters.h"
23 #include "components/sync/engine/events/protocol_event.h" 24 #include "components/sync/engine/events/protocol_event.h"
24 #include "components/sync/js/js_event_details.h" 25 #include "components/sync/js/js_event_details.h"
25 #include "content/public/browser/browser_thread.h" 26 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/web_ui.h" 27 #include "content/public/browser/web_ui.h"
27 28
29 using base::DictionaryValue;
30 using base::ListValue;
31 using base::Value;
28 using browser_sync::ProfileSyncService; 32 using browser_sync::ProfileSyncService;
29 using syncer::JsEventDetails; 33 using syncer::JsEventDetails;
30 using syncer::ModelTypeSet; 34 using syncer::ModelTypeSet;
35 using syncer::SyncService;
31 using syncer::WeakHandle; 36 using syncer::WeakHandle;
32 37
33 namespace {
34 class UtilAboutSyncDataExtractor : public AboutSyncDataExtractor {
35 public:
36 std::unique_ptr<base::DictionaryValue> ConstructAboutInformation(
37 syncer::SyncService* service,
38 SigninManagerBase* signin) override {
39 return syncer::sync_ui_util::ConstructAboutInformation(
40 service, signin, chrome::GetChannel());
41 }
42 };
43 } // namespace
44
45 SyncInternalsMessageHandler::SyncInternalsMessageHandler() 38 SyncInternalsMessageHandler::SyncInternalsMessageHandler()
46 : SyncInternalsMessageHandler( 39 : SyncInternalsMessageHandler(
47 base::MakeUnique<UtilAboutSyncDataExtractor>()) {} 40 base::BindRepeating(
41 &SyncInternalsMessageHandler::BindForSyncServiceProvider,
42 base::Unretained(this)),
43 base::BindRepeating(
44 &syncer::sync_ui_util::ConstructAboutInformation)) {}
48 45
49 SyncInternalsMessageHandler::SyncInternalsMessageHandler( 46 SyncInternalsMessageHandler::SyncInternalsMessageHandler(
50 std::unique_ptr<AboutSyncDataExtractor> about_sync_data_extractor) 47 SyncServiceProvider sync_service_provider,
51 : about_sync_data_extractor_(std::move(about_sync_data_extractor)), 48 AboutSyncDataDelegate about_sync_data_delegate)
49 : sync_service_provider_(std::move(sync_service_provider)),
50 about_sync_data_delegate_(std::move(about_sync_data_delegate)),
52 weak_ptr_factory_(this) {} 51 weak_ptr_factory_(this) {}
53 52
54 SyncInternalsMessageHandler::~SyncInternalsMessageHandler() { 53 SyncInternalsMessageHandler::~SyncInternalsMessageHandler() {
55 if (js_controller_) 54 UnregisterModelNotifications();
56 js_controller_->RemoveJsEventHandler(this); 55 }
57 56
58 ProfileSyncService* service = GetProfileSyncService(); 57 void SyncInternalsMessageHandler::OnJavascriptDisallowed() {
59 if (service && service->HasObserver(this)) { 58 UnregisterModelNotifications();
Dan Beam 2017/05/22 23:31:43 can we just call weak_ptr_factory_.InvalidateWeakP
skym 2017/05/24 00:20:16 Woah. It seems I can call WeakPtrFactory::Invalida
60 service->RemoveObserver(this);
61 service->RemoveProtocolEventObserver(this);
62 }
63
64 if (service && is_registered_for_counters_) {
65 service->RemoveTypeDebugInfoObserver(this);
66 }
67 } 59 }
68 60
69 void SyncInternalsMessageHandler::RegisterMessages() { 61 void SyncInternalsMessageHandler::RegisterMessages() {
70 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 62 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
71 63
72 web_ui()->RegisterMessageCallback( 64 web_ui()->RegisterMessageCallback(
73 syncer::sync_ui_util::kRegisterForEvents, 65 syncer::sync_ui_util::kRegisterForEvents,
74 base::Bind(&SyncInternalsMessageHandler::HandleRegisterForEvents, 66 base::Bind(&SyncInternalsMessageHandler::HandleRegisterForEvents,
75 base::Unretained(this))); 67 base::Unretained(this)));
76 68
(...skipping 12 matching lines...) Expand all
89 base::Bind(&SyncInternalsMessageHandler::HandleRequestListOfTypes, 81 base::Bind(&SyncInternalsMessageHandler::HandleRequestListOfTypes,
90 base::Unretained(this))); 82 base::Unretained(this)));
91 83
92 web_ui()->RegisterMessageCallback( 84 web_ui()->RegisterMessageCallback(
93 syncer::sync_ui_util::kGetAllNodes, 85 syncer::sync_ui_util::kGetAllNodes,
94 base::Bind(&SyncInternalsMessageHandler::HandleGetAllNodes, 86 base::Bind(&SyncInternalsMessageHandler::HandleGetAllNodes,
95 base::Unretained(this))); 87 base::Unretained(this)));
96 } 88 }
97 89
98 void SyncInternalsMessageHandler::HandleRegisterForEvents( 90 void SyncInternalsMessageHandler::HandleRegisterForEvents(
99 const base::ListValue* args) { 91 const ListValue* args) {
100 DCHECK(args->empty()); 92 DCHECK(args->empty());
93 AllowJavascript();
101 94
102 // is_registered_ flag protects us from double-registering. This could 95 // is_registered_ flag protects us from double-registering. This could
103 // happen on a page refresh, where the JavaScript gets re-run but the 96 // happen on a page refresh, where the JavaScript gets re-run but the
104 // message handler remains unchanged. 97 // message handler remains unchanged.
105 ProfileSyncService* service = GetProfileSyncService(); 98 SyncService* service = sync_service_provider_.Run();
106 if (service && !is_registered_) { 99 if (service && !is_registered_) {
107 service->AddObserver(this); 100 service->AddObserver(this);
108 service->AddProtocolEventObserver(this); 101 service->AddProtocolEventObserver(this);
109 js_controller_ = service->GetJsController(); 102 js_controller_ = service->GetJsController();
110 js_controller_->AddJsEventHandler(this); 103 js_controller_->AddJsEventHandler(this);
111 is_registered_ = true; 104 is_registered_ = true;
112 } 105 }
113 } 106 }
114 107
115 void SyncInternalsMessageHandler::HandleRegisterForPerTypeCounters( 108 void SyncInternalsMessageHandler::HandleRegisterForPerTypeCounters(
116 const base::ListValue* args) { 109 const ListValue* args) {
117 DCHECK(args->empty()); 110 DCHECK(args->empty());
111 AllowJavascript();
118 112
119 if (ProfileSyncService* service = GetProfileSyncService()) { 113 if (SyncService* service = sync_service_provider_.Run()) {
Dan Beam 2017/05/22 23:31:43 i think it's fairly uncommon to do assignment in a
skym 2017/05/24 00:20:16 Moved this invocation out of the if check, added a
120 if (!is_registered_for_counters_) { 114 if (!is_registered_for_counters_) {
121 service->AddTypeDebugInfoObserver(this); 115 service->AddTypeDebugInfoObserver(this);
122 is_registered_for_counters_ = true; 116 is_registered_for_counters_ = true;
123 } else { 117 } else {
124 // Re-register to ensure counters get re-emitted. 118 // Re-register to ensure counters get re-emitted.
125 service->RemoveTypeDebugInfoObserver(this); 119 service->RemoveTypeDebugInfoObserver(this);
126 service->AddTypeDebugInfoObserver(this); 120 service->AddTypeDebugInfoObserver(this);
127 } 121 }
128 } 122 }
129 } 123 }
130 124
131 void SyncInternalsMessageHandler::HandleRequestUpdatedAboutInfo( 125 void SyncInternalsMessageHandler::HandleRequestUpdatedAboutInfo(
132 const base::ListValue* args) { 126 const ListValue* args) {
133 DCHECK(args->empty()); 127 DCHECK(args->empty());
128 AllowJavascript();
134 SendAboutInfo(); 129 SendAboutInfo();
135 } 130 }
136 131
137 void SyncInternalsMessageHandler::HandleRequestListOfTypes( 132 void SyncInternalsMessageHandler::HandleRequestListOfTypes(
138 const base::ListValue* args) { 133 const ListValue* args) {
139 DCHECK(args->empty()); 134 DCHECK(args->empty());
140 base::DictionaryValue event_details; 135 AllowJavascript();
141 std::unique_ptr<base::ListValue> type_list(new base::ListValue()); 136
142 ModelTypeSet protocol_types = syncer::ProtocolTypes(); 137 DictionaryValue event_details;
143 for (ModelTypeSet::Iterator it = protocol_types.First(); 138 auto type_list = base::MakeUnique<ListValue>();
144 it.Good(); it.Inc()) { 139 for (ModelTypeSet::Iterator it = syncer::ProtocolTypes().First(); it.Good();
140 it.Inc()) {
145 type_list->AppendString(ModelTypeToString(it.Get())); 141 type_list->AppendString(ModelTypeToString(it.Get()));
146 } 142 }
147 event_details.Set(syncer::sync_ui_util::kTypes, std::move(type_list)); 143 event_details.Set(syncer::sync_ui_util::kTypes, std::move(type_list));
148 web_ui()->CallJavascriptFunctionUnsafe( 144 DispatchEvent(syncer::sync_ui_util::kOnReceivedListOfTypes, event_details);
149 syncer::sync_ui_util::kDispatchEvent,
150 base::Value(syncer::sync_ui_util::kOnReceivedListOfTypes), event_details);
151 } 145 }
152 146
153 void SyncInternalsMessageHandler::HandleGetAllNodes( 147 void SyncInternalsMessageHandler::HandleGetAllNodes(const ListValue* args) {
154 const base::ListValue* args) {
155 DCHECK_EQ(1U, args->GetSize()); 148 DCHECK_EQ(1U, args->GetSize());
149 AllowJavascript();
150
156 int request_id = 0; 151 int request_id = 0;
157 bool success = ExtractIntegerValue(args, &request_id); 152 bool success = ExtractIntegerValue(args, &request_id);
158 DCHECK(success); 153 DCHECK(success);
159 154
160 ProfileSyncService* service = GetProfileSyncService(); 155 SyncService* service = sync_service_provider_.Run();
161 if (service) { 156 if (service) {
162 service->GetAllNodes( 157 service->GetAllNodes(
163 base::Bind(&SyncInternalsMessageHandler::OnReceivedAllNodes, 158 base::Bind(&SyncInternalsMessageHandler::OnReceivedAllNodes,
164 weak_ptr_factory_.GetWeakPtr(), request_id)); 159 weak_ptr_factory_.GetWeakPtr(), request_id));
165 } 160 }
166 } 161 }
167 162
168 void SyncInternalsMessageHandler::OnReceivedAllNodes( 163 void SyncInternalsMessageHandler::OnReceivedAllNodes(
169 int request_id, 164 int request_id,
170 std::unique_ptr<base::ListValue> nodes) { 165 std::unique_ptr<ListValue> nodes) {
171 base::Value id(request_id); 166 // This is a callback that's invoked asyncrhonously. However, it's possible
172 web_ui()->CallJavascriptFunctionUnsafe( 167 // that our UI is no longer allowing javascript, and we need to manually check
173 syncer::sync_ui_util::kGetAllNodesCallback, id, *nodes); 168 // before proceeding.
169 if (IsJavascriptAllowed()) {
170 CallJavascriptFunction(syncer::sync_ui_util::kGetAllNodesCallback,
171 Value(request_id), *nodes);
172 }
174 } 173 }
175 174
176 void SyncInternalsMessageHandler::OnStateChanged(syncer::SyncService* sync) { 175 void SyncInternalsMessageHandler::OnStateChanged(SyncService* sync) {
177 SendAboutInfo(); 176 SendAboutInfo();
178 } 177 }
179 178
180 void SyncInternalsMessageHandler::OnProtocolEvent( 179 void SyncInternalsMessageHandler::OnProtocolEvent(
181 const syncer::ProtocolEvent& event) { 180 const syncer::ProtocolEvent& event) {
182 std::unique_ptr<base::DictionaryValue> value( 181 std::unique_ptr<DictionaryValue> value(syncer::ProtocolEvent::ToValue(event));
183 syncer::ProtocolEvent::ToValue(event)); 182 DispatchEvent(syncer::sync_ui_util::kOnProtocolEvent, *value);
184 web_ui()->CallJavascriptFunctionUnsafe(
185 syncer::sync_ui_util::kDispatchEvent,
186 base::Value(syncer::sync_ui_util::kOnProtocolEvent), *value);
187 } 183 }
188 184
189 void SyncInternalsMessageHandler::OnCommitCountersUpdated( 185 void SyncInternalsMessageHandler::OnCommitCountersUpdated(
190 syncer::ModelType type, 186 syncer::ModelType type,
191 const syncer::CommitCounters& counters) { 187 const syncer::CommitCounters& counters) {
192 EmitCounterUpdate(type, syncer::sync_ui_util::kCommit, counters.ToValue()); 188 EmitCounterUpdate(type, syncer::sync_ui_util::kCommit, counters.ToValue());
193 } 189 }
194 190
195 void SyncInternalsMessageHandler::OnUpdateCountersUpdated( 191 void SyncInternalsMessageHandler::OnUpdateCountersUpdated(
196 syncer::ModelType type, 192 syncer::ModelType type,
197 const syncer::UpdateCounters& counters) { 193 const syncer::UpdateCounters& counters) {
198 EmitCounterUpdate(type, syncer::sync_ui_util::kUpdate, counters.ToValue()); 194 EmitCounterUpdate(type, syncer::sync_ui_util::kUpdate, counters.ToValue());
199 } 195 }
200 196
201 void SyncInternalsMessageHandler::OnStatusCountersUpdated( 197 void SyncInternalsMessageHandler::OnStatusCountersUpdated(
202 syncer::ModelType type, 198 syncer::ModelType type,
203 const syncer::StatusCounters& counters) { 199 const syncer::StatusCounters& counters) {
204 EmitCounterUpdate(type, syncer::sync_ui_util::kStatus, counters.ToValue()); 200 EmitCounterUpdate(type, syncer::sync_ui_util::kStatus, counters.ToValue());
205 } 201 }
206 202
207 void SyncInternalsMessageHandler::EmitCounterUpdate( 203 void SyncInternalsMessageHandler::EmitCounterUpdate(
208 syncer::ModelType type, 204 syncer::ModelType type,
209 const std::string& counter_type, 205 const std::string& counter_type,
210 std::unique_ptr<base::DictionaryValue> value) { 206 std::unique_ptr<DictionaryValue> value) {
211 std::unique_ptr<base::DictionaryValue> details(new base::DictionaryValue()); 207 auto details = base::MakeUnique<DictionaryValue>();
212 details->SetString(syncer::sync_ui_util::kModelType, ModelTypeToString(type)); 208 details->SetString(syncer::sync_ui_util::kModelType, ModelTypeToString(type));
213 details->SetString(syncer::sync_ui_util::kCounterType, counter_type); 209 details->SetString(syncer::sync_ui_util::kCounterType, counter_type);
214 details->Set(syncer::sync_ui_util::kCounters, std::move(value)); 210 details->Set(syncer::sync_ui_util::kCounters, std::move(value));
215 web_ui()->CallJavascriptFunctionUnsafe( 211 DispatchEvent(syncer::sync_ui_util::kOnCountersUpdated, *details);
216 syncer::sync_ui_util::kDispatchEvent,
217 base::Value(syncer::sync_ui_util::kOnCountersUpdated), *details);
218 } 212 }
219 213
220 void SyncInternalsMessageHandler::HandleJsEvent( 214 void SyncInternalsMessageHandler::HandleJsEvent(
221 const std::string& name, 215 const std::string& name,
222 const JsEventDetails& details) { 216 const JsEventDetails& details) {
223 DVLOG(1) << "Handling event: " << name 217 DVLOG(1) << "Handling event: " << name
224 << " with details " << details.ToString(); 218 << " with details " << details.ToString();
225 web_ui()->CallJavascriptFunctionUnsafe(syncer::sync_ui_util::kDispatchEvent, 219 DispatchEvent(name, details.Get());
226 base::Value(name), details.Get());
227 } 220 }
228 221
229 void SyncInternalsMessageHandler::SendAboutInfo() { 222 void SyncInternalsMessageHandler::SendAboutInfo() {
230 ProfileSyncService* sync_service = GetProfileSyncService(); 223 std::unique_ptr<DictionaryValue> value = about_sync_data_delegate_.Run(
231 SigninManagerBase* signin = sync_service ? sync_service->signin() : nullptr; 224 sync_service_provider_.Run(), chrome::GetChannel());
232 std::unique_ptr<base::DictionaryValue> value = 225 DispatchEvent(syncer::sync_ui_util::kOnAboutInfoUpdated, *value);
233 about_sync_data_extractor_->ConstructAboutInformation(sync_service,
234 signin);
235 web_ui()->CallJavascriptFunctionUnsafe(
236 syncer::sync_ui_util::kDispatchEvent,
237 base::Value(syncer::sync_ui_util::kOnAboutInfoUpdated), *value);
238 } 226 }
239 227
240 // Gets the ProfileSyncService of the underlying original profile. 228 SyncService* SyncInternalsMessageHandler::BindForSyncServiceProvider() {
241 // May return NULL (e.g., if sync is disabled on the command line).
242 ProfileSyncService* SyncInternalsMessageHandler::GetProfileSyncService() {
243 Profile* profile = Profile::FromWebUI(web_ui());
244 return ProfileSyncServiceFactory::GetForProfile( 229 return ProfileSyncServiceFactory::GetForProfile(
245 profile->GetOriginalProfile()); 230 Profile::FromWebUI(web_ui())->GetOriginalProfile());
246 } 231 }
232
233 void SyncInternalsMessageHandler::DispatchEvent(const std::string& name,
234 const Value& details_value) {
235 CallJavascriptFunction(syncer::sync_ui_util::kDispatchEvent, Value(name),
236 details_value);
237 }
238
239 void SyncInternalsMessageHandler::UnregisterModelNotifications() {
240 // Cannot use ScopedObserver to do all the tracking because most don't follow
241 // AddObserver/RemoveObserver method naming style.
242 SyncService* service = sync_service_provider_.Run();
Dan Beam 2017/05/22 23:31:43 can we get this later (inside both ifs) or early o
skym 2017/05/24 00:20:16 Done, and removed the DCHECKs that don't make sens
243 if (is_registered_) {
244 DCHECK(js_controller_);
245 DCHECK(service);
246
247 service->RemoveObserver(this);
248 service->RemoveProtocolEventObserver(this);
249 js_controller_->RemoveJsEventHandler(this);
250
251 js_controller_ = nullptr;
252 is_registered_ = false;
253 }
254
255 if (is_registered_for_counters_) {
256 DCHECK(service);
257 service->RemoveTypeDebugInfoObserver(this);
258 is_registered_for_counters_ = false;
259 }
260 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698