sync: Add UI code for per type debug counters

Adds a new tab to the about:sync page to display the latest per-type
counters.  These counters will eventually replace the StatusControllers
that contain much of the same information.

This includes some changes to the C++ SyncInternalsMessageHandler to
register to observe these counters as well as some new WebUI to display
them.

There is a known bug in this code.  The StausCounter update logic has
not been implemented yet, so the item counts will always be zero.  This
will be fixed in a future CL.

BUG=349301

Review URL: https://codereview.chromium.org/290023003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@274348 0039d316-1c4b-4281-b951-d872f2087c98
parent daeffe6e
...@@ -55,6 +55,7 @@ IDR_SYNC_INTERNALS_SEARCH_JS ...@@ -55,6 +55,7 @@ IDR_SYNC_INTERNALS_SEARCH_JS
IDR_SYNC_INTERNALS_SYNC_LOG_JS IDR_SYNC_INTERNALS_SYNC_LOG_JS
IDR_SYNC_INTERNALS_SYNC_NODE_BROWSER_JS IDR_SYNC_INTERNALS_SYNC_NODE_BROWSER_JS
IDR_SYNC_INTERNALS_SYNC_SEARCH_JS IDR_SYNC_INTERNALS_SYNC_SEARCH_JS
IDR_SYNC_INTERNALS_TYPES_JS
IDR_THROBBER IDR_THROBBER
IDR_TRANSLATE_JS IDR_TRANSLATE_JS
IDR_WEBUI_I18N_PROCESS_JS IDR_WEBUI_I18N_PROCESS_JS
......
...@@ -53,6 +53,14 @@ cr.define('chrome.sync', function() { ...@@ -53,6 +53,14 @@ cr.define('chrome.sync', function() {
chrome.send('registerForEvents'); chrome.send('registerForEvents');
}; };
/**
* Registers to receive a stream of status counter update events
* chrome.sync.dispatchEvent().
*/
var registerForPerTypeCounters = function() {
chrome.send('registerForPerTypeCounters');
}
/** /**
* Asks the browser to refresh our snapshot of sync state. Should result * Asks the browser to refresh our snapshot of sync state. Should result
* in an onAboutInfoUpdated event being emitted. * in an onAboutInfoUpdated event being emitted.
...@@ -111,6 +119,7 @@ cr.define('chrome.sync', function() { ...@@ -111,6 +119,7 @@ cr.define('chrome.sync', function() {
getAllNodes: getAllNodes, getAllNodes: getAllNodes,
getAllNodesCallback: getAllNodesCallback, getAllNodesCallback: getAllNodesCallback,
registerForEvents: registerForEvents, registerForEvents: registerForEvents,
registerForPerTypeCounters: registerForPerTypeCounters,
requestUpdatedAboutInfo: requestUpdatedAboutInfo, requestUpdatedAboutInfo: requestUpdatedAboutInfo,
requestListOfTypes: requestListOfTypes, requestListOfTypes: requestListOfTypes,
}; };
......
...@@ -9,6 +9,7 @@ chrome/test/functional/special_tabs.py. --> ...@@ -9,6 +9,7 @@ chrome/test/functional/special_tabs.py. -->
<link rel="stylesheet" href="chrome://resources/css/tabs.css"> <link rel="stylesheet" href="chrome://resources/css/tabs.css">
<link rel="stylesheet" href="chrome://resources/css/tree.css"> <link rel="stylesheet" href="chrome://resources/css/tree.css">
<link rel="stylesheet" href="about.css"> <link rel="stylesheet" href="about.css">
<link rel="stylesheet" href="types.css">
<link rel="stylesheet" href="sync_search.css"> <link rel="stylesheet" href="sync_search.css">
<link rel="stylesheet" href="sync_node_browser.css"> <link rel="stylesheet" href="sync_node_browser.css">
...@@ -34,6 +35,7 @@ chrome/test/functional/special_tabs.py. --> ...@@ -34,6 +35,7 @@ chrome/test/functional/special_tabs.py. -->
<script src="chrome://resources/js/util.js"></script> <script src="chrome://resources/js/util.js"></script>
<script src="chrome://sync-internals/chrome_sync.js"></script> <script src="chrome://sync-internals/chrome_sync.js"></script>
<script src="chrome://sync-internals/about.js"></script> <script src="chrome://sync-internals/about.js"></script>
<script src="chrome://sync-internals/types.js"></script>
<script src="chrome://sync-internals/sync_log.js"></script> <script src="chrome://sync-internals/sync_log.js"></script>
<script src="chrome://sync-internals/sync_node_browser.js"></script> <script src="chrome://sync-internals/sync_node_browser.js"></script>
<script src="chrome://sync-internals/sync_search.js"></script> <script src="chrome://sync-internals/sync_search.js"></script>
...@@ -52,6 +54,7 @@ chrome/test/functional/special_tabs.py. --> ...@@ -52,6 +54,7 @@ chrome/test/functional/special_tabs.py. -->
<tabbox id="sync-page"> <tabbox id="sync-page">
<tabs> <tabs>
<tab id="sync-about-tab">About</tab> <tab id="sync-about-tab">About</tab>
<tab id="sync-types-tab">Types</tab>
<tab id="sync-data-tab">Data</tab> <tab id="sync-data-tab">Data</tab>
<tab id="sync-events-tab">Events</tab> <tab id="sync-events-tab">Events</tab>
<tab id="sync-browser-tab">Sync Node Browser</tab> <tab id="sync-browser-tab">Sync Node Browser</tab>
...@@ -61,6 +64,9 @@ chrome/test/functional/special_tabs.py. --> ...@@ -61,6 +64,9 @@ chrome/test/functional/special_tabs.py. -->
<tabpanel> <tabpanel>
<include src="about.html" /> <include src="about.html" />
</tabpanel> </tabpanel>
<tabpanel>
<include src="types.html" />
</tabpanel>
<tabpanel> <tabpanel>
<include src="data.html" /> <include src="data.html" />
</tabpanel> </tabpanel>
......
/* Copyright 2014 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#type-counters-table {
table-layout: fixed;
}
#type-counters-table th {
max-width: 80px;
width: 80px;
}
#type-counters-table th.type {
max-width: 200px;
width: 200px;
}
#type-counters-table tr:nth-child(odd) {
background: rgb(239, 243, 255);
}
<div id="type-counters-container-wrapper" jsskip="true">
<div class="section">
<h2>Type Counters</h2>
<table id="type-counters-table">
<thead>
<tr>
<th class='type'>Type</th>
<th>Total Entries</th>
<th>Updates Received</th>
<th>Reflected Updates Received</th>
<th>Tombstone Updates Received</th>
<th>Updates Applied</th>
<th>Hierarchy Conflict Application Failures</th>
<th>Encryption Conflict Application Failures</th>
<th>Server Overwrite Conflicts</th>
<th>Local Overwrite Conflicts</th>
<th>Commit Attempts</th>
<th>Commit Successes</th>
<th>Commit Conflicts</th>
<th>Commit Errors</th>
</tr>
</thead>
<tbody>
<tr jsselect="rows">
<td jscontent="type"></td>
<td jscontent="counters.numEntries || 0">0</td>
<td jscontent="counters.numUpdatesReceived || 0">0</td>
<td jscontent="counters.numReflectedUpdatesReceived || 0">0</td>
<td jscontent="counters.numTombstoneUpdatesReceived || 0">0</td>
<td jscontent="counters.numUpdatesApplied || 0">0</td>
<td jscontent="counters.numHierarchyConflictApplicationFailures || 0">0</td>
<td jscontent="counters.numEncryptionConflictApplicationFailures || 0">0</td>
<td jscontent="counters.numServerOverwrites || 0">0</td>
<td jscontent="counters.numLocalOverwrites || 0">0</td>
<td jscontent="counters.numCommitsAttempted || 0">0</td>
<td jscontent="counters.numCommitsSuccess || 0">0</td>
<td jscontent="counters.numCommitsConflict || 0">0</td>
<td jscontent="counters.numCommitsError || 0">0</td>
</tr>
</tbody>
</table>
</div>
</div>
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
cr.define('chrome.sync.types', function() {
var typeCountersMap = {};
/**
* Redraws the counters table taking advantage of the most recent
* available information.
*
* Makes use of typeCountersMap, which is defined in the containing scope.
*/
var refreshTypeCountersDisplay = function() {
var typeCountersArray = [];
// Transform our map into an array to make jstemplate happy.
Object.keys(typeCountersMap).sort().forEach(function(t) {
typeCountersArray.push({
type: t,
counters: typeCountersMap[t],
});
});
jstProcess(
new JsEvalContext({ rows: typeCountersArray }),
$('type-counters-table'));
};
/**
* Helps to initialize the table by picking up where initTypeCounters() left
* off. That function registers this listener and requests that this event
* be emitted.
*
* @param {!Object} e An event containing the list of known sync types.
*/
var onReceivedListOfTypes = function(e) {
var types = e.details.types;
types.map(function(type) {
if (!typeCountersMap.hasOwnProperty(type)) {
typeCountersMap[type] = {};
}
});
chrome.sync.events.removeEventListener(
'onReceivedListOfTypes',
onReceivedListOfTypes);
refreshTypeCountersDisplay();
};
/**
* Callback for receipt of updated per-type counters.
*
* @param {!Object} e An event containing an updated counter.
*/
var onCountersUpdated = function(e) {
var details = e.details;
var modelType = details.modelType;
var counters = details.counters;
if (typeCountersMap.hasOwnProperty(modelType))
for (k in counters) {
typeCountersMap[modelType][k] = counters[k];
}
refreshTypeCountersDisplay();
};
/**
* Initializes state and callbacks for the per-type counters and status UI.
*/
var initTypeCounters = function() {
chrome.sync.events.addEventListener(
'onCountersUpdated',
onCountersUpdated);
chrome.sync.events.addEventListener(
'onReceivedListOfTypes',
onReceivedListOfTypes);
chrome.sync.requestListOfTypes();
chrome.sync.registerForPerTypeCounters();
};
var onLoad = function() {
initTypeCounters();
};
return {
onLoad: onLoad
};
});
document.addEventListener('DOMContentLoaded', chrome.sync.types.onLoad, false);
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
<include name="IDR_SYNC_INTERNALS_INDEX_HTML" file="sync_internals/sync_index.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> <include name="IDR_SYNC_INTERNALS_INDEX_HTML" file="sync_internals/sync_index.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_SYNC_INTERNALS_INDEX_JS" file="sync_internals/sync_index.js" type="BINDATA" /> <include name="IDR_SYNC_INTERNALS_INDEX_JS" file="sync_internals/sync_index.js" type="BINDATA" />
<include name="IDR_SYNC_INTERNALS_CHROME_SYNC_JS" file="sync_internals/chrome_sync.js" type="BINDATA" /> <include name="IDR_SYNC_INTERNALS_CHROME_SYNC_JS" file="sync_internals/chrome_sync.js" type="BINDATA" />
<include name="IDR_SYNC_INTERNALS_TYPES_JS" file="sync_internals/types.js" type="BINDATA" />
<include name="IDR_SYNC_INTERNALS_SYNC_LOG_JS" file="sync_internals/sync_log.js" type="BINDATA" /> <include name="IDR_SYNC_INTERNALS_SYNC_LOG_JS" file="sync_internals/sync_log.js" type="BINDATA" />
<include name="IDR_SYNC_INTERNALS_SYNC_NODE_BROWSER_JS" file="sync_internals/sync_node_browser.js" type="BINDATA" /> <include name="IDR_SYNC_INTERNALS_SYNC_NODE_BROWSER_JS" file="sync_internals/sync_node_browser.js" type="BINDATA" />
<include name="IDR_SYNC_INTERNALS_SYNC_SEARCH_JS" file="sync_internals/sync_search.js" type="BINDATA" /> <include name="IDR_SYNC_INTERNALS_SYNC_SEARCH_JS" file="sync_internals/sync_search.js" type="BINDATA" />
......
...@@ -3,8 +3,9 @@ include_rules = [ ...@@ -3,8 +3,9 @@ include_rules = [
"+js2webui/chrome/test/data", "+js2webui/chrome/test/data",
"+sync/js", "+sync/js",
"+sync/internal_api/public/util/weak_handle.h", "+sync/internal_api/public/sessions",
"+sync/internal_api/public/events", "+sync/internal_api/public/events",
"+sync/internal_api/public/util/weak_handle.h",
# Other libraries. # Other libraries.
"+components/onc", "+components/onc",
......
...@@ -14,6 +14,9 @@ ...@@ -14,6 +14,9 @@
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui.h"
#include "sync/internal_api/public/events/protocol_event.h" #include "sync/internal_api/public/events/protocol_event.h"
#include "sync/internal_api/public/sessions/commit_counters.h"
#include "sync/internal_api/public/sessions/status_counters.h"
#include "sync/internal_api/public/sessions/update_counters.h"
#include "sync/internal_api/public/util/weak_handle.h" #include "sync/internal_api/public/util/weak_handle.h"
#include "sync/js/js_event_details.h" #include "sync/js/js_event_details.h"
...@@ -23,7 +26,9 @@ using syncer::WeakHandle; ...@@ -23,7 +26,9 @@ using syncer::WeakHandle;
SyncInternalsMessageHandler::SyncInternalsMessageHandler() SyncInternalsMessageHandler::SyncInternalsMessageHandler()
: is_registered_(false), : is_registered_(false),
weak_ptr_factory_(this) {} is_registered_for_counters_(false),
weak_ptr_factory_(this) {
}
SyncInternalsMessageHandler::~SyncInternalsMessageHandler() { SyncInternalsMessageHandler::~SyncInternalsMessageHandler() {
if (js_controller_) if (js_controller_)
...@@ -34,6 +39,10 @@ SyncInternalsMessageHandler::~SyncInternalsMessageHandler() { ...@@ -34,6 +39,10 @@ SyncInternalsMessageHandler::~SyncInternalsMessageHandler() {
service->RemoveObserver(this); service->RemoveObserver(this);
service->RemoveProtocolEventObserver(this); service->RemoveProtocolEventObserver(this);
} }
if (service && is_registered_for_counters_) {
service->RemoveTypeDebugInfoObserver(this);
}
} }
void SyncInternalsMessageHandler::RegisterMessages() { void SyncInternalsMessageHandler::RegisterMessages() {
...@@ -44,6 +53,11 @@ void SyncInternalsMessageHandler::RegisterMessages() { ...@@ -44,6 +53,11 @@ void SyncInternalsMessageHandler::RegisterMessages() {
base::Bind(&SyncInternalsMessageHandler::HandleRegisterForEvents, base::Bind(&SyncInternalsMessageHandler::HandleRegisterForEvents,
base::Unretained(this))); base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"registerForPerTypeCounters",
base::Bind(&SyncInternalsMessageHandler::HandleRegisterForPerTypeCounters,
base::Unretained(this)));
web_ui()->RegisterMessageCallback( web_ui()->RegisterMessageCallback(
"requestUpdatedAboutInfo", "requestUpdatedAboutInfo",
base::Bind(&SyncInternalsMessageHandler::HandleRequestUpdatedAboutInfo, base::Bind(&SyncInternalsMessageHandler::HandleRequestUpdatedAboutInfo,
...@@ -77,6 +91,21 @@ void SyncInternalsMessageHandler::HandleRegisterForEvents( ...@@ -77,6 +91,21 @@ void SyncInternalsMessageHandler::HandleRegisterForEvents(
} }
} }
void SyncInternalsMessageHandler::HandleRegisterForPerTypeCounters(
const base::ListValue* args) {
DCHECK(args->empty());
ProfileSyncService* service = GetProfileSyncService();
if (service && !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( void SyncInternalsMessageHandler::HandleRequestUpdatedAboutInfo(
const base::ListValue* args) { const base::ListValue* args) {
DCHECK(args->empty()); DCHECK(args->empty());
...@@ -137,6 +166,37 @@ void SyncInternalsMessageHandler::OnProtocolEvent( ...@@ -137,6 +166,37 @@ void SyncInternalsMessageHandler::OnProtocolEvent(
*value); *value);
} }
void SyncInternalsMessageHandler::OnCommitCountersUpdated(
syncer::ModelType type,
const syncer::CommitCounters& counters) {
EmitCounterUpdate(type, "commit", counters.ToValue());
}
void SyncInternalsMessageHandler::OnUpdateCountersUpdated(
syncer::ModelType type,
const syncer::UpdateCounters& counters) {
EmitCounterUpdate(type, "update", counters.ToValue());
}
void SyncInternalsMessageHandler::OnStatusCountersUpdated(
syncer::ModelType type,
const syncer::StatusCounters& counters) {
EmitCounterUpdate(type, "status", counters.ToValue());
}
void SyncInternalsMessageHandler::EmitCounterUpdate(
syncer::ModelType type,
const std::string& counter_type,
scoped_ptr<base::DictionaryValue> value) {
scoped_ptr<base::DictionaryValue> details(new base::DictionaryValue());
details->SetString("modelType", ModelTypeToString(type));
details->SetString("counterType", counter_type);
details->Set("counters", value.release());
web_ui()->CallJavascriptFunction("chrome.sync.dispatchEvent",
base::StringValue("onCountersUpdated"),
*details);
}
void SyncInternalsMessageHandler::HandleJsEvent( void SyncInternalsMessageHandler::HandleJsEvent(
const std::string& name, const std::string& name,
const JsEventDetails& details) { const JsEventDetails& details) {
...@@ -163,4 +223,3 @@ ProfileSyncService* SyncInternalsMessageHandler::GetProfileSyncService() { ...@@ -163,4 +223,3 @@ ProfileSyncService* SyncInternalsMessageHandler::GetProfileSyncService() {
ProfileSyncServiceFactory* factory = ProfileSyncServiceFactory::GetInstance(); ProfileSyncServiceFactory* factory = ProfileSyncServiceFactory::GetInstance();
return factory->GetForProfile(profile->GetOriginalProfile()); return factory->GetForProfile(profile->GetOriginalProfile());
} }
...@@ -15,17 +15,18 @@ ...@@ -15,17 +15,18 @@
#include "chrome/browser/sync/profile_sync_service_observer.h" #include "chrome/browser/sync/profile_sync_service_observer.h"
#include "chrome/browser/sync/protocol_event_observer.h" #include "chrome/browser/sync/protocol_event_observer.h"
#include "content/public/browser/web_ui_message_handler.h" #include "content/public/browser/web_ui_message_handler.h"
#include "sync/internal_api/public/sessions/type_debug_info_observer.h"
#include "sync/js/js_controller.h" #include "sync/js/js_controller.h"
#include "sync/js/js_event_handler.h" #include "sync/js/js_event_handler.h"
class ProfileSyncService; class ProfileSyncService;
// The implementation for the chrome://sync-internals page. // The implementation for the chrome://sync-internals page.
class SyncInternalsMessageHandler class SyncInternalsMessageHandler : public content::WebUIMessageHandler,
: public content::WebUIMessageHandler, public syncer::JsEventHandler,
public syncer::JsEventHandler, public ProfileSyncServiceObserver,
public ProfileSyncServiceObserver, public browser_sync::ProtocolEventObserver,
public browser_sync::ProtocolEventObserver { public syncer::TypeDebugInfoObserver {
public: public:
SyncInternalsMessageHandler(); SyncInternalsMessageHandler();
virtual ~SyncInternalsMessageHandler(); virtual ~SyncInternalsMessageHandler();
...@@ -35,6 +36,9 @@ class SyncInternalsMessageHandler ...@@ -35,6 +36,9 @@ class SyncInternalsMessageHandler
// Sets up observers to receive events and forward them to the UI. // Sets up observers to receive events and forward them to the UI.
void HandleRegisterForEvents(const base::ListValue* args); void HandleRegisterForEvents(const base::ListValue* args);
// Sets up observers to receive per-type counters and forward them to the UI.
void HandleRegisterForPerTypeCounters(const base::ListValue* args);
// Fires an event to send updated info back to the page. // Fires an event to send updated info back to the page.
void HandleRequestUpdatedAboutInfo(const base::ListValue* args); void HandleRequestUpdatedAboutInfo(const base::ListValue* args);
...@@ -58,6 +62,26 @@ class SyncInternalsMessageHandler ...@@ -58,6 +62,26 @@ class SyncInternalsMessageHandler
// ProtocolEventObserver implementation. // ProtocolEventObserver implementation.
virtual void OnProtocolEvent(const syncer::ProtocolEvent& e) OVERRIDE; virtual void OnProtocolEvent(const syncer::ProtocolEvent& e) OVERRIDE;
// TypeDebugInfoObserver implementation.
virtual void OnCommitCountersUpdated(
syncer::ModelType type,
const syncer::CommitCounters& counters) OVERRIDE;
virtual void OnUpdateCountersUpdated(
syncer::ModelType type,
const syncer::UpdateCounters& counters) OVERRIDE;
virtual void OnStatusCountersUpdated(
syncer::ModelType type,
const syncer::StatusCounters& counters) OVERRIDE;
// Helper to emit counter updates.
//
// Used in implementation of On*CounterUpdated methods. Emits the given
// dictionary value with additional data to specify the model type and
// counter type.
void EmitCounterUpdate(syncer::ModelType type,
const std::string& counter_type,
scoped_ptr<base::DictionaryValue> value);
private: private:
// Fetches updated aboutInfo and sends it to the page in the form of an // Fetches updated aboutInfo and sends it to the page in the form of an
// onAboutInfoUpdated event. // onAboutInfoUpdated event.
...@@ -70,6 +94,10 @@ class SyncInternalsMessageHandler ...@@ -70,6 +94,10 @@ class SyncInternalsMessageHandler
// A flag used to prevent double-registration with ProfileSyncService. // A flag used to prevent double-registration with ProfileSyncService.
bool is_registered_; bool is_registered_;
// A flag used to prevent double-registration as TypeDebugInfoObserver with
// ProfileSyncService.
bool is_registered_for_counters_;
base::WeakPtrFactory<SyncInternalsMessageHandler> weak_ptr_factory_; base::WeakPtrFactory<SyncInternalsMessageHandler> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(SyncInternalsMessageHandler); DISALLOW_COPY_AND_ASSIGN(SyncInternalsMessageHandler);
......
...@@ -24,6 +24,7 @@ content::WebUIDataSource* CreateSyncInternalsHTMLSource() { ...@@ -24,6 +24,7 @@ content::WebUIDataSource* CreateSyncInternalsHTMLSource() {
source->AddResourcePath("sync_index.js", IDR_SYNC_INTERNALS_INDEX_JS); source->AddResourcePath("sync_index.js", IDR_SYNC_INTERNALS_INDEX_JS);
source->AddResourcePath("chrome_sync.js", source->AddResourcePath("chrome_sync.js",
IDR_SYNC_INTERNALS_CHROME_SYNC_JS); IDR_SYNC_INTERNALS_CHROME_SYNC_JS);
source->AddResourcePath("types.js", IDR_SYNC_INTERNALS_TYPES_JS);
source->AddResourcePath("sync_log.js", IDR_SYNC_INTERNALS_SYNC_LOG_JS); source->AddResourcePath("sync_log.js", IDR_SYNC_INTERNALS_SYNC_LOG_JS);
source->AddResourcePath("sync_node_browser.js", source->AddResourcePath("sync_node_browser.js",
IDR_SYNC_INTERNALS_SYNC_NODE_BROWSER_JS); IDR_SYNC_INTERNALS_SYNC_NODE_BROWSER_JS);
......
...@@ -10,13 +10,13 @@ ...@@ -10,13 +10,13 @@
namespace syncer { namespace syncer {
StatusCounters::StatusCounters() StatusCounters::StatusCounters()
: num_total_entries(0) {} : num_entries(0) {}
StatusCounters::~StatusCounters() {} StatusCounters::~StatusCounters() {}
scoped_ptr<base::DictionaryValue> StatusCounters::ToValue() const { scoped_ptr<base::DictionaryValue> StatusCounters::ToValue() const {
scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
value->SetInteger("numTotalEntries", num_total_entries); value->SetInteger("numEntries", num_entries);
return value.Pass(); return value.Pass();
} }
......
...@@ -19,7 +19,7 @@ struct SYNC_EXPORT_PRIVATE StatusCounters { ...@@ -19,7 +19,7 @@ struct SYNC_EXPORT_PRIVATE StatusCounters {
scoped_ptr<base::DictionaryValue> ToValue() const; scoped_ptr<base::DictionaryValue> ToValue() const;
std::string ToString() const; std::string ToString() const;
size_t num_total_entries; size_t num_entries;
}; };
} // namespace syncer } // namespace syncer
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment