Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(489)

Side by Side Diff: chrome/browser/extensions/image_loading_tracker.cc

Issue 2867008: Show extension icons next to their top-level context menu items.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/image_loading_tracker.h" 5 #include "chrome/browser/extensions/image_loading_tracker.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "chrome/browser/chrome_thread.h" 8 #include "chrome/browser/chrome_thread.h"
9 #include "chrome/common/extensions/extension.h" 9 #include "chrome/common/extensions/extension.h"
10 #include "chrome/common/extensions/extension_resource.h" 10 #include "chrome/common/extensions/extension_resource.h"
11 #include "chrome/common/notification_service.h" 11 #include "chrome/common/notification_service.h"
12 #include "chrome/common/notification_type.h" 12 #include "chrome/common/notification_type.h"
13 #include "skia/ext/image_operations.h" 13 #include "skia/ext/image_operations.h"
14 #include "third_party/skia/include/core/SkBitmap.h" 14 #include "third_party/skia/include/core/SkBitmap.h"
15 #include "webkit/glue/image_decoder.h" 15 #include "webkit/glue/image_decoder.h"
16 16
17 ImageLoadingTracker::Observer::~Observer() {}
18
17 //////////////////////////////////////////////////////////////////////////////// 19 ////////////////////////////////////////////////////////////////////////////////
18 // ImageLoadingTracker::ImageLoader 20 // ImageLoadingTracker::ImageLoader
19 21
20 // A RefCounted class for loading images on the File thread and reporting back 22 // A RefCounted class for loading images on the File thread and reporting back
21 // on the UI thread. 23 // on the UI thread.
22 class ImageLoadingTracker::ImageLoader 24 class ImageLoadingTracker::ImageLoader
23 : public base::RefCountedThreadSafe<ImageLoader> { 25 : public base::RefCountedThreadSafe<ImageLoader> {
24 public: 26 public:
25 explicit ImageLoader(ImageLoadingTracker* tracker) 27 explicit ImageLoader(ImageLoadingTracker* tracker)
26 : tracker_(tracker) { 28 : tracker_(tracker) {
(...skipping 20 matching lines...) Expand all
47 49
48 void LoadOnFileThread(ExtensionResource resource, 50 void LoadOnFileThread(ExtensionResource resource,
49 const gfx::Size& max_size, 51 const gfx::Size& max_size,
50 int id) { 52 int id) {
51 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 53 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
52 54
53 // Read the file from disk. 55 // Read the file from disk.
54 std::string file_contents; 56 std::string file_contents;
55 FilePath path = resource.GetFilePath(); 57 FilePath path = resource.GetFilePath();
56 if (path.empty() || !file_util::ReadFileToString(path, &file_contents)) { 58 if (path.empty() || !file_util::ReadFileToString(path, &file_contents)) {
57 ReportBack(NULL, resource, id); 59 ReportBack(NULL, resource, gfx::Size(), id);
58 return; 60 return;
59 } 61 }
60 62
61 // Decode the image using WebKit's image decoder. 63 // Decode the image using WebKit's image decoder.
62 const unsigned char* data = 64 const unsigned char* data =
63 reinterpret_cast<const unsigned char*>(file_contents.data()); 65 reinterpret_cast<const unsigned char*>(file_contents.data());
64 webkit_glue::ImageDecoder decoder; 66 webkit_glue::ImageDecoder decoder;
65 scoped_ptr<SkBitmap> decoded(new SkBitmap()); 67 scoped_ptr<SkBitmap> decoded(new SkBitmap());
66 *decoded = decoder.Decode(data, file_contents.length()); 68 *decoded = decoder.Decode(data, file_contents.length());
67 if (decoded->empty()) { 69 if (decoded->empty()) {
68 ReportBack(NULL, resource, id); 70 ReportBack(NULL, resource, gfx::Size(), id);
69 return; // Unable to decode. 71 return; // Unable to decode.
70 } 72 }
71 73
74 gfx::Size original_size(decoded->width(), decoded->height());
75
72 if (decoded->width() > max_size.width() || 76 if (decoded->width() > max_size.width() ||
73 decoded->height() > max_size.height()) { 77 decoded->height() > max_size.height()) {
74 // The bitmap is too big, re-sample. 78 // The bitmap is too big, re-sample.
75 *decoded = skia::ImageOperations::Resize( 79 *decoded = skia::ImageOperations::Resize(
76 *decoded, skia::ImageOperations::RESIZE_LANCZOS3, 80 *decoded, skia::ImageOperations::RESIZE_LANCZOS3,
77 max_size.width(), max_size.height()); 81 max_size.width(), max_size.height());
78 } 82 }
79 83
80 ReportBack(decoded.release(), resource, id); 84 ReportBack(decoded.release(), resource, original_size, id);
81 } 85 }
82 86
83 void ReportBack(SkBitmap* image, const ExtensionResource& resource, 87 void ReportBack(SkBitmap* image, const ExtensionResource& resource,
84 int id) { 88 const gfx::Size& original_size, int id) {
85 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 89 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
86 90
87 ChromeThread::PostTask( 91 ChromeThread::PostTask(
88 callback_thread_id_, FROM_HERE, 92 callback_thread_id_, FROM_HERE,
89 NewRunnableMethod(this, &ImageLoader::ReportOnUIThread, 93 NewRunnableMethod(this, &ImageLoader::ReportOnUIThread,
90 image, resource, id)); 94 image, resource, original_size, id));
91 } 95 }
92 96
93 void ReportOnUIThread(SkBitmap* image, ExtensionResource resource, 97 void ReportOnUIThread(SkBitmap* image, ExtensionResource resource,
94 int id) { 98 const gfx::Size& original_size, int id) {
95 DCHECK(!ChromeThread::CurrentlyOn(ChromeThread::FILE)); 99 DCHECK(!ChromeThread::CurrentlyOn(ChromeThread::FILE));
96 100
97 if (tracker_) 101 if (tracker_)
98 tracker_->OnImageLoaded(image, resource, id); 102 tracker_->OnImageLoaded(image, resource, original_size, id);
99 103
100 delete image; 104 delete image;
101 } 105 }
102 106
103 private: 107 private:
104 // The tracker we are loading the image for. If NULL, it means the tracker is 108 // The tracker we are loading the image for. If NULL, it means the tracker is
105 // no longer interested in the reply. 109 // no longer interested in the reply.
106 ImageLoadingTracker* tracker_; 110 ImageLoadingTracker* tracker_;
107 111
108 // The thread that we need to call back on to report that we are done. 112 // The thread that we need to call back on to report that we are done.
(...skipping 22 matching lines...) Expand all
131 } 135 }
132 136
133 void ImageLoadingTracker::LoadImage(Extension* extension, 137 void ImageLoadingTracker::LoadImage(Extension* extension,
134 const ExtensionResource& resource, 138 const ExtensionResource& resource,
135 const gfx::Size& max_size, 139 const gfx::Size& max_size,
136 CacheParam cache) { 140 CacheParam cache) {
137 // If we don't have a path we don't need to do any further work, just respond 141 // If we don't have a path we don't need to do any further work, just respond
138 // back. 142 // back.
139 int id = next_id_++; 143 int id = next_id_++;
140 if (resource.relative_path().empty()) { 144 if (resource.relative_path().empty()) {
141 OnImageLoaded(NULL, resource, id); 145 OnImageLoaded(NULL, resource, max_size, id);
142 return; 146 return;
143 } 147 }
144 148
145 DCHECK(extension->path() == resource.extension_root()); 149 DCHECK(extension->path() == resource.extension_root());
146 150
147 // See if the extension has the image already. 151 // See if the extension has the image already.
148 if (extension->HasCachedImage(resource)) { 152 if (extension->HasCachedImage(resource, max_size)) {
149 SkBitmap image = extension->GetCachedImage(resource); 153 SkBitmap image = extension->GetCachedImage(resource, max_size);
150 OnImageLoaded(&image, resource, id); 154 OnImageLoaded(&image, resource, max_size, id);
151 return; 155 return;
152 } 156 }
153 157
154 if (cache == CACHE) { 158 if (cache == CACHE) {
155 load_map_[id] = extension; 159 load_map_[id] = extension;
156 } 160 }
157 161
158 // Instruct the ImageLoader to load this on the File thread. LoadImage does 162 // Instruct the ImageLoader to load this on the File thread. LoadImage does
159 // not block. 163 // not block.
160 if (!loader_) 164 if (!loader_)
161 loader_ = new ImageLoader(this); 165 loader_ = new ImageLoader(this);
162 loader_->LoadImage(resource, max_size, id); 166 loader_->LoadImage(resource, max_size, id);
163 } 167 }
164 168
165 void ImageLoadingTracker::OnImageLoaded( 169 void ImageLoadingTracker::OnImageLoaded(
166 SkBitmap* image, 170 SkBitmap* image,
167 const ExtensionResource& resource, 171 const ExtensionResource& resource,
172 const gfx::Size& original_size,
168 int id) { 173 int id) {
169 LoadMap::iterator i = load_map_.find(id); 174 LoadMap::iterator i = load_map_.find(id);
170 if (i != load_map_.end()) { 175 if (i != load_map_.end()) {
171 i->second->SetCachedImage(resource, image ? *image : SkBitmap()); 176 i->second->SetCachedImage(resource, image ? *image : SkBitmap(),
177 original_size);
172 load_map_.erase(i); 178 load_map_.erase(i);
173 } 179 }
174 180
175 observer_->OnImageLoaded(image, resource, id); 181 observer_->OnImageLoaded(image, resource, id);
176 } 182 }
177 183
178 void ImageLoadingTracker::Observe(NotificationType type, 184 void ImageLoadingTracker::Observe(NotificationType type,
179 const NotificationSource& source, 185 const NotificationSource& source,
180 const NotificationDetails& details) { 186 const NotificationDetails& details) {
181 DCHECK(type == NotificationType::EXTENSION_UNLOADED || 187 DCHECK(type == NotificationType::EXTENSION_UNLOADED ||
182 type == NotificationType::EXTENSION_UNLOADED_DISABLED); 188 type == NotificationType::EXTENSION_UNLOADED_DISABLED);
183 189
184 Extension* extension = Details<Extension>(details).ptr(); 190 Extension* extension = Details<Extension>(details).ptr();
185 191
186 // Remove all entries in the load_map_ referencing the extension. This ensures 192 // Remove all entries in the load_map_ referencing the extension. This ensures
187 // we don't attempt to cache the image when the load completes. 193 // we don't attempt to cache the image when the load completes.
188 for (LoadMap::iterator i = load_map_.begin(); i != load_map_.end();) { 194 for (LoadMap::iterator i = load_map_.begin(); i != load_map_.end();) {
189 if (i->second == extension) { 195 if (i->second == extension) {
190 load_map_.erase(i++); 196 load_map_.erase(i++);
191 } else { 197 } else {
192 ++i; 198 ++i;
193 } 199 }
194 } 200 }
195 } 201 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/image_loading_tracker.h ('k') | chrome/browser/extensions/image_loading_tracker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698