summaryrefslogtreecommitdiffstats
path: root/chrome/browser/jumplist_win.h
blob: 5cd8fdc277399cf1b3a19ffe6901f9203cd84439 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_JUMPLIST_WIN_H_
#define CHROME_BROWSER_JUMPLIST_WIN_H_

#include <list>
#include <string>
#include <utility>
#include <vector>

#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
#include "chrome/browser/cancelable_request.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/history/history_types.h"
#include "chrome/browser/sessions/tab_restore_service.h"
#include "chrome/browser/sessions/tab_restore_service_observer.h"

namespace content {
class NotificationRegistrar;
}
class FilePath;
class Profile;
class PageUsageData;

// Represents a class used for creating an IShellLink object by the utility
// functions in this file.
// This class consists of three strings and a integer.
// * arguments (std::wstring)
//   The arguments for the application.
// * title (std::wstring)
//   The string to be displayed in a JumpList.
// * icon (std::wstring)
//   The absolute path to an icon to be displayed in a JumpList.
// * index (int)
//   The icon index in the icon file. If an icon file consists of two or more
//   icons, set this value to identify the icon. If an icon file consists of
// one icon, this value is 0.
// Even though an IShellLink also needs the absolute path to an application to
// be executed, this class does not have any variables for it because our
// utility functions always use "chrome.exe" as the application and we don't
// need it.
class ShellLinkItem : public base::RefCountedThreadSafe<ShellLinkItem> {
 public:
  ShellLinkItem() : index_(0), favicon_(false) {
  }

  const std::wstring& arguments() const { return arguments_; }
  const std::wstring& title() const { return title_; }
  const std::wstring& icon() const { return icon_; }
  int index() const { return index_; }
  scoped_refptr<base::RefCountedMemory> data() const { return data_; }

  void SetArguments(const std::wstring& arguments) {
    arguments_ = arguments;
  }

  void SetTitle(const std::wstring& title) {
    title_ = title;
  }

  void SetIcon(const std::wstring& icon, int index, bool favicon) {
    icon_ = icon;
    index_ = index;
    favicon_ = favicon;
  }

  void SetIconData(scoped_refptr<base::RefCountedMemory> data) {
    data_ = data;
  }

 private:
  friend class base::RefCountedThreadSafe<ShellLinkItem>;

  ~ShellLinkItem() {}

  std::wstring arguments_;
  std::wstring title_;
  std::wstring icon_;
  scoped_refptr<base::RefCountedMemory> data_;
  int index_;
  bool favicon_;

  DISALLOW_COPY_AND_ASSIGN(ShellLinkItem);
};

typedef std::vector<scoped_refptr<ShellLinkItem> > ShellLinkItemList;

// A class which implements an application JumpList.
// This class encapsulates operations required for updating an application
// JumpList:
// * Retrieving "Most Visited" pages from HistoryService;
// * Retrieving strings from the application resource;
// * Creatng COM objects used by JumpList from PageUsageData objects;
// * Adding COM objects to JumpList, etc.
//
// This class also implements TabRestoreServiceObserver. So, once we call
// AddObserver() and register this class as an observer, it automatically
// updates a JumpList when a tab is added or removed.
//
// Updating a JumpList requires some file operations and it is not good to
// update it in a UI thread. To solve this problem, this class posts to a
// runnable method when it actually updates a JumpList.
class JumpList : public TabRestoreServiceObserver,
                 public content::NotificationObserver,
                 public base::RefCountedThreadSafe<JumpList> {
 public:
  JumpList();

  // NotificationObserver implementation.
  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details);

  // Registers (or unregisters) this object as an observer.
  // When the TabRestoreService object notifies the tab status is changed, this
  // class automatically updates an application JumpList.
  bool AddObserver(Profile* profile);
  void RemoveObserver();

  // Observer callback for TabRestoreService::Observer to notify when a tab is
  // added or removed.
  // This function sends a query that retrieves "Most Visited" pages to
  // HistoryService. When the query finishes successfully, HistoryService call
  // OnSegmentUsageAvailable().
  virtual void TabRestoreServiceChanged(TabRestoreService* service);

  // Observer callback to notice when our associated TabRestoreService
  // is destroyed.
  virtual void TabRestoreServiceDestroyed(TabRestoreService* service);

  // Cancel a pending jumplist update.
  void CancelPendingUpdate();

  // Terminate the jumplist: cancel any pending updates and remove observer
  // from TabRestoreService. This must be called before the profile provided
  // in the AddObserver method is destroyed.
  void Terminate();

  // Returns true if the custom JumpList is enabled.
  // We use the custom JumpList when we satisfy the following conditions:
  // * Chromium is running on Windows 7 and;
  // * Chromium is lauched without a "--disable-custom-jumplist" option.
  // TODO(hbono): to be enabled by default when we finalize the categories and
  // items of our JumpList.
  static bool Enabled();

 protected:
  // Creates a ShellLinkItem object from a tab (or a window) and add it to the
  // given list.
  // These functions are copied from the RecentlyClosedTabsHandler class for
  // compatibility with the new-tab page.
  bool AddTab(const TabRestoreService::Tab* tab,
              ShellLinkItemList* list,
              size_t max_items);
  void AddWindow(const TabRestoreService::Window* window,
                 ShellLinkItemList* list,
                 size_t max_items);

  // Starts loading a favicon for each URL in |icon_urls_|.
  // This function just sends a query to HistoryService.
  bool StartLoadingFavicon();

  // A callback function for HistoryService that notify when the "Most Visited"
  // list is available.
  // This function updates the ShellLinkItemList objects and send another query
  // that retrieves a favicon for each URL in the list.
  void OnSegmentUsageAvailable(CancelableRequestProvider::Handle handle,
                               std::vector<PageUsageData*>* data);

  // A callback function for HistoryService that notify when a requested favicon
  // is available.
  // To avoid file operations, this function just attaches the given data to
  // a ShellLinkItem object.
  // When finishing loading all favicons, this function posts a task that
  // decompresses collected favicons and updates a JumpList.
  void OnFaviconDataAvailable(HistoryService::Handle handle,
                              history::FaviconData favicon);

  // Callback for TopSites that notifies when the "Most
  // Visited" list is available. This function updates the ShellLinkItemList
  // objects and send another query that retrieves a favicon for each URL in
  // the list.
  void OnMostVisitedURLsAvailable(
      const history::MostVisitedURLList& data);

  // Runnable method that updates the jumplist, once all the data
  // has been fetched.
  void RunUpdate();

  // Helper method for RunUpdate to decode the data about the asynchrounously
  // loaded icons.
  void DecodeIconData(const ShellLinkItemList& item_list);

 private:
  friend class base::RefCountedThreadSafe<JumpList>;
  ~JumpList();

  // Our consumers for HistoryService.
  CancelableRequestConsumer most_visited_consumer_;
  CancelableRequestConsumer favicon_consumer_;
  CancelableRequestConsumer topsites_consumer_;

  // The Profile object is used to listen for events
  Profile* profile_;

  // Lives on the UI thread.
  scoped_ptr<content::NotificationRegistrar> registrar_;

  // App id to associate with the jump list.
  std::wstring app_id_;

  // The directory which contains JumpList icons.
  FilePath icon_dir_;

  // Items in the "Most Visited" category of the application JumpList,
  // protected by the list_lock_.
  ShellLinkItemList most_visited_pages_;

  // Items in the "Recently Closed" category of the application JumpList,
  // protected by the list_lock_.
  ShellLinkItemList recently_closed_pages_;

  // A list of URLs we need to retrieve their favicons,
  // protected by the list_lock_.
  typedef std::pair<std::string, scoped_refptr<ShellLinkItem> > URLPair;
  std::list<URLPair> icon_urls_;

  // Handle of last favicon request used to cancel if a new request
  // comes in before the current one returns.
  FaviconService::Handle handle_;

  // Lock for most_visited_pages_, recently_closed_pages_, icon_urls_
  // as they may be used by up to 3 threads.
  base::Lock list_lock_;
};

#endif  // CHROME_BROWSER_JUMPLIST_WIN_H_