1// Copyright (c) 2011 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#pragma once
8
9#include <list>
10#include <string>
11#include <utility>
12#include <vector>
13
14#include "base/memory/ref_counted.h"
15#include "chrome/browser/history/history.h"
16#include "chrome/browser/sessions/tab_restore_service.h"
17#include "chrome/browser/sessions/tab_restore_service_observer.h"
18#include "content/browser/cancelable_request.h"
19
20class FilePath;
21class Profile;
22class PageUsageData;
23
24// Represents a class used for creating an IShellLink object by the utility
25// functions in this file.
26// This class consists of three strings and a integer.
27// * arguments (std::wstring)
28//   The arguments for the application.
29// * title (std::wstring)
30//   The string to be displayed in a JumpList.
31// * icon (std::wstring)
32//   The absolute path to an icon to be displayed in a JumpList.
33// * index (int)
34//   The icon index in the icon file. If an icon file consists of two or more
35//   icons, set this value to identify the icon. If an icon file consists of
36// one icon, this value is 0.
37// Even though an IShellLink also needs the absolute path to an application to
38// be executed, this class does not have any variables for it because our
39// utility functions always use "chrome.exe" as the application and we don't
40// need it.
41class ShellLinkItem : public base::RefCountedThreadSafe<ShellLinkItem> {
42 public:
43  ShellLinkItem() : index_(0), favicon_(false) {
44  }
45
46  const std::wstring& arguments() const { return arguments_; }
47  const std::wstring& title() const { return title_; }
48  const std::wstring& icon() const { return icon_; }
49  int index() const { return index_; }
50  scoped_refptr<RefCountedMemory> data() const { return data_; }
51
52  void SetArguments(const std::wstring& arguments) {
53    arguments_ = arguments;
54  }
55
56  void SetTitle(const std::wstring& title) {
57    title_ = title;
58  }
59
60  void SetIcon(const std::wstring& icon, int index, bool favicon) {
61    icon_ = icon;
62    index_ = index;
63    favicon_ = favicon;
64  }
65
66  void SetIconData(scoped_refptr<RefCountedMemory> data) {
67    data_ = data;
68  }
69
70 private:
71  friend class base::RefCountedThreadSafe<ShellLinkItem>;
72
73  ~ShellLinkItem() {}
74
75  std::wstring arguments_;
76  std::wstring title_;
77  std::wstring icon_;
78  scoped_refptr<RefCountedMemory> data_;
79  int index_;
80  bool favicon_;
81
82  DISALLOW_COPY_AND_ASSIGN(ShellLinkItem);
83};
84
85typedef std::vector<scoped_refptr<ShellLinkItem> > ShellLinkItemList;
86
87// A class which implements an application JumpList.
88// This class encapsulates operations required for updating an application
89// JumpList:
90// * Retrieving "Most Visited" pages from HistoryService;
91// * Retrieving strings from the application resource;
92// * Creatng COM objects used by JumpList from PageUsageData objects;
93// * Adding COM objects to JumpList, etc.
94//
95// This class also implements TabRestoreServiceObserver. So, once we call
96// AddObserver() and register this class as an observer, it automatically
97// updates a JumpList when a tab is added or removed.
98//
99// Updating a JumpList requires some file operations and it is not good to
100// update it in a UI thread. To solve this problem, this class posts a
101// task when it actually updates a JumpList. (This task is implemented in an
102// anomynous namespace in "jumplist_win.cc".)
103class JumpList : public TabRestoreServiceObserver {
104 public:
105  JumpList();
106  ~JumpList();
107
108  // Registers (or unregisters) this object as an observer.
109  // When the TabRestoreService object notifies the tab status is changed, this
110  // class automatically updates an application JumpList.
111  bool AddObserver(Profile* profile);
112  void RemoveObserver();
113
114  // Observer callback for TabRestoreService::Observer to notify when a tab is
115  // added or removed.
116  // This function sends a query that retrieves "Most Visited" pages to
117  // HistoryService. When the query finishes successfully, HistoryService call
118  // OnSegmentUsageAvailable().
119  virtual void TabRestoreServiceChanged(TabRestoreService* service);
120
121  // Observer callback to notice when our associated TabRestoreService
122  // is destroyed.
123  virtual void TabRestoreServiceDestroyed(TabRestoreService* service);
124
125  // Returns true if the custom JumpList is enabled.
126  // We use the custom JumpList when we satisfy the following conditions:
127  // * Chromium is running on Windows 7 and;
128  // * Chromium is lauched without a "--disable-custom-jumplist" option.
129  // TODO(hbono): to be enabled by default when we finalize the categories and
130  // items of our JumpList.
131  static bool Enabled();
132
133 protected:
134  // Creates a ShellLinkItem object from a tab (or a window) and add it to the
135  // given list.
136  // These functions are copied from the RecentlyClosedTabsHandler class for
137  // compatibility with the new-tab page.
138  bool AddTab(const TabRestoreService::Tab* tab,
139              ShellLinkItemList* list,
140              size_t max_items);
141  bool AddWindow(const TabRestoreService::Window* window,
142                 ShellLinkItemList* list,
143                 size_t max_items);
144
145  // Starts loading a favicon for each URL in |icon_urls_|.
146  // This function just sends a query to HistoryService.
147  bool StartLoadingFavicon();
148
149  // A callback function for HistoryService that notify when the "Most Visited"
150  // list is available.
151  // This function updates the ShellLinkItemList objects and send another query
152  // that retrieves a favicon for each URL in the list.
153  void OnSegmentUsageAvailable(CancelableRequestProvider::Handle handle,
154                               std::vector<PageUsageData*>* data);
155
156  // A callback function for HistoryService that notify when a requested favicon
157  // is available.
158  // To avoid file operations, this function just attaches the given data to
159  // a ShellLinkItem object.
160  // When finishing loading all favicons, this function posts a task that
161  // decompresses collected favicons and updates a JumpList.
162  void OnFaviconDataAvailable(HistoryService::Handle handle,
163                              history::FaviconData favicon);
164
165 private:
166  // Our consumers for HistoryService.
167  CancelableRequestConsumer most_visited_consumer_;
168  CancelableRequestConsumer favicon_consumer_;
169
170  // The Profile object used for listening its events.
171  Profile* profile_;
172
173  // App id to associate with the jump list.
174  std::wstring app_id_;
175
176  // The directory which contains JumpList icons.
177  FilePath icon_dir_;
178
179  // Items in the "Most Visited" category of the application JumpList.
180  ShellLinkItemList most_visited_pages_;
181
182  // Items in the "Recently Closed" category of the application JumpList.
183  ShellLinkItemList recently_closed_pages_;
184
185  // A list of URLs we need to retrieve their favicons.
186  typedef std::pair<std::string, scoped_refptr<ShellLinkItem> > URLPair;
187  std::list<URLPair> icon_urls_;
188};
189
190#endif  // CHROME_BROWSER_JUMPLIST_WIN_H_
191