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