// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_SYNC_GLUE_BOOKMARK_CHANGE_PROCESSOR_H_ #define CHROME_BROWSER_SYNC_GLUE_BOOKMARK_CHANGE_PROCESSOR_H_ #include #include "base/compiler_specific.h" #include "chrome/browser/bookmarks/bookmark_model_observer.h" #include "chrome/browser/sync/glue/bookmark_model_associator.h" #include "chrome/browser/sync/glue/change_processor.h" #include "chrome/browser/sync/glue/data_type_error_handler.h" #include "chrome/browser/sync/glue/sync_backend_host.h" namespace base { class RefCountedMemory; } namespace syncer { class WriteNode; class WriteTransaction; } // namespace syncer namespace browser_sync { extern const char kBookmarkTransactionVersionKey[]; // This class is responsible for taking changes from the BookmarkModel // and applying them to the sync API 'syncable' model, and vice versa. // All operations and use of this class are from the UI thread. // This is currently bookmarks specific. class BookmarkChangeProcessor : public BookmarkModelObserver, public ChangeProcessor { public: BookmarkChangeProcessor(BookmarkModelAssociator* model_associator, DataTypeErrorHandler* error_handler); virtual ~BookmarkChangeProcessor(); // BookmarkModelObserver implementation. // BookmarkModel -> sync API model change application. virtual void Loaded(BookmarkModel* model, bool ids_reassigned) OVERRIDE; virtual void BookmarkModelBeingDeleted(BookmarkModel* model) OVERRIDE; virtual void BookmarkNodeMoved(BookmarkModel* model, const BookmarkNode* old_parent, int old_index, const BookmarkNode* new_parent, int new_index) OVERRIDE; virtual void BookmarkNodeAdded(BookmarkModel* model, const BookmarkNode* parent, int index) OVERRIDE; virtual void BookmarkNodeRemoved(BookmarkModel* model, const BookmarkNode* parent, int index, const BookmarkNode* node) OVERRIDE; virtual void BookmarkAllNodesRemoved(BookmarkModel* model) OVERRIDE; virtual void BookmarkNodeChanged(BookmarkModel* model, const BookmarkNode* node) OVERRIDE; virtual void BookmarkNodeFaviconChanged(BookmarkModel* model, const BookmarkNode* node) OVERRIDE; virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, const BookmarkNode* node) OVERRIDE; // The change processor implementation, responsible for applying changes from // the sync model to the bookmarks model. virtual void ApplyChangesFromSyncModel( const syncer::BaseTransaction* trans, int64 model_version, const syncer::ImmutableChangeRecordList& changes) OVERRIDE; // Create a bookmark node corresponding to |src| if one is not already // associated with |src|. Returns the node that was created or updated. static const BookmarkNode* CreateOrUpdateBookmarkNode( syncer::BaseNode* src, BookmarkModel* model, Profile* profile, BookmarkModelAssociator* model_associator); // The following methods are static and hence may be invoked at any time, // and do not depend on having a running ChangeProcessor. // Creates a bookmark node under the given parent node from the given sync // node. Returns the newly created node. static const BookmarkNode* CreateBookmarkNode( syncer::BaseNode* sync_node, const BookmarkNode* parent, BookmarkModel* model, Profile* profile, int index); // Sets the favicon of the given bookmark node from the given sync node. // Returns whether the favicon was set in the bookmark node. // |profile| is the profile that contains the HistoryService and BookmarkModel // for the bookmark in question. static bool SetBookmarkFavicon(syncer::BaseNode* sync_node, const BookmarkNode* bookmark_node, BookmarkModel* model, Profile* profile); // Applies the 1x favicon |bitmap_data| and |icon_url| to |bookmark_node|. // |profile| is the profile that contains the HistoryService and BookmarkModel // for the bookmark in question. static void ApplyBookmarkFavicon( const BookmarkNode* bookmark_node, Profile* profile, const GURL& icon_url, const scoped_refptr& bitmap_data); // Sets the favicon of the given sync node from the given bookmark node. static void SetSyncNodeFavicon(const BookmarkNode* bookmark_node, BookmarkModel* model, syncer::WriteNode* sync_node); // Treat the |index|th child of |parent| as a newly added node, and create a // corresponding node in the sync domain using |trans|. All properties // will be transferred to the new node. A node corresponding to |parent| // must already exist and be associated for this call to succeed. Returns // the ID of the just-created node, or if creation fails, kInvalidID. static int64 CreateSyncNode(const BookmarkNode* parent, BookmarkModel* model, int index, syncer::WriteTransaction* trans, BookmarkModelAssociator* associator, DataTypeErrorHandler* error_handler); // Update transaction version of |model| and |nodes| to |new_version| if // it's valid. static void UpdateTransactionVersion( int64 new_version, BookmarkModel* model, const std::vector& nodes); protected: virtual void StartImpl(Profile* profile) OVERRIDE; private: enum MoveOrCreate { MOVE, CREATE, }; // Helper function to determine the appropriate insertion index of sync node // |node| under the Bookmark model node |parent|, to make the positions // match up between the two models. This presumes that the predecessor of the // item (in the bookmark model) has already been moved into its appropriate // position. static int CalculateBookmarkModelInsertionIndex( const BookmarkNode* parent, const syncer::BaseNode* node, BookmarkModelAssociator* model_associator); // Helper function used to fix the position of a sync node so that it matches // the position of a corresponding bookmark model node. |parent| and // |index| identify the bookmark model position. |dst| is the node whose // position is to be fixed. If |operation| is CREATE, treat |dst| as an // uncreated node and set its position via InitByCreation(); otherwise, // |dst| is treated as an existing node, and its position will be set via // SetPosition(). |trans| is the transaction to which |dst| belongs. Returns // false on failure. static bool PlaceSyncNode(MoveOrCreate operation, const BookmarkNode* parent, int index, syncer::WriteTransaction* trans, syncer::WriteNode* dst, BookmarkModelAssociator* associator); // Copy properties (but not position) from |src| to |dst|. static void UpdateSyncNodeProperties(const BookmarkNode* src, BookmarkModel* model, syncer::WriteNode* dst); // Helper function to encode a bookmark's favicon into raw PNG data. static void EncodeFavicon(const BookmarkNode* src, BookmarkModel* model, scoped_refptr* dst); // Remove |sync_node|. It should not have any children void RemoveOneSyncNode(syncer::WriteNode* sync_node); // Remove all sync nodes, except the permanent nodes. void RemoveAllSyncNodes(); // Remove all children of the bookmark node with bookmark node id: // |topmost_node_id|. void RemoveAllChildNodes(syncer::WriteTransaction* trans, const int64& topmost_node_id); // Remove all the sync nodes associated with |node| and its children. void RemoveSyncNodeHierarchy(const BookmarkNode* node); // The bookmark model we are processing changes from. Non-NULL when // |running_| is true. BookmarkModel* bookmark_model_; Profile* profile_; // The two models should be associated according to this ModelAssociator. BookmarkModelAssociator* model_associator_; DISALLOW_COPY_AND_ASSIGN(BookmarkChangeProcessor); }; } // namespace browser_sync #endif // CHROME_BROWSER_SYNC_GLUE_BOOKMARK_CHANGE_PROCESSOR_H_