Index: chrome/browser/sync/profile_sync_service.cc |
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc |
index 2e704e3c97434d120980d988e8191fabf7c2be27..1fc431e65ef7c48d2ecf2beb505d3f4d2734c67f 100644 |
--- a/chrome/browser/sync/profile_sync_service.cc |
+++ b/chrome/browser/sync/profile_sync_service.cc |
@@ -82,7 +82,6 @@ |
#include "sync/internal_api/public/sync_encryption_handler.h" |
#include "sync/internal_api/public/util/experiments.h" |
#include "sync/internal_api/public/util/sync_string_conversions.h" |
-#include "sync/js/js_arg_list.h" |
#include "sync/js/js_event_details.h" |
#include "sync/util/cryptographer.h" |
#include "ui/base/l10n/l10n_util.h" |
@@ -2079,6 +2078,104 @@ void ProfileSyncService::RemoveProtocolEventObserver( |
} |
} |
+namespace { |
+ |
+class GetAllNodesRequestHelper |
+ : public base::RefCountedThreadSafe<GetAllNodesRequestHelper> { |
+ public: |
+ GetAllNodesRequestHelper( |
+ syncer::ModelTypeSet requested_types, |
+ const base::Callback<void(scoped_ptr<base::ListValue>)>& callback); |
+ |
+ void OnReceivedNodesForTypes( |
+ const std::vector<syncer::ModelType>& types, |
+ ScopedVector<base::ListValue> scoped_node_lists); |
+ |
+ private: |
+ friend class base::RefCountedThreadSafe<GetAllNodesRequestHelper>; |
+ virtual ~GetAllNodesRequestHelper(); |
+ |
+ scoped_ptr<base::ListValue> result_accumulator_; |
+ |
+ syncer::ModelTypeSet awaiting_types_; |
+ base::Callback<void(scoped_ptr<base::ListValue>)> callback_; |
+}; |
+ |
+GetAllNodesRequestHelper::GetAllNodesRequestHelper( |
+ syncer::ModelTypeSet requested_types, |
+ const base::Callback<void(scoped_ptr<base::ListValue>)>& callback) |
+ : result_accumulator_(new base::ListValue()), |
+ awaiting_types_(requested_types), |
+ callback_(callback) {} |
+ |
+GetAllNodesRequestHelper::~GetAllNodesRequestHelper() { |
+ if (!awaiting_types_.Empty()) { |
+ DLOG(WARNING) |
+ << "GetAllNodesRequest deleted before request was fulfilled. " |
+ << "Missing types are: " << ModelTypeSetToString(awaiting_types_); |
+ } |
+} |
+ |
+// Called when the set of nodes for a type or set of types has been returned. |
+// |
+// The nodes for several types can be returned at the same time by specifying |
+// their types in the |types| array, and putting their results at the |
+// correspnding indices in the |scoped_node_lists|. |
+void GetAllNodesRequestHelper::OnReceivedNodesForTypes( |
+ const std::vector<syncer::ModelType>& types, |
+ ScopedVector<base::ListValue> scoped_node_lists) { |
+ DCHECK_EQ(types.size(), scoped_node_lists.size()); |
+ |
+ // Take unsafe ownership of the node list. |
+ std::vector<base::ListValue*> node_lists; |
+ scoped_node_lists.release(&node_lists); |
+ |
+ for (size_t i = 0; i < node_lists.size() && i < types.size(); ++i) { |
+ const ModelType type = types[i]; |
+ base::ListValue* node_list = node_lists[i]; |
+ |
+ // Add these results to our list. |
+ scoped_ptr<base::DictionaryValue> type_dict(new base::DictionaryValue()); |
+ type_dict->SetString("type", ModelTypeToString(type)); |
+ type_dict->Set("nodes", node_list); |
+ result_accumulator_->Append(type_dict.release()); |
+ |
+ // Remember that this part of the request is satisfied. |
+ awaiting_types_.Remove(type); |
+ } |
+ |
+ if (awaiting_types_.Empty()) { |
+ callback_.Run(result_accumulator_.Pass()); |
+ callback_.Reset(); |
+ } |
+} |
+ |
+} // namespace |
+ |
+void ProfileSyncService::GetAllNodes( |
+ const base::Callback<void(scoped_ptr<base::ListValue>)>& callback) { |
+ // TODO(rlarocque): Should be GetRegisteredDirectoryTypes. |
+ const ModelTypeSet directory_types = GetRegisteredDataTypes(); |
+ scoped_refptr<GetAllNodesRequestHelper> helper = |
+ new GetAllNodesRequestHelper(directory_types, callback); |
+ |
+ if (!backend_initialized_) { |
+ // If there's no backend available to fulfill the request, handle it here. |
+ ScopedVector<base::ListValue> empty_results; |
+ std::vector<ModelType> type_vector; |
+ for (ModelTypeSet::Iterator it = directory_types.First(); |
+ it.Good(); it.Inc()) { |
+ type_vector.push_back(it.Get()); |
+ empty_results.push_back(new base::ListValue()); |
+ } |
+ helper->OnReceivedNodesForTypes(type_vector, empty_results.Pass()); |
+ } else { |
+ backend_->GetAllNodesForTypes( |
+ directory_types, |
+ base::Bind(&GetAllNodesRequestHelper::OnReceivedNodesForTypes, helper)); |
+ } |
+} |
+ |
bool ProfileSyncService::HasObserver( |
ProfileSyncServiceBase::Observer* observer) const { |
return observers_.HasObserver(observer); |