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

Side by Side Diff: chrome/browser/sync/about_sync_util.cc

Issue 10696107: sync: Track validity of about:sync fields (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Move code between files Created 8 years, 5 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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.
4
5 #include "chrome/browser/sync/about_sync_util.h"
6
7 #include <string>
8
9 #include "base/string16.h"
10 #include "base/values.h"
11 #include "chrome/browser/signin/signin_manager.h"
12 #include "chrome/browser/sync/profile_sync_service.h"
13 #include "chrome/common/chrome_version_info.h"
14 #include "sync/protocol/proto_enum_conversions.h"
15
16 namespace {
17
18 // Creates a 'section' for discplay on about:sync, consisting of a title
akalin 2012/07/12 00:01:55 discplay -> display
rlarocque 2012/07/12 01:02:20 Done.
19 // and a list of fields.
20 ListValue* AddSection(ListValue* parent_list, const std::string& title) {
akalin 2012/07/12 00:01:55 scoped_ptr<>?
rlarocque 2012/07/12 01:02:20 That would be wrong in this case. The pointer is
21 DictionaryValue* section = new DictionaryValue();
22 ListValue* section_contents = new ListValue();
23 section->SetString("title", title);
24 section->Set("data", section_contents);
25 parent_list->Append(section);
26 return section_contents;
27 }
28
29 // The following helper classes help manage the about:sync fields which will be
30 // populated in method in ConstructAboutInformation.
31 //
32 // Each instance of one of thse classes indicates a field in about:sync. Each
33 // field will be serialized to a DictionaryValue with entries for 'stat_name',
34 // 'stat_value' and 'is_valid'.
35
36 class StringSyncStat {
37 public:
38 StringSyncStat(ListValue* section, const std::string& key);
39 void SetValue(std::string value);
akalin 2012/07/12 00:01:55 const ref?
rlarocque 2012/07/12 01:02:20 Done.
40 void SetValue(string16 value);
akalin 2012/07/12 00:01:55 const ref?
rlarocque 2012/07/12 01:02:20 Done.
41
42 private:
43 DictionaryValue* stat_;
akalin 2012/07/12 00:01:55 specify that this is owned by |section| (Value* c
rlarocque 2012/07/12 01:02:20 Done.
44 };
45
46 StringSyncStat::StringSyncStat(ListValue* section, const std::string& key) {
47 stat_ = new DictionaryValue();
48 stat_->SetString("stat_name", key);
49 stat_->SetString("stat_value", "Uninitialized");
50 stat_->SetBoolean("is_valid", false);
51 section->Append(stat_);
52 }
53
54 void StringSyncStat::SetValue(std::string value) {
55 stat_->SetString("stat_value", value);
56 stat_->SetBoolean("is_valid", true);
57 }
58
59 void StringSyncStat::SetValue(string16 value) {
60 stat_->SetString("stat_value", value);
61 stat_->SetBoolean("is_valid", true);
62 }
63
64 class BoolSyncStat {
65 public:
66 BoolSyncStat(ListValue* section, const std::string& key);
67 void SetValue(bool value);
68
69 private:
70 DictionaryValue* stat_;
71 };
72
73 BoolSyncStat::BoolSyncStat(ListValue* section, const std::string& key) {
74 stat_ = new DictionaryValue();
75 stat_->SetString("stat_name", key);
76 stat_->SetBoolean("stat_value", false);
77 stat_->SetBoolean("is_valid", false);
78 section->Append(stat_);
79 }
80
81 void BoolSyncStat::SetValue(bool value) {
82 stat_->SetBoolean("stat_value", value);
83 stat_->SetBoolean("is_valid", true);
84 }
85
86 class IntSyncStat {
87 public:
88 IntSyncStat(ListValue* section, const std::string& key);
89 void SetValue(int value);
90
91 private:
92 DictionaryValue* stat_;
93 };
94
95 IntSyncStat::IntSyncStat(ListValue* section, const std::string& key) {
96 stat_ = new DictionaryValue();
97 stat_->SetString("stat_name", key);
98 stat_->SetInteger("stat_value", 0);
99 stat_->SetBoolean("is_valid", false);
100 section->Append(stat_);
101 }
102
103 void IntSyncStat::SetValue(int value) {
104 stat_->SetInteger("stat_value", value);
105 stat_->SetBoolean("is_valid", true);
106 }
107
108 // Returns a string describing the chrome version environment. Version format:
109 // <Build Info> <OS> <Version number> (<Last change>)<channel or "-devel">
110 // If version information is unavailable, returns "invalid."
111 // TODO(zea): this approximately matches MakeUserAgentForSyncApi in
112 // sync_backend_host.cc. Unify the two if possible.
113 std::string GetVersionString() {
114 // Build a version string that matches MakeUserAgentForSyncApi with the
115 // addition of channel info and proper OS names.
116 chrome::VersionInfo chrome_version;
117 if (!chrome_version.is_valid())
118 return "invalid";
119 // GetVersionStringModifier returns empty string for stable channel or
120 // unofficial builds, the channel string otherwise. We want to have "-devel"
121 // for unofficial builds only.
122 std::string version_modifier =
123 chrome::VersionInfo::GetVersionStringModifier();
124 if (version_modifier.empty()) {
125 if (chrome::VersionInfo::GetChannel() !=
126 chrome::VersionInfo::CHANNEL_STABLE) {
127 version_modifier = "-devel";
128 }
129 } else {
130 version_modifier = " " + version_modifier;
131 }
132 return chrome_version.Name() + " " + chrome_version.OSType() + " " +
133 chrome_version.Version() + " (" + chrome_version.LastChange() + ")" +
134 version_modifier;
135 }
136
137 } // namespace
138
139 namespace sync_ui_util {
140
141 // This function both defines the structure of the message to be returned and
142 // its contents. Most of the message consists of simple fields in about:sync
143 // which are grouped into sections and populated with the help of the SyncStat
144 // classes defined above.
145 DictionaryValue* ConstructAboutInformation(ProfileSyncService* service) {
146 DictionaryValue* strings = new DictionaryValue(); // The value to return.
akalin 2012/07/12 00:01:55 scoped_ptr?
rlarocque 2012/07/12 01:02:20 Done. I also renamed it because 'strings' is a ba
147 ListValue* stats_list = new ListValue(); // 'details': A list of sections.
148
149 // The following lines define the sections and their fields. For each field,
150 // a class is instantiated, which allows us to reference the fields in
151 // 'setter' code later on in this function.
152 ListValue* section_summary = AddSection(stats_list, "Summary");
153 StringSyncStat summary_string(section_summary, "Summary");
154
155 ListValue* section_version = AddSection(stats_list, "Version Info");
156 StringSyncStat client_version(section_version, "Client Version");
157 StringSyncStat server_url(section_version, "Server URL");
158
159 ListValue* section_credentials = AddSection(stats_list, "Credentials");
160 StringSyncStat client_id(section_credentials, "Client ID");
161 StringSyncStat username(section_credentials, "Username");
162 BoolSyncStat is_token_available(section_credentials, "Sync Token Available");
163
164 ListValue* section_local = AddSection(stats_list, "Local State");
165 StringSyncStat last_synced(section_local, "Last Synced");
166 BoolSyncStat is_setup_complete(section_local,
167 "Sync First-Time Setup Complete");
168 BoolSyncStat is_backend_initialized(section_local,
169 "Sync Backend Initialized");
170 BoolSyncStat is_download_complete(section_local, "Initial Download Complete");
171 BoolSyncStat is_syncing(section_local, "Syncing");
172
173 ListValue* section_network = AddSection(stats_list, "Network");
174 BoolSyncStat is_throttled(section_network, "Throttled");
175 BoolSyncStat are_notifications_enabled(section_network,
176 "Notifications Enabled");
177
178 ListValue* section_encryption = AddSection(stats_list, "Encryption");
179 BoolSyncStat is_using_explicit_passphrase(section_encryption,
180 "Explicit Passphrase");
181 BoolSyncStat is_passphrase_required(section_encryption,
182 "Passphrase Required");
183 BoolSyncStat is_cryptographer_ready(section_encryption,
184 "Cryptographer Ready");
185 BoolSyncStat has_pending_keys(section_encryption,
186 "Cryptographer Has Pending Keys");
187 StringSyncStat encrypted_types(section_encryption, "Encrypted Types");
188
189 ListValue* section_last_session = AddSection(
190 stats_list, "Status from Last Completed Session");
191 StringSyncStat session_source(section_last_session, "Sync Source");
192 StringSyncStat download_result(section_last_session, "Download Step Result");
193 StringSyncStat commit_result(section_last_session, "Commit Step Result");
194
195 ListValue* section_counters = AddSection(stats_list, "Running Totals");
196 IntSyncStat notifications_received(section_counters,
197 "Notifications Received");
198 IntSyncStat empty_get_updates(section_counters, "Cycles Without Updates");
199 IntSyncStat non_empty_get_updates(section_counters, "Cycles With Updated");
200 IntSyncStat sync_cycles_without_commits(section_counters,
201 "Cycles Without Commits");
202 IntSyncStat sync_cycles_with_commits(section_counters, "Cycles With Commits");
203 IntSyncStat useless_sync_cycles(section_counters,
204 "Cycles Without Commits or Updates");
205 IntSyncStat useful_sync_cycles(section_counters,
206 "Cycles With Commit or Update");
207 IntSyncStat updates_received(section_counters, "Updates Downloaded");
208 IntSyncStat tombstone_updates(section_counters, "Tombstone Updates");
209 IntSyncStat reflected_updates(section_counters, "Reflected Updates");
210 IntSyncStat successful_commits(section_counters, "Syccessful Commits");
211 IntSyncStat conflicts_resolved_local_wins(section_counters,
212 "Conflicts Resolved: Client Wins");
213 IntSyncStat conflicts_resolved_server_wins(section_counters,
214 "Conflicts Resolved: Server Wins");
215
216 ListValue *section_this_cycle = AddSection(stats_list,
217 "Transient Counters (this cycle)");
218 IntSyncStat encryption_conflicts(section_this_cycle, "Encryption Conflicts");
219 IntSyncStat hierarchy_conflicts(section_this_cycle, "Hierarchy Conflicts");
220 IntSyncStat simple_conflicts(section_this_cycle, "Simple Conflicts");
221 IntSyncStat server_conflicts(section_this_cycle, "Server Conflicts");
222 IntSyncStat committed_items(section_this_cycle, "Committed Items");
223 IntSyncStat updates_remaining(section_this_cycle, "Updates Remaining");
224
225 ListValue* section_that_cycle = AddSection(
226 stats_list, "Transient Counters (last cycle of last completed session)");
227 IntSyncStat updates_downloaded(section_that_cycle, "Updates Downloaded");
228 IntSyncStat committed_count(section_that_cycle, "Committed Count");
229 IntSyncStat entries(section_that_cycle, "Entries");
230
231 // This list of sections belongs in the 'details' field of the returned
232 // message.
233 strings->Set("details", stats_list);
234
235 // Populate all the fields we declared above.
236 if (!service) {
237 summary_string.SetValue("Sync service does not exist");
238 return strings;
239 }
240
241 syncer::SyncStatus full_status;
242 bool is_status_valid = service->QueryDetailedSyncStatus(&full_status);
243 bool sync_initialized = service->sync_initialized();
244 const syncer::sessions::SyncSessionSnapshot& snapshot =
245 sync_initialized ?
246 service->GetLastSessionSnapshot() :
247 syncer::sessions::SyncSessionSnapshot();
248
249 if (is_status_valid)
250 summary_string.SetValue(service->QuerySyncStatusSummary());
251
252 client_version.SetValue(GetVersionString());
akalin 2012/07/12 00:01:55 move client_version line before !service check?
rlarocque 2012/07/12 01:02:20 Done.
253 server_url.SetValue(service->sync_service_url().spec());
254
255 if (is_status_valid && !full_status.unique_id.empty())
256 client_id.SetValue(full_status.unique_id);
257 if (service->signin())
258 username.SetValue(service->signin()->GetAuthenticatedUsername());
259 is_token_available.SetValue(service->IsSyncTokenAvailable());
260
261 last_synced.SetValue(service->GetLastSyncedTimeString());
262 is_setup_complete.SetValue(service->HasSyncSetupCompleted());
263 is_backend_initialized.SetValue(sync_initialized);
264 if (is_status_valid) {
265 is_download_complete.SetValue(full_status.initial_sync_ended);
266 is_syncing.SetValue(full_status.syncing);
267 }
268
269 if (snapshot.is_initialized())
270 is_throttled.SetValue(snapshot.is_silenced());
271 if (is_status_valid) {
272 are_notifications_enabled.SetValue(
273 full_status.notifications_enabled);
274 }
275
276 if (sync_initialized) {
277 is_using_explicit_passphrase.SetValue(
278 service->IsUsingSecondaryPassphrase());
279 is_passphrase_required.SetValue(service->IsPassphraseRequired());
280 }
281 if (is_status_valid) {
282 is_cryptographer_ready.SetValue(full_status.cryptographer_ready);
283 has_pending_keys.SetValue(full_status.crypto_has_pending_keys);
284 encrypted_types.SetValue(
285 ModelTypeSetToString(full_status.encrypted_types));
286 }
287
288 if (snapshot.is_initialized()) {
289 session_source.SetValue(
290 syncer::GetUpdatesSourceString(snapshot.source().updates_source));
291 download_result.SetValue(
292 GetSyncerErrorString(
293 snapshot.model_neutral_state().last_download_updates_result));
294 commit_result.SetValue(
295 GetSyncerErrorString(
296 snapshot.model_neutral_state().commit_result));
297 }
298
299 if (is_status_valid) {
300 notifications_received.SetValue(full_status.notifications_received);
301 empty_get_updates.SetValue(full_status.empty_get_updates);
302 non_empty_get_updates.SetValue(full_status.nonempty_get_updates);
303 sync_cycles_without_commits.SetValue(
304 full_status.sync_cycles_without_commits);
305 sync_cycles_with_commits.SetValue(
306 full_status.sync_cycles_with_commits);
307 useless_sync_cycles.SetValue(full_status.useless_sync_cycles);
308 useful_sync_cycles.SetValue(full_status.useful_sync_cycles);
309 updates_received.SetValue(full_status.updates_received);
310 tombstone_updates.SetValue(full_status.tombstone_updates_received);
311 reflected_updates.SetValue(full_status.reflected_updates_received);
312 successful_commits.SetValue(full_status.num_commits_total);
313 conflicts_resolved_local_wins.SetValue(
314 full_status.num_local_overwrites_total);
315 conflicts_resolved_server_wins.SetValue(
316 full_status.num_server_overwrites_total);
317 }
318
319 if (is_status_valid) {
320 encryption_conflicts.SetValue(full_status.encryption_conflicts);
321 hierarchy_conflicts.SetValue(full_status.hierarchy_conflicts);
322 simple_conflicts.SetValue(full_status.simple_conflicts);
323 server_conflicts.SetValue(full_status.server_conflicts);
324 committed_items.SetValue(full_status.committed_count);
325 updates_remaining.SetValue(full_status.updates_available);
326 }
327
328 if (snapshot.is_initialized()) {
329 updates_downloaded.SetValue(
330 snapshot.model_neutral_state().num_updates_downloaded_total);
331 committed_count.SetValue(
332 snapshot.model_neutral_state().num_successful_commits);
333 entries.SetValue(snapshot.num_entries());
334 }
335
336 // The values set from this point onwards do not belong in the
337 // details list.
338
339 // We don't need to check is_status_valid here.
340 // full_status.sync_protocol_error is exported directly from the
341 // ProfileSyncService, even if the backend doesn't exist.
342 const bool actionable_error_detected =
343 full_status.sync_protocol_error.error_type != syncer::UNKNOWN_ERROR &&
344 full_status.sync_protocol_error.error_type != syncer::SYNC_SUCCESS;
345
346 strings->Set("actionable_error_detected",
akalin 2012/07/12 00:01:55 SetString?
rlarocque 2012/07/12 01:02:20 SetBoolean.
347 new base::FundamentalValue(actionable_error_detected));
348
349 // NOTE: We won't bother showing any of the following values unless
350 // actionable_error_detected is set.
351
352 ListValue* actionable_error = new ListValue();
353 strings->Set("actionable_error", actionable_error);
akalin 2012/07/12 00:01:55 shouldn't this go in the if (actionable_error_dete
rlarocque 2012/07/12 01:02:20 That's debatable. If !actionable_error_detected,
354
355 StringSyncStat error_type(actionable_error, "Error Type");
356 StringSyncStat action(actionable_error, "Action");
357 StringSyncStat url(actionable_error, "URL");
358 StringSyncStat description(actionable_error, "Error Description");
359
360 if (actionable_error_detected) {
361 error_type.SetValue(syncer::GetSyncErrorTypeString(
362 full_status.sync_protocol_error.error_type));
363 action.SetValue(syncer::GetClientActionString(
364 full_status.sync_protocol_error.action));
365 url.SetValue(full_status.sync_protocol_error.url);
366 description.SetValue(full_status.sync_protocol_error.error_description);
367 }
368
369 strings->Set("unrecoverable_error_detected",
akalin 2012/07/12 00:01:55 SetString?
rlarocque 2012/07/12 01:02:20 I changed this to SetBoolean, too.
370 new base::FundamentalValue(service->HasUnrecoverableError()));
371
372 if (service->HasUnrecoverableError()) {
373 tracked_objects::Location loc(service->unrecoverable_error_location());
374 std::string location_str;
375 loc.Write(true, true, &location_str);
376 std::string unrecoverable_error_message =
377 "Unrecoverable error detected at " + location_str +
378 ": " + service->unrecoverable_error_message();
379 strings->SetString("unrecoverable_error_message",
380 unrecoverable_error_message);
381 }
382
383 strings->Set("type_status", service->GetTypeStatusMap());
384
385 return strings;
386 }
387
388 } // namespace sync_ui_util
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698