1 // Copyright 2013 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_ANDROID_BOOKMARKS_PARTNER_BOOKMARKS_SHIM_H_ 6 #define CHROME_BROWSER_ANDROID_BOOKMARKS_PARTNER_BOOKMARKS_SHIM_H_ 7 8 #include "base/android/jni_weak_ref.h" 9 #include "base/memory/scoped_ptr.h" 10 #include "base/strings/string16.h" 11 #include "base/supports_user_data.h" 12 #include "components/bookmarks/browser/bookmark_model.h" 13 #include "url/gurl.h" 14 15 class PrefService; 16 17 namespace content { 18 class BrowserContext; 19 class WebContents; 20 } 21 22 namespace user_prefs { 23 class PrefRegistrySyncable; 24 } 25 26 // A shim that lives on top of a BookmarkModel that allows the injection of 27 // partner bookmarks without submitting changes to the bookmark model. 28 // The shim persists bookmark renames/deletions in a user profile and could be 29 // queried via shim->GetTitle(node) and shim->IsReachable(node). 30 // Note that node->GetTitle() returns an original (unmodified) title. 31 class PartnerBookmarksShim : public base::SupportsUserData::Data { 32 public: 33 // Returns an instance of the shim for a given |browser_context|. 34 static PartnerBookmarksShim* BuildForBrowserContext( 35 content::BrowserContext* browser_context); 36 37 // Registers preferences. 38 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); 39 40 // Disables the editing and stops any edits from being applied. 41 // The user will start to see the original (unedited) partner bookmarks. 42 // Edits are stored in the user profile, so once the editing is enabled 43 // ("not disabled") the user would see the edited partner bookmarks. 44 // This method should be called as early as possible: it does NOT send any 45 // notifications to already existing shims. 46 static void DisablePartnerBookmarksEditing(); 47 48 // Returns true if everything got loaded. 49 bool IsLoaded() const; 50 51 // Returns true if there are partner bookmarks. 52 bool HasPartnerBookmarks() const; 53 54 // Returns true if a given bookmark is reachable (i.e. neither the bookmark, 55 // nor any of its parents were "removed"). 56 bool IsReachable(const BookmarkNode* node) const; 57 58 // Returns true if a given node is editable and if editing is allowed. 59 bool IsEditable(const BookmarkNode* node) const; 60 61 // Removes a given bookmark. 62 // Makes the |node| (and, consequently, all its children) unreachable. 63 void RemoveBookmark(const BookmarkNode* node); 64 65 // Renames a given bookmark. 66 void RenameBookmark(const BookmarkNode* node, const base::string16& title); 67 68 // For Loaded/Changed/ShimBeingDeleted notifications 69 class Observer { 70 public: 71 // Called when the set of bookmarks, or their values/visibility changes PartnerShimChanged(PartnerBookmarksShim *)72 virtual void PartnerShimChanged(PartnerBookmarksShim*) {} 73 // Called when everything is loaded PartnerShimLoaded(PartnerBookmarksShim *)74 virtual void PartnerShimLoaded(PartnerBookmarksShim*) {} 75 // Called just before everything got destroyed ShimBeingDeleted(PartnerBookmarksShim *)76 virtual void ShimBeingDeleted(PartnerBookmarksShim*) {} 77 protected: ~Observer()78 virtual ~Observer() {} 79 }; 80 81 void AddObserver(Observer* observer); 82 void RemoveObserver(Observer* observer); 83 84 // PartnerBookmarksShim versions of BookmarkModel/BookmarkNode methods 85 const BookmarkNode* GetNodeByID(int64 id) const; 86 base::string16 GetTitle(const BookmarkNode* node) const; 87 88 bool IsPartnerBookmark(const BookmarkNode* node) const; 89 const BookmarkNode* GetPartnerBookmarksRoot() const; 90 91 // Sets the root node of the partner bookmarks and notifies any observers that 92 // the shim has now been loaded. Takes ownership of |root_node|. 93 void SetPartnerBookmarksRoot(BookmarkNode* root_node); 94 95 // Used as a "unique" identifier of the partner bookmark node for the purposes 96 // of node deletion and title editing. Two bookmarks with the same URLs and 97 // titles are considered indistinguishable. 98 class NodeRenamingMapKey { 99 public: 100 NodeRenamingMapKey(const GURL& url, const base::string16& provider_title); 101 ~NodeRenamingMapKey(); url()102 const GURL& url() const { return url_; } provider_title()103 const base::string16& provider_title() const { return provider_title_; } 104 friend bool operator<(const NodeRenamingMapKey& a, 105 const NodeRenamingMapKey& b); 106 private: 107 GURL url_; 108 base::string16 provider_title_; 109 }; 110 typedef std::map<NodeRenamingMapKey, base::string16> NodeRenamingMap; 111 112 // For testing: clears an instance of the shim in a given |browser_context|. 113 static void ClearInBrowserContextForTesting( 114 content::BrowserContext* browser_context); 115 116 // For testing: clears partner bookmark model data. 117 static void ClearPartnerModelForTesting(); 118 119 // For testing: re-enables partner bookmarks editing. 120 static void EnablePartnerBookmarksEditing(); 121 122 private: 123 explicit PartnerBookmarksShim(PrefService* prefs); 124 virtual ~PartnerBookmarksShim(); 125 126 const BookmarkNode* GetNodeByID(const BookmarkNode* parent, int64 id) const; 127 void ReloadNodeMapping(); 128 void SaveNodeMapping(); 129 130 scoped_ptr<BookmarkNode> partner_bookmarks_root_; 131 PrefService* prefs_; 132 NodeRenamingMap node_rename_remove_map_; 133 134 // The observers. 135 ObserverList<Observer> observers_; 136 137 DISALLOW_COPY_AND_ASSIGN(PartnerBookmarksShim); 138 }; 139 140 #endif // CHROME_BROWSER_ANDROID_BOOKMARKS_PARTNER_BOOKMARKS_SHIM_H_ 141