Clear a preference when sync tries to delete a preference

Preference can be deleted during sync rollback if the preference was not set before
first signin. Clear the preference if that happens.

BUG=362679

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

Cr-Commit-Position: refs/heads/master@{#289048}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289048 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/prefs/pref_model_associator.cc b/chrome/browser/prefs/pref_model_associator.cc
index bcf87ea..5ddbf1f 100644
--- a/chrome/browser/prefs/pref_model_associator.cc
+++ b/chrome/browser/prefs/pref_model_associator.cc
@@ -471,26 +471,10 @@
   for (iter = change_list.begin(); iter != change_list.end(); ++iter) {
     DCHECK_EQ(type_, iter->sync_data().GetDataType());
 
-    std::string name;
     const sync_pb::PreferenceSpecifics& pref_specifics =
         GetSpecifics(iter->sync_data());
 
-    scoped_ptr<base::Value> value(ReadPreferenceSpecifics(pref_specifics,
-                                                          &name));
-
-    if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) {
-      // We never delete preferences.
-      NOTREACHED() << "Attempted to process sync delete change for " << name
-                   << ". Skipping.";
-      continue;
-    }
-
-    // Skip values we can't deserialize.
-    // TODO(zea): consider taking some further action such as erasing the bad
-    // data.
-    if (!value.get())
-      continue;
-
+    std::string name = pref_specifics.name();
     // It is possible that we may receive a change to a preference we do not
     // want to sync. For example if the user is syncing a Mac client and a
     // Windows client, the Windows client does not support
@@ -506,9 +490,18 @@
     if (!IsPrefRegistered(pref_name))
       continue;
 
-    const PrefService::Preference* pref =
-        pref_service_->FindPreference(pref_name);
-    DCHECK(pref);
+    if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) {
+      pref_service_->ClearPref(pref_name);
+      continue;
+    }
+
+    scoped_ptr<base::Value> value(ReadPreferenceSpecifics(pref_specifics));
+    if (!value.get()) {
+      // Skip values we can't deserialize.
+      // TODO(zea): consider taking some further action such as erasing the bad
+      // data.
+      continue;
+    }
 
     // This will only modify the user controlled value store, which takes
     // priority over the default value but is ignored if the preference is
@@ -526,8 +519,7 @@
 }
 
 base::Value* PrefModelAssociator::ReadPreferenceSpecifics(
-    const sync_pb::PreferenceSpecifics& preference,
-    std::string* name) {
+    const sync_pb::PreferenceSpecifics& preference) {
   base::JSONReader reader;
   scoped_ptr<base::Value> value(reader.ReadToValue(preference.value()));
   if (!value.get()) {
@@ -536,7 +528,6 @@
     LOG(ERROR) << err;
     return NULL;
   }
-  *name = preference.name();
   return value.release();
 }