1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Class for finding and caching Windows explorer icons. The IconManager
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// lives on the UI thread but performs icon extraction work on the file thread
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// to avoid blocking the UI thread with potentially expensive COM and disk
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// operations.
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Terminology
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Windows files have icons associated with them that can be of two types:
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//   1. "Per class": the icon used for this file is used for all files with the
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//      same file extension or class. Examples are PDF or MP3 files, which use
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//      the same icon for all files of that type.
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//   2. "Per instance": the icon used for this file is embedded in the file
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//      itself and is unique. Executable files are typically "per instance".
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Files that end in the following extensions are considered "per instance":
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//   .exe
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//   .dll
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//   .ico
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The IconManager will do explicit icon loads on the full path of these files
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// and cache the results per file. All other file types will be looked up by
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// file extension and the results will be cached per extension. That way, all
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// .mp3 files will share one icon, but all .exe files will have their own icon.
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// POSIX files don't have associated icons. We query the OS by the file's
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// mime type.
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The IconManager can be queried in two ways:
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//   1. A quick, synchronous check of its caches which does not touch the disk:
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//      IconManager::LookupIcon()
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//   2. An asynchronous icon load from a file on the file thread:
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//      IconManager::LoadIcon()
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// When using the second (asychronous) method, callers must supply a callback
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// which will be run once the icon has been extracted. The icon manager will
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// cache the results of the icon extraction so that subsequent lookups will be
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// fast.
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Icon bitmaps returned should be treated as const since they may be referenced
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// by other clients. Make a copy of the icon if you need to modify it.
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef CHROME_BROWSER_ICON_MANAGER_H_
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define CHROME_BROWSER_ICON_MANAGER_H_
473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <map>
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/callback.h"
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/hash_tables.h"
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/icon_loader.h"
54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/cancelable_request.h"
55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "ui/gfx/image.h"
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass FilePath;
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass IconManager : public IconLoader::Delegate,
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    public CancelableRequestProvider {
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  IconManager();
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~IconManager();
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Synchronous call to examine the internal caches for the icon. Returns the
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // icon if we have already loaded it, NULL if we don't have it and must load
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // it via 'LoadIcon'. The returned bitmap is owned by the IconManager and must
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // not be free'd by the caller. If the caller needs to modify the icon, it
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // must make a copy and modify the copy.
70dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  gfx::Image* LookupIcon(const FilePath& file_name,
71dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                         IconLoader::IconSize size);
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef CancelableRequestProvider::Handle Handle;
74dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  typedef Callback2<Handle, gfx::Image*>::Type IconRequestCallback;
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Asynchronous call to lookup and return the icon associated with file. The
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // work is done on the file thread, with the callbacks running on the UI
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // thread. The return value is the 'request_id' that will be passed to the
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // client in the callback. Note: this does *not* check the cache.
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // WATCH OUT: The returned bitmap pointer may be NULL if decoding failed.
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Handle LoadIcon(const FilePath& file_name,
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  IconLoader::IconSize size,
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  CancelableRequestConsumerBase* consumer,
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  IconRequestCallback* callback);
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // IconLoader::Delegate interface.
88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  virtual bool OnImageLoaded(IconLoader* source, gfx::Image* result);
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Get the identifying string for the given file. The implementation
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // is in icon_manager_[platform].cc.
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static IconGroupID GetGroupIDFromFilepath(const FilePath& path);
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct CacheKey {
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CacheKey(const IconGroupID& group, IconLoader::IconSize size);
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Used as a key in the map below, so we need this comparator.
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool operator<(const CacheKey &other) const;
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IconGroupID group;
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IconLoader::IconSize size;
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  typedef std::map<CacheKey, gfx::Image*> IconMap;
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  IconMap icon_cache_;
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef CancelableRequest<IconRequestCallback> IconRequest;
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Asynchronous requests that have not yet been completed.
111513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  struct ClientRequest;
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef std::map<IconLoader*, ClientRequest> ClientRequests;
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientRequests requests_;
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(IconManager);
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // CHROME_BROWSER_ICON_MANAGER_H_
119