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 #include "chrome/browser/icon_manager.h"
      6 
      7 #include "base/file_util.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/stl_util-inl.h"
     10 #include "third_party/skia/include/core/SkBitmap.h"
     11 #include "third_party/skia/include/core/SkCanvas.h"
     12 
     13 struct IconManager::ClientRequest {
     14   scoped_refptr<IconRequest> request;
     15   IconGroupID group;
     16   IconLoader::IconSize size;
     17 };
     18 
     19 IconManager::IconManager() {
     20 }
     21 
     22 IconManager::~IconManager() {
     23   STLDeleteValues(&icon_cache_);
     24 }
     25 
     26 gfx::Image* IconManager::LookupIcon(const FilePath& file_name,
     27                                     IconLoader::IconSize size) {
     28   IconGroupID group = GetGroupIDFromFilepath(file_name);
     29   IconMap::iterator it = icon_cache_.find(CacheKey(group, size));
     30   if (it != icon_cache_.end())
     31     return it->second;
     32 
     33   return NULL;
     34 }
     35 
     36 IconManager::Handle IconManager::LoadIcon(
     37     const FilePath& file_name,
     38     IconLoader::IconSize size,
     39     CancelableRequestConsumerBase* consumer,
     40     IconRequestCallback* callback) {
     41   IconGroupID group = GetGroupIDFromFilepath(file_name);
     42   IconRequest* request = new IconRequest(callback);
     43   AddRequest(request, consumer);
     44 
     45   IconLoader* loader = new IconLoader(group, size, this);
     46   loader->AddRef();
     47   loader->Start();
     48   ClientRequest client_request = { request, group, size };
     49   requests_[loader] = client_request;
     50   return request->handle();
     51 }
     52 
     53 // IconLoader::Delegate implementation -----------------------------------------
     54 
     55 bool IconManager::OnImageLoaded(IconLoader* source, gfx::Image* result) {
     56   ClientRequests::iterator rit = requests_.find(source);
     57   // Balances the AddRef() in LoadIcon().
     58   source->Release();
     59 
     60   // Look up our client state.
     61   if (rit == requests_.end()) {
     62     NOTREACHED();
     63     return false;  // Return false to indicate result should be deleted.
     64   }
     65 
     66   ClientRequest client_request = rit->second;
     67   if (client_request.request->canceled()) {
     68     requests_.erase(rit);
     69     return false;  // Return false to indicate result should be deleted.
     70   }
     71 
     72   // Cache the bitmap. Watch out: |result| or the cached bitmap may be NULL to
     73   // indicate a current or past failure.
     74   CacheKey key(client_request.group, client_request.size);
     75   IconMap::iterator it = icon_cache_.find(key);
     76   if (it != icon_cache_.end() && result && it->second) {
     77     it->second->SwapRepresentations(result);
     78     delete result;
     79     result = it->second;
     80   } else {
     81     icon_cache_[key] = result;
     82   }
     83 
     84   // Inform our client that the request has completed.
     85   IconRequest* icon_request = client_request.request;
     86   icon_request->ForwardResult(IconRequest::TupleType(icon_request->handle(),
     87                                                      result));
     88   requests_.erase(rit);
     89 
     90   return true;  // Indicates we took ownership of result.
     91 }
     92 
     93 IconManager::CacheKey::CacheKey(const IconGroupID& group,
     94                                 IconLoader::IconSize size)
     95     : group(group),
     96       size(size) {
     97 }
     98 
     99 bool IconManager::CacheKey::operator<(const CacheKey &other) const {
    100   if (group != other.group)
    101     return group < other.group;
    102   return size < other.size;
    103 }
    104