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 55 class 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