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_JUMPLIST_WIN_H_ 6 #define CHROME_BROWSER_JUMPLIST_WIN_H_ 7 8 #include <list> 9 #include <string> 10 #include <utility> 11 #include <vector> 12 13 #include "base/files/file_path.h" 14 #include "base/memory/weak_ptr.h" 15 #include "base/synchronization/lock.h" 16 #include "base/task/cancelable_task_tracker.h" 17 #include "chrome/browser/history/history_service.h" 18 #include "chrome/browser/history/history_types.h" 19 #include "chrome/browser/jumplist_updater_win.h" 20 #include "chrome/browser/sessions/tab_restore_service.h" 21 #include "chrome/browser/sessions/tab_restore_service_observer.h" 22 #include "content/public/browser/browser_thread.h" 23 24 namespace chrome { 25 struct FaviconImageResult; 26 } 27 28 namespace content { 29 class NotificationRegistrar; 30 } 31 32 class Profile; 33 class PageUsageData; 34 35 // A class which implements an application JumpList. 36 // This class encapsulates operations required for updating an application 37 // JumpList: 38 // * Retrieving "Most Visited" pages from HistoryService; 39 // * Retrieving strings from the application resource; 40 // * Creatng COM objects used by JumpList from PageUsageData objects; 41 // * Adding COM objects to JumpList, etc. 42 // 43 // This class also implements TabRestoreServiceObserver. So, once we call 44 // AddObserver() and register this class as an observer, it automatically 45 // updates a JumpList when a tab is added or removed. 46 // 47 // Updating a JumpList requires some file operations and it is not good to 48 // update it in a UI thread. To solve this problem, this class posts to a 49 // runnable method when it actually updates a JumpList. 50 // 51 // Note. base::CancelableTaskTracker is not thread safe, so we 52 // always delete JumpList on UI thread (the same thread it got constructed on). 53 class JumpList : public TabRestoreServiceObserver, 54 public content::NotificationObserver, 55 public base::RefCountedThreadSafe< 56 JumpList, content::BrowserThread::DeleteOnUIThread> { 57 public: 58 JumpList(); 59 60 // NotificationObserver implementation. 61 virtual void Observe(int type, 62 const content::NotificationSource& source, 63 const content::NotificationDetails& details); 64 65 // Registers (or unregisters) this object as an observer. 66 // When the TabRestoreService object notifies the tab status is changed, this 67 // class automatically updates an application JumpList. 68 bool AddObserver(Profile* profile); 69 void RemoveObserver(); 70 71 // Observer callback for TabRestoreService::Observer to notify when a tab is 72 // added or removed. 73 // This function sends a query that retrieves "Most Visited" pages to 74 // HistoryService. When the query finishes successfully, HistoryService call 75 // OnSegmentUsageAvailable(). 76 virtual void TabRestoreServiceChanged(TabRestoreService* service); 77 78 // Observer callback to notice when our associated TabRestoreService 79 // is destroyed. 80 virtual void TabRestoreServiceDestroyed(TabRestoreService* service); 81 82 // Cancel a pending jumplist update. 83 void CancelPendingUpdate(); 84 85 // Terminate the jumplist: cancel any pending updates and remove observer 86 // from TabRestoreService. This must be called before the profile provided 87 // in the AddObserver method is destroyed. 88 void Terminate(); 89 90 // Returns true if the custom JumpList is enabled. 91 // The custom jumplist works only on Windows 7 and above. 92 static bool Enabled(); 93 94 protected: 95 // Creates a ShellLinkItem object from a tab (or a window) and add it to the 96 // given list. 97 // These functions are copied from the RecentlyClosedTabsHandler class for 98 // compatibility with the new-tab page. 99 bool AddTab(const TabRestoreService::Tab* tab, 100 ShellLinkItemList* list, 101 size_t max_items); 102 void AddWindow(const TabRestoreService::Window* window, 103 ShellLinkItemList* list, 104 size_t max_items); 105 106 // Starts loading a favicon for each URL in |icon_urls_|. 107 // This function sends a query to HistoryService. 108 // When finishing loading all favicons, this function posts a task that 109 // decompresses collected favicons and updates a JumpList. 110 void StartLoadingFavicon(); 111 112 // A callback function for HistoryService that notify when the "Most Visited" 113 // list is available. 114 // This function updates the ShellLinkItemList objects and send another query 115 // that retrieves a favicon for each URL in the list. 116 void OnSegmentUsageAvailable(CancelableRequestProvider::Handle handle, 117 std::vector<PageUsageData*>* data); 118 119 // A callback function for HistoryService that notify when a requested favicon 120 // is available. 121 // To avoid file operations, this function just attaches the given data to 122 // a ShellLinkItem object. 123 void OnFaviconDataAvailable( 124 const favicon_base::FaviconImageResult& image_result); 125 126 // Callback for TopSites that notifies when the "Most 127 // Visited" list is available. This function updates the ShellLinkItemList 128 // objects and send another query that retrieves a favicon for each URL in 129 // the list. 130 void OnMostVisitedURLsAvailable( 131 const history::MostVisitedURLList& data); 132 133 // Runnable method that updates the jumplist, once all the data 134 // has been fetched. 135 void RunUpdate(); 136 137 // Helper method for RunUpdate to create icon files for the asynchrounously 138 // loaded icons. 139 void CreateIconFiles(const ShellLinkItemList& item_list); 140 141 private: 142 friend struct content::BrowserThread::DeleteOnThread< 143 content::BrowserThread::UI>; 144 friend class base::DeleteHelper<JumpList>; 145 ~JumpList(); 146 147 // For callbacks may be run after destruction. 148 base::WeakPtrFactory<JumpList> weak_ptr_factory_; 149 150 // Tracks FaviconService tasks. 151 base::CancelableTaskTracker cancelable_task_tracker_; 152 153 // The Profile object is used to listen for events 154 Profile* profile_; 155 156 // Lives on the UI thread. 157 scoped_ptr<content::NotificationRegistrar> registrar_; 158 159 // App id to associate with the jump list. 160 std::wstring app_id_; 161 162 // The directory which contains JumpList icons. 163 base::FilePath icon_dir_; 164 165 // Items in the "Most Visited" category of the application JumpList, 166 // protected by the list_lock_. 167 ShellLinkItemList most_visited_pages_; 168 169 // Items in the "Recently Closed" category of the application JumpList, 170 // protected by the list_lock_. 171 ShellLinkItemList recently_closed_pages_; 172 173 // A list of URLs we need to retrieve their favicons, 174 // protected by the list_lock_. 175 typedef std::pair<std::string, scoped_refptr<ShellLinkItem> > URLPair; 176 std::list<URLPair> icon_urls_; 177 178 // Id of last favicon task. It's used to cancel current task if a new one 179 // comes in before it finishes. 180 base::CancelableTaskTracker::TaskId task_id_; 181 182 // Lock for most_visited_pages_, recently_closed_pages_, icon_urls_ 183 // as they may be used by up to 3 threads. 184 base::Lock list_lock_; 185 186 DISALLOW_COPY_AND_ASSIGN(JumpList); 187 }; 188 189 #endif // CHROME_BROWSER_JUMPLIST_WIN_H_ 190