Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / history / typed_url_syncable_service.h
1 // Copyright (c) 2013 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_HISTORY_TYPED_URL_SYNCABLE_SERVICE_H_
6 #define CHROME_BROWSER_HISTORY_TYPED_URL_SYNCABLE_SERVICE_H_
7
8 #include <set>
9 #include <vector>
10
11 #include "chrome/browser/history/history_notifications.h"
12 #include "chrome/browser/history/history_types.h"
13 #include "content/public/common/page_transition_types.h"
14 #include "sync/api/sync_change.h"
15 #include "sync/api/sync_data.h"
16 #include "sync/api/sync_error.h"
17 #include "sync/api/sync_error_factory.h"
18 #include "sync/api/syncable_service.h"
19
20 class GURL;
21 class TypedUrlSyncableServiceTest;
22
23 namespace base {
24 class MessageLoop;
25 };
26
27 namespace sync_pb {
28 class TypedUrlSpecifics;
29 };
30
31 namespace history {
32
33 class HistoryBackend;
34 class URLRow;
35
36 extern const char kTypedUrlTag[];
37
38 class TypedUrlSyncableService : public syncer::SyncableService {
39  public:
40   explicit TypedUrlSyncableService(HistoryBackend* history_backend);
41   virtual ~TypedUrlSyncableService();
42
43   static syncer::ModelType model_type() { return syncer::TYPED_URLS; }
44
45   // syncer::SyncableService implementation.
46   virtual syncer::SyncMergeResult MergeDataAndStartSyncing(
47       syncer::ModelType type,
48       const syncer::SyncDataList& initial_sync_data,
49       scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
50       scoped_ptr<syncer::SyncErrorFactory> error_handler) OVERRIDE;
51   virtual void StopSyncing(syncer::ModelType type) OVERRIDE;
52   virtual syncer::SyncDataList GetAllSyncData(
53       syncer::ModelType type) const OVERRIDE;
54   virtual syncer::SyncError ProcessSyncChanges(
55       const tracked_objects::Location& from_here,
56       const syncer::SyncChangeList& change_list) OVERRIDE;
57
58   // Called directly by HistoryBackend when local url data changes.
59   void OnUrlsModified(URLRows* changed_urls);
60   void OnUrlVisited(content::PageTransition transition, URLRow* row);
61   void OnUrlsDeleted(bool all_history, bool archived, URLRows* rows);
62
63  protected:
64   void GetSyncedUrls(std::set<GURL>* urls) {
65     urls->insert(synced_typed_urls_.begin(), synced_typed_urls_.end());
66   }
67
68  private:
69   typedef std::vector<std::pair<URLID, URLRow> > TypedUrlUpdateVector;
70   typedef std::vector<std::pair<GURL, std::vector<VisitInfo> > >
71       TypedUrlVisitVector;
72
73   // This is a helper map used only in Merge/Process* functions. The lifetime
74   // of the iterator is longer than the map object.
75   typedef std::map<GURL, std::pair<syncer::SyncChange::SyncChangeType,
76                                    URLRows::iterator> > TypedUrlMap;
77   // This is a helper map used to associate visit vectors from the history db
78   // to the typed urls in the above map.
79   typedef std::map<GURL, VisitVector> UrlVisitVectorMap;
80
81   // Helper function that determines if we should ignore a URL for the purposes
82   // of sync, because it contains invalid data.
83   bool ShouldIgnoreUrl(const GURL& url);
84
85   // Returns true if the caller should sync as a result of the passed visit
86   // notification. We use this to throttle the number of sync changes we send
87   // to the server so we don't hit the server for every
88   // single typed URL visit.
89   bool ShouldSyncVisit(content::PageTransition transition, URLRow* row);
90
91   // Utility routine that either updates an existing sync node or creates a
92   // new one for the passed |typed_url| if one does not already exist. Returns
93   // false and sets an unrecoverable error if the operation failed.
94   bool CreateOrUpdateSyncNode(URLRow typed_url,
95                               syncer::SyncChangeList* changes);
96
97   void AddTypedUrlToChangeList(
98     syncer::SyncChange::SyncChangeType change_type,
99     const URLRow& row,
100     const VisitVector& visits,
101     std::string title,
102     syncer::SyncChangeList* change_list);
103
104   // Converts the passed URL information to a TypedUrlSpecifics structure for
105   // writing to the sync DB.
106   static void WriteToTypedUrlSpecifics(const URLRow& url,
107                                        const VisitVector& visits,
108                                        sync_pb::TypedUrlSpecifics* specifics);
109
110   // Fetches visits from the history DB corresponding to the passed URL. This
111   // function compensates for the fact that the history DB has rather poor data
112   // integrity (duplicate visits, visit timestamps that don't match the
113   // last_visit timestamp, huge data sets that exhaust memory when fetched,
114   // etc) by modifying the passed |url| object and |visits| vector.
115   // Returns false if we could not fetch the visits for the passed URL, and
116   // tracks DB error statistics internally for reporting via UMA.
117   virtual bool FixupURLAndGetVisits(URLRow* url,
118                                     VisitVector* visits);
119
120   // TODO(sync): Consider using "delete all" sync logic instead of in-memory
121   // cache of typed urls. See http://crbug.com/231689.
122   std::set<GURL> synced_typed_urls_;
123
124   HistoryBackend* const history_backend_;
125
126   // Whether we're currently processing changes from the syncer. While this is
127   // true, we ignore any local url changes, since we triggered them.
128   bool processing_syncer_changes_;
129
130   // We receive ownership of |sync_processor_| and |error_handler_| in
131   // MergeDataAndStartSyncing() and destroy them in StopSyncing().
132   scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
133   scoped_ptr<syncer::SyncErrorFactory> sync_error_handler_;
134
135   // Statistics for the purposes of tracking the percentage of DB accesses that
136   // fail for each client via UMA.
137   int num_db_accesses_;
138   int num_db_errors_;
139
140   base::MessageLoop* expected_loop_;
141
142   FRIEND_TEST_ALL_PREFIXES(TypedUrlSyncableServiceTest,
143                            AddLocalTypedUrlAndSync);
144   FRIEND_TEST_ALL_PREFIXES(TypedUrlSyncableServiceTest,
145                            UpdateLocalTypedUrlAndSync);
146   FRIEND_TEST_ALL_PREFIXES(TypedUrlSyncableServiceTest,
147                            LinkVisitLocalTypedUrlAndSync);
148   FRIEND_TEST_ALL_PREFIXES(TypedUrlSyncableServiceTest,
149                            TypedVisitLocalTypedUrlAndSync);
150   FRIEND_TEST_ALL_PREFIXES(TypedUrlSyncableServiceTest,
151                            DeleteLocalTypedUrlAndSync);
152   FRIEND_TEST_ALL_PREFIXES(TypedUrlSyncableServiceTest,
153                            DeleteAllLocalTypedUrlAndSync);
154   FRIEND_TEST_ALL_PREFIXES(TypedUrlSyncableServiceTest,
155                            MaxVisitLocalTypedUrlAndSync);
156   FRIEND_TEST_ALL_PREFIXES(TypedUrlSyncableServiceTest,
157                            ThrottleVisitLocalTypedUrlSync);
158
159   DISALLOW_COPY_AND_ASSIGN(TypedUrlSyncableService);
160 };
161
162 }  // namespace history
163
164 #endif  // CHROME_BROWSER_HISTORY_TYPED_URL_SYNCABLE_SERVICE_H_