1 // Copyright (c) 2012 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_HISTORY_SHORTCUTS_BACKEND_H_ 6 #define CHROME_BROWSER_HISTORY_SHORTCUTS_BACKEND_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/files/file_path.h" 13 #include "base/gtest_prod_util.h" 14 #include "base/memory/ref_counted.h" 15 #include "base/memory/scoped_ptr.h" 16 #include "base/observer_list.h" 17 #include "base/strings/string16.h" 18 #include "base/synchronization/lock.h" 19 #include "base/time/time.h" 20 #include "chrome/browser/autocomplete/autocomplete_match.h" 21 #include "components/browser_context_keyed_service/refcounted_browser_context_keyed_service.h" 22 #include "content/public/browser/notification_observer.h" 23 #include "content/public/browser/notification_registrar.h" 24 #include "url/gurl.h" 25 26 class Profile; 27 28 namespace history { 29 30 class ShortcutsDatabase; 31 32 // This class manages the shortcut provider backend - access to database on the 33 // db thread, etc. 34 class ShortcutsBackend : public RefcountedBrowserContextKeyedService, 35 public content::NotificationObserver { 36 public: 37 // The following struct encapsulates one previously selected omnibox shortcut. 38 struct Shortcut { 39 Shortcut(const std::string& id, 40 const string16& text, 41 const GURL& url, 42 const string16& contents, 43 const ACMatchClassifications& contents_class, 44 const string16& description, 45 const ACMatchClassifications& description_class, 46 const base::Time& last_access_time, 47 int number_of_hits); 48 // Required for STL, we don't use this directly. 49 Shortcut(); 50 ~Shortcut(); 51 52 std::string id; // Unique guid for the shortcut. 53 string16 text; // The user's original input string. 54 GURL url; // The corresponding destination URL. 55 56 // Contents and description from the original match, along with their 57 // corresponding markup. We need these in order to correctly mark which 58 // parts are URLs, dim, etc. However, we strip all MATCH classifications 59 // from these since we'll mark the matching portions ourselves as we match 60 // the user's current typing against these Shortcuts. 61 string16 contents; 62 ACMatchClassifications contents_class; 63 string16 description; 64 ACMatchClassifications description_class; 65 66 base::Time last_access_time; // Last time shortcut was selected. 67 int number_of_hits; // How many times shortcut was selected. 68 }; 69 70 typedef std::multimap<string16, ShortcutsBackend::Shortcut> ShortcutMap; 71 72 // |profile| is necessary for profile notifications only and can be NULL in 73 // unit-tests. For unit testing, set |suppress_db| to true to prevent creation 74 // of the database, in which case all operations are performed in memory only. 75 ShortcutsBackend(Profile* profile, bool suppress_db); 76 77 // The interface is guaranteed to be called on the thread AddObserver() 78 // was called. 79 class ShortcutsBackendObserver { 80 public: 81 // Called after the database is loaded and Init() completed. 82 virtual void OnShortcutsLoaded() = 0; 83 // Called when shortcuts changed (added/updated/removed) in the database. 84 virtual void OnShortcutsChanged() {} 85 86 protected: 87 virtual ~ShortcutsBackendObserver() {} 88 }; 89 90 // Asynchronously initializes the ShortcutsBackend, it is safe to call 91 // multiple times - only the first call will be processed. 92 bool Init(); 93 94 bool initialized() const { return current_state_ == INITIALIZED; } 95 96 // All of the public functions *must* be called on UI thread only! 97 98 // Adds the Shortcut to the database. 99 bool AddShortcut(const ShortcutsBackend::Shortcut& shortcut); 100 101 // Updates timing and selection count for the Shortcut. 102 bool UpdateShortcut(const ShortcutsBackend::Shortcut& shortcut); 103 104 // Deletes the Shortcuts with the id. 105 bool DeleteShortcutsWithIds(const std::vector<std::string>& shortcut_ids); 106 107 // Deletes the Shortcuts with the url. 108 bool DeleteShortcutsWithUrl(const GURL& shortcut_url); 109 110 // Deletes all of the shortcuts. 111 bool DeleteAllShortcuts(); 112 113 const ShortcutMap& shortcuts_map() const { 114 return shortcuts_map_; 115 } 116 117 void AddObserver(ShortcutsBackendObserver* obs) { 118 observer_list_.AddObserver(obs); 119 } 120 121 void RemoveObserver(ShortcutsBackendObserver* obs) { 122 observer_list_.RemoveObserver(obs); 123 } 124 125 private: 126 friend class base::RefCountedThreadSafe<ShortcutsBackend>; 127 128 typedef std::map<std::string, ShortcutMap::iterator> 129 GuidToShortcutsIteratorMap; 130 131 virtual ~ShortcutsBackend(); 132 133 // Internal initialization of the back-end. Posted by Init() to the DB thread. 134 // On completion posts InitCompleted() back to UI thread. 135 void InitInternal(); 136 137 // Finishes initialization on UI thread, notifies all observers. 138 void InitCompleted(); 139 140 // content::NotificationObserver: 141 virtual void Observe(int type, 142 const content::NotificationSource& source, 143 const content::NotificationDetails& details) OVERRIDE; 144 145 // RefcountedBrowserContextKeyedService 146 virtual void ShutdownOnUIThread() OVERRIDE; 147 148 enum CurrentState { 149 NOT_INITIALIZED, // Backend created but not initialized. 150 INITIALIZING, // Init() called, but not completed yet. 151 INITIALIZED, // Initialization completed, all accessors can be safely 152 // called. 153 }; 154 155 CurrentState current_state_; 156 ObserverList<ShortcutsBackendObserver> observer_list_; 157 scoped_refptr<ShortcutsDatabase> db_; 158 159 // The |temp_shortcuts_map_| and |temp_guid_map_| used for temporary storage 160 // between InitInternal() and InitComplete() to avoid doing a potentially huge 161 // copy. 162 scoped_ptr<ShortcutMap> temp_shortcuts_map_; 163 scoped_ptr<GuidToShortcutsIteratorMap> temp_guid_map_; 164 165 ShortcutMap shortcuts_map_; 166 // This is a helper map for quick access to a shortcut by guid. 167 GuidToShortcutsIteratorMap guid_map_; 168 169 content::NotificationRegistrar notification_registrar_; 170 171 // For some unit-test only. 172 bool no_db_access_; 173 174 DISALLOW_COPY_AND_ASSIGN(ShortcutsBackend); 175 }; 176 177 } // namespace history 178 179 #endif // CHROME_BROWSER_HISTORY_SHORTCUTS_BACKEND_H_ 180