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

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(const string16& title,
170 const string16& url,
171 const gfx::ImageSkia& favicon);
146 172
147 class MetroPinTabHelper::TaskRunner 173 void Run();
148 : public base::RefCountedThreadSafe<TaskRunner> { 174 void RunOnFileThread();
149 public:
150 TaskRunner() {}
151
152 void PinPageToStartScreen(const string16& title,
153 const string16& url,
154 const gfx::ImageSkia& image);
155 175
156 private: 176 private:
157 ~TaskRunner() {} 177 ~PinPageTaskRunner() {}
158 178
159 friend class base::RefCountedThreadSafe<TaskRunner>; 179 // Details of the page being pinned.
160 DISALLOW_COPY_AND_ASSIGN(TaskRunner); 180 const string16 title_;
181 const string16 url_;
182 gfx::ImageSkia favicon_;
183
184 friend class base::RefCountedThreadSafe<PinPageTaskRunner>;
185 DISALLOW_COPY_AND_ASSIGN(PinPageTaskRunner);
161 }; 186 };
162 187
163 void MetroPinTabHelper::TaskRunner::PinPageToStartScreen( 188 PinPageTaskRunner::PinPageTaskRunner(const string16& title,
164 const string16& title, 189 const string16& url,
165 const string16& url, 190 const gfx::ImageSkia& favicon)
166 const gfx::ImageSkia& image) { 191 : title_(title),
192 url_(url),
193 favicon_(favicon) {}
194
195 void PinPageTaskRunner::Run() {
196 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
197
198 content::BrowserThread::PostTask(
199 content::BrowserThread::FILE,
200 FROM_HERE,
201 base::Bind(&PinPageTaskRunner::RunOnFileThread, this));
202 }
203
204 void PinPageTaskRunner::RunOnFileThread() {
167 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 205 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
168 206
169 string16 tile_id = GenerateTileId(url); 207 string16 tile_id = GenerateTileId(url_);
170 FilePath logo_dir = GetTileImagesDir(); 208 FilePath logo_dir = GetTileImagesDir();
171 if (logo_dir.empty()) { 209 if (logo_dir.empty()) {
172 LOG(ERROR) << "Could not create directory to store tile image."; 210 LOG(ERROR) << "Could not create directory to store tile image.";
173 return; 211 return;
174 } 212 }
175 213
176 FilePath logo_path; 214 FilePath logo_path;
177 if (!CreateSiteSpecificLogo(image, tile_id, logo_dir, &logo_path) && 215 if (!CreateSiteSpecificLogo(favicon_, tile_id, logo_dir, &logo_path) &&
178 !GetPathToBackupLogo(logo_dir, &logo_path)) { 216 !GetPathToBackupLogo(logo_dir, &logo_path)) {
179 LOG(ERROR) << "Count not get path to logo tile."; 217 LOG(ERROR) << "Count not get path to logo tile.";
180 return; 218 return;
181 } 219 }
182 220
183 HMODULE metro_module = base::win::GetMetroModule(); 221 HMODULE metro_module = base::win::GetMetroModule();
184 if (!metro_module) 222 if (!metro_module)
185 return; 223 return;
186 224
187 typedef void (*MetroPinToStartScreen)(const string16&, const string16&, 225 typedef void (*MetroPinToStartScreen)(const string16&, const string16&,
188 const string16&, const FilePath&); 226 const string16&, const FilePath&);
189 MetroPinToStartScreen metro_pin_to_start_screen = 227 MetroPinToStartScreen metro_pin_to_start_screen =
190 reinterpret_cast<MetroPinToStartScreen>( 228 reinterpret_cast<MetroPinToStartScreen>(
191 ::GetProcAddress(metro_module, "MetroPinToStartScreen")); 229 ::GetProcAddress(metro_module, "MetroPinToStartScreen"));
192 if (!metro_pin_to_start_screen) { 230 if (!metro_pin_to_start_screen) {
193 NOTREACHED(); 231 NOTREACHED();
194 return; 232 return;
195 } 233 }
196 234
197 VLOG(1) << __FUNCTION__ << " calling pin with title: " << title 235 metro_pin_to_start_screen(tile_id, title_, url_, logo_path);
198 << " and url: " << url; 236 }
199 metro_pin_to_start_screen(tile_id, title, url, logo_path); 237
238 } // namespace
239
240 class MetroPinTabHelper::FaviconDownloader {
241 public:
242 FaviconDownloader(MetroPinTabHelper* helper,
243 const string16& title,
244 const string16& url,
245 const gfx::ImageSkia& history_image);
246 ~FaviconDownloader() {}
247
248 void Start(content::RenderViewHost* host,
249 const std::vector<FaviconURL>& candidates);
250
251 // Callback for when a favicon has been downloaded. The best bitmap so far
252 // will be stored in |best_candidate_|. If this is the last URL that was being
253 // downloaded, the page is pinned by calling PinPageToStartScreen on the FILE
254 // thread.
255 void OnDidDownloadFavicon(int id,
256 const GURL& image_url,
257 bool errored,
258 int requested_size,
259 const std::vector<SkBitmap>& bitmaps);
260
261 private:
262 // The tab helper that this downloader is operating for.
263 MetroPinTabHelper* helper_;
264
265 // Title and URL of the page being pinned.
266 const string16 title_;
267 const string16 url_;
268
269 // The best candidate we have so far for the current pin operation.
270 gfx::ImageSkia best_candidate_;
271
272 // Outstanding favicon download requests.
273 std::set<int> in_progress_requests_;
274
275 DISALLOW_COPY_AND_ASSIGN(FaviconDownloader);
276 };
277
278 MetroPinTabHelper::FaviconDownloader::FaviconDownloader(
279 MetroPinTabHelper* helper,
280 const string16& title,
281 const string16& url,
282 const gfx::ImageSkia& history_image)
283 : helper_(helper),
284 title_(title),
285 url_(url),
286 best_candidate_(history_image) {}
287
288 void MetroPinTabHelper::FaviconDownloader::Start(
289 content::RenderViewHost* host,
290 const std::vector<FaviconURL>& candidates) {
291 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
292
293 // If there are no candidate URLs, progress straight to pinning.
294 if (candidates.empty()) {
295 scoped_refptr<PinPageTaskRunner> runner(
296 new PinPageTaskRunner(title_, url_, best_candidate_));
297 runner->Run();
298 helper_->FaviconDownloaderFinished();
299 return;
300 }
301
302 // Request all the candidates.
303 int image_size = 0; // Request the full sized image.
304 for (std::vector<FaviconURL>::const_iterator iter = candidates.begin();
305 iter != candidates.end();
306 ++iter) {
307 in_progress_requests_.insert(
308 FaviconUtil::DownloadFavicon(host, iter->icon_url, image_size));
309 }
310 }
311
312 void MetroPinTabHelper::FaviconDownloader::OnDidDownloadFavicon(
313 int id,
314 const GURL& image_url,
315 bool errored,
316 int requested_size,
317 const std::vector<SkBitmap>& bitmaps) {
318 const int kMaxIconSize = 32;
319
320 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
321 std::set<int>::iterator iter = in_progress_requests_.find(id);
322 // Check that this request is one of ours.
323 if (iter == in_progress_requests_.end())
324 return;
325
326 in_progress_requests_.erase(iter);
327
328 // Process the bitmaps, keeping the one that is best so far.
329 if (!errored) {
330 for (std::vector<SkBitmap>::const_iterator iter = bitmaps.begin();
331 iter != bitmaps.end();
332 ++iter) {
333
334 // If the new bitmap is too big, ignore it.
335 if (iter->height() > kMaxIconSize || iter->width() > kMaxIconSize)
336 continue;
337
338 // If we don't have a best candidate yet, this is better so just grab it.
339 if (best_candidate_.isNull()) {
340 best_candidate_ = gfx::ImageSkia(*iter).DeepCopy();
341 continue;
342 }
343
344 // If it is smaller than our best one so far, ignore it.
345 if (iter->height() <= best_candidate_.height() ||
346 iter->width() <= best_candidate_.width()) {
347 continue;
348 }
349
350 // Othewise it is our new best candidate.
351 best_candidate_ = gfx::ImageSkia(*iter).DeepCopy();
352 }
353 }
354
355 // If there are no more outstanding requests, pin the page on the FILE thread.
356 // Once this happens this downloader has done its job, so delete it.
357 if (in_progress_requests_.empty()) {
358 scoped_refptr<PinPageTaskRunner> runner(
359 new PinPageTaskRunner(title_, url_, best_candidate_));
360 runner->Run();
361 helper_->FaviconDownloaderFinished();
362 }
200 } 363 }
201 364
202 MetroPinTabHelper::MetroPinTabHelper(content::WebContents* web_contents) 365 MetroPinTabHelper::MetroPinTabHelper(content::WebContents* web_contents)
203 : content::WebContentsObserver(web_contents), 366 : content::WebContentsObserver(web_contents),
204 is_pinned_(false), 367 is_pinned_(false) {}
205 task_runner_(new TaskRunner) {}
206 368
207 MetroPinTabHelper::~MetroPinTabHelper() {} 369 MetroPinTabHelper::~MetroPinTabHelper() {}
208 370
209 void MetroPinTabHelper::TogglePinnedToStartScreen() { 371 void MetroPinTabHelper::TogglePinnedToStartScreen() {
210 UpdatePinnedStateForCurrentURL(); 372 UpdatePinnedStateForCurrentURL();
211 bool was_pinned = is_pinned_; 373 bool was_pinned = is_pinned_;
212 374
213 // TODO(benwells): This will update the state incorrectly if the user 375 // 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 376 // cancels. To fix this some sort of callback needs to be introduced as
215 // the pinning happens on another thread. 377 // the pinning happens on another thread.
216 is_pinned_ = !is_pinned_; 378 is_pinned_ = !is_pinned_;
217 379
218 if (was_pinned) { 380 if (was_pinned) {
219 UnPinPageFromStartScreen(); 381 UnPinPageFromStartScreen();
220 return; 382 return;
221 } 383 }
222 384
223 // TODO(benwells): Handle downloading a larger favicon if there is one.
224 GURL url = web_contents()->GetURL(); 385 GURL url = web_contents()->GetURL();
225 string16 url_str = UTF8ToUTF16(url.spec()); 386 string16 url_str = UTF8ToUTF16(url.spec());
226 string16 title = web_contents()->GetTitle(); 387 string16 title = web_contents()->GetTitle();
227 TabContents* tab_contents = TabContents::FromWebContents(web_contents()); 388 gfx::ImageSkia favicon;
228 DCHECK(tab_contents);
229 FaviconTabHelper* favicon_tab_helper = FaviconTabHelper::FromWebContents( 389 FaviconTabHelper* favicon_tab_helper = FaviconTabHelper::FromWebContents(
230 tab_contents->web_contents()); 390 web_contents());
231 if (favicon_tab_helper->FaviconIsValid()) { 391 if (favicon_tab_helper->FaviconIsValid())
232 gfx::Image favicon = favicon_tab_helper->GetFavicon(); 392 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 393
245 content::BrowserThread::PostTask( 394 favicon_downloader_.reset(new FaviconDownloader(this, title, url_str,
246 content::BrowserThread::FILE, 395 favicon));
247 FROM_HERE, 396 favicon_downloader_->Start(web_contents()->GetRenderViewHost(),
248 base::Bind(&TaskRunner::PinPageToStartScreen, 397 favicon_url_candidates_);
249 task_runner_,
250 title,
251 url_str,
252 gfx::ImageSkia()));
253 } 398 }
254 399
255 void MetroPinTabHelper::DidNavigateMainFrame( 400 void MetroPinTabHelper::DidNavigateMainFrame(
256 const content::LoadCommittedDetails& /*details*/, 401 const content::LoadCommittedDetails& /*details*/,
257 const content::FrameNavigateParams& /*params*/) { 402 const content::FrameNavigateParams& /*params*/) {
258 UpdatePinnedStateForCurrentURL(); 403 UpdatePinnedStateForCurrentURL();
404 // Cancel any outstanding pin operations once the user navigates away from
405 // the page.
406 if (favicon_downloader_.get())
407 favicon_downloader_.reset();
408 // Any candidate favicons we have are now out of date so clear them.
409 favicon_url_candidates_.clear();
410 }
411
412 bool MetroPinTabHelper::OnMessageReceived(const IPC::Message& message) {
413 bool message_handled = false; // Allow other handlers to receive these.
414 IPC_BEGIN_MESSAGE_MAP(MetroPinTabHelper, message)
415 IPC_MESSAGE_HANDLER(IconHostMsg_UpdateFaviconURL, OnUpdateFaviconURL)
416 IPC_MESSAGE_HANDLER(IconHostMsg_DidDownloadFavicon, OnDidDownloadFavicon)
417 IPC_MESSAGE_UNHANDLED(message_handled = false)
418 IPC_END_MESSAGE_MAP()
419 return message_handled;
420 }
421
422 void MetroPinTabHelper::OnUpdateFaviconURL(
423 int32 page_id,
424 const std::vector<FaviconURL>& candidates) {
425 favicon_url_candidates_ = candidates;
426 }
427
428 void MetroPinTabHelper::OnDidDownloadFavicon(
429 int id,
430 const GURL& image_url,
431 bool errored,
432 int requested_size,
433 const std::vector<SkBitmap>& bitmaps) {
434 if (favicon_downloader_.get())
435 favicon_downloader_->OnDidDownloadFavicon(id, image_url, errored,
436 requested_size, bitmaps);
259 } 437 }
260 438
261 void MetroPinTabHelper::UpdatePinnedStateForCurrentURL() { 439 void MetroPinTabHelper::UpdatePinnedStateForCurrentURL() {
262 HMODULE metro_module = base::win::GetMetroModule(); 440 HMODULE metro_module = base::win::GetMetroModule();
263 if (!metro_module) 441 if (!metro_module)
264 return; 442 return;
265 443
266 typedef BOOL (*MetroIsPinnedToStartScreen)(const string16&); 444 typedef BOOL (*MetroIsPinnedToStartScreen)(const string16&);
267 MetroIsPinnedToStartScreen metro_is_pinned_to_start_screen = 445 MetroIsPinnedToStartScreen metro_is_pinned_to_start_screen =
268 reinterpret_cast<MetroIsPinnedToStartScreen>( 446 reinterpret_cast<MetroIsPinnedToStartScreen>(
269 ::GetProcAddress(metro_module, "MetroIsPinnedToStartScreen")); 447 ::GetProcAddress(metro_module, "MetroIsPinnedToStartScreen"));
270 if (!metro_is_pinned_to_start_screen) { 448 if (!metro_is_pinned_to_start_screen) {
271 NOTREACHED(); 449 NOTREACHED();
272 return; 450 return;
273 } 451 }
274 452
275 GURL url = web_contents()->GetURL(); 453 GURL url = web_contents()->GetURL();
276 string16 tile_id = GenerateTileId(UTF8ToUTF16(url.spec())); 454 string16 tile_id = GenerateTileId(UTF8ToUTF16(url.spec()));
277 is_pinned_ = metro_is_pinned_to_start_screen(tile_id) != 0; 455 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 } 456 }
281 457
282 void MetroPinTabHelper::UnPinPageFromStartScreen() { 458 void MetroPinTabHelper::UnPinPageFromStartScreen() {
283 HMODULE metro_module = base::win::GetMetroModule(); 459 HMODULE metro_module = base::win::GetMetroModule();
284 if (!metro_module) 460 if (!metro_module)
285 return; 461 return;
286 462
287 typedef void (*MetroUnPinFromStartScreen)(const string16&); 463 typedef void (*MetroUnPinFromStartScreen)(const string16&);
288 MetroUnPinFromStartScreen metro_un_pin_from_start_screen = 464 MetroUnPinFromStartScreen metro_un_pin_from_start_screen =
289 reinterpret_cast<MetroUnPinFromStartScreen>( 465 reinterpret_cast<MetroUnPinFromStartScreen>(
290 ::GetProcAddress(metro_module, "MetroUnPinFromStartScreen")); 466 ::GetProcAddress(metro_module, "MetroUnPinFromStartScreen"));
291 if (!metro_un_pin_from_start_screen) { 467 if (!metro_un_pin_from_start_screen) {
292 NOTREACHED(); 468 NOTREACHED();
293 return; 469 return;
294 } 470 }
295 471
296 GURL url = web_contents()->GetURL(); 472 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())); 473 string16 tile_id = GenerateTileId(UTF8ToUTF16(url.spec()));
300 metro_un_pin_from_start_screen(tile_id); 474 metro_un_pin_from_start_screen(tile_id);
301 } 475 }
476
477 void MetroPinTabHelper::FaviconDownloaderFinished() {
478 favicon_downloader_.reset();
479 }
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