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

Side by Side Diff: chrome/browser/sync/engine/syncapi.cc

Issue 7033043: [Sync] Speed up sync node browser/search in about:sync (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 6 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
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/sync/engine/syncapi.h" 5 #include "chrome/browser/sync/engine/syncapi.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <bitset> 8 #include <bitset>
9 #include <iomanip> 9 #include <iomanip>
10 #include <list> 10 #include <list>
11 #include <map>
11 #include <queue> 12 #include <queue>
12 #include <string> 13 #include <string>
13 #include <vector> 14 #include <vector>
14 15
15 #include "base/base64.h" 16 #include "base/base64.h"
17 #include "base/bind.h"
18 #include "base/callback.h"
16 #include "base/command_line.h" 19 #include "base/command_line.h"
17 #include "base/json/json_writer.h" 20 #include "base/json/json_writer.h"
18 #include "base/logging.h" 21 #include "base/logging.h"
19 #include "base/memory/scoped_ptr.h" 22 #include "base/memory/scoped_ptr.h"
20 #include "base/message_loop.h" 23 #include "base/message_loop.h"
21 #include "base/observer_list.h" 24 #include "base/observer_list.h"
22 #include "base/sha1.h" 25 #include "base/sha1.h"
23 #include "base/string_number_conversions.h" 26 #include "base/string_number_conversions.h"
24 #include "base/string_util.h" 27 #include "base/string_util.h"
25 #include "base/synchronization/lock.h" 28 #include "base/synchronization/lock.h"
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 int64 BaseNode::GetFirstChildId() const { 326 int64 BaseNode::GetFirstChildId() const {
324 syncable::Directory* dir = GetTransaction()->GetLookup(); 327 syncable::Directory* dir = GetTransaction()->GetLookup();
325 syncable::BaseTransaction* trans = GetTransaction()->GetWrappedTrans(); 328 syncable::BaseTransaction* trans = GetTransaction()->GetWrappedTrans();
326 syncable::Id id_string = 329 syncable::Id id_string =
327 dir->GetFirstChildId(trans, GetEntry()->Get(syncable::ID)); 330 dir->GetFirstChildId(trans, GetEntry()->Get(syncable::ID));
328 if (id_string.IsRoot()) 331 if (id_string.IsRoot())
329 return kInvalidId; 332 return kInvalidId;
330 return IdToMetahandle(GetTransaction()->GetWrappedTrans(), id_string); 333 return IdToMetahandle(GetTransaction()->GetWrappedTrans(), id_string);
331 } 334 }
332 335
333 DictionaryValue* BaseNode::ToValue() const { 336 DictionaryValue* BaseNode::GetSummaryAsValue() const {
334 DictionaryValue* node_info = new DictionaryValue(); 337 DictionaryValue* node_info = new DictionaryValue();
335 node_info->SetString("id", base::Int64ToString(GetId())); 338 node_info->SetString("id", base::Int64ToString(GetId()));
339 node_info->SetBoolean("isFolder", GetIsFolder());
340 // TODO(akalin): Add a std::string accessor for the title.
341 node_info->SetString("title", WideToUTF8(GetTitle()));
342 node_info->Set("type", ModelTypeToValue(GetModelType()));
343 return node_info;
344 }
345
346 DictionaryValue* BaseNode::GetDetailsAsValue() const {
347 DictionaryValue* node_info = GetSummaryAsValue();
336 // TODO(akalin): Return time in a better format. 348 // TODO(akalin): Return time in a better format.
337 node_info->SetString("modificationTime", 349 node_info->SetString("modificationTime",
338 base::Int64ToString(GetModificationTime())); 350 base::Int64ToString(GetModificationTime()));
339 node_info->SetString("parentId", base::Int64ToString(GetParentId())); 351 node_info->SetString("parentId", base::Int64ToString(GetParentId()));
340 node_info->SetBoolean("isFolder", GetIsFolder());
341 // TODO(akalin): Add a std::string accessor for the title.
342 node_info->SetString("title", WideToUTF8(GetTitle()));
343 node_info->Set("type", ModelTypeToValue(GetModelType()));
344 // Specifics are already in the Entry value, so no need to duplicate 352 // Specifics are already in the Entry value, so no need to duplicate
345 // it here. 353 // it here.
346 node_info->SetString("externalId", 354 node_info->SetString("externalId",
347 base::Int64ToString(GetExternalId())); 355 base::Int64ToString(GetExternalId()));
348 node_info->SetString("predecessorId", 356 node_info->SetString("predecessorId",
349 base::Int64ToString(GetPredecessorId())); 357 base::Int64ToString(GetPredecessorId()));
350 node_info->SetString("successorId", 358 node_info->SetString("successorId",
351 base::Int64ToString(GetSuccessorId())); 359 base::Int64ToString(GetSuccessorId()));
352 node_info->SetString("firstChildId", 360 node_info->SetString("firstChildId",
353 base::Int64ToString(GetFirstChildId())); 361 base::Int64ToString(GetFirstChildId()));
(...skipping 740 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 node_dict->SetString("id", base::Int64ToString(id)); 1102 node_dict->SetString("id", base::Int64ToString(id));
1095 node_dict->Set("specifics", 1103 node_dict->Set("specifics",
1096 browser_sync::EntitySpecificsToValue(specifics)); 1104 browser_sync::EntitySpecificsToValue(specifics));
1097 if (extra.get()) { 1105 if (extra.get()) {
1098 node_dict->Set("extra", extra->ToValue()); 1106 node_dict->Set("extra", extra->ToValue());
1099 } 1107 }
1100 node_value = node_dict; 1108 node_value = node_dict;
1101 } else { 1109 } else {
1102 ReadNode node(trans); 1110 ReadNode node(trans);
1103 if (node.InitByIdLookup(id)) { 1111 if (node.InitByIdLookup(id)) {
1104 node_value = node.ToValue(); 1112 node_value = node.GetDetailsAsValue();
1105 } 1113 }
1106 } 1114 }
1107 if (!node_value) { 1115 if (!node_value) {
1108 NOTREACHED(); 1116 NOTREACHED();
1109 node_value = Value::CreateNullValue(); 1117 node_value = Value::CreateNullValue();
1110 } 1118 }
1111 value->Set("node", node_value); 1119 value->Set("node", node_value);
1112 return value; 1120 return value;
1113 } 1121 }
1114 1122
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1217 initialized_(false), 1225 initialized_(false),
1218 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 1226 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
1219 js_directory_change_listener_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { 1227 js_directory_change_listener_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
1220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1221 // Pre-fill |notification_info_map_|. 1229 // Pre-fill |notification_info_map_|.
1222 for (int i = syncable::FIRST_REAL_MODEL_TYPE; 1230 for (int i = syncable::FIRST_REAL_MODEL_TYPE;
1223 i < syncable::MODEL_TYPE_COUNT; ++i) { 1231 i < syncable::MODEL_TYPE_COUNT; ++i) {
1224 notification_info_map_.insert( 1232 notification_info_map_.insert(
1225 std::make_pair(syncable::ModelTypeFromInt(i), NotificationInfo())); 1233 std::make_pair(syncable::ModelTypeFromInt(i), NotificationInfo()));
1226 } 1234 }
1235
1236 // Bind message handlers.
1237 BindJsMessageHandler(
1238 "getNotificationState",
1239 &SyncManager::SyncInternal::GetNotificationState);
1240 BindJsMessageHandler(
1241 "getNotificationInfo",
1242 &SyncManager::SyncInternal::GetNotificationInfo);
1243 BindJsMessageHandler(
1244 "getRootNodeDetails",
1245 &SyncManager::SyncInternal::GetRootNodeDetails);
1246 BindJsMessageHandler(
1247 "getNodeSummariesById",
1248 &SyncManager::SyncInternal::GetNodeSummariesById);
1249 BindJsMessageHandler(
1250 "getNodeDetailsById",
1251 &SyncManager::SyncInternal::GetNodeDetailsById);
1252 BindJsMessageHandler(
1253 "getChildNodeIds",
1254 &SyncManager::SyncInternal::GetChildNodeIds);
1255 BindJsMessageHandler(
1256 "findNodesContainingString",
1257 &SyncManager::SyncInternal::FindNodesContainingString);
1227 } 1258 }
1228 1259
1229 virtual ~SyncInternal() { 1260 virtual ~SyncInternal() {
1230 CHECK(!core_message_loop_); 1261 CHECK(!core_message_loop_);
1231 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1232 } 1263 }
1233 1264
1234 bool Init(const FilePath& database_location, 1265 bool Init(const FilePath& database_location,
1235 const std::string& sync_server_and_path, 1266 const std::string& sync_server_and_path,
1236 int port, 1267 int port,
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 1466
1436 // JsEventRouter implementation. 1467 // JsEventRouter implementation.
1437 virtual void RouteJsEvent( 1468 virtual void RouteJsEvent(
1438 const std::string& name, 1469 const std::string& name,
1439 const browser_sync::JsEventDetails& details) OVERRIDE; 1470 const browser_sync::JsEventDetails& details) OVERRIDE;
1440 virtual void RouteJsMessageReply( 1471 virtual void RouteJsMessageReply(
1441 const std::string& name, 1472 const std::string& name,
1442 const browser_sync::JsArgList& args, 1473 const browser_sync::JsArgList& args,
1443 const browser_sync::JsEventHandler* target) OVERRIDE; 1474 const browser_sync::JsEventHandler* target) OVERRIDE;
1444 1475
1445 ListValue* FindNodesContainingString(const std::string& query); 1476 private:
1477 typedef browser_sync::JsArgList
1478 (SyncManager::SyncInternal::*UnboundJsMessageHandler)(
1479 const browser_sync::JsArgList&);
1480 typedef base::Callback<browser_sync::JsArgList(browser_sync::JsArgList)>
1481 JsMessageHandler;
1482 typedef std::map<std::string, JsMessageHandler> JsMessageHandlerMap;
1446 1483
1447 private:
1448 // Helper to call OnAuthError when no authentication credentials are 1484 // Helper to call OnAuthError when no authentication credentials are
1449 // available. 1485 // available.
1450 void RaiseAuthNeededEvent(); 1486 void RaiseAuthNeededEvent();
1451 1487
1452 // Helper to set initialized_ to true and raise an event to clients to notify 1488 // Helper to set initialized_ to true and raise an event to clients to notify
1453 // that initialization is complete and it is safe to send us changes. If 1489 // that initialization is complete and it is safe to send us changes. If
1454 // already initialized, this is a no-op. 1490 // already initialized, this is a no-op.
1455 void MarkAndNotifyInitializationComplete(); 1491 void MarkAndNotifyInitializationComplete();
1456 1492
1457 // Sends notifications to peers. 1493 // Sends notifications to peers.
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1549 // Helper for migration to new nigori proto to set 1585 // Helper for migration to new nigori proto to set
1550 // 'using_explicit_passphrase' in the NigoriSpecifics. 1586 // 'using_explicit_passphrase' in the NigoriSpecifics.
1551 // TODO(tim): Bug 62103. Remove this after it has been pushed out to dev 1587 // TODO(tim): Bug 62103. Remove this after it has been pushed out to dev
1552 // channel users. 1588 // channel users.
1553 void SetUsingExplicitPassphrasePrefForMigration( 1589 void SetUsingExplicitPassphrasePrefForMigration(
1554 WriteTransaction* const trans); 1590 WriteTransaction* const trans);
1555 1591
1556 // Checks for server reachabilty and requests a nudge. 1592 // Checks for server reachabilty and requests a nudge.
1557 void OnIPAddressChangedImpl(); 1593 void OnIPAddressChangedImpl();
1558 1594
1559 // Functions called by ProcessMessage(). 1595 // Helper function used only by the constructor.
1560 browser_sync::JsArgList ProcessGetNodesByIdMessage( 1596 void BindJsMessageHandler(
1597 const std::string& name,
1598 UnboundJsMessageHandler unbound_message_handler);
1599
1600 // JS message handlers.
1601 browser_sync::JsArgList GetNotificationState(
1561 const browser_sync::JsArgList& args); 1602 const browser_sync::JsArgList& args);
1562 1603
1563 browser_sync::JsArgList ProcessGetChildNodeIdsMessage( 1604 browser_sync::JsArgList GetNotificationInfo(
1564 const browser_sync::JsArgList& args); 1605 const browser_sync::JsArgList& args);
1565 1606
1566 browser_sync::JsArgList ProcessFindNodesContainingString( 1607 browser_sync::JsArgList GetRootNodeDetails(
1608 const browser_sync::JsArgList& args);
1609
1610 browser_sync::JsArgList GetNodeSummariesById(
1611 const browser_sync::JsArgList& args);
1612
1613 browser_sync::JsArgList GetNodeDetailsById(
1614 const browser_sync::JsArgList& args);
1615
1616 browser_sync::JsArgList GetChildNodeIds(
1617 const browser_sync::JsArgList& args);
1618
1619 browser_sync::JsArgList FindNodesContainingString(
1567 const browser_sync::JsArgList& args); 1620 const browser_sync::JsArgList& args);
1568 1621
1569 // We couple the DirectoryManager and username together in a UserShare member 1622 // We couple the DirectoryManager and username together in a UserShare member
1570 // so we can return a handle to share_ to clients of the API for use when 1623 // so we can return a handle to share_ to clients of the API for use when
1571 // constructing any transaction type. 1624 // constructing any transaction type.
1572 UserShare share_; 1625 UserShare share_;
1573 1626
1574 MessageLoop* core_message_loop_; 1627 MessageLoop* core_message_loop_;
1575 1628
1576 ObserverList<SyncManager::Observer> observers_; 1629 ObserverList<SyncManager::Observer> observers_;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1621 // True if the SyncManager should be running in test mode (no syncer thread 1674 // True if the SyncManager should be running in test mode (no syncer thread
1622 // actually communicating with the server). 1675 // actually communicating with the server).
1623 bool setup_for_test_mode_; 1676 bool setup_for_test_mode_;
1624 1677
1625 ScopedRunnableMethodFactory<SyncManager::SyncInternal> method_factory_; 1678 ScopedRunnableMethodFactory<SyncManager::SyncInternal> method_factory_;
1626 1679
1627 // Map used to store the notification info to be displayed in about:sync page. 1680 // Map used to store the notification info to be displayed in about:sync page.
1628 NotificationInfoMap notification_info_map_; 1681 NotificationInfoMap notification_info_map_;
1629 1682
1630 browser_sync::JsDirectoryChangeListener js_directory_change_listener_; 1683 browser_sync::JsDirectoryChangeListener js_directory_change_listener_;
1684
1685 JsMessageHandlerMap js_message_handlers_;
1631 }; 1686 };
1632 const int SyncManager::SyncInternal::kDefaultNudgeDelayMilliseconds = 200; 1687 const int SyncManager::SyncInternal::kDefaultNudgeDelayMilliseconds = 200;
1633 const int SyncManager::SyncInternal::kPreferencesNudgeDelayMilliseconds = 2000; 1688 const int SyncManager::SyncInternal::kPreferencesNudgeDelayMilliseconds = 2000;
1634 1689
1635 SyncManager::Observer::~Observer() {} 1690 SyncManager::Observer::~Observer() {}
1636 1691
1637 SyncManager::SyncManager() { 1692 SyncManager::SyncManager() {
1638 data_ = new SyncInternal(this); 1693 data_ = new SyncInternal(this);
1639 } 1694 }
1640 1695
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
2119 syncable::FillNigoriEncryptedTypes(newly_encrypted_types, &nigori); 2174 syncable::FillNigoriEncryptedTypes(newly_encrypted_types, &nigori);
2120 node.SetNigoriSpecifics(nigori); 2175 node.SetNigoriSpecifics(nigori);
2121 2176
2122 // TODO(zea): only reencrypt this datatype? ReEncrypting everything is a 2177 // TODO(zea): only reencrypt this datatype? ReEncrypting everything is a
2123 // safer approach, and should not impact anything that is already encrypted 2178 // safer approach, and should not impact anything that is already encrypted
2124 // (redundant changes are ignored). 2179 // (redundant changes are ignored).
2125 ReEncryptEverything(&trans); 2180 ReEncryptEverything(&trans);
2126 return; 2181 return;
2127 } 2182 }
2128 2183
2129 namespace {
2130
2131 void FindChildNodesContainingString(const std::string& lowercase_query,
2132 const ReadNode& parent_node,
2133 sync_api::ReadTransaction* trans,
2134 ListValue* result) {
2135 int64 child_id = parent_node.GetFirstChildId();
2136 while (child_id != kInvalidId) {
2137 ReadNode node(trans);
2138 if (node.InitByIdLookup(child_id)) {
2139 if (node.ContainsString(lowercase_query)) {
2140 result->Append(new StringValue(base::Int64ToString(child_id)));
2141 }
2142 FindChildNodesContainingString(lowercase_query, node, trans, result);
2143 child_id = node.GetSuccessorId();
2144 } else {
2145 LOG(WARNING) << "Lookup of node failed. Id: " << child_id;
2146 return;
2147 }
2148 }
2149 }
2150 } // namespace
2151
2152 // Returned pointer owned by the caller.
2153 ListValue* SyncManager::SyncInternal::FindNodesContainingString(
2154 const std::string& query) {
2155 // Convert the query string to lower case to perform case insensitive
2156 // searches.
2157 std::string lowercase_query = query;
2158 StringToLowerASCII(&lowercase_query);
2159 ReadTransaction trans(GetUserShare());
2160 ReadNode root(&trans);
2161 root.InitByRootLookup();
2162
2163 ListValue* result = new ListValue();
2164
2165 base::Time start_time = base::Time::Now();
2166 FindChildNodesContainingString(lowercase_query, root, &trans, result);
2167 base::Time end_time = base::Time::Now();
2168
2169 base::TimeDelta delta = end_time - start_time;
2170 VLOG(1) << "Time taken in milliseconds to search " << delta.InMilliseconds();
2171
2172 return result;
2173 }
2174
2175 void SyncManager::SyncInternal::ReEncryptEverything(WriteTransaction* trans) { 2184 void SyncManager::SyncInternal::ReEncryptEverything(WriteTransaction* trans) {
2176 syncable::ModelTypeSet encrypted_types = 2185 syncable::ModelTypeSet encrypted_types =
2177 GetEncryptedDataTypes(trans->GetWrappedTrans()); 2186 GetEncryptedDataTypes(trans->GetWrappedTrans());
2178 ModelSafeRoutingInfo routes; 2187 ModelSafeRoutingInfo routes;
2179 registrar_->GetModelSafeRoutingInfo(&routes); 2188 registrar_->GetModelSafeRoutingInfo(&routes);
2180 std::string tag; 2189 std::string tag;
2181 for (syncable::ModelTypeSet::iterator iter = encrypted_types.begin(); 2190 for (syncable::ModelTypeSet::iterator iter = encrypted_types.begin();
2182 iter != encrypted_types.end(); ++iter) { 2191 iter != encrypted_types.end(); ++iter) {
2183 if (*iter == syncable::PASSWORDS || routes.count(*iter) == 0) 2192 if (*iter == syncable::PASSWORDS || routes.count(*iter) == 0)
2184 continue; 2193 continue;
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
2678 } 2687 }
2679 2688
2680 lookup->RemoveChangeListener(&js_directory_change_listener_); 2689 lookup->RemoveChangeListener(&js_directory_change_listener_);
2681 } 2690 }
2682 2691
2683 const browser_sync::JsEventRouter* 2692 const browser_sync::JsEventRouter*
2684 SyncManager::SyncInternal::GetParentJsEventRouter() const { 2693 SyncManager::SyncInternal::GetParentJsEventRouter() const {
2685 return parent_router_; 2694 return parent_router_;
2686 } 2695 }
2687 2696
2688 namespace {
2689
2690 void LogNoRouter(const std::string& name,
2691 const browser_sync::JsArgList& args) {
2692 VLOG(1) << "No parent router; not replying to message " << name
2693 << " with args " << args.ToString();
2694 }
2695
2696 } // namespace
2697
2698 void SyncManager::SyncInternal::ProcessMessage( 2697 void SyncManager::SyncInternal::ProcessMessage(
2699 const std::string& name, const browser_sync::JsArgList& args, 2698 const std::string& name, const browser_sync::JsArgList& args,
2700 const browser_sync::JsEventHandler* sender) { 2699 const browser_sync::JsEventHandler* sender) {
2701 DCHECK(initialized_); 2700 DCHECK(initialized_);
2702 if (name == "getNotificationState") { 2701 if (!parent_router_) {
2703 if (!parent_router_) { 2702 VLOG(1) << "No parent router; not replying to message " << name
2704 LogNoRouter(name, args); 2703 << " with args " << args.ToString();
2705 return; 2704 return;
2706 } 2705 }
2707 bool notifications_enabled = allstatus_.status().notifications_enabled;
2708 ListValue return_args;
2709 return_args.Append(Value::CreateBooleanValue(notifications_enabled));
2710 parent_router_->RouteJsMessageReply(
2711 name, browser_sync::JsArgList(&return_args), sender);
2712 } else if (name == "getNotificationInfo") {
2713 if (!parent_router_) {
2714 LogNoRouter(name, args);
2715 return;
2716 }
2717 2706
2718 ListValue return_args; 2707 JsMessageHandler js_message_handler = js_message_handlers_[name];
2719 return_args.Append(NotificationInfoToValue(notification_info_map_)); 2708 if (js_message_handler.is_null()) {
2720 parent_router_->RouteJsMessageReply(
2721 name, browser_sync::JsArgList(&return_args), sender);
2722 } else if (name == "getRootNode") {
2723 if (!parent_router_) {
2724 LogNoRouter(name, args);
2725 return;
2726 }
2727 ReadTransaction trans(GetUserShare());
2728 ReadNode root(&trans);
2729 root.InitByRootLookup();
2730 ListValue return_args;
2731 return_args.Append(root.ToValue());
2732 parent_router_->RouteJsMessageReply(
2733 name, browser_sync::JsArgList(&return_args), sender);
2734 } else if (name == "getNodesById") {
2735 if (!parent_router_) {
2736 LogNoRouter(name, args);
2737 return;
2738 }
2739 parent_router_->RouteJsMessageReply(
2740 name, ProcessGetNodesByIdMessage(args), sender);
2741 } else if (name == "getChildNodeIds") {
2742 if (!parent_router_) {
2743 LogNoRouter(name, args);
2744 return;
2745 }
2746 parent_router_->RouteJsMessageReply(
2747 name, ProcessGetChildNodeIdsMessage(args), sender);
2748 } else if (name == "findNodesContainingString") {
2749 if (!parent_router_) {
2750 LogNoRouter(name, args);
2751 return;
2752 }
2753 parent_router_->RouteJsMessageReply(
2754 name, ProcessFindNodesContainingString(args), sender);
2755 } else {
2756 VLOG(1) << "Dropping unknown message " << name 2709 VLOG(1) << "Dropping unknown message " << name
2757 << " with args " << args.ToString(); 2710 << " with args " << args.ToString();
2711 return;
2758 } 2712 }
2713
2714 parent_router_->RouteJsMessageReply(
2715 name, js_message_handler.Run(args), sender);
2759 } 2716 }
2760 2717
2761 void SyncManager::SyncInternal::RouteJsEvent( 2718 void SyncManager::SyncInternal::RouteJsEvent(
2762 const std::string& name, 2719 const std::string& name,
2763 const browser_sync::JsEventDetails& details) { 2720 const browser_sync::JsEventDetails& details) {
2764 if (!parent_router_) { 2721 if (!parent_router_) {
2765 return; 2722 return;
2766 } 2723 }
2767 parent_router_->RouteJsEvent(name, details); 2724 parent_router_->RouteJsEvent(name, details);
2768 } 2725 }
2769 2726
2770 void SyncManager::SyncInternal::RouteJsMessageReply( 2727 void SyncManager::SyncInternal::RouteJsMessageReply(
2771 const std::string& name, 2728 const std::string& name,
2772 const browser_sync::JsArgList& args, 2729 const browser_sync::JsArgList& args,
2773 const browser_sync::JsEventHandler* target) { 2730 const browser_sync::JsEventHandler* target) {
2774 if (!parent_router_) { 2731 if (!parent_router_) {
2775 return; 2732 return;
2776 } 2733 }
2777 parent_router_->RouteJsMessageReply(name, args, target); 2734 parent_router_->RouteJsMessageReply(name, args, target);
2778 } 2735 }
2779 2736
2737 void SyncManager::SyncInternal::BindJsMessageHandler(
2738 const std::string& name,
2739 UnboundJsMessageHandler unbound_message_handler) {
2740 js_message_handlers_[name] =
2741 base::Bind(unbound_message_handler, base::Unretained(this));
2742 }
2743
2744 browser_sync::JsArgList
2745 SyncManager::SyncInternal::GetNotificationState(
2746 const browser_sync::JsArgList& args) {
2747 bool notifications_enabled = allstatus_.status().notifications_enabled;
2748 ListValue return_args;
2749 return_args.Append(Value::CreateBooleanValue(notifications_enabled));
2750 return browser_sync::JsArgList(&return_args);
2751 }
2752
2753 browser_sync::JsArgList
2754 SyncManager::SyncInternal::GetNotificationInfo(
2755 const browser_sync::JsArgList& args) {
2756 ListValue return_args;
2757 return_args.Append(NotificationInfoToValue(notification_info_map_));
2758 return browser_sync::JsArgList(&return_args);
2759 }
2760
2761 browser_sync::JsArgList
2762 SyncManager::SyncInternal::GetRootNodeDetails(
2763 const browser_sync::JsArgList& args) {
2764 ReadTransaction trans(GetUserShare());
2765 ReadNode root(&trans);
2766 root.InitByRootLookup();
2767 ListValue return_args;
2768 return_args.Append(root.GetDetailsAsValue());
2769 return browser_sync::JsArgList(&return_args);
2770 }
2771
2780 namespace { 2772 namespace {
2781 2773
2782 bool GetId(const ListValue& ids, int i, int64* id) { 2774 int64 GetId(const ListValue& ids, int i) {
2783 std::string id_str; 2775 std::string id_str;
2784 if (!ids.GetString(i, &id_str)) { 2776 if (!ids.GetString(i, &id_str)) {
2785 return false; 2777 return kInvalidId;
2786 } 2778 }
2787 if (!base::StringToInt64(id_str, id)) { 2779 int64 id = kInvalidId;
2788 return false; 2780 if (!base::StringToInt64(id_str, &id)) {
2781 return kInvalidId;
2789 } 2782 }
2790 if (*id == kInvalidId) { 2783 return id;
2791 return false;
2792 }
2793 return true;
2794 } 2784 }
2795 2785
2796 } // namespace 2786 browser_sync::JsArgList GetNodeInfoById(
2797 2787 const browser_sync::JsArgList& args,
2798 browser_sync::JsArgList SyncManager::SyncInternal::ProcessGetNodesByIdMessage( 2788 UserShare* user_share,
2799 const browser_sync::JsArgList& args) { 2789 DictionaryValue* (BaseNode::*info_getter)() const) {
lipalani1 2011/06/02 18:51:52 CHECK(info_getter != NULL)
akalin 2011/06/02 22:13:33 Done. Chrome/Google style is CHECK(ptr);
2800 ListValue return_args; 2790 ListValue return_args;
2801 ListValue* nodes = new ListValue(); 2791 ListValue* node_summaries = new ListValue();
2802 return_args.Append(nodes); 2792 return_args.Append(node_summaries);
2803 ListValue* id_list = NULL; 2793 ListValue* id_list = NULL;
2804 ReadTransaction trans(GetUserShare()); 2794 ReadTransaction trans(user_share);
2805 if (args.Get().GetList(0, &id_list)) { 2795 if (args.Get().GetList(0, &id_list)) {
lipalani1 2011/06/02 18:51:52 We should check if id_list is null and execute the
akalin 2011/06/02 22:13:33 GetList() guarantees that it fills in id_list with
2806 for (size_t i = 0; i < id_list->GetSize(); ++i) { 2796 for (size_t i = 0; i < id_list->GetSize(); ++i) {
2807 int64 id = kInvalidId; 2797 int64 id = GetId(*id_list, i);
2808 if (!GetId(*id_list, i, &id)) { 2798 if (id == kInvalidId) {
lipalani1 2011/06/02 18:51:52 Should we do a DCHECK here and in the InitByIdLook
akalin 2011/06/02 22:13:33 Nah, we don't want to crash if the javascript code
2809 continue; 2799 continue;
2810 } 2800 }
2811 ReadNode node(&trans); 2801 ReadNode node(&trans);
2812 if (!node.InitByIdLookup(id)) { 2802 if (!node.InitByIdLookup(id)) {
2813 continue; 2803 continue;
2814 } 2804 }
2815 nodes->Append(node.ToValue()); 2805 node_summaries->Append((node.*info_getter)());
2806 }
2807 }
2808 return browser_sync::JsArgList(&return_args);
2809 }
2810
2811 } // namespace
2812
2813 browser_sync::JsArgList
2814 SyncManager::SyncInternal::GetNodeSummariesById(
2815 const browser_sync::JsArgList& args) {
2816 return GetNodeInfoById(args, GetUserShare(), &BaseNode::GetSummaryAsValue);
2817 }
2818
2819 browser_sync::JsArgList
2820 SyncManager::SyncInternal::GetNodeDetailsById(
2821 const browser_sync::JsArgList& args) {
2822 return GetNodeInfoById(args, GetUserShare(), &BaseNode::GetDetailsAsValue);
2823 }
2824
2825 browser_sync::JsArgList SyncManager::SyncInternal::
2826 GetChildNodeIds(
2827 const browser_sync::JsArgList& args) {
2828 ListValue return_args;
2829 ListValue* child_ids = new ListValue();
2830 return_args.Append(child_ids);
2831 int64 id = GetId(args.Get(), 0);
2832 if (id != kInvalidId) {
2833 ReadTransaction trans(GetUserShare());
2834 // TODO(akalin): Avoid the need for the intermediate vector.
2835 syncable::Directory::ChildHandles child_handles;
2836 trans.GetLookup()->GetChildHandlesByHandle(trans.GetWrappedTrans(),
2837 id, &child_handles);
2838 for (syncable::Directory::ChildHandles::const_iterator it =
2839 child_handles.begin(); it != child_handles.end(); ++it) {
2840 child_ids->Append(Value::CreateStringValue(
2841 base::Int64ToString(*it)));
2816 } 2842 }
2817 } 2843 }
2818 return browser_sync::JsArgList(&return_args); 2844 return browser_sync::JsArgList(&return_args);
2819 } 2845 }
2820 2846
2821 browser_sync::JsArgList SyncManager::SyncInternal:: 2847 browser_sync::JsArgList SyncManager::SyncInternal::
2822 ProcessGetChildNodeIdsMessage( 2848 FindNodesContainingString(
2823 const browser_sync::JsArgList& args) { 2849 const browser_sync::JsArgList& args) {
2824 ListValue return_args;
2825 ListValue* child_ids = new ListValue();
2826 return_args.Append(child_ids);
2827 int64 id = kInvalidId;
2828 if (GetId(args.Get(), 0, &id)) {
2829 ReadTransaction trans(GetUserShare());
2830 ReadNode node(&trans);
2831 if (node.InitByIdLookup(id)) {
2832 int64 child_id = node.GetFirstChildId();
2833 while (child_id != kInvalidId) {
2834 ReadNode child_node(&trans);
2835 if (!child_node.InitByIdLookup(child_id)) {
2836 break;
2837 }
2838 child_ids->Append(Value::CreateStringValue(
2839 base::Int64ToString(child_id)));
2840 child_id = child_node.GetSuccessorId();
2841 }
2842 }
2843 }
2844 return browser_sync::JsArgList(&return_args);
2845 }
2846
2847 browser_sync::JsArgList SyncManager::SyncInternal::
2848 ProcessFindNodesContainingString(
2849 const browser_sync::JsArgList& args) {
2850 std::string query; 2850 std::string query;
2851 ListValue return_args; 2851 ListValue return_args;
2852 if (!args.Get().GetString(0, &query)) { 2852 if (!args.Get().GetString(0, &query)) {
2853 return_args.Append(new ListValue()); 2853 return_args.Append(new ListValue());
2854 return browser_sync::JsArgList(&return_args); 2854 return browser_sync::JsArgList(&return_args);
2855 } 2855 }
2856 2856
2857 ListValue* result = FindNodesContainingString(query); 2857 // Convert the query string to lower case to perform case insensitive
2858 // searches.
2859 std::string lowercase_query = query;
2860 StringToLowerASCII(&lowercase_query);
2861
2862 ListValue* result = new ListValue();
2858 return_args.Append(result); 2863 return_args.Append(result);
2864
2865 ReadTransaction trans(GetUserShare());
2866 // TODO(akalin): Avoid the need for the intermediate set.
2867 syncable::MetahandleSet all_handles;
2868 trans.GetLookup()->GetAllMetaHandles(trans.GetWrappedTrans(), &all_handles);
lipalani1 2011/06/02 18:51:52 May be we can have this as a TODO if you think thi
akalin 2011/06/02 22:13:33 Added GetAllEntryKernels function and use that ins
2869
2870 for (syncable::MetahandleSet::const_iterator it = all_handles.begin();
2871 it != all_handles.end(); ++it) {
2872 ReadNode node(&trans);
2873 if (!node.InitByIdLookup(*it)) {
2874 LOG(WARNING) << "Lookup of node failed. Id: " << *it;
2875 }
2876 if (node.ContainsString(lowercase_query)) {
2877 result->Append(new StringValue(base::Int64ToString(*it)));
2878 }
2879 }
2880
2859 return browser_sync::JsArgList(&return_args); 2881 return browser_sync::JsArgList(&return_args);
2860 } 2882 }
2861 2883
2862 void SyncManager::SyncInternal::OnNotificationStateChange( 2884 void SyncManager::SyncInternal::OnNotificationStateChange(
2863 bool notifications_enabled) { 2885 bool notifications_enabled) {
2864 VLOG(1) << "P2P: Notifications enabled = " 2886 VLOG(1) << "P2P: Notifications enabled = "
2865 << (notifications_enabled ? "true" : "false"); 2887 << (notifications_enabled ? "true" : "false");
2866 allstatus_.SetNotificationsEnabled(notifications_enabled); 2888 allstatus_.SetNotificationsEnabled(notifications_enabled);
2867 if (syncer_thread()) { 2889 if (syncer_thread()) {
2868 syncer_thread()->set_notifications_enabled(notifications_enabled); 2890 syncer_thread()->set_notifications_enabled(notifications_enabled);
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
2995 void SyncManager::LogUnsyncedItems(int level) const { 3017 void SyncManager::LogUnsyncedItems(int level) const {
2996 std::vector<int64> unsynced_handles; 3018 std::vector<int64> unsynced_handles;
2997 sync_api::ReadTransaction trans(GetUserShare()); 3019 sync_api::ReadTransaction trans(GetUserShare());
2998 trans.GetWrappedTrans()->directory()->GetUnsyncedMetaHandles( 3020 trans.GetWrappedTrans()->directory()->GetUnsyncedMetaHandles(
2999 trans.GetWrappedTrans(), &unsynced_handles); 3021 trans.GetWrappedTrans(), &unsynced_handles);
3000 3022
3001 for (std::vector<int64>::const_iterator it = unsynced_handles.begin(); 3023 for (std::vector<int64>::const_iterator it = unsynced_handles.begin();
3002 it != unsynced_handles.end(); ++it) { 3024 it != unsynced_handles.end(); ++it) {
3003 ReadNode node(&trans); 3025 ReadNode node(&trans);
3004 if (node.InitByIdLookup(*it)) { 3026 if (node.InitByIdLookup(*it)) {
3005 scoped_ptr<DictionaryValue> value(node.ToValue()); 3027 scoped_ptr<DictionaryValue> value(node.GetDetailsAsValue());
3006 std::string info; 3028 std::string info;
3007 base::JSONWriter::Write(value.get(), true, &info); 3029 base::JSONWriter::Write(value.get(), true, &info);
3008 VLOG(level) << info; 3030 VLOG(level) << info;
3009 } 3031 }
3010 } 3032 }
3011 } 3033 }
3012 3034
3013 void SyncManager::TriggerOnNotificationStateChangeForTest( 3035 void SyncManager::TriggerOnNotificationStateChangeForTest(
3014 bool notifications_enabled) { 3036 bool notifications_enabled) {
3015 data_->OnNotificationStateChange(notifications_enabled); 3037 data_->OnNotificationStateChange(notifications_enabled);
3016 } 3038 }
3017 3039
3018 void SyncManager::TriggerOnIncomingNotificationForTest( 3040 void SyncManager::TriggerOnIncomingNotificationForTest(
3019 const syncable::ModelTypeBitSet& model_types) { 3041 const syncable::ModelTypeBitSet& model_types) {
3020 syncable::ModelTypePayloadMap model_types_with_payloads = 3042 syncable::ModelTypePayloadMap model_types_with_payloads =
3021 syncable::ModelTypePayloadMapFromBitSet(model_types, 3043 syncable::ModelTypePayloadMapFromBitSet(model_types,
3022 std::string()); 3044 std::string());
3023 3045
3024 data_->OnIncomingNotification(model_types_with_payloads); 3046 data_->OnIncomingNotification(model_types_with_payloads);
3025 } 3047 }
3026 3048
3027 } // namespace sync_api 3049 } // namespace sync_api
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698