Home | History | Annotate | Download | only in glue
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_SYNC_GLUE_AUTOFILL_MODEL_ASSOCIATOR_H_
      6 #define CHROME_BROWSER_SYNC_GLUE_AUTOFILL_MODEL_ASSOCIATOR_H_
      7 #pragma once
      8 
      9 #include <map>
     10 #include <set>
     11 #include <string>
     12 #include <vector>
     13 
     14 #include "base/basictypes.h"
     15 #include "base/memory/ref_counted.h"
     16 #include "base/synchronization/lock.h"
     17 #include "chrome/browser/autofill/personal_data_manager.h"
     18 #include "chrome/browser/sync/engine/syncapi.h"
     19 #include "chrome/browser/sync/glue/model_associator.h"
     20 #include "chrome/browser/sync/protocol/autofill_specifics.pb.h"
     21 #include "chrome/browser/webdata/autofill_entry.h"
     22 
     23 class AutofillProfile;
     24 
     25 class ProfileSyncService;
     26 class WebDatabase;
     27 
     28 namespace sync_api {
     29 class WriteTransaction;
     30 }
     31 
     32 namespace browser_sync {
     33 
     34 class AutofillChangeProcessor;
     35 class UnrecoverableErrorHandler;
     36 
     37 extern const char kAutofillTag[];
     38 extern const char kAutofillProfileNamespaceTag[];
     39 extern const char kAutofillEntryNamespaceTag[];
     40 
     41 // Contains all model association related logic:
     42 // * Algorithm to associate autofill model and sync model.
     43 // We do not check if we have local data before this run; we always
     44 // merge and sync.
     45 class AutofillModelAssociator
     46     : public PerDataTypeAssociatorInterface<std::string, std::string> {
     47  public:
     48   static syncable::ModelType model_type() { return syncable::AUTOFILL; }
     49   AutofillModelAssociator(ProfileSyncService* sync_service,
     50                           WebDatabase* web_database,
     51                           PersonalDataManager* data_manager);
     52   virtual ~AutofillModelAssociator();
     53 
     54   // PerDataTypeAssociatorInterface implementation.
     55   //
     56   // Iterates through the sync model looking for matched pairs of items.
     57   virtual bool AssociateModels();
     58 
     59   // Clears all associations.
     60   virtual bool DisassociateModels();
     61 
     62   // The has_nodes out param is true if the sync model has nodes other
     63   // than the permanent tagged nodes.
     64   virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes);
     65 
     66   // See ModelAssociator interface.
     67   virtual void AbortAssociation();
     68 
     69   // See ModelAssociator interface.
     70   virtual bool CryptoReadyIfNecessary();
     71 
     72   // Not implemented.
     73   virtual const std::string* GetChromeNodeFromSyncId(int64 sync_id);
     74 
     75   // Not implemented.
     76   virtual bool InitSyncNodeFromChromeId(const std::string& node_id,
     77                                         sync_api::BaseNode* sync_node);
     78 
     79   // Returns the sync id for the given autofill name, or sync_api::kInvalidId
     80   // if the autofill name is not associated to any sync id.
     81   virtual int64 GetSyncIdFromChromeId(const std::string& node_id);
     82 
     83   // Associates the given autofill name with the given sync id.
     84   virtual void Associate(const std::string* node, int64 sync_id);
     85 
     86   // Remove the association that corresponds to the given sync id.
     87   virtual void Disassociate(int64 sync_id);
     88 
     89   // Returns whether a node with the given permanent tag was found and update
     90   // |sync_id| with that node's id.
     91   virtual bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id);
     92 
     93   static std::string KeyToTag(const string16& name, const string16& value);
     94 
     95   static bool MergeTimestamps(const sync_pb::AutofillSpecifics& autofill,
     96                               const std::vector<base::Time>& timestamps,
     97                               std::vector<base::Time>* new_timestamps);
     98   static bool FillProfileWithServerData(
     99       AutofillProfile* merge_into,
    100       const sync_pb::AutofillProfileSpecifics& specifics);
    101 
    102   // TODO(georgey) : add the same processing for CC info (already in protocol
    103   // buffers).
    104 
    105   // Is called to determine if we need to upgrade to the new
    106   // autofillprofile2 data type. If so we need to sync up autofillprofile
    107   // first to the latest available changes on the server and then upgrade
    108   // to autofillprofile2.
    109   virtual bool HasNotMigratedYet(const sync_api::BaseTransaction* trans);
    110 
    111  protected:
    112   // Given a profile from sync db it tries to match the profile against
    113   // one in web db. it ignores the guid and compares the actual data.
    114   AutofillProfile* FindCorrespondingNodeFromWebDB(
    115       const sync_pb::AutofillProfileSpecifics& profile,
    116       const std::vector<AutofillProfile*>& all_profiles_from_db);
    117 
    118  private:
    119   typedef std::map<std::string, int64> AutofillToSyncIdMap;
    120   typedef std::map<int64, std::string> SyncIdToAutofillMap;
    121 
    122   // A convenience wrapper of a bunch of state we pass around while associating
    123   // models, and send to the WebDatabase for persistence.
    124   struct DataBundle;
    125 
    126   // Helper to query WebDatabase for the current autofill state.
    127   bool LoadAutofillData(std::vector<AutofillEntry>* entries,
    128                         std::vector<AutofillProfile*>* profiles);
    129 
    130   // We split up model association first by autofill sub-type (entries, and
    131   // profiles.  There is a Traverse* method for each of these.
    132   bool TraverseAndAssociateChromeAutofillEntries(
    133       sync_api::WriteTransaction* write_trans,
    134       const sync_api::ReadNode& autofill_root,
    135       const std::vector<AutofillEntry>& all_entries_from_db,
    136       std::set<AutofillKey>* current_entries,
    137       std::vector<AutofillEntry>* new_entries);
    138   bool TraverseAndAssociateChromeAutofillProfiles(
    139       sync_api::WriteTransaction* write_trans,
    140       const sync_api::ReadNode& autofill_root,
    141       const std::vector<AutofillProfile*>& all_profiles_from_db,
    142       std::set<string16>* current_profiles,
    143       std::vector<AutofillProfile*>* updated_profiles);
    144 
    145   // Once the above traversals are complete, we traverse the sync model to
    146   // associate all remaining nodes.
    147   bool TraverseAndAssociateAllSyncNodes(
    148       sync_api::WriteTransaction* write_trans,
    149       const sync_api::ReadNode& autofill_root,
    150       DataBundle* bundle,
    151       const std::vector<AutofillProfile*>& all_profiles_from_db);
    152 
    153   // Helper to persist any changes that occured during model association to
    154   // the WebDatabase.
    155   bool SaveChangesToWebData(const DataBundle& bundle);
    156 
    157   // Helper to insert an AutofillEntry into the WebDatabase (e.g. in response
    158   // to encountering a sync node that doesn't exist yet locally).
    159   void AddNativeEntryIfNeeded(const sync_pb::AutofillSpecifics& autofill,
    160                               DataBundle* bundle,
    161                               const sync_api::ReadNode& node);
    162 
    163   // Helper to insert an AutofillProfile into the WebDatabase (e.g. in response
    164   // to encountering a sync node that doesn't exist yet locally).
    165   void AddNativeProfileIfNeeded(
    166       const sync_pb::AutofillProfileSpecifics& profile,
    167       DataBundle* bundle,
    168       const sync_api::ReadNode& node,
    169       const std::vector<AutofillProfile*>& all_profiles_from_db);
    170 
    171   // Called at various points in model association to determine if the
    172   // user requested an abort.
    173   bool IsAbortPending();
    174 
    175   ProfileSyncService* sync_service_;
    176   WebDatabase* web_database_;
    177   PersonalDataManager* personal_data_;
    178   int64 autofill_node_id_;
    179 
    180   AutofillToSyncIdMap id_map_;
    181   SyncIdToAutofillMap id_map_inverse_;
    182 
    183   // Abort association pending flag and lock.  If this is set to true
    184   // (via the AbortAssociation method), return from the
    185   // AssociateModels method as soon as possible.
    186   base::Lock abort_association_pending_lock_;
    187   bool abort_association_pending_;
    188   int number_of_entries_created_;
    189 
    190   DISALLOW_COPY_AND_ASSIGN(AutofillModelAssociator);
    191 };
    192 
    193 }  // namespace browser_sync
    194 
    195 #endif  // CHROME_BROWSER_SYNC_GLUE_AUTOFILL_MODEL_ASSOCIATOR_H_
    196