1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/icon_manager.h"
10 #include "base/functional/bind.h"
11 #include "base/task/task_runner.h"
12 #include "third_party/skia/include/core/SkBitmap.h"
13 #include "third_party/skia/include/core/SkCanvas.h"
17 void RunCallbackIfNotCanceled(
18 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled,
19 IconManager::IconRequestCallback callback,
21 if (is_canceled.Run())
23 std::move(callback).Run(std::move(image));
28 IconManager::IconManager() = default;
30 IconManager::~IconManager() = default;
32 gfx::Image* IconManager::LookupIconFromFilepath(const base::FilePath& file_path,
33 IconLoader::IconSize size,
35 // Since loading the icon is synchronous on Chrome OS (and doesn't require
36 // disk access), if it hasn't already been loaded, load immediately.
37 #if BUILDFLAG(IS_CHROMEOS)
38 gfx::Image* image = DoLookupIconFromFilepath(file_path, size, scale);
43 file_path, size, scale,
44 base::BindOnce(&IconManager::OnIconLoaded, weak_factory_.GetWeakPtr(),
45 base::DoNothing(), file_path, size, scale));
47 return DoLookupIconFromFilepath(file_path, size, scale);
50 base::CancelableTaskTracker::TaskId IconManager::LoadIcon(
51 const base::FilePath& file_path,
52 IconLoader::IconSize size,
54 IconRequestCallback callback,
55 base::CancelableTaskTracker* tracker) {
56 base::CancelableTaskTracker::IsCanceledCallback is_canceled;
57 base::CancelableTaskTracker::TaskId id =
58 tracker->NewTrackedTaskId(&is_canceled);
59 IconRequestCallback callback_runner = base::BindOnce(
60 &RunCallbackIfNotCanceled, is_canceled, std::move(callback));
63 file_path, size, scale,
64 base::BindOnce(&IconManager::OnIconLoaded, weak_factory_.GetWeakPtr(),
65 std::move(callback_runner), file_path, size, scale));
70 gfx::Image* IconManager::DoLookupIconFromFilepath(
71 const base::FilePath& file_path,
72 IconLoader::IconSize size,
74 auto group_it = group_cache_.find(file_path);
75 if (group_it == group_cache_.end())
78 CacheKey key(group_it->second, size, scale);
79 auto icon_it = icon_cache_.find(key);
80 if (icon_it == icon_cache_.end())
83 return &icon_it->second;
86 void IconManager::OnIconLoaded(IconRequestCallback callback,
87 base::FilePath file_path,
88 IconLoader::IconSize size,
91 const IconLoader::IconGroup& group) {
92 // Cache the bitmap. Watch out: |result| may be null, which indicates a
93 // failure. We assume that if we have an entry in |icon_cache_| it must not be
95 CacheKey key(group, size, scale);
96 std::move(callback).Run(result);
97 if (!result.IsEmpty())
98 icon_cache_[key] = std::move(result);
100 icon_cache_.erase(key);
102 group_cache_[file_path] = group;
105 IconManager::CacheKey::CacheKey(const IconLoader::IconGroup& group,
106 IconLoader::IconSize size,
108 : group(group), size(size), scale(scale) {}
110 bool IconManager::CacheKey::operator<(const CacheKey& other) const {
111 return std::tie(group, size, scale) <
112 std::tie(other.group, other.size, other.scale);