summaryrefslogtreecommitdiffstats
path: root/chrome/browser/icon_manager.h
blob: ad10d732f284b5742dfe9450b3f3f5f4464f86d1 (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
// 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.
//
// Class for finding and caching Windows explorer icons. The IconManager
// lives on the UI thread but performs icon extraction work on the file thread
// to avoid blocking the UI thread with potentially expensive COM and disk
// operations.
//
// Terminology
//
// Windows files have icons associated with them that can be of two types:
//   1. "Per class": the icon used for this file is used for all files with the
//      same file extension or class. Examples are PDF or MP3 files, which use
//      the same icon for all files of that type.
//   2. "Per instance": the icon used for this file is embedded in the file
//      itself and is unique. Executable files are typically "per instance".
//
// Files that end in the following extensions are considered "per instance":
//   .exe
//   .dll
//   .ico
// The IconManager will do explicit icon loads on the full path of these files
// and cache the results per file. All other file types will be looked up by
// file extension and the results will be cached per extension. That way, all
// .mp3 files will share one icon, but all .exe files will have their own icon.
//
// POSIX files don't have associated icons. We query the OS by the file's
// mime type.
//
// The IconManager can be queried in two ways:
//   1. A quick, synchronous check of its caches which does not touch the disk:
//      IconManager::LookupIcon()
//   2. An asynchronous icon load from a file on the file thread:
//      IconManager::LoadIcon()
//
// When using the second (asychronous) method, callers must supply a callback
// which will be run once the icon has been extracted. The icon manager will
// cache the results of the icon extraction so that subsequent lookups will be
// fast.
//
// Icon bitmaps returned should be treated as const since they may be referenced
// by other clients. Make a copy of the icon if you need to modify it.

#ifndef CHROME_BROWSER_ICON_MANAGER_H_
#define CHROME_BROWSER_ICON_MANAGER_H_

#include <map>

#include "base/files/file_path.h"
#include "base/task/cancelable_task_tracker.h"
#include "chrome/browser/icon_loader.h"
#include "ui/gfx/image/image.h"

class IconManager : public IconLoader::Delegate {
 public:
  IconManager();
  virtual ~IconManager();

  // Synchronous call to examine the internal caches for the icon. Returns the
  // icon if we have already loaded it, NULL if we don't have it and must load
  // it via 'LoadIcon'. The returned bitmap is owned by the IconManager and must
  // not be free'd by the caller. If the caller needs to modify the icon, it
  // must make a copy and modify the copy.
  gfx::Image* LookupIconFromFilepath(const base::FilePath& file_name,
                                     IconLoader::IconSize size);

  typedef base::Callback<void(gfx::Image*)> IconRequestCallback;

  // Asynchronous call to lookup and return the icon associated with file. The
  // work is done on the file thread, with the callbacks running on the thread
  // this function is called.
  //
  // Note:
  // 1. This does *not* check the cache.
  // 2. The returned bitmap pointer is *not* owned by callback. So callback
  //    should never keep it or delete it.
  // 3. The gfx::Image pointer passed to the callback may be NULL if decoding
  //    failed.
  base::CancelableTaskTracker::TaskId LoadIcon(
      const base::FilePath& file_name,
      IconLoader::IconSize size,
      const IconRequestCallback& callback,
      base::CancelableTaskTracker* tracker);

  // IconLoader::Delegate interface.
  virtual bool OnGroupLoaded(IconLoader* loader,
                             const IconGroupID& group) OVERRIDE;
  virtual bool OnImageLoaded(IconLoader* loader,
                             gfx::Image* result,
                             const IconGroupID& group) OVERRIDE;

 private:
  struct CacheKey {
    CacheKey(const IconGroupID& group, IconLoader::IconSize size);

    // Used as a key in the map below, so we need this comparator.
    bool operator<(const CacheKey &other) const;

    IconGroupID group;
    IconLoader::IconSize size;
  };

  gfx::Image* LookupIconFromGroup(const IconGroupID& group,
                                  IconLoader::IconSize size);

  typedef std::map<CacheKey, gfx::Image*> IconMap;
  IconMap icon_cache_;

  typedef std::map<base::FilePath, IconGroupID> GroupMap;
  GroupMap group_cache_;

  // Asynchronous requests that have not yet been completed.
  struct ClientRequest;
  typedef std::map<IconLoader*, ClientRequest> ClientRequests;
  ClientRequests requests_;

  DISALLOW_COPY_AND_ASSIGN(IconManager);
};

#endif  // CHROME_BROWSER_ICON_MANAGER_H_