| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/glue/preference_model_associator.h" | 5 #include "chrome/browser/sync/glue/preference_model_associator.h" |
| 6 | 6 |
| 7 #include "base/json/json_reader.h" | 7 #include "base/json/json_reader.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/values.h" | 9 #include "base/values.h" |
| 10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 i < static_cast<size_t>(arraysize(kSynchronizedPreferences)); ++i) { | 36 i < static_cast<size_t>(arraysize(kSynchronizedPreferences)); ++i) { |
| 37 if (pref_service->FindPreference(kSynchronizedPreferences[i])) | 37 if (pref_service->FindPreference(kSynchronizedPreferences[i])) |
| 38 synced_preferences_.insert(kSynchronizedPreferences[i]); | 38 synced_preferences_.insert(kSynchronizedPreferences[i]); |
| 39 } | 39 } |
| 40 } | 40 } |
| 41 | 41 |
| 42 PreferenceModelAssociator::~PreferenceModelAssociator() { | 42 PreferenceModelAssociator::~PreferenceModelAssociator() { |
| 43 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | 43 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
| 44 } | 44 } |
| 45 | 45 |
| 46 bool PreferenceModelAssociator::InitPrefNodeAndAssociate( |
| 47 sync_api::WriteTransaction* trans, |
| 48 const sync_api::BaseNode& root, |
| 49 const PrefService::Preference* pref) { |
| 50 DCHECK(pref); |
| 51 |
| 52 PrefService* pref_service = sync_service_->profile()->GetPrefs(); |
| 53 base::JSONReader reader; |
| 54 std::string tag = pref->name(); |
| 55 sync_api::WriteNode node(trans); |
| 56 if (node.InitByClientTagLookup(syncable::PREFERENCES, tag)) { |
| 57 // The server has a value for the preference. |
| 58 const sync_pb::PreferenceSpecifics& preference( |
| 59 node.GetPreferenceSpecifics()); |
| 60 DCHECK_EQ(tag, preference.name()); |
| 61 |
| 62 if (pref->IsUserModifiable()) { |
| 63 scoped_ptr<Value> value( |
| 64 reader.JsonToValue(preference.value(), false, false)); |
| 65 std::string pref_name = preference.name(); |
| 66 if (!value.get()) { |
| 67 LOG(ERROR) << "Failed to deserialize preference value: " |
| 68 << reader.GetErrorMessage(); |
| 69 return false; |
| 70 } |
| 71 |
| 72 // Merge the server value of this preference with the local value. |
| 73 scoped_ptr<Value> new_value(MergePreference(*pref, *value)); |
| 74 |
| 75 // Update the local preference based on what we got from the |
| 76 // sync server. |
| 77 if (!pref->GetValue()->Equals(new_value.get())) |
| 78 pref_service->Set(pref_name.c_str(), *new_value); |
| 79 |
| 80 AfterUpdateOperations(pref_name); |
| 81 |
| 82 // If the merge resulted in an updated value, write it back to |
| 83 // the sync node. |
| 84 if (!value->Equals(new_value.get()) && |
| 85 !WritePreferenceToNode(pref->name(), *new_value, &node)) |
| 86 return false; |
| 87 } |
| 88 Associate(pref, node.GetId()); |
| 89 } else if (pref->IsUserControlled()) { |
| 90 // The server doesn't have a value, but we have a user-controlled value, |
| 91 // so we push it to the server. |
| 92 sync_api::WriteNode write_node(trans); |
| 93 if (!write_node.InitUniqueByCreation(syncable::PREFERENCES, root, tag)) { |
| 94 LOG(ERROR) << "Failed to create preference sync node."; |
| 95 return false; |
| 96 } |
| 97 |
| 98 // Update the sync node with the local value for this preference. |
| 99 if (!WritePreferenceToNode(pref->name(), *pref->GetValue(), &write_node)) |
| 100 return false; |
| 101 |
| 102 Associate(pref, write_node.GetId()); |
| 103 } |
| 104 |
| 105 return true; |
| 106 } |
| 107 |
| 46 bool PreferenceModelAssociator::AssociateModels() { | 108 bool PreferenceModelAssociator::AssociateModels() { |
| 47 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | 109 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
| 48 PrefService* pref_service = sync_service_->profile()->GetPrefs(); | 110 PrefService* pref_service = sync_service_->profile()->GetPrefs(); |
| 49 | 111 |
| 50 int64 root_id; | 112 int64 root_id; |
| 51 if (!GetSyncIdForTaggedNode(kPreferencesTag, &root_id)) { | 113 if (!GetSyncIdForTaggedNode(kPreferencesTag, &root_id)) { |
| 52 LOG(ERROR) << "Server did not create the top-level preferences node. We " | 114 LOG(ERROR) << "Server did not create the top-level preferences node. We " |
| 53 << "might be running against an out-of-date server."; | 115 << "might be running against an out-of-date server."; |
| 54 return false; | 116 return false; |
| 55 } | 117 } |
| 56 | 118 |
| 57 sync_api::WriteTransaction trans( | 119 sync_api::WriteTransaction trans( |
| 58 sync_service()->backend()->GetUserShareHandle()); | 120 sync_service()->backend()->GetUserShareHandle()); |
| 59 sync_api::ReadNode root(&trans); | 121 sync_api::ReadNode root(&trans); |
| 60 if (!root.InitByIdLookup(root_id)) { | 122 if (!root.InitByIdLookup(root_id)) { |
| 61 LOG(ERROR) << "Server did not create the top-level preferences node. We " | 123 LOG(ERROR) << "Server did not create the top-level preferences node. We " |
| 62 << "might be running against an out-of-date server."; | 124 << "might be running against an out-of-date server."; |
| 63 return false; | 125 return false; |
| 64 } | 126 } |
| 65 | 127 |
| 66 base::JSONReader reader; | |
| 67 for (std::set<std::string>::iterator it = synced_preferences_.begin(); | 128 for (std::set<std::string>::iterator it = synced_preferences_.begin(); |
| 68 it != synced_preferences_.end(); ++it) { | 129 it != synced_preferences_.end(); ++it) { |
| 69 const std::string& tag = *it; | |
| 70 const PrefService::Preference* pref = | 130 const PrefService::Preference* pref = |
| 71 pref_service->FindPreference(tag.c_str()); | 131 pref_service->FindPreference((*it).c_str()); |
| 72 DCHECK(pref); | 132 InitPrefNodeAndAssociate(&trans, root, pref); |
| 73 | |
| 74 sync_api::WriteNode node(&trans); | |
| 75 if (node.InitByClientTagLookup(syncable::PREFERENCES, tag)) { | |
| 76 // The server has a value for the preference. | |
| 77 const sync_pb::PreferenceSpecifics& preference( | |
| 78 node.GetPreferenceSpecifics()); | |
| 79 DCHECK_EQ(tag, preference.name()); | |
| 80 | |
| 81 if (pref->IsUserModifiable()) { | |
| 82 scoped_ptr<Value> value( | |
| 83 reader.JsonToValue(preference.value(), false, false)); | |
| 84 std::string pref_name = preference.name(); | |
| 85 if (!value.get()) { | |
| 86 LOG(ERROR) << "Failed to deserialize preference value: " | |
| 87 << reader.GetErrorMessage(); | |
| 88 return false; | |
| 89 } | |
| 90 | |
| 91 // Merge the server value of this preference with the local value. | |
| 92 scoped_ptr<Value> new_value(MergePreference(*pref, *value)); | |
| 93 | |
| 94 // Update the local preference based on what we got from the | |
| 95 // sync server. | |
| 96 if (!pref->GetValue()->Equals(new_value.get())) | |
| 97 pref_service->Set(pref_name.c_str(), *new_value); | |
| 98 | |
| 99 AfterUpdateOperations(pref_name); | |
| 100 | |
| 101 // If the merge resulted in an updated value, write it back to | |
| 102 // the sync node. | |
| 103 if (!value->Equals(new_value.get()) && | |
| 104 !WritePreferenceToNode(pref->name(), *new_value, &node)) | |
| 105 return false; | |
| 106 } | |
| 107 Associate(pref, node.GetId()); | |
| 108 } else if (pref->IsUserControlled()) { | |
| 109 // The server doesn't have a value, but we have a user-controlled value, | |
| 110 // so we push it to the server. | |
| 111 sync_api::WriteNode write_node(&trans); | |
| 112 if (!write_node.InitUniqueByCreation(syncable::PREFERENCES, root, tag)) { | |
| 113 LOG(ERROR) << "Failed to create preference sync node."; | |
| 114 return false; | |
| 115 } | |
| 116 | |
| 117 // Update the sync node with the local value for this preference. | |
| 118 if (!WritePreferenceToNode(pref->name(), *pref->GetValue(), &write_node)) | |
| 119 return false; | |
| 120 | |
| 121 Associate(pref, write_node.GetId()); | |
| 122 } | |
| 123 } | 133 } |
| 124 return true; | 134 return true; |
| 125 } | 135 } |
| 126 | 136 |
| 127 bool PreferenceModelAssociator::DisassociateModels() { | 137 bool PreferenceModelAssociator::DisassociateModels() { |
| 128 id_map_.clear(); | 138 id_map_.clear(); |
| 129 id_map_inverse_.clear(); | 139 id_map_inverse_.clear(); |
| 130 return true; | 140 return true; |
| 131 } | 141 } |
| 132 | 142 |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 // notification to update the UI. | 307 // notification to update the UI. |
| 298 if (0 == pref_name.compare(prefs::kShowBookmarkBar)) { | 308 if (0 == pref_name.compare(prefs::kShowBookmarkBar)) { |
| 299 NotificationService::current()->Notify( | 309 NotificationService::current()->Notify( |
| 300 NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED, | 310 NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED, |
| 301 Source<PreferenceModelAssociator>(this), | 311 Source<PreferenceModelAssociator>(this), |
| 302 NotificationService::NoDetails()); | 312 NotificationService::NoDetails()); |
| 303 } | 313 } |
| 304 } | 314 } |
| 305 | 315 |
| 306 } // namespace browser_sync | 316 } // namespace browser_sync |
| OLD | NEW |