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 57 class FilePath; 58 59 class 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