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/memory/ref_counted.h" 14#include "base/memory/weak_ptr.h" 15#include "base/synchronization/lock.h" 16#include "chrome/browser/history/history_service.h" 17#include "chrome/browser/history/history_types.h" 18#include "chrome/browser/sessions/tab_restore_service.h" 19#include "chrome/browser/sessions/tab_restore_service_observer.h" 20#include "chrome/common/cancelable_task_tracker.h" 21#include "content/public/browser/browser_thread.h" 22#include "third_party/skia/include/core/SkBitmap.h" 23 24namespace base { 25class FilePath; 26} 27 28namespace chrome { 29struct FaviconImageResult; 30} 31 32namespace content { 33class NotificationRegistrar; 34} 35 36class Profile; 37class PageUsageData; 38 39// Represents a class used for creating an IShellLink object by the utility 40// functions in this file. 41// This class consists of three strings and a integer. 42// * arguments (std::wstring) 43// The arguments for the application. 44// * title (std::wstring) 45// The string to be displayed in a JumpList. 46// * icon (std::wstring) 47// The absolute path to an icon to be displayed in a JumpList. 48// * index (int) 49// The icon index in the icon file. If an icon file consists of two or more 50// icons, set this value to identify the icon. If an icon file consists of 51// one icon, this value is 0. 52// Even though an IShellLink also needs the absolute path to an application to 53// be executed, this class does not have any variables for it because our 54// utility functions always use "chrome.exe" as the application and we don't 55// need it. 56class ShellLinkItem : public base::RefCountedThreadSafe<ShellLinkItem> { 57 public: 58 ShellLinkItem() : index_(0), favicon_(false) { 59 } 60 61 const std::wstring& arguments() const { return arguments_; } 62 const std::wstring& title() const { return title_; } 63 const std::wstring& icon() const { return icon_; } 64 int index() const { return index_; } 65 const SkBitmap& data() const { return data_; } 66 67 void SetArguments(const std::wstring& arguments) { 68 arguments_ = arguments; 69 } 70 71 void SetTitle(const std::wstring& title) { 72 title_ = title; 73 } 74 75 void SetIcon(const std::wstring& icon, int index, bool favicon) { 76 icon_ = icon; 77 index_ = index; 78 favicon_ = favicon; 79 } 80 81 void SetIconData(const SkBitmap& data) { 82 data_ = data; 83 } 84 85 private: 86 friend class base::RefCountedThreadSafe<ShellLinkItem>; 87 88 ~ShellLinkItem() {} 89 90 std::wstring arguments_; 91 std::wstring title_; 92 std::wstring icon_; 93 SkBitmap data_; 94 int index_; 95 bool favicon_; 96 97 DISALLOW_COPY_AND_ASSIGN(ShellLinkItem); 98}; 99 100typedef std::vector<scoped_refptr<ShellLinkItem> > ShellLinkItemList; 101 102// A class which implements an application JumpList. 103// This class encapsulates operations required for updating an application 104// JumpList: 105// * Retrieving "Most Visited" pages from HistoryService; 106// * Retrieving strings from the application resource; 107// * Creatng COM objects used by JumpList from PageUsageData objects; 108// * Adding COM objects to JumpList, etc. 109// 110// This class also implements TabRestoreServiceObserver. So, once we call 111// AddObserver() and register this class as an observer, it automatically 112// updates a JumpList when a tab is added or removed. 113// 114// Updating a JumpList requires some file operations and it is not good to 115// update it in a UI thread. To solve this problem, this class posts to a 116// runnable method when it actually updates a JumpList. 117// 118// Note. CancelableTaskTracker is not thread safe, so we always delete JumpList 119// on UI thread (the same thread it got constructed on). 120class JumpList : public TabRestoreServiceObserver, 121 public content::NotificationObserver, 122 public base::RefCountedThreadSafe< 123 JumpList, content::BrowserThread::DeleteOnUIThread> { 124 public: 125 JumpList(); 126 127 // NotificationObserver implementation. 128 virtual void Observe(int type, 129 const content::NotificationSource& source, 130 const content::NotificationDetails& details); 131 132 // Registers (or unregisters) this object as an observer. 133 // When the TabRestoreService object notifies the tab status is changed, this 134 // class automatically updates an application JumpList. 135 bool AddObserver(Profile* profile); 136 void RemoveObserver(); 137 138 // Observer callback for TabRestoreService::Observer to notify when a tab is 139 // added or removed. 140 // This function sends a query that retrieves "Most Visited" pages to 141 // HistoryService. When the query finishes successfully, HistoryService call 142 // OnSegmentUsageAvailable(). 143 virtual void TabRestoreServiceChanged(TabRestoreService* service); 144 145 // Observer callback to notice when our associated TabRestoreService 146 // is destroyed. 147 virtual void TabRestoreServiceDestroyed(TabRestoreService* service); 148 149 // Cancel a pending jumplist update. 150 void CancelPendingUpdate(); 151 152 // Terminate the jumplist: cancel any pending updates and remove observer 153 // from TabRestoreService. This must be called before the profile provided 154 // in the AddObserver method is destroyed. 155 void Terminate(); 156 157 // Returns true if the custom JumpList is enabled. 158 // We use the custom JumpList when we satisfy the following conditions: 159 // * Chromium is running on Windows 7 and; 160 // * Chromium is lauched without a "--disable-custom-jumplist" option. 161 // TODO(hbono): to be enabled by default when we finalize the categories and 162 // items of our JumpList. 163 static bool Enabled(); 164 165 protected: 166 // Creates a ShellLinkItem object from a tab (or a window) and add it to the 167 // given list. 168 // These functions are copied from the RecentlyClosedTabsHandler class for 169 // compatibility with the new-tab page. 170 bool AddTab(const TabRestoreService::Tab* tab, 171 ShellLinkItemList* list, 172 size_t max_items); 173 void AddWindow(const TabRestoreService::Window* window, 174 ShellLinkItemList* list, 175 size_t max_items); 176 177 // Starts loading a favicon for each URL in |icon_urls_|. 178 // This function sends a query to HistoryService. 179 // When finishing loading all favicons, this function posts a task that 180 // decompresses collected favicons and updates a JumpList. 181 void StartLoadingFavicon(); 182 183 // A callback function for HistoryService that notify when the "Most Visited" 184 // list is available. 185 // This function updates the ShellLinkItemList objects and send another query 186 // that retrieves a favicon for each URL in the list. 187 void OnSegmentUsageAvailable(CancelableRequestProvider::Handle handle, 188 std::vector<PageUsageData*>* data); 189 190 // A callback function for HistoryService that notify when a requested favicon 191 // is available. 192 // To avoid file operations, this function just attaches the given data to 193 // a ShellLinkItem object. 194 void OnFaviconDataAvailable(const chrome::FaviconImageResult& image_result); 195 196 // Callback for TopSites that notifies when the "Most 197 // Visited" list is available. This function updates the ShellLinkItemList 198 // objects and send another query that retrieves a favicon for each URL in 199 // the list. 200 void OnMostVisitedURLsAvailable( 201 const history::MostVisitedURLList& data); 202 203 // Runnable method that updates the jumplist, once all the data 204 // has been fetched. 205 void RunUpdate(); 206 207 // Helper method for RunUpdate to create icon files for the asynchrounously 208 // loaded icons. 209 void CreateIconFiles(const ShellLinkItemList& item_list); 210 211 private: 212 friend struct content::BrowserThread::DeleteOnThread< 213 content::BrowserThread::UI>; 214 friend class base::DeleteHelper<JumpList>; 215 ~JumpList(); 216 217 // For callbacks may be run after destruction. 218 base::WeakPtrFactory<JumpList> weak_ptr_factory_; 219 220 // Tracks FaviconService tasks. 221 CancelableTaskTracker cancelable_task_tracker_; 222 223 // The Profile object is used to listen for events 224 Profile* profile_; 225 226 // Lives on the UI thread. 227 scoped_ptr<content::NotificationRegistrar> registrar_; 228 229 // App id to associate with the jump list. 230 std::wstring app_id_; 231 232 // The directory which contains JumpList icons. 233 base::FilePath icon_dir_; 234 235 // Items in the "Most Visited" category of the application JumpList, 236 // protected by the list_lock_. 237 ShellLinkItemList most_visited_pages_; 238 239 // Items in the "Recently Closed" category of the application JumpList, 240 // protected by the list_lock_. 241 ShellLinkItemList recently_closed_pages_; 242 243 // A list of URLs we need to retrieve their favicons, 244 // protected by the list_lock_. 245 typedef std::pair<std::string, scoped_refptr<ShellLinkItem> > URLPair; 246 std::list<URLPair> icon_urls_; 247 248 // Id of last favicon task. It's used to cancel current task if a new one 249 // comes in before it finishes. 250 CancelableTaskTracker::TaskId task_id_; 251 252 // Lock for most_visited_pages_, recently_closed_pages_, icon_urls_ 253 // as they may be used by up to 3 threads. 254 base::Lock list_lock_; 255 256 DISALLOW_COPY_AND_ASSIGN(JumpList); 257}; 258 259#endif // CHROME_BROWSER_JUMPLIST_WIN_H_ 260