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_TYPED_URL_MODEL_ASSOCIATOR_H_
6#define CHROME_BROWSER_SYNC_GLUE_TYPED_URL_MODEL_ASSOCIATOR_H_
7#pragma once
8
9#include <map>
10#include <string>
11#include <vector>
12
13#include "base/basictypes.h"
14#include "base/string16.h"
15#include "base/task.h"
16#include "chrome/browser/history/history_types.h"
17#include "chrome/browser/sync/glue/model_associator.h"
18#include "chrome/browser/sync/protocol/typed_url_specifics.pb.h"
19
20class GURL;
21class MessageLoop;
22class ProfileSyncService;
23
24namespace history {
25class HistoryBackend;
26class URLRow;
27};
28
29namespace sync_api {
30class WriteNode;
31class WriteTransaction;
32};
33
34namespace browser_sync {
35
36class TypedUrlChangeProcessor;
37class UnrecoverableErrorHandler;
38
39extern const char kTypedUrlTag[];
40
41// Contains all model association related logic:
42// * Algorithm to associate typed_url model and sync model.
43// * Persisting model associations and loading them back.
44// We do not check if we have local data before this run; we always
45// merge and sync.
46class TypedUrlModelAssociator
47  : public PerDataTypeAssociatorInterface<std::string, std::string> {
48 public:
49  typedef std::vector<std::pair<GURL, string16> > TypedUrlTitleVector;
50  typedef std::vector<history::URLRow> TypedUrlVector;
51  typedef std::vector<std::pair<history::URLID, history::URLRow> >
52      TypedUrlUpdateVector;
53  typedef std::vector<std::pair<GURL, std::vector<base::Time> > >
54      TypedUrlVisitVector;
55
56  static syncable::ModelType model_type() { return syncable::TYPED_URLS; }
57  TypedUrlModelAssociator(ProfileSyncService* sync_service,
58                          history::HistoryBackend* history_backend);
59  virtual ~TypedUrlModelAssociator();
60
61  // PerDataTypeAssociatorInterface implementation.
62  //
63  // Iterates through the sync model looking for matched pairs of items.
64  virtual bool AssociateModels();
65
66  // Delete all typed url nodes.
67  bool DeleteAllNodes(sync_api::WriteTransaction* trans);
68
69  // Clears all associations.
70  virtual bool DisassociateModels();
71
72  // The has_nodes out param is true if the sync model has nodes other
73  // than the permanent tagged nodes.
74  virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes);
75
76  virtual void AbortAssociation();
77
78  virtual bool CryptoReadyIfNecessary();
79
80  // Not implemented.
81  virtual const std::string* GetChromeNodeFromSyncId(int64 sync_id);
82
83  // Not implemented.
84  virtual bool InitSyncNodeFromChromeId(const std::string& node_id,
85                                        sync_api::BaseNode* sync_node);
86
87  // Returns the sync id for the given typed_url name, or sync_api::kInvalidId
88  // if the typed_url name is not associated to any sync id.
89  virtual int64 GetSyncIdFromChromeId(const std::string& node_id);
90
91  // Associates the given typed_url name with the given sync id.
92  virtual void Associate(const std::string* node, int64 sync_id);
93
94  // Remove the association that corresponds to the given sync id.
95  virtual void Disassociate(int64 sync_id);
96
97  // Returns whether a node with the given permanent tag was found and update
98  // |sync_id| with that node's id.
99  virtual bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id);
100
101  bool WriteToHistoryBackend(const TypedUrlTitleVector* titles,
102                             const TypedUrlVector* new_urls,
103                             const TypedUrlUpdateVector* updated_urls,
104                             const TypedUrlVisitVector* new_visits,
105                             const history::VisitVector* deleted_visits);
106
107  enum {
108    DIFF_NONE           = 0x0000,
109    DIFF_NODE_CHANGED   = 0x0001,
110    DIFF_TITLE_CHANGED  = 0x0002,
111    DIFF_ROW_CHANGED    = 0x0004,
112    DIFF_VISITS_ADDED   = 0x0008,
113  };
114
115  static int MergeUrls(const sync_pb::TypedUrlSpecifics& typed_url,
116                       const history::URLRow& url,
117                       history::VisitVector* visits,
118                       history::URLRow* new_url,
119                       std::vector<base::Time>* new_visits);
120  static void WriteToSyncNode(const history::URLRow& url,
121                              const history::VisitVector& visits,
122                              sync_api::WriteNode* node);
123
124  static void DiffVisits(const history::VisitVector& old_visits,
125                         const sync_pb::TypedUrlSpecifics& new_url,
126                         std::vector<base::Time>* new_visits,
127                         history::VisitVector* removed_visits);
128
129 private:
130  typedef std::map<std::string, int64> TypedUrlToSyncIdMap;
131  typedef std::map<int64, std::string> SyncIdToTypedUrlMap;
132
133  ProfileSyncService* sync_service_;
134  history::HistoryBackend* history_backend_;
135  int64 typed_url_node_id_;
136
137  MessageLoop* expected_loop_;
138
139  TypedUrlToSyncIdMap id_map_;
140  SyncIdToTypedUrlMap id_map_inverse_;
141
142  DISALLOW_COPY_AND_ASSIGN(TypedUrlModelAssociator);
143};
144
145}  // namespace browser_sync
146
147#endif  // CHROME_BROWSER_SYNC_GLUE_TYPED_URL_MODEL_ASSOCIATOR_H_
148