Home | History | Annotate | Download | only in browser
      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