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