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

Side by Side Diff: chrome/browser/ui/metro_pin_tab_helper_win.cc

Issue 11306005: Download large icon if available when creating secondary tiles on Windows 8. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Feedback Created 8 years, 1 month 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
« no previous file with comments | « chrome/browser/ui/metro_pin_tab_helper_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/ui/metro_pin_tab_helper_win.h" 5 #include "chrome/browser/ui/metro_pin_tab_helper_win.h"
6 6
7 #include <set>
8
7 #include "base/base_paths.h" 9 #include "base/base_paths.h"
8 #include "base/bind.h" 10 #include "base/bind.h"
9 #include "base/file_path.h" 11 #include "base/file_path.h"
10 #include "base/file_util.h" 12 #include "base/file_util.h"
11 #include "base/logging.h" 13 #include "base/logging.h"
12 #include "base/memory/ref_counted.h" 14 #include "base/memory/ref_counted.h"
13 #include "base/memory/ref_counted_memory.h" 15 #include "base/memory/ref_counted_memory.h"
14 #include "base/path_service.h" 16 #include "base/path_service.h"
15 #include "base/string_number_conversions.h" 17 #include "base/string_number_conversions.h"
16 #include "base/utf_string_conversions.h" 18 #include "base/utf_string_conversions.h"
17 #include "base/win/metro.h" 19 #include "base/win/metro.h"
18 #include "chrome/browser/favicon/favicon_tab_helper.h" 20 #include "chrome/browser/favicon/favicon_tab_helper.h"
21 #include "chrome/browser/favicon/favicon_util.h"
19 #include "chrome/browser/ui/tab_contents/tab_contents.h" 22 #include "chrome/browser/ui/tab_contents/tab_contents.h"
20 #include "chrome/common/chrome_paths.h" 23 #include "chrome/common/chrome_paths.h"
24 #include "chrome/common/icon_messages.h"
21 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/web_contents.h" 26 #include "content/public/browser/web_contents.h"
23 #include "crypto/sha2.h" 27 #include "crypto/sha2.h"
28 #include "third_party/skia/include/core/SkCanvas.h"
29 #include "third_party/skia/include/core/SkColor.h"
24 #include "ui/gfx/canvas.h" 30 #include "ui/gfx/canvas.h"
25 #include "ui/gfx/codec/png_codec.h" 31 #include "ui/gfx/codec/png_codec.h"
26 #include "ui/gfx/color_analysis.h" 32 #include "ui/gfx/color_analysis.h"
27 #include "ui/gfx/color_utils.h" 33 #include "ui/gfx/color_utils.h"
28 #include "ui/gfx/image/image.h" 34 #include "ui/gfx/image/image.h"
29 #include "ui/gfx/rect.h" 35 #include "ui/gfx/rect.h"
30 #include "ui/gfx/size.h" 36 #include "ui/gfx/size.h"
31 37
32 DEFINE_WEB_CONTENTS_USER_DATA_KEY(MetroPinTabHelper) 38 DEFINE_WEB_CONTENTS_USER_DATA_KEY(MetroPinTabHelper)
33 39
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 const int kBoxWidth = 40; 74 const int kBoxWidth = 40;
69 const int kBoxHeight = 40; 75 const int kBoxHeight = 40;
70 const int kCaptionHeight = 20; 76 const int kCaptionHeight = 20;
71 const double kBoxFade = 0.75; 77 const double kBoxFade = 0.75;
72 const int kColorMeanDarknessLimit = 100; 78 const int kColorMeanDarknessLimit = 100;
73 const int kColorMeanLightnessLimit = 650; 79 const int kColorMeanLightnessLimit = 650;
74 80
75 if (image.isNull()) 81 if (image.isNull())
76 return false; 82 return false;
77 83
78 *logo_path = logo_dir.Append(tile_id).ReplaceExtension(L".png"); 84 // First paint the image onto an opaque background to get rid of transparency.
79 85 // White is used as it will be disregarded in the mean calculation because of
80 // Use a canvas to paint the tile logo. 86 // lightness limit.
81 gfx::Canvas canvas(gfx::Size(kLogoWidth, kLogoHeight), ui::SCALE_FACTOR_100P, 87 SkPaint paint;
82 true); 88 paint.setColor(SK_ColorWHITE);
89 gfx::Canvas favicon_canvas(gfx::Size(image.width(), image.height()),
90 ui::SCALE_FACTOR_100P, true);
91 favicon_canvas.DrawRect(gfx::Rect(0, 0, image.width(), image.height()),
92 paint);
93 favicon_canvas.DrawImageInt(image, 0, 0);
83 94
84 // Fill the tile logo with the average color from bitmap. To do this we need 95 // Fill the tile logo with the average color from bitmap. To do this we need
85 // to work out the 'average color' which is calculated using PNG encoded data 96 // to work out the 'average color' which is calculated using PNG encoded data
86 // of the bitmap. 97 // of the bitmap.
87 SkPaint paint;
88 std::vector<unsigned char> icon_png; 98 std::vector<unsigned char> icon_png;
89 if (!gfx::PNGCodec::EncodeBGRASkBitmap(*image.bitmap(), true, &icon_png)) 99 if (!gfx::PNGCodec::EncodeBGRASkBitmap(
100 favicon_canvas.ExtractImageRep().sk_bitmap(), false, &icon_png)) {
90 return false; 101 return false;
102 }
91 103
92 scoped_refptr<base::RefCountedStaticMemory> icon_mem( 104 scoped_refptr<base::RefCountedStaticMemory> icon_mem(
93 new base::RefCountedStaticMemory(&icon_png.front(), icon_png.size())); 105 new base::RefCountedStaticMemory(&icon_png.front(), icon_png.size()));
94 color_utils::GridSampler sampler; 106 color_utils::GridSampler sampler;
95 SkColor mean_color = color_utils::CalculateKMeanColorOfPNG( 107 SkColor mean_color = color_utils::CalculateKMeanColorOfPNG(
96 icon_mem, kColorMeanDarknessLimit, kColorMeanLightnessLimit, sampler); 108 icon_mem, kColorMeanDarknessLimit, kColorMeanLightnessLimit, sampler);
97 paint.setColor(mean_color); 109 paint.setColor(mean_color);
110 gfx::Canvas canvas(gfx::Size(kLogoWidth, kLogoHeight), ui::SCALE_FACTOR_100P,
111 true);
98 canvas.DrawRect(gfx::Rect(0, 0, kLogoWidth, kLogoHeight), paint); 112 canvas.DrawRect(gfx::Rect(0, 0, kLogoWidth, kLogoHeight), paint);
99 113
100 // Now paint a faded square for the favicon to go in. 114 // Now paint a faded square for the favicon to go in.
101 color_utils::HSL shift = {-1, -1, kBoxFade}; 115 color_utils::HSL shift = {-1, -1, kBoxFade};
102 paint.setColor(color_utils::HSLShift(mean_color, shift)); 116 paint.setColor(color_utils::HSLShift(mean_color, shift));
103 int box_left = (kLogoWidth - kBoxWidth) / 2; 117 int box_left = (kLogoWidth - kBoxWidth) / 2;
104 int box_top = (kLogoHeight - kCaptionHeight - kBoxHeight) / 2; 118 int box_top = (kLogoHeight - kCaptionHeight - kBoxHeight) / 2;
105 canvas.DrawRect(gfx::Rect(box_left, box_top, kBoxWidth, kBoxHeight), paint); 119 canvas.DrawRect(gfx::Rect(box_left, box_top, kBoxWidth, kBoxHeight), paint);
106 120
107 // Now paint the favicon into the tile, leaving some room at the bottom for 121 // Now paint the favicon into the tile, leaving some room at the bottom for
108 // the caption. 122 // the caption.
109 int left = (kLogoWidth - image.width()) / 2; 123 int left = (kLogoWidth - image.width()) / 2;
110 int top = (kLogoHeight - kCaptionHeight - image.height()) / 2; 124 int top = (kLogoHeight - kCaptionHeight - image.height()) / 2;
111 canvas.DrawImageInt(image, left, top); 125 canvas.DrawImageInt(image, left, top);
112 126
113 SkBitmap logo_bitmap = canvas.ExtractImageRep().sk_bitmap(); 127 SkBitmap logo_bitmap = canvas.ExtractImageRep().sk_bitmap();
114 std::vector<unsigned char> logo_png; 128 std::vector<unsigned char> logo_png;
115 if (!gfx::PNGCodec::EncodeBGRASkBitmap(logo_bitmap, true, &logo_png)) 129 if (!gfx::PNGCodec::EncodeBGRASkBitmap(logo_bitmap, true, &logo_png))
116 return false; 130 return false;
117 131
132 *logo_path = logo_dir.Append(tile_id).ReplaceExtension(L".png");
118 return file_util::WriteFile(*logo_path, 133 return file_util::WriteFile(*logo_path,
119 reinterpret_cast<char*>(&logo_png[0]), 134 reinterpret_cast<char*>(&logo_png[0]),
120 logo_png.size()) > 0; 135 logo_png.size()) > 0;
121 } 136 }
122 137
123 // Get the path to the backup logo. If the backup logo already exists in 138 // Get the path to the backup logo. If the backup logo already exists in
124 // |logo_dir|, it will be used, otherwise it will be copied out of the install 139 // |logo_dir|, it will be used, otherwise it will be copied out of the install
125 // folder. (The version in the install folder is not used as it may disappear 140 // folder. (The version in the install folder is not used as it may disappear
126 // after an upgrade, causing tiles to lose their images if Windows rebuilds 141 // after an upgrade, causing tiles to lose their images if Windows rebuilds
127 // its tile image cache.) 142 // its tile image cache.)
128 // The path to the logo is returned in |logo_path|, with the return value 143 // The path to the logo is returned in |logo_path|, with the return value
129 // indicating success. 144 // indicating success.
130 bool GetPathToBackupLogo(const FilePath& logo_dir, 145 bool GetPathToBackupLogo(const FilePath& logo_dir,
131 FilePath* logo_path) { 146 FilePath* logo_path) {
132 const wchar_t kDefaultLogoFileName[] = L"SecondaryTile.png"; 147 const wchar_t kDefaultLogoFileName[] = L"SecondaryTile.png";
133 *logo_path = logo_dir.Append(kDefaultLogoFileName); 148 *logo_path = logo_dir.Append(kDefaultLogoFileName);
134 if (file_util::PathExists(*logo_path)) 149 if (file_util::PathExists(*logo_path))
135 return true; 150 return true;
136 151
137 FilePath default_logo_path; 152 FilePath default_logo_path;
138 if (!PathService::Get(base::DIR_MODULE, &default_logo_path)) 153 if (!PathService::Get(base::DIR_MODULE, &default_logo_path))
139 return false; 154 return false;
140 155
141 default_logo_path = default_logo_path.Append(kDefaultLogoFileName); 156 default_logo_path = default_logo_path.Append(kDefaultLogoFileName);
142 return file_util::CopyFile(default_logo_path, *logo_path); 157 return file_util::CopyFile(default_logo_path, *logo_path);
143 } 158 }
144 159
145 } // namespace 160 // The PinPageTaskRunner class performs the necessary FILE thread actions to
161 // pin a page, such as generating or copying the tile image file. When it
162 // has performed these actions it will send the tile creation request to the
163 // metro driver.
164 class PinPageTaskRunner : public base::RefCountedThreadSafe<PinPageTaskRunner> {
165 public:
166 // Creates a task runner for the pinning operation with the given details.
167 // |favicon| can be a null image (i.e. favicon.isNull() can be true), in
168 // which case the backup tile image will be used.
169 PinPageTaskRunner(string16& title, string16& url, gfx::ImageSkia& favicon);
146 170
147 class MetroPinTabHelper::TaskRunner 171 void Run();
148 : public base::RefCountedThreadSafe<TaskRunner> { 172 void RunOnFileThread();
149 public:
150 TaskRunner() {}
151
152 void PinPageToStartScreen(const string16& title,
153 const string16& url,
154 const gfx::ImageSkia& image);
155 173
156 private: 174 private:
157 ~TaskRunner() {} 175 ~PinPageTaskRunner() {}
158 176
159 friend class base::RefCountedThreadSafe<TaskRunner>; 177 // Details of the page being pinned.
160 DISALLOW_COPY_AND_ASSIGN(TaskRunner); 178 string16 title_;
179 string16 url_;
180 gfx::ImageSkia favicon_;
181
182 friend class base::RefCountedThreadSafe<PinPageTaskRunner>;
183 DISALLOW_COPY_AND_ASSIGN(PinPageTaskRunner);
161 }; 184 };
162 185
163 void MetroPinTabHelper::TaskRunner::PinPageToStartScreen( 186 PinPageTaskRunner::PinPageTaskRunner(string16& title,
164 const string16& title, 187 string16& url,
165 const string16& url, 188 gfx::ImageSkia& favicon)
166 const gfx::ImageSkia& image) { 189 : title_(title), url_(url), favicon_(favicon) {}
sky 2012/10/29 15:06:41 Since you wrapped the constructor each param on it
benwells 2012/10/29 23:20:44 Done.
190
191 void PinPageTaskRunner::Run() {
192 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
193
194 content::BrowserThread::PostTask(
195 content::BrowserThread::FILE,
196 FROM_HERE,
197 base::Bind(&PinPageTaskRunner::RunOnFileThread, this));
198 }
199
200 void PinPageTaskRunner::RunOnFileThread() {
167 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 201 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
168 202
169 string16 tile_id = GenerateTileId(url); 203 string16 tile_id = GenerateTileId(url_);
170 FilePath logo_dir = GetTileImagesDir(); 204 FilePath logo_dir = GetTileImagesDir();
171 if (logo_dir.empty()) { 205 if (logo_dir.empty()) {
172 LOG(ERROR) << "Could not create directory to store tile image."; 206 LOG(ERROR) << "Could not create directory to store tile image.";
173 return; 207 return;
174 } 208 }
175 209
176 FilePath logo_path; 210 FilePath logo_path;
177 if (!CreateSiteSpecificLogo(image, tile_id, logo_dir, &logo_path) && 211 if (!CreateSiteSpecificLogo(favicon_, tile_id, logo_dir, &logo_path) &&
178 !GetPathToBackupLogo(logo_dir, &logo_path)) { 212 !GetPathToBackupLogo(logo_dir, &logo_path)) {
179 LOG(ERROR) << "Count not get path to logo tile."; 213 LOG(ERROR) << "Count not get path to logo tile.";
180 return; 214 return;
181 } 215 }
182 216
183 HMODULE metro_module = base::win::GetMetroModule(); 217 HMODULE metro_module = base::win::GetMetroModule();
sky 2012/10/29 15:06:41 I'm not familiar with the metro module, is is thre
benwells 2012/10/29 23:20:44 Yes, this part is. This code just calls a metro fu
184 if (!metro_module) 218 if (!metro_module)
185 return; 219 return;
186 220
187 typedef void (*MetroPinToStartScreen)(const string16&, const string16&, 221 typedef void (*MetroPinToStartScreen)(const string16&, const string16&,
188 const string16&, const FilePath&); 222 const string16&, const FilePath&);
189 MetroPinToStartScreen metro_pin_to_start_screen = 223 MetroPinToStartScreen metro_pin_to_start_screen =
190 reinterpret_cast<MetroPinToStartScreen>( 224 reinterpret_cast<MetroPinToStartScreen>(
191 ::GetProcAddress(metro_module, "MetroPinToStartScreen")); 225 ::GetProcAddress(metro_module, "MetroPinToStartScreen"));
192 if (!metro_pin_to_start_screen) { 226 if (!metro_pin_to_start_screen) {
193 NOTREACHED(); 227 NOTREACHED();
194 return; 228 return;
195 } 229 }
196 230
197 VLOG(1) << __FUNCTION__ << " calling pin with title: " << title 231 metro_pin_to_start_screen(tile_id, title_, url_, logo_path);
198 << " and url: " << url; 232 }
199 metro_pin_to_start_screen(tile_id, title, url, logo_path); 233
234 } // namespace
235
236 class MetroPinTabHelper::FaviconDownloader {
237 public:
238 FaviconDownloader(MetroPinTabHelper* helper,
239 const string16& title,
240 const string16& url,
241 const gfx::ImageSkia& history_image);
242 ~FaviconDownloader() {}
243
244 void Start(content::RenderViewHost* host,
245 const std::vector<FaviconURL>& candidates);
246
247 // Callback for when a favicon has been downloaded. The best bitmap so far
248 // will be stored in |best_candidate_|. If this is the last URL that was being
249 // downloaded, the page is pinned by calling PinPageToStartScreen on the FILE
250 // thread.
251 void OnDidDownloadFavicon(int id,
252 const GURL& image_url,
253 bool errored,
254 int requested_size,
255 const std::vector<SkBitmap>& bitmaps);
256
257 private:
258 // The tab helper that this downloader is operating for.
259 MetroPinTabHelper* helper_;
260
261 // Title and URL of the page being pinned.
262 string16 title_;
sky 2012/10/29 15:06:41 const title_ and url_
benwells 2012/10/29 23:20:44 Done.
263 string16 url_;
264
265 // The best candidate we have so far for the current pin operation.
266 gfx::ImageSkia best_candidate_;
267
268 // Outstanding favicon download requests.
269 std::set<int> in_progress_requests_;
270
271 DISALLOW_COPY_AND_ASSIGN(FaviconDownloader);
272 };
273
274 MetroPinTabHelper::FaviconDownloader::FaviconDownloader(
275 MetroPinTabHelper* helper,
276 const string16& title,
277 const string16& url,
278 const gfx::ImageSkia& history_image)
279 : helper_(helper),
280 title_(title),
281 url_(url),
282 best_candidate_(history_image) {}
283
284 void MetroPinTabHelper::FaviconDownloader::Start(
285 content::RenderViewHost* host,
286 const std::vector<FaviconURL>& candidates) {
287 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
288
289 // If there are no candidate URLs, progress straight to pinning.
290 if (candidates.empty()) {
291 scoped_refptr<PinPageTaskRunner> runner(
292 new PinPageTaskRunner(title_, url_, best_candidate_));
293 runner->Run();
294 helper_->FaviconDownloaderFinished();
295 return;
296 }
297
298 // Request all the candidates.
299 int image_size = 0; // Request the full sized image.
300 for (std::vector<FaviconURL>::const_iterator iter = candidates.begin();
301 iter != candidates.end();
302 ++iter) {
303 in_progress_requests_.insert(
304 FaviconUtil::DownloadFavicon(host, iter->icon_url, image_size));
305 }
306 }
307
308 void MetroPinTabHelper::FaviconDownloader::OnDidDownloadFavicon(
309 int id,
310 const GURL& image_url,
311 bool errored,
312 int requested_size,
313 const std::vector<SkBitmap>& bitmaps) {
314 const int kMaxIconSize = 32;
315
316 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
317 std::set<int>::iterator iter = in_progress_requests_.find(id);
318 // Check that this request is one of ours.
319 if (iter == in_progress_requests_.end())
320 return;
321
322 in_progress_requests_.erase(iter);
323
324 // Process the bitmaps, keeping the one that is best so far.
325 if (!errored) {
326 for (std::vector<SkBitmap>::const_iterator iter = bitmaps.begin();
327 iter != bitmaps.end();
328 ++iter) {
329
330 // If we don't have a best candidate yet, this is better so just grab it.
331 if (best_candidate_.isNull()) {
sky 2012/10/29 15:06:41 Might this result in an image bigger than kMaxIcon
benwells 2012/10/29 23:20:44 Oh yes, good catch.
332 best_candidate_ = gfx::ImageSkia(*iter).DeepCopy();
333 continue;
334 }
335 // If the new bitmap is bigger than the best candidate, and not greater
336 // than the max size, grab it.
337 if (iter->height() > kMaxIconSize || iter->width() > kMaxIconSize)
338 continue;
339
340 if (iter->height() <= best_candidate_.height() ||
341 iter->width() <= best_candidate_.width()) {
342 continue;
343 }
344
345 best_candidate_ = gfx::ImageSkia(*iter).DeepCopy();
346 }
347 }
348
349 // If there are no more outstanding requests, pin the page on the FILE thread.
350 // Once this happens this downloader has done its job, so delete it.
351 if (in_progress_requests_.empty()) {
352 scoped_refptr<PinPageTaskRunner> runner(
353 new PinPageTaskRunner(title_, url_, best_candidate_));
354 runner->Run();
355 helper_->FaviconDownloaderFinished();
356 }
200 } 357 }
201 358
202 MetroPinTabHelper::MetroPinTabHelper(content::WebContents* web_contents) 359 MetroPinTabHelper::MetroPinTabHelper(content::WebContents* web_contents)
203 : content::WebContentsObserver(web_contents), 360 : content::WebContentsObserver(web_contents),
204 is_pinned_(false), 361 is_pinned_(false) {}
205 task_runner_(new TaskRunner) {}
206 362
207 MetroPinTabHelper::~MetroPinTabHelper() {} 363 MetroPinTabHelper::~MetroPinTabHelper() {}
208 364
209 void MetroPinTabHelper::TogglePinnedToStartScreen() { 365 void MetroPinTabHelper::TogglePinnedToStartScreen() {
210 UpdatePinnedStateForCurrentURL(); 366 UpdatePinnedStateForCurrentURL();
211 bool was_pinned = is_pinned_; 367 bool was_pinned = is_pinned_;
212 368
213 // TODO(benwells): This will update the state incorrectly if the user 369 // TODO(benwells): This will update the state incorrectly if the user
214 // cancels. To fix this some sort of callback needs to be introduced as 370 // cancels. To fix this some sort of callback needs to be introduced as
215 // the pinning happens on another thread. 371 // the pinning happens on another thread.
216 is_pinned_ = !is_pinned_; 372 is_pinned_ = !is_pinned_;
217 373
218 if (was_pinned) { 374 if (was_pinned) {
219 UnPinPageFromStartScreen(); 375 UnPinPageFromStartScreen();
220 return; 376 return;
221 } 377 }
222 378
223 // TODO(benwells): Handle downloading a larger favicon if there is one.
224 GURL url = web_contents()->GetURL(); 379 GURL url = web_contents()->GetURL();
225 string16 url_str = UTF8ToUTF16(url.spec()); 380 string16 url_str = UTF8ToUTF16(url.spec());
226 string16 title = web_contents()->GetTitle(); 381 string16 title = web_contents()->GetTitle();
227 TabContents* tab_contents = TabContents::FromWebContents(web_contents()); 382 gfx::ImageSkia favicon;
228 DCHECK(tab_contents);
229 FaviconTabHelper* favicon_tab_helper = FaviconTabHelper::FromWebContents( 383 FaviconTabHelper* favicon_tab_helper = FaviconTabHelper::FromWebContents(
230 tab_contents->web_contents()); 384 web_contents());
231 if (favicon_tab_helper->FaviconIsValid()) { 385 if (favicon_tab_helper->FaviconIsValid())
232 gfx::Image favicon = favicon_tab_helper->GetFavicon(); 386 favicon = favicon_tab_helper->GetFavicon().AsImageSkia().DeepCopy();
233 gfx::ImageSkia favicon_skia = favicon.AsImageSkia().DeepCopy();
234 content::BrowserThread::PostTask(
235 content::BrowserThread::FILE,
236 FROM_HERE,
237 base::Bind(&TaskRunner::PinPageToStartScreen,
238 task_runner_,
239 title,
240 url_str,
241 favicon_skia));
242 return;
243 }
244 387
245 content::BrowserThread::PostTask( 388 favicon_downloader_.reset(new FaviconDownloader(this, title, url_str,
246 content::BrowserThread::FILE, 389 favicon));
247 FROM_HERE, 390 favicon_downloader_->Start(web_contents()->GetRenderViewHost(),
248 base::Bind(&TaskRunner::PinPageToStartScreen, 391 favicon_url_candidates_);
249 task_runner_,
250 title,
251 url_str,
252 gfx::ImageSkia()));
253 } 392 }
254 393
255 void MetroPinTabHelper::DidNavigateMainFrame( 394 void MetroPinTabHelper::DidNavigateMainFrame(
256 const content::LoadCommittedDetails& /*details*/, 395 const content::LoadCommittedDetails& /*details*/,
257 const content::FrameNavigateParams& /*params*/) { 396 const content::FrameNavigateParams& /*params*/) {
258 UpdatePinnedStateForCurrentURL(); 397 UpdatePinnedStateForCurrentURL();
398 // Cancel any outstanding pin operations once the user navigates away from
399 // the page.
400 if (favicon_downloader_.get())
401 favicon_downloader_.reset();
sky 2012/10/29 15:06:41 Does this mean if the user pins something and the
benwells 2012/10/29 23:20:44 I think it makes the most sense. The pin action co
402 // Any candidate favicons we have are now out of date so clear them.
403 favicon_url_candidates_.clear();
404 }
405
406 bool MetroPinTabHelper::OnMessageReceived(const IPC::Message& message) {
407 bool message_handled = false; // Allow other handlers to receive these.
408 IPC_BEGIN_MESSAGE_MAP(MetroPinTabHelper, message)
409 IPC_MESSAGE_HANDLER(IconHostMsg_UpdateFaviconURL, OnUpdateFaviconURL)
410 IPC_MESSAGE_HANDLER(IconHostMsg_DidDownloadFavicon, OnDidDownloadFavicon)
411 IPC_MESSAGE_UNHANDLED(message_handled = false)
412 IPC_END_MESSAGE_MAP()
413 return message_handled;
414 }
415
416 void MetroPinTabHelper::OnUpdateFaviconURL(
417 int32 page_id,
418 const std::vector<FaviconURL>& candidates) {
419 favicon_url_candidates_ = candidates;
420 }
421
422 void MetroPinTabHelper::OnDidDownloadFavicon(
423 int id,
424 const GURL& image_url,
425 bool errored,
426 int requested_size,
427 const std::vector<SkBitmap>& bitmaps) {
428 if (favicon_downloader_.get())
429 favicon_downloader_->OnDidDownloadFavicon(id, image_url, errored,
430 requested_size, bitmaps);
259 } 431 }
260 432
261 void MetroPinTabHelper::UpdatePinnedStateForCurrentURL() { 433 void MetroPinTabHelper::UpdatePinnedStateForCurrentURL() {
262 HMODULE metro_module = base::win::GetMetroModule(); 434 HMODULE metro_module = base::win::GetMetroModule();
263 if (!metro_module) 435 if (!metro_module)
264 return; 436 return;
265 437
266 typedef BOOL (*MetroIsPinnedToStartScreen)(const string16&); 438 typedef BOOL (*MetroIsPinnedToStartScreen)(const string16&);
267 MetroIsPinnedToStartScreen metro_is_pinned_to_start_screen = 439 MetroIsPinnedToStartScreen metro_is_pinned_to_start_screen =
268 reinterpret_cast<MetroIsPinnedToStartScreen>( 440 reinterpret_cast<MetroIsPinnedToStartScreen>(
269 ::GetProcAddress(metro_module, "MetroIsPinnedToStartScreen")); 441 ::GetProcAddress(metro_module, "MetroIsPinnedToStartScreen"));
270 if (!metro_is_pinned_to_start_screen) { 442 if (!metro_is_pinned_to_start_screen) {
271 NOTREACHED(); 443 NOTREACHED();
272 return; 444 return;
273 } 445 }
274 446
275 GURL url = web_contents()->GetURL(); 447 GURL url = web_contents()->GetURL();
276 string16 tile_id = GenerateTileId(UTF8ToUTF16(url.spec())); 448 string16 tile_id = GenerateTileId(UTF8ToUTF16(url.spec()));
277 is_pinned_ = metro_is_pinned_to_start_screen(tile_id) != 0; 449 is_pinned_ = metro_is_pinned_to_start_screen(tile_id) != 0;
278 VLOG(1) << __FUNCTION__ << " with url " << UTF8ToUTF16(url.spec())
279 << " result: " << is_pinned_;
280 } 450 }
281 451
282 void MetroPinTabHelper::UnPinPageFromStartScreen() { 452 void MetroPinTabHelper::UnPinPageFromStartScreen() {
283 HMODULE metro_module = base::win::GetMetroModule(); 453 HMODULE metro_module = base::win::GetMetroModule();
284 if (!metro_module) 454 if (!metro_module)
285 return; 455 return;
286 456
287 typedef void (*MetroUnPinFromStartScreen)(const string16&); 457 typedef void (*MetroUnPinFromStartScreen)(const string16&);
288 MetroUnPinFromStartScreen metro_un_pin_from_start_screen = 458 MetroUnPinFromStartScreen metro_un_pin_from_start_screen =
289 reinterpret_cast<MetroUnPinFromStartScreen>( 459 reinterpret_cast<MetroUnPinFromStartScreen>(
290 ::GetProcAddress(metro_module, "MetroUnPinFromStartScreen")); 460 ::GetProcAddress(metro_module, "MetroUnPinFromStartScreen"));
291 if (!metro_un_pin_from_start_screen) { 461 if (!metro_un_pin_from_start_screen) {
292 NOTREACHED(); 462 NOTREACHED();
293 return; 463 return;
294 } 464 }
295 465
296 GURL url = web_contents()->GetURL(); 466 GURL url = web_contents()->GetURL();
297 VLOG(1) << __FUNCTION__ << " calling unpin with url: "
298 << UTF8ToUTF16(url.spec());
299 string16 tile_id = GenerateTileId(UTF8ToUTF16(url.spec())); 467 string16 tile_id = GenerateTileId(UTF8ToUTF16(url.spec()));
300 metro_un_pin_from_start_screen(tile_id); 468 metro_un_pin_from_start_screen(tile_id);
301 } 469 }
470
471 void MetroPinTabHelper::FaviconDownloaderFinished() {
472 favicon_downloader_.reset();
473 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/metro_pin_tab_helper_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698