// Copyright (c) 2011 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_ #pragma once #include <vector> #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/sync/engine/syncapi.h" #include "chrome/browser/sync/glue/change_processor.h" #include "chrome/browser/sync/glue/bookmark_model_associator.h" #include "chrome/browser/sync/glue/sync_backend_host.h" namespace browser_sync { // 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, UnrecoverableErrorHandler* error_handler); virtual ~BookmarkChangeProcessor() {} // BookmarkModelObserver implementation. // BookmarkModel -> sync_api model change application. virtual void Loaded(BookmarkModel* model); virtual void BookmarkModelBeingDeleted(BookmarkModel* model); virtual void BookmarkNodeMoved(BookmarkModel* model, const BookmarkNode* old_parent, int old_index, const BookmarkNode* new_parent, int new_index); virtual void BookmarkNodeAdded(BookmarkModel* model, const BookmarkNode* parent, int index); virtual void BookmarkNodeRemoved(BookmarkModel* model, const BookmarkNode* parent, int index, const BookmarkNode* node); virtual void BookmarkNodeChanged(BookmarkModel* model, const BookmarkNode* node); virtual void BookmarkNodeFaviconLoaded(BookmarkModel* model, const BookmarkNode* node); virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, const BookmarkNode* node); // The change processor implementation, responsible for applying changes from // the sync model to the bookmarks model. virtual void ApplyChangesFromSyncModel( const sync_api::BaseTransaction* trans, const sync_api::SyncManager::ChangeRecord* changes, int change_count); // 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( sync_api::BaseNode* sync_node, const BookmarkNode* parent, BookmarkModel* model, 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(sync_api::BaseNode* sync_node, const BookmarkNode* bookmark_node, BookmarkModel* model); // Applies the favicon data in |icon_bytes_vector| 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 std::vector<unsigned char>& icon_bytes_vector); // Sets the favicon of the given sync node from the given bookmark node. static void SetSyncNodeFavicon(const BookmarkNode* bookmark_node, BookmarkModel* model, sync_api::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, sync_api::WriteTransaction* trans, BookmarkModelAssociator* associator, UnrecoverableErrorHandler* error_handler); protected: virtual void StartImpl(Profile* profile); virtual void StopImpl(); private: enum MoveOrCreate { MOVE, CREATE, }; // Create a bookmark node corresponding to |src| if one is not already // associated with |src|. Returns the node that was created or updated. const BookmarkNode* CreateOrUpdateBookmarkNode( sync_api::BaseNode* src, BookmarkModel* model); // 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. int CalculateBookmarkModelInsertionIndex( const BookmarkNode* parent, const sync_api::BaseNode* node) const; // 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, sync_api::WriteTransaction* trans, sync_api::WriteNode* dst, BookmarkModelAssociator* associator); // Copy properties (but not position) from |src| to |dst|. static void UpdateSyncNodeProperties(const BookmarkNode* src, BookmarkModel* model, sync_api::WriteNode* dst); // Helper function to encode a bookmark's favicon into a PNG byte vector. static void EncodeFavicon(const BookmarkNode* src, BookmarkModel* model, std::vector<unsigned char>* dst); // Remove the sync node corresponding to |node|. It shouldn't have // any children. void RemoveOneSyncNode(sync_api::WriteTransaction* trans, const BookmarkNode* node); // 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_; // 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_