Home | History | Annotate | Download | only in glue
      1 // Copyright (c) 2012 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_CHANGE_PROCESSOR_H_
      6 #define CHROME_BROWSER_SYNC_GLUE_TYPED_URL_CHANGE_PROCESSOR_H_
      7 
      8 #include "components/sync_driver/change_processor.h"
      9 
     10 #include "base/basictypes.h"
     11 #include "base/compiler_specific.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "chrome/browser/sync/glue/sync_backend_host.h"
     14 #include "chrome/browser/sync/glue/typed_url_model_associator.h"
     15 #include "components/sync_driver/data_type_error_handler.h"
     16 #include "content/public/browser/notification_observer.h"
     17 #include "content/public/browser/notification_registrar.h"
     18 #include "content/public/browser/notification_types.h"
     19 
     20 class Profile;
     21 
     22 namespace base {
     23 class MessageLoop;
     24 }
     25 
     26 namespace content {
     27 class NotificationService;
     28 }
     29 
     30 namespace history {
     31 class HistoryBackend;
     32 struct URLsDeletedDetails;
     33 struct URLsModifiedDetails;
     34 struct URLVisitedDetails;
     35 class URLRow;
     36 };
     37 
     38 namespace browser_sync {
     39 
     40 class DataTypeErrorHandler;
     41 
     42 // This class is responsible for taking changes from the history backend and
     43 // applying them to the sync API 'syncable' model, and vice versa. All
     44 // operations and use of this class are from the UI thread.
     45 class TypedUrlChangeProcessor : public sync_driver::ChangeProcessor,
     46                                 public content::NotificationObserver {
     47  public:
     48   TypedUrlChangeProcessor(Profile* profile,
     49                           TypedUrlModelAssociator* model_associator,
     50                           history::HistoryBackend* history_backend,
     51                           sync_driver::DataTypeErrorHandler* error_handler);
     52   virtual ~TypedUrlChangeProcessor();
     53 
     54   // content::NotificationObserver implementation.
     55   // History -> sync API change application.
     56   virtual void Observe(int type,
     57                        const content::NotificationSource& source,
     58                        const content::NotificationDetails& details) OVERRIDE;
     59 
     60   // sync API model -> WebDataService change application.
     61   virtual void ApplyChangesFromSyncModel(
     62       const syncer::BaseTransaction* trans,
     63       int64 model_version,
     64       const syncer::ImmutableChangeRecordList& changes) OVERRIDE;
     65 
     66   // Commit changes here, after we've released the transaction lock to avoid
     67   // jank.
     68   virtual void CommitChangesFromSyncModel() OVERRIDE;
     69 
     70   // Stop processing changes and wait for being destroyed.
     71   void Disconnect();
     72 
     73  protected:
     74   virtual void StartImpl() OVERRIDE;
     75 
     76  private:
     77   friend class ScopedStopObserving<TypedUrlChangeProcessor>;
     78   void StartObserving();
     79   void StopObserving();
     80 
     81   void HandleURLsModified(history::URLsModifiedDetails* details);
     82   void HandleURLsDeleted(history::URLsDeletedDetails* details);
     83   void HandleURLsVisited(history::URLVisitedDetails* details);
     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(history::URLVisitedDetails* details);
     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(history::URLRow typed_url,
     95                               syncer::WriteTransaction* transaction);
     96 
     97   // The profile with which we are associated.
     98   Profile* profile_;
     99 
    100   // The two models should be associated according to this ModelAssociator.
    101   TypedUrlModelAssociator* model_associator_;
    102 
    103   // The model we are processing changes from.  This is owned by the
    104   // WebDataService which is kept alive by our data type controller
    105   // holding a reference.
    106   history::HistoryBackend* history_backend_;
    107   base::MessageLoop* backend_loop_;
    108 
    109   content::NotificationRegistrar notification_registrar_;
    110 
    111   scoped_ptr<content::NotificationService> notification_service_;
    112 
    113   // The set of pending changes that will be written out on the next
    114   // CommitChangesFromSyncModel() call.
    115   history::URLRows pending_new_urls_;
    116   history::URLRows pending_updated_urls_;
    117   std::vector<GURL> pending_deleted_urls_;
    118   TypedUrlModelAssociator::TypedUrlVisitVector pending_new_visits_;
    119   history::VisitVector pending_deleted_visits_;
    120 
    121   bool disconnected_;
    122   base::Lock disconnect_lock_;
    123 
    124   DISALLOW_COPY_AND_ASSIGN(TypedUrlChangeProcessor);
    125 };
    126 
    127 }  // namespace browser_sync
    128 
    129 #endif  // CHROME_BROWSER_SYNC_GLUE_TYPED_URL_CHANGE_PROCESSOR_H_
    130