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