[email protected] | 66171ab | 2011-03-03 15:50:07 | [diff] [blame] | 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 4 | |
| 5 | #include "chrome/browser/icon_manager.h" |
| 6 | |
[email protected] | c189698 | 2012-12-05 20:26:17 | [diff] [blame^] | 7 | #include "base/bind.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 8 | #include "base/file_util.h" |
[email protected] | 3b63f8f4 | 2011-03-28 01:54:15 | [diff] [blame] | 9 | #include "base/memory/scoped_ptr.h" |
[email protected] | 7286e3fc | 2011-07-19 22:13:24 | [diff] [blame] | 10 | #include "base/stl_util.h" |
[email protected] | c189698 | 2012-12-05 20:26:17 | [diff] [blame^] | 11 | #include "base/task_runner.h" |
[email protected] | c43c668 | 2009-05-19 14:51:44 | [diff] [blame] | 12 | #include "third_party/skia/include/core/SkBitmap.h" |
| 13 | #include "third_party/skia/include/core/SkCanvas.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 14 | |
[email protected] | c189698 | 2012-12-05 20:26:17 | [diff] [blame^] | 15 | namespace { |
| 16 | |
| 17 | void 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] | 38e0898 | 2010-10-22 17:28:43 | [diff] [blame] | 28 | struct IconManager::ClientRequest { |
[email protected] | c189698 | 2012-12-05 20:26:17 | [diff] [blame^] | 29 | IconRequestCallback callback; |
[email protected] | 38e0898 | 2010-10-22 17:28:43 | [diff] [blame] | 30 | IconGroupID group; |
| 31 | IconLoader::IconSize size; |
| 32 | }; |
| 33 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 34 | IconManager::IconManager() { |
| 35 | } |
| 36 | |
| 37 | IconManager::~IconManager() { |
| 38 | STLDeleteValues(&icon_cache_); |
| 39 | } |
| 40 | |
[email protected] | 66171ab | 2011-03-03 15:50:07 | [diff] [blame] | 41 | gfx::Image* IconManager::LookupIcon(const FilePath& file_name, |
| 42 | IconLoader::IconSize size) { |
[email protected] | 0f38ceae | 2009-05-08 19:01:02 | [diff] [blame] | 43 | IconGroupID group = GetGroupIDFromFilepath(file_name); |
| 44 | IconMap::iterator it = icon_cache_.find(CacheKey(group, size)); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 45 | if (it != icon_cache_.end()) |
| 46 | return it->second; |
| 47 | |
| 48 | return NULL; |
| 49 | } |
| 50 | |
[email protected] | c189698 | 2012-12-05 20:26:17 | [diff] [blame^] | 51 | CancelableTaskTracker::TaskId IconManager::LoadIcon( |
[email protected] | 7ced67af | 2009-04-14 23:25:16 | [diff] [blame] | 52 | const FilePath& file_name, |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 53 | IconLoader::IconSize size, |
[email protected] | c189698 | 2012-12-05 20:26:17 | [diff] [blame^] | 54 | const IconRequestCallback& callback, |
| 55 | CancelableTaskTracker* tracker) { |
[email protected] | 0f38ceae | 2009-05-08 19:01:02 | [diff] [blame] | 56 | IconGroupID group = GetGroupIDFromFilepath(file_name); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 57 | |
[email protected] | 0f38ceae | 2009-05-08 19:01:02 | [diff] [blame] | 58 | IconLoader* loader = new IconLoader(group, size, this); |
[email protected] | 46728b1f | 2009-05-07 20:42:24 | [diff] [blame] | 59 | loader->AddRef(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 60 | loader->Start(); |
[email protected] | c189698 | 2012-12-05 20:26:17 | [diff] [blame^] | 61 | |
| 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.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 68 | requests_[loader] = client_request; |
[email protected] | c189698 | 2012-12-05 20:26:17 | [diff] [blame^] | 69 | return id; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 70 | } |
| 71 | |
| 72 | // IconLoader::Delegate implementation ----------------------------------------- |
| 73 | |
[email protected] | c189698 | 2012-12-05 20:26:17 | [diff] [blame^] | 74 | bool IconManager::OnImageLoaded(IconLoader* loader, gfx::Image* result) { |
| 75 | ClientRequests::iterator rit = requests_.find(loader); |
| 76 | |
[email protected] | 46728b1f | 2009-05-07 20:42:24 | [diff] [blame] | 77 | // Balances the AddRef() in LoadIcon(). |
[email protected] | c189698 | 2012-12-05 20:26:17 | [diff] [blame^] | 78 | loader->Release(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 79 | |
| 80 | // Look up our client state. |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 81 | if (rit == requests_.end()) { |
| 82 | NOTREACHED(); |
[email protected] | cf2ef75 | 2008-09-11 21:19:29 | [diff] [blame] | 83 | return false; // Return false to indicate result should be deleted. |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 84 | } |
| 85 | |
[email protected] | c189698 | 2012-12-05 20:26:17 | [diff] [blame^] | 86 | const ClientRequest& client_request = rit->second; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 87 | |
[email protected] | e79f10f3 | 2008-11-07 16:13:31 | [diff] [blame] | 88 | // Cache the bitmap. Watch out: |result| or the cached bitmap may be NULL to |
| 89 | // indicate a current or past failure. |
[email protected] | 0f38ceae | 2009-05-08 19:01:02 | [diff] [blame] | 90 | CacheKey key(client_request.group, client_request.size); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 91 | IconMap::iterator it = icon_cache_.find(key); |
[email protected] | e79f10f3 | 2008-11-07 16:13:31 | [diff] [blame] | 92 | if (it != icon_cache_.end() && result && it->second) { |
[email protected] | 66171ab | 2011-03-03 15:50:07 | [diff] [blame] | 93 | it->second->SwapRepresentations(result); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 94 | delete result; |
[email protected] | cf2ef75 | 2008-09-11 21:19:29 | [diff] [blame] | 95 | result = it->second; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 96 | } else { |
| 97 | icon_cache_[key] = result; |
| 98 | } |
| 99 | |
| 100 | // Inform our client that the request has completed. |
[email protected] | c189698 | 2012-12-05 20:26:17 | [diff] [blame^] | 101 | client_request.callback.Run(result); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 102 | requests_.erase(rit); |
| 103 | |
[email protected] | cf2ef75 | 2008-09-11 21:19:29 | [diff] [blame] | 104 | return true; // Indicates we took ownership of result. |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 105 | } |
| 106 | |
[email protected] | 0f38ceae | 2009-05-08 19:01:02 | [diff] [blame] | 107 | IconManager::CacheKey::CacheKey(const IconGroupID& group, |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 108 | IconLoader::IconSize size) |
[email protected] | 0f38ceae | 2009-05-08 19:01:02 | [diff] [blame] | 109 | : group(group), |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 110 | size(size) { |
| 111 | } |
| 112 | |
| 113 | bool IconManager::CacheKey::operator<(const CacheKey &other) const { |
[email protected] | 0f38ceae | 2009-05-08 19:01:02 | [diff] [blame] | 114 | if (group != other.group) |
| 115 | return group < other.group; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 116 | return size < other.size; |
| 117 | } |