blob: 3622203244cc9eff5fdf4f3a3f1dc8bf5a32c547 [file] [log] [blame]
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Class for finding and caching Windows explorer icons. The IconManager
// lives on the UI thread but performs icon extraction work on the file thread
// to avoid blocking the UI thread with potentially expensive COM and disk
// operations.
//
// Terminology
//
// Windows files have icons associated with them that can be of two types:
// 1. "Per class": the icon used for this file is used for all files with the
// same file extension or class. Examples are PDF or MP3 files, which use
// the same icon for all files of that type.
// 2. "Per instance": the icon used for this file is embedded in the file
// itself and is unique. Executable files are typically "per instance".
//
// Files that end in the following extensions are considered "per instance":
// .exe
// .dll
// .ico
// The IconManager will do explicit icon loads on the full path of these files
// and cache the results per file. All other file types will be looked up by
// file extension and the results will be cached per extension. That way, all
// .mp3 files will share one icon, but all .exe files will have their own icon.
//
// POSIX files don't have associated icons. We query the OS by the file's
// mime type.
//
// The IconManager can be queried in two ways:
// 1. A quick, synchronous check of its caches which does not touch the disk:
// IconManager::LookupIcon()
// 2. An asynchronous icon load from a file on the file thread:
// IconManager::LoadIcon()
//
// When using the second (asychronous) method, callers must supply a callback
// which will be run once the icon has been extracted. The icon manager will
// cache the results of the icon extraction so that subsequent lookups will be
// fast.
//
// Icon bitmaps returned should be treated as const since they may be referenced
// by other clients. Make a copy of the icon if you need to modify it.
#ifndef CHROME_BROWSER_ICON_MANAGER_H_
#define CHROME_BROWSER_ICON_MANAGER_H_
#pragma once
#include <map>
#include "base/callback_old.h"
#include "base/hash_tables.h"
#include "chrome/browser/icon_loader.h"
#include "content/browser/cancelable_request.h"
#include "ui/gfx/image/image.h"
class FilePath;
class IconManager : public IconLoader::Delegate,
public CancelableRequestProvider {
public:
IconManager();
virtual ~IconManager();
// Synchronous call to examine the internal caches for the icon. Returns the
// icon if we have already loaded it, NULL if we don't have it and must load
// it via 'LoadIcon'. The returned bitmap is owned by the IconManager and must
// not be free'd by the caller. If the caller needs to modify the icon, it
// must make a copy and modify the copy.
gfx::Image* LookupIcon(const FilePath& file_name,
IconLoader::IconSize size);
typedef CancelableRequestProvider::Handle Handle;
typedef base::Callback<void(Handle, gfx::Image*)> IconRequestCallback;
// Asynchronous call to lookup and return the icon associated with file. The
// work is done on the file thread, with the callbacks running on the UI
// thread. The return value is the 'request_id' that will be passed to the
// client in the callback. Note: this does *not* check the cache.
//
// WATCH OUT: The returned bitmap pointer may be NULL if decoding failed.
Handle LoadIcon(const FilePath& file_name,
IconLoader::IconSize size,
CancelableRequestConsumerBase* consumer,
const IconRequestCallback& callback);
// IconLoader::Delegate interface.
virtual bool OnImageLoaded(IconLoader* source, gfx::Image* result);
// Get the identifying string for the given file. The implementation
// is in icon_manager_[platform].cc.
static IconGroupID GetGroupIDFromFilepath(const FilePath& path);
private:
struct CacheKey {
CacheKey(const IconGroupID& group, IconLoader::IconSize size);
// Used as a key in the map below, so we need this comparator.
bool operator<(const CacheKey &other) const;
IconGroupID group;
IconLoader::IconSize size;
};
typedef std::map<CacheKey, gfx::Image*> IconMap;
IconMap icon_cache_;
typedef CancelableRequest<IconRequestCallback> IconRequest;
// Asynchronous requests that have not yet been completed.
struct ClientRequest;
typedef std::map<IconLoader*, ClientRequest> ClientRequests;
ClientRequests requests_;
DISALLOW_COPY_AND_ASSIGN(IconManager);
};
#endif // CHROME_BROWSER_ICON_MANAGER_H_