blob: 2f1444e83d0d7e999d93a9e818c95fc0ea4db953 [file] [log] [blame]
[email protected]66171ab2011-03-03 15:50:071// Copyright (c) 2011 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
5#include "chrome/browser/icon_manager.h"
6
[email protected]c1896982012-12-05 20:26:177#include "base/bind.h"
initial.commit09911bf2008-07-26 23:55:298#include "base/file_util.h"
[email protected]3b63f8f42011-03-28 01:54:159#include "base/memory/scoped_ptr.h"
[email protected]7286e3fc2011-07-19 22:13:2410#include "base/stl_util.h"
[email protected]c1896982012-12-05 20:26:1711#include "base/task_runner.h"
[email protected]c43c6682009-05-19 14:51:4412#include "third_party/skia/include/core/SkBitmap.h"
13#include "third_party/skia/include/core/SkCanvas.h"
initial.commit09911bf2008-07-26 23:55:2914
[email protected]c1896982012-12-05 20:26:1715namespace {
16
17void RunCallbackIfNotCanceled(
18 const CancelableTaskTracker::IsCanceledCallback& is_canceled,
19 const IconManager::IconRequestCallback& callback,
20 gfx::Image* image) {
21 if (is_canceled.Run())
22 return;
23 callback.Run(image);
24}
25
26} // namespace
27
[email protected]38e08982010-10-22 17:28:4328struct IconManager::ClientRequest {
[email protected]c1896982012-12-05 20:26:1729 IconRequestCallback callback;
[email protected]38e08982010-10-22 17:28:4330 IconGroupID group;
31 IconLoader::IconSize size;
32};
33
initial.commit09911bf2008-07-26 23:55:2934IconManager::IconManager() {
35}
36
37IconManager::~IconManager() {
38 STLDeleteValues(&icon_cache_);
39}
40
[email protected]66171ab2011-03-03 15:50:0741gfx::Image* IconManager::LookupIcon(const FilePath& file_name,
42 IconLoader::IconSize size) {
[email protected]0f38ceae2009-05-08 19:01:0243 IconGroupID group = GetGroupIDFromFilepath(file_name);
44 IconMap::iterator it = icon_cache_.find(CacheKey(group, size));
initial.commit09911bf2008-07-26 23:55:2945 if (it != icon_cache_.end())
46 return it->second;
47
48 return NULL;
49}
50
[email protected]c1896982012-12-05 20:26:1751CancelableTaskTracker::TaskId IconManager::LoadIcon(
[email protected]7ced67af2009-04-14 23:25:1652 const FilePath& file_name,
initial.commit09911bf2008-07-26 23:55:2953 IconLoader::IconSize size,
[email protected]c1896982012-12-05 20:26:1754 const IconRequestCallback& callback,
55 CancelableTaskTracker* tracker) {
[email protected]0f38ceae2009-05-08 19:01:0256 IconGroupID group = GetGroupIDFromFilepath(file_name);
initial.commit09911bf2008-07-26 23:55:2957
[email protected]0f38ceae2009-05-08 19:01:0258 IconLoader* loader = new IconLoader(group, size, this);
[email protected]46728b1f2009-05-07 20:42:2459 loader->AddRef();
initial.commit09911bf2008-07-26 23:55:2960 loader->Start();
[email protected]c1896982012-12-05 20:26:1761
62 CancelableTaskTracker::IsCanceledCallback is_canceled;
63 CancelableTaskTracker::TaskId id = tracker->NewTrackedTaskId(&is_canceled);
64 IconRequestCallback callback_runner = base::Bind(
65 &RunCallbackIfNotCanceled, is_canceled, callback);
66
67 ClientRequest client_request = { callback_runner, group, size };
initial.commit09911bf2008-07-26 23:55:2968 requests_[loader] = client_request;
[email protected]c1896982012-12-05 20:26:1769 return id;
initial.commit09911bf2008-07-26 23:55:2970}
71
72// IconLoader::Delegate implementation -----------------------------------------
73
[email protected]c1896982012-12-05 20:26:1774bool IconManager::OnImageLoaded(IconLoader* loader, gfx::Image* result) {
75 ClientRequests::iterator rit = requests_.find(loader);
76
[email protected]46728b1f2009-05-07 20:42:2477 // Balances the AddRef() in LoadIcon().
[email protected]c1896982012-12-05 20:26:1778 loader->Release();
initial.commit09911bf2008-07-26 23:55:2979
80 // Look up our client state.
initial.commit09911bf2008-07-26 23:55:2981 if (rit == requests_.end()) {
82 NOTREACHED();
[email protected]cf2ef752008-09-11 21:19:2983 return false; // Return false to indicate result should be deleted.
initial.commit09911bf2008-07-26 23:55:2984 }
85
[email protected]c1896982012-12-05 20:26:1786 const ClientRequest& client_request = rit->second;
initial.commit09911bf2008-07-26 23:55:2987
[email protected]e79f10f32008-11-07 16:13:3188 // Cache the bitmap. Watch out: |result| or the cached bitmap may be NULL to
89 // indicate a current or past failure.
[email protected]0f38ceae2009-05-08 19:01:0290 CacheKey key(client_request.group, client_request.size);
initial.commit09911bf2008-07-26 23:55:2991 IconMap::iterator it = icon_cache_.find(key);
[email protected]e79f10f32008-11-07 16:13:3192 if (it != icon_cache_.end() && result && it->second) {
[email protected]66171ab2011-03-03 15:50:0793 it->second->SwapRepresentations(result);
initial.commit09911bf2008-07-26 23:55:2994 delete result;
[email protected]cf2ef752008-09-11 21:19:2995 result = it->second;
initial.commit09911bf2008-07-26 23:55:2996 } else {
97 icon_cache_[key] = result;
98 }
99
100 // Inform our client that the request has completed.
[email protected]c1896982012-12-05 20:26:17101 client_request.callback.Run(result);
initial.commit09911bf2008-07-26 23:55:29102 requests_.erase(rit);
103
[email protected]cf2ef752008-09-11 21:19:29104 return true; // Indicates we took ownership of result.
initial.commit09911bf2008-07-26 23:55:29105}
106
[email protected]0f38ceae2009-05-08 19:01:02107IconManager::CacheKey::CacheKey(const IconGroupID& group,
initial.commit09911bf2008-07-26 23:55:29108 IconLoader::IconSize size)
[email protected]0f38ceae2009-05-08 19:01:02109 : group(group),
initial.commit09911bf2008-07-26 23:55:29110 size(size) {
111}
112
113bool IconManager::CacheKey::operator<(const CacheKey &other) const {
[email protected]0f38ceae2009-05-08 19:01:02114 if (group != other.group)
115 return group < other.group;
initial.commit09911bf2008-07-26 23:55:29116 return size < other.size;
117}