Add UpdateSyncMetadata, ClearSyncMetadata, UpdateModelTypeState,
ClearModelTypeState into SyncMetadataStore interface.
Let AutofillTable inherit SyncMetadataStore.
Also create a SyncMetadataStoreChangeList for autofill.
Will do this change for typed url in next CL.

BUG=708275

Review-Url: https://codereview.chromium.org/2794413002
Cr-Commit-Position: refs/heads/master@{#466568}
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn
index 87a22f6e..5bd47bf 100644
--- a/components/autofill/core/browser/BUILD.gn
+++ b/components/autofill/core/browser/BUILD.gn
@@ -136,8 +136,6 @@
     "webdata/autofill_data_type_controller.h",
     "webdata/autofill_entry.cc",
     "webdata/autofill_entry.h",
-    "webdata/autofill_metadata_change_list.cc",
-    "webdata/autofill_metadata_change_list.h",
     "webdata/autofill_profile_data_type_controller.cc",
     "webdata/autofill_profile_data_type_controller.h",
     "webdata/autofill_profile_syncable_service.cc",
@@ -184,9 +182,7 @@
   }
 
   if (!is_android) {
-    sources += [
-      "ui/save_card_bubble_controller.h",
-    ]
+    sources += [ "ui/save_card_bubble_controller.h" ]
   }
 
   configs += [ "//build/config:precompiled_headers" ]
diff --git a/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc b/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc
index 9ed91408..2077b7a8 100644
--- a/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc
+++ b/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc
@@ -15,13 +15,13 @@
 #include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/autofill/core/browser/proto/autofill_sync.pb.h"
-#include "components/autofill/core/browser/webdata/autofill_metadata_change_list.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_backend.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
 #include "components/sync/model/entity_data.h"
 #include "components/sync/model/model_type_change_processor.h"
 #include "components/sync/model/mutable_data_batch.h"
+#include "components/sync/model_impl/sync_metadata_store_change_list.h"
 #include "net/base/escape.h"
 
 using base::Optional;
@@ -216,7 +216,8 @@
                               metadata_change_list.get());
       }
     }
-    return static_cast<AutofillMetadataChangeList*>(metadata_change_list.get())
+    return static_cast<syncer::SyncMetadataStoreChangeList*>(
+               metadata_change_list.get())
         ->TakeError();
   }
 
@@ -319,8 +320,8 @@
 std::unique_ptr<MetadataChangeList>
 AutocompleteSyncBridge::CreateMetadataChangeList() {
   DCHECK(thread_checker_.CalledOnValidThread());
-  return base::MakeUnique<AutofillMetadataChangeList>(GetAutofillTable(),
-                                                      syncer::AUTOFILL);
+  return base::MakeUnique<syncer::SyncMetadataStoreChangeList>(
+      GetAutofillTable(), syncer::AUTOFILL);
 }
 
 Optional<syncer::ModelError> AutocompleteSyncBridge::MergeSyncData(
@@ -412,8 +413,9 @@
     return;
   }
 
-  auto metadata_change_list = base::MakeUnique<AutofillMetadataChangeList>(
-      GetAutofillTable(), syncer::AUTOFILL);
+  auto metadata_change_list =
+      base::MakeUnique<syncer::SyncMetadataStoreChangeList>(GetAutofillTable(),
+                                                            syncer::AUTOFILL);
   for (const auto& change : changes) {
     const std::string storage_key = GetStorageKeyFromModel(change.key());
     switch (change.type()) {
diff --git a/components/autofill/core/browser/webdata/autofill_metadata_change_list.cc b/components/autofill/core/browser/webdata/autofill_metadata_change_list.cc
deleted file mode 100644
index 24876e4a..0000000
--- a/components/autofill/core/browser/webdata/autofill_metadata_change_list.cc
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/autofill/core/browser/webdata/autofill_metadata_change_list.h"
-
-#include "base/location.h"
-
-using base::Optional;
-using syncer::ModelError;
-
-namespace autofill {
-
-AutofillMetadataChangeList::AutofillMetadataChangeList(AutofillTable* table,
-                                                       syncer::ModelType type)
-    : table_(table), type_(type) {
-  DCHECK(table_);
-  // This should be changed as new autofill types are converted to USS.
-  DCHECK_EQ(syncer::AUTOFILL, type_);
-}
-
-AutofillMetadataChangeList::~AutofillMetadataChangeList() {
-  DCHECK(!error_);
-}
-
-void AutofillMetadataChangeList::UpdateModelTypeState(
-    const sync_pb::ModelTypeState& model_type_state) {
-  if (error_) {
-    return;
-  }
-
-  if (!table_->UpdateModelTypeState(type_, model_type_state)) {
-    error_ = ModelError(FROM_HERE, "Failed to update ModelTypeState.");
-  }
-}
-
-void AutofillMetadataChangeList::ClearModelTypeState() {
-  if (error_) {
-    return;
-  }
-
-  if (!table_->ClearModelTypeState(type_)) {
-    error_ = ModelError(FROM_HERE, "Failed to clear ModelTypeState.");
-  }
-}
-
-void AutofillMetadataChangeList::UpdateMetadata(
-    const std::string& storage_key,
-    const sync_pb::EntityMetadata& metadata) {
-  if (error_) {
-    return;
-  }
-
-  if (!table_->UpdateSyncMetadata(type_, storage_key, metadata)) {
-    error_ = ModelError(FROM_HERE, "Failed to update entity metadata.");
-  }
-}
-
-void AutofillMetadataChangeList::ClearMetadata(const std::string& storage_key) {
-  if (error_) {
-    return;
-  }
-
-  if (!table_->ClearSyncMetadata(type_, storage_key)) {
-    error_ = ModelError(FROM_HERE, "Failed to clear entity metadata.");
-  }
-}
-
-Optional<ModelError> AutofillMetadataChangeList::TakeError() {
-  Optional<ModelError> temp = error_;
-  error_.reset();
-  return temp;
-}
-
-}  // namespace autofill
diff --git a/components/autofill/core/browser/webdata/autofill_metadata_change_list.h b/components/autofill/core/browser/webdata/autofill_metadata_change_list.h
deleted file mode 100644
index e924e20..0000000
--- a/components/autofill/core/browser/webdata/autofill_metadata_change_list.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_METADATA_CHANGE_LIST_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_METADATA_CHANGE_LIST_H_
-
-#include <string>
-
-#include "base/optional.h"
-#include "components/autofill/core/browser/webdata/autofill_table.h"
-#include "components/sync/base/model_type.h"
-#include "components/sync/model/metadata_change_list.h"
-#include "components/sync/model/model_error.h"
-#include "components/sync/model/sync_error.h"
-#include "components/sync/protocol/entity_metadata.pb.h"
-#include "components/sync/protocol/model_type_state.pb.h"
-
-namespace autofill {
-
-// A thin wrapper around an AutofillTable that implements sync's
-// MetadataChangeList interface. Changes are passed directly into the table and
-// not stored inside this object. Since the table calls can fail, |TakeError()|
-// must be called before this object is destroyed to check whether any
-// operations failed.
-class AutofillMetadataChangeList : public syncer::MetadataChangeList {
- public:
-  AutofillMetadataChangeList(AutofillTable* table, syncer::ModelType type);
-  ~AutofillMetadataChangeList() override;
-
-  // syncer::MetadataChangeList implementation.
-  void UpdateModelTypeState(
-      const sync_pb::ModelTypeState& model_type_state) override;
-  void ClearModelTypeState() override;
-  void UpdateMetadata(const std::string& storage_key,
-                      const sync_pb::EntityMetadata& metadata) override;
-  void ClearMetadata(const std::string& storage_key) override;
-
-  // Returns the value of |error_| and unsets it.
-  base::Optional<syncer::ModelError> TakeError();
-
- private:
-  // The autofill table to store metadata in; always outlives |this|.
-  AutofillTable* table_;
-
-  // The sync model type for this metadata.
-  syncer::ModelType type_;
-
-  // The first error encountered by this object, if any.
-  base::Optional<syncer::ModelError> error_;
-};
-
-}  // namespace autofill
-
-#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_METADATA_CHANGE_LIST_H_
diff --git a/components/autofill/core/browser/webdata/autofill_table.h b/components/autofill/core/browser/webdata/autofill_table.h
index 872d127..bbbf477cd 100644
--- a/components/autofill/core/browser/webdata/autofill_table.h
+++ b/components/autofill/core/browser/webdata/autofill_table.h
@@ -16,6 +16,7 @@
 #include "base/strings/string16.h"
 #include "components/sync/base/model_type.h"
 #include "components/sync/model/metadata_batch.h"
+#include "components/sync/model/sync_metadata_store.h"
 #include "components/webdata/common/web_database_table.h"
 
 class WebDatabase;
@@ -249,7 +250,8 @@
 //
 //   value              The serialized ModelTypeState record.
 
-class AutofillTable : public WebDatabaseTable {
+class AutofillTable : public WebDatabaseTable,
+                      public syncer::SyncMetadataStore {
  public:
   AutofillTable();
   ~AutofillTable() override;
@@ -426,22 +428,16 @@
   bool GetAllSyncMetadata(syncer::ModelType model_type,
                           syncer::MetadataBatch* metadata_batch);
 
-  // Update the metadata row for |model_type|, keyed by |storage_key|, to
-  // contain the contents of |metadata|.
+  // syncer::SyncMetadataStore implementation.
   bool UpdateSyncMetadata(syncer::ModelType model_type,
                           const std::string& storage_key,
-                          const sync_pb::EntityMetadata& metadata);
-
-  // Remove the metadata row of type |model_type| keyed by |storage|key|.
+                          const sync_pb::EntityMetadata& metadata) override;
   bool ClearSyncMetadata(syncer::ModelType model_type,
-                         const std::string& storage_key);
-
-  // Update the stored sync state for the |model_type|.
-  bool UpdateModelTypeState(syncer::ModelType model_type,
-                            const sync_pb::ModelTypeState& model_type_state);
-
-  // Clear the stored sync state for |model_type|.
-  bool ClearModelTypeState(syncer::ModelType model_type);
+                         const std::string& storage_key) override;
+  bool UpdateModelTypeState(
+      syncer::ModelType model_type,
+      const sync_pb::ModelTypeState& model_type_state) override;
+  bool ClearModelTypeState(syncer::ModelType model_type) override;
 
   // Table migration functions. NB: These do not and should not rely on other
   // functions in this class. The implementation of a function such as
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn
index a941fa22..2f4ccad9 100644
--- a/components/sync/BUILD.gn
+++ b/components/sync/BUILD.gn
@@ -461,6 +461,7 @@
     "model/sync_error_factory.h",
     "model/sync_merge_result.cc",
     "model/sync_merge_result.h",
+    "model/sync_metadata_store.h",
     "model/syncable_service.cc",
     "model/syncable_service.h",
     "model/time.h",
@@ -481,6 +482,8 @@
     "model_impl/processor_entity_tracker.h",
     "model_impl/shared_model_type_processor.cc",
     "model_impl/shared_model_type_processor.h",
+    "model_impl/sync_metadata_store_change_list.cc",
+    "model_impl/sync_metadata_store_change_list.h",
     "protocol/proto_enum_conversions.cc",
     "protocol/proto_enum_conversions.h",
     "protocol/proto_memory_estimations.cc",
diff --git a/components/sync/model/sync_metadata_store.h b/components/sync/model/sync_metadata_store.h
new file mode 100644
index 0000000..4a06f7d
--- /dev/null
+++ b/components/sync/model/sync_metadata_store.h
@@ -0,0 +1,59 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SYNC_MODEL_SYNC_METADATA_STORE_H_
+#define COMPONENTS_SYNC_MODEL_SYNC_METADATA_STORE_H_
+
+#include <string>
+
+#include "components/sync/base/model_type.h"
+
+namespace sync_pb {
+class EntityMetadata;
+class ModelTypeState;
+}  // namespace sync_pb
+
+namespace syncer {
+
+// SyncMetadataStore defines interface implemented by model types for persisting
+// sync metadata and datatype state. It allows model type to use common
+// implementation of MetadataChangeList (SyncMetadataStoreChangeList) instead of
+// implementing their own.
+// Model type in implementation of ModelTypeSyncBridge::CreateMetadataChangeList
+// should create instance of SyncMetadataStoreChangeList passing pointer to
+// SyncMetadataStore to its constructor.
+// Implementations of SyncMetadataStore methods should support add/update/delete
+// metadata in model type specific sync metadata storage.
+
+class SyncMetadataStore {
+ public:
+  SyncMetadataStore() {}
+  virtual ~SyncMetadataStore() {}
+
+  // Update the metadata row for |model_type|, keyed by |storage_key|, to
+  // contain the contents of |metadata|.
+  // Return true on success.
+  virtual bool UpdateSyncMetadata(syncer::ModelType model_type,
+                                  const std::string& storage_key,
+                                  const sync_pb::EntityMetadata& metadata) = 0;
+
+  // Remove the metadata row of type |model_type| keyed by |storage_key|.
+  // Return true on success.
+  virtual bool ClearSyncMetadata(syncer::ModelType model_type,
+                                 const std::string& storage_key) = 0;
+
+  // Update the stored sync state for the |model_type|.
+  // Return true on success.
+  virtual bool UpdateModelTypeState(
+      syncer::ModelType model_type,
+      const sync_pb::ModelTypeState& model_type_state) = 0;
+
+  // Clear the stored sync state for |model_type|.
+  // Return true on success.
+  virtual bool ClearModelTypeState(syncer::ModelType model_type) = 0;
+};
+
+}  // namespace syncer
+
+#endif  // COMPONENTS_SYNC_MODEL_SYNC_METADATA_STORE_H_
diff --git a/components/sync/model_impl/sync_metadata_store_change_list.cc b/components/sync/model_impl/sync_metadata_store_change_list.cc
new file mode 100644
index 0000000..59f1e89
--- /dev/null
+++ b/components/sync/model_impl/sync_metadata_store_change_list.cc
@@ -0,0 +1,75 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/sync/model_impl/sync_metadata_store_change_list.h"
+
+#include "base/location.h"
+
+using base::Optional;
+using syncer::ModelError;
+
+namespace syncer {
+
+SyncMetadataStoreChangeList::SyncMetadataStoreChangeList(
+    SyncMetadataStore* store,
+    syncer::ModelType type)
+    : store_(store), type_(type) {
+  DCHECK(store_);
+}
+
+SyncMetadataStoreChangeList::~SyncMetadataStoreChangeList() {
+  DCHECK(!error_);
+}
+
+void SyncMetadataStoreChangeList::UpdateModelTypeState(
+    const sync_pb::ModelTypeState& model_type_state) {
+  if (error_) {
+    return;
+  }
+
+  if (!store_->UpdateModelTypeState(type_, model_type_state)) {
+    error_ = ModelError(FROM_HERE, "Failed to update ModelTypeState.");
+  }
+}
+
+void SyncMetadataStoreChangeList::ClearModelTypeState() {
+  if (error_) {
+    return;
+  }
+
+  if (!store_->ClearModelTypeState(type_)) {
+    error_ = ModelError(FROM_HERE, "Failed to clear ModelTypeState.");
+  }
+}
+
+void SyncMetadataStoreChangeList::UpdateMetadata(
+    const std::string& storage_key,
+    const sync_pb::EntityMetadata& metadata) {
+  if (error_) {
+    return;
+  }
+
+  if (!store_->UpdateSyncMetadata(type_, storage_key, metadata)) {
+    error_ = ModelError(FROM_HERE, "Failed to update entity metadata.");
+  }
+}
+
+void SyncMetadataStoreChangeList::ClearMetadata(
+    const std::string& storage_key) {
+  if (error_) {
+    return;
+  }
+
+  if (!store_->ClearSyncMetadata(type_, storage_key)) {
+    error_ = ModelError(FROM_HERE, "Failed to clear entity metadata.");
+  }
+}
+
+Optional<ModelError> SyncMetadataStoreChangeList::TakeError() {
+  Optional<ModelError> temp = error_;
+  error_.reset();
+  return temp;
+}
+
+}  // namespace syncer
diff --git a/components/sync/model_impl/sync_metadata_store_change_list.h b/components/sync/model_impl/sync_metadata_store_change_list.h
new file mode 100644
index 0000000..e1b949e
--- /dev/null
+++ b/components/sync/model_impl/sync_metadata_store_change_list.h
@@ -0,0 +1,52 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SYNC_MODEL_IMPL_SYNC_METADATA_STORE_CHANGE_LIST_H_
+#define COMPONENTS_SYNC_MODEL_IMPL_SYNC_METADATA_STORE_CHANGE_LIST_H_
+
+#include <string>
+
+#include "base/optional.h"
+#include "components/sync/base/model_type.h"
+#include "components/sync/model/metadata_change_list.h"
+#include "components/sync/model/model_error.h"
+#include "components/sync/model/sync_metadata_store.h"
+#include "components/sync/protocol/entity_metadata.pb.h"
+#include "components/sync/protocol/model_type_state.pb.h"
+
+namespace syncer {
+
+// A thin wrapper around an SyncMetadataStore that implements sync's
+// MetadataChangeList interface. Changes are passed directly into the store and
+// not stored inside this object. Since the store calls can fail, |TakeError()|
+// must be called before this object is destroyed to check whether any
+// operations failed.
+class SyncMetadataStoreChangeList : public MetadataChangeList {
+ public:
+  SyncMetadataStoreChangeList(SyncMetadataStore* store, syncer::ModelType type);
+  ~SyncMetadataStoreChangeList() override;
+
+  // MetadataChangeList implementation.
+  void UpdateModelTypeState(
+      const sync_pb::ModelTypeState& model_type_state) override;
+  void ClearModelTypeState() override;
+  void UpdateMetadata(const std::string& storage_key,
+                      const sync_pb::EntityMetadata& metadata) override;
+  void ClearMetadata(const std::string& storage_key) override;
+  base::Optional<syncer::ModelError> TakeError();
+
+ private:
+  // The metadata store to store metadata in; always outlives |this|.
+  SyncMetadataStore* store_;
+
+  // The sync model type for this metadata.
+  syncer::ModelType type_;
+
+  // The first error encountered by this object, if any.
+  base::Optional<syncer::ModelError> error_;
+};
+
+}  // namespace syncer
+
+#endif  // COMPONENTS_SYNC_MODEL_IMPL_SYNC_METADATA_STORE_CHANGE_LIST_H_