OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |