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// 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#pragma once 48 49#include <map> 50 51#include "base/callback.h" 52#include "base/hash_tables.h" 53#include "chrome/browser/icon_loader.h" 54#include "content/browser/cancelable_request.h" 55#include "ui/gfx/image.h" 56 57class FilePath; 58 59class IconManager : public IconLoader::Delegate, 60 public CancelableRequestProvider { 61 public: 62 IconManager(); 63 ~IconManager(); 64 65 // Synchronous call to examine the internal caches for the icon. Returns the 66 // icon if we have already loaded it, NULL if we don't have it and must load 67 // it via 'LoadIcon'. The returned bitmap is owned by the IconManager and must 68 // not be free'd by the caller. If the caller needs to modify the icon, it 69 // must make a copy and modify the copy. 70 gfx::Image* LookupIcon(const FilePath& file_name, 71 IconLoader::IconSize size); 72 73 typedef CancelableRequestProvider::Handle Handle; 74 typedef Callback2<Handle, gfx::Image*>::Type IconRequestCallback; 75 76 // Asynchronous call to lookup and return the icon associated with file. The 77 // work is done on the file thread, with the callbacks running on the UI 78 // thread. The return value is the 'request_id' that will be passed to the 79 // client in the callback. Note: this does *not* check the cache. 80 // 81 // WATCH OUT: The returned bitmap pointer may be NULL if decoding failed. 82 Handle LoadIcon(const FilePath& file_name, 83 IconLoader::IconSize size, 84 CancelableRequestConsumerBase* consumer, 85 IconRequestCallback* callback); 86 87 // IconLoader::Delegate interface. 88 virtual bool OnImageLoaded(IconLoader* source, gfx::Image* result); 89 90 // Get the identifying string for the given file. The implementation 91 // is in icon_manager_[platform].cc. 92 static IconGroupID GetGroupIDFromFilepath(const FilePath& path); 93 94 private: 95 struct CacheKey { 96 CacheKey(const IconGroupID& group, IconLoader::IconSize size); 97 98 // Used as a key in the map below, so we need this comparator. 99 bool operator<(const CacheKey &other) const; 100 101 IconGroupID group; 102 IconLoader::IconSize size; 103 }; 104 105 typedef std::map<CacheKey, gfx::Image*> IconMap; 106 IconMap icon_cache_; 107 108 typedef CancelableRequest<IconRequestCallback> IconRequest; 109 110 // Asynchronous requests that have not yet been completed. 111 struct ClientRequest; 112 typedef std::map<IconLoader*, ClientRequest> ClientRequests; 113 ClientRequests requests_; 114 115 DISALLOW_COPY_AND_ASSIGN(IconManager); 116}; 117 118#endif // CHROME_BROWSER_ICON_MANAGER_H_ 119