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