• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
IconManager()19 IconManager::IconManager() {
20 }
21 
~IconManager()22 IconManager::~IconManager() {
23   STLDeleteValues(&icon_cache_);
24 }
25 
LookupIcon(const FilePath & file_name,IconLoader::IconSize size)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 
LoadIcon(const FilePath & file_name,IconLoader::IconSize size,CancelableRequestConsumerBase * consumer,IconRequestCallback * callback)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 
OnImageLoaded(IconLoader * source,gfx::Image * result)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 
CacheKey(const IconGroupID & group,IconLoader::IconSize size)93 IconManager::CacheKey::CacheKey(const IconGroupID& group,
94                                 IconLoader::IconSize size)
95     : group(group),
96       size(size) {
97 }
98 
operator <(const CacheKey & other) const99 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