1 // Copyright (c) 2011 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_BOOKMARK_CHANGE_PROCESSOR_H_ 6 #define CHROME_BROWSER_SYNC_GLUE_BOOKMARK_CHANGE_PROCESSOR_H_ 7 #pragma once 8 9 #include <vector> 10 11 #include "chrome/browser/bookmarks/bookmark_model.h" 12 #include "chrome/browser/sync/engine/syncapi.h" 13 #include "chrome/browser/sync/glue/change_processor.h" 14 #include "chrome/browser/sync/glue/bookmark_model_associator.h" 15 #include "chrome/browser/sync/glue/sync_backend_host.h" 16 17 namespace browser_sync { 18 19 // This class is responsible for taking changes from the BookmarkModel 20 // and applying them to the sync_api 'syncable' model, and vice versa. 21 // All operations and use of this class are from the UI thread. 22 // This is currently bookmarks specific. 23 class BookmarkChangeProcessor : public BookmarkModelObserver, 24 public ChangeProcessor { 25 public: 26 BookmarkChangeProcessor(BookmarkModelAssociator* model_associator, 27 UnrecoverableErrorHandler* error_handler); ~BookmarkChangeProcessor()28 virtual ~BookmarkChangeProcessor() {} 29 30 // BookmarkModelObserver implementation. 31 // BookmarkModel -> sync_api model change application. 32 virtual void Loaded(BookmarkModel* model); 33 virtual void BookmarkModelBeingDeleted(BookmarkModel* model); 34 virtual void BookmarkNodeMoved(BookmarkModel* model, 35 const BookmarkNode* old_parent, 36 int old_index, 37 const BookmarkNode* new_parent, 38 int new_index); 39 virtual void BookmarkNodeAdded(BookmarkModel* model, 40 const BookmarkNode* parent, 41 int index); 42 virtual void BookmarkNodeRemoved(BookmarkModel* model, 43 const BookmarkNode* parent, 44 int index, 45 const BookmarkNode* node); 46 virtual void BookmarkNodeChanged(BookmarkModel* model, 47 const BookmarkNode* node); 48 virtual void BookmarkNodeFaviconLoaded(BookmarkModel* model, 49 const BookmarkNode* node); 50 virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, 51 const BookmarkNode* node); 52 53 // The change processor implementation, responsible for applying changes from 54 // the sync model to the bookmarks model. 55 virtual void ApplyChangesFromSyncModel( 56 const sync_api::BaseTransaction* trans, 57 const sync_api::SyncManager::ChangeRecord* changes, 58 int change_count); 59 60 // The following methods are static and hence may be invoked at any time, 61 // and do not depend on having a running ChangeProcessor. 62 // Creates a bookmark node under the given parent node from the given sync 63 // node. Returns the newly created node. 64 static const BookmarkNode* CreateBookmarkNode( 65 sync_api::BaseNode* sync_node, 66 const BookmarkNode* parent, 67 BookmarkModel* model, 68 int index); 69 70 // Sets the favicon of the given bookmark node from the given sync node. 71 // Returns whether the favicon was set in the bookmark node. 72 // |profile| is the profile that contains the HistoryService and BookmarkModel 73 // for the bookmark in question. 74 static bool SetBookmarkFavicon(sync_api::BaseNode* sync_node, 75 const BookmarkNode* bookmark_node, 76 BookmarkModel* model); 77 78 // Applies the favicon data in |icon_bytes_vector| to |bookmark_node|. 79 // |profile| is the profile that contains the HistoryService and BookmarkModel 80 // for the bookmark in question. 81 static void ApplyBookmarkFavicon( 82 const BookmarkNode* bookmark_node, 83 Profile* profile, 84 const std::vector<unsigned char>& icon_bytes_vector); 85 86 // Sets the favicon of the given sync node from the given bookmark node. 87 static void SetSyncNodeFavicon(const BookmarkNode* bookmark_node, 88 BookmarkModel* model, 89 sync_api::WriteNode* sync_node); 90 91 // Treat the |index|th child of |parent| as a newly added node, and create a 92 // corresponding node in the sync domain using |trans|. All properties 93 // will be transferred to the new node. A node corresponding to |parent| 94 // must already exist and be associated for this call to succeed. Returns 95 // the ID of the just-created node, or if creation fails, kInvalidID. 96 static int64 CreateSyncNode(const BookmarkNode* parent, 97 BookmarkModel* model, 98 int index, 99 sync_api::WriteTransaction* trans, 100 BookmarkModelAssociator* associator, 101 UnrecoverableErrorHandler* error_handler); 102 103 protected: 104 virtual void StartImpl(Profile* profile); 105 virtual void StopImpl(); 106 107 private: 108 enum MoveOrCreate { 109 MOVE, 110 CREATE, 111 }; 112 113 // Create a bookmark node corresponding to |src| if one is not already 114 // associated with |src|. Returns the node that was created or updated. 115 const BookmarkNode* CreateOrUpdateBookmarkNode( 116 sync_api::BaseNode* src, 117 BookmarkModel* model); 118 119 // Helper function to determine the appropriate insertion index of sync node 120 // |node| under the Bookmark model node |parent|, to make the positions 121 // match up between the two models. This presumes that the predecessor of the 122 // item (in the bookmark model) has already been moved into its appropriate 123 // position. 124 int CalculateBookmarkModelInsertionIndex( 125 const BookmarkNode* parent, 126 const sync_api::BaseNode* node) const; 127 128 // Helper function used to fix the position of a sync node so that it matches 129 // the position of a corresponding bookmark model node. |parent| and 130 // |index| identify the bookmark model position. |dst| is the node whose 131 // position is to be fixed. If |operation| is CREATE, treat |dst| as an 132 // uncreated node and set its position via InitByCreation(); otherwise, 133 // |dst| is treated as an existing node, and its position will be set via 134 // SetPosition(). |trans| is the transaction to which |dst| belongs. Returns 135 // false on failure. 136 static bool PlaceSyncNode(MoveOrCreate operation, 137 const BookmarkNode* parent, 138 int index, 139 sync_api::WriteTransaction* trans, 140 sync_api::WriteNode* dst, 141 BookmarkModelAssociator* associator); 142 143 // Copy properties (but not position) from |src| to |dst|. 144 static void UpdateSyncNodeProperties(const BookmarkNode* src, 145 BookmarkModel* model, 146 sync_api::WriteNode* dst); 147 148 // Helper function to encode a bookmark's favicon into a PNG byte vector. 149 static void EncodeFavicon(const BookmarkNode* src, 150 BookmarkModel* model, 151 std::vector<unsigned char>* dst); 152 153 // Remove the sync node corresponding to |node|. It shouldn't have 154 // any children. 155 void RemoveOneSyncNode(sync_api::WriteTransaction* trans, 156 const BookmarkNode* node); 157 158 // Remove all the sync nodes associated with |node| and its children. 159 void RemoveSyncNodeHierarchy(const BookmarkNode* node); 160 161 // The bookmark model we are processing changes from. Non-NULL when 162 // |running_| is true. 163 BookmarkModel* bookmark_model_; 164 165 // The two models should be associated according to this ModelAssociator. 166 BookmarkModelAssociator* model_associator_; 167 168 DISALLOW_COPY_AND_ASSIGN(BookmarkChangeProcessor); 169 }; 170 171 } // namespace browser_sync 172 173 #endif // CHROME_BROWSER_SYNC_GLUE_BOOKMARK_CHANGE_PROCESSOR_H_ 174