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

Side by Side Diff: win8/metro_driver/secondary_tile.cc

Issue 11198025: Site specific secondary tiles for Windows 8. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleanup Created 8 years, 2 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) 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 "stdafx.h" 5 #include "stdafx.h"
6 #include "secondary_tile.h" 6 #include "secondary_tile.h"
7 7
8 #include <windows.ui.startscreen.h> 8 #include <windows.ui.startscreen.h>
9 9
10 #include "base/base_paths.h" 10 #include "base/base_paths.h"
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/file_path.h" 12 #include "base/file_path.h"
13 #include "base/file_util.h"
13 #include "base/logging.h" 14 #include "base/logging.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"
19 #include "chrome/common/chrome_paths.h"
17 #include "crypto/sha2.h" 20 #include "crypto/sha2.h"
18 #include "googleurl/src/gurl.h" 21 #include "googleurl/src/gurl.h"
19 #include "win8/metro_driver/chrome_app_view.h" 22 #include "metro_driver/chrome_app_view.h"
20 #include "win8/metro_driver/winrt_utils.h" 23 #include "metro_driver/winrt_utils.h"
24 #include "third_party/skia/include/core/SkPaint.h"
25 #include "ui/base/layout.h"
26 #include "ui/gfx/canvas.h"
27 #include "ui/gfx/codec/png_codec.h"
28 #include "ui/gfx/color_analysis.h"
29 #include "ui/gfx/color_utils.h"
30 #include "ui/gfx/rect.h"
31 #include "ui/gfx/size.h"
21 32
22 namespace { 33 namespace {
23 34
24 string16 GenerateTileId(const string16& url_str) { 35 string16 GenerateTileId(const string16& url_str) {
25 uint8 hash[crypto::kSHA256Length]; 36 uint8 hash[crypto::kSHA256Length];
26 crypto::SHA256HashString(UTF16ToUTF8(url_str), hash, sizeof(hash)); 37 crypto::SHA256HashString(UTF16ToUTF8(url_str), hash, sizeof(hash));
27 std::string hash_str = base::HexEncode(hash, sizeof(hash)); 38 std::string hash_str = base::HexEncode(hash, sizeof(hash));
28 return UTF8ToUTF16(hash_str); 39 return UTF8ToUTF16(hash_str);
29 } 40 }
30 41
31 string16 GetLogoUrlString() { 42 bool CreateLogoFromFavicon(const SkBitmap* icon_bitmap,
32 FilePath module_path; 43 const FilePath& tile_path) {
33 PathService::Get(base::DIR_MODULE, &module_path); 44 static int k_logo_width = 120;
sky 2012/10/19 16:09:56 constants like this are kFooBar.
benwells 2012/10/22 06:20:47 Done.
34 string16 scheme(L"ms-appx:///"); 45 static int k_logo_height = 120;
35 return scheme.append(module_path.BaseName().value()) 46 static int k_box_width = 40;
36 .append(L"/SecondaryTile.png"); 47 static int k_box_height = 40;
48 static int k_caption_height = 20;
49 static double k_box_fade = 0.75;
cpu_(ooo_6.6-7.5) 2012/10/19 19:39:08 I don't see any metro specific calls here. Wouldn'
benwells 2012/10/22 06:20:47 OK, yeah that sounds like a great idea! It will ma
50
51 // Use a canvas to paint the tile logo.
52 gfx::Canvas canvas(gfx::Size(k_logo_width, k_logo_height),
53 ui::SCALE_FACTOR_100P,
54 true);
55 // Fill the tile logo with the average color from bitmap. To do this we need
56 // to work out the 'average color' which is calculated using PNG encoded data
57 // of the bitmap.
58 SkPaint paint;
59 std::vector<unsigned char> icon_png;
60 if (!gfx::PNGCodec::EncodeBGRASkBitmap(*icon_bitmap, true, &icon_png))
61 return false;
62
63 scoped_refptr<base::RefCountedStaticMemory> icon_mem(
64 new base::RefCountedStaticMemory(&icon_png.front(), icon_png.size()));
65 color_utils::GridSampler sampler;
66 SkColor mean_color =
67 color_utils::CalculateKMeanColorOfPNG(icon_mem, 100, 665, sampler);
68 paint.setColor(mean_color);
69 canvas.DrawRect(gfx::Rect(0, 0, k_logo_width, k_logo_height), paint);
70
71 // Now paint a faded square for the favicon to go in.
72 color_utils::HSL shift = {-1, -1, k_box_fade};
73 paint.setColor(color_utils::HSLShift(mean_color, shift));
74 int box_left = (k_logo_width - k_box_width) / 2;
75 int box_top = (k_logo_height - k_caption_height - k_box_height) / 2;
76 canvas.DrawRect(gfx::Rect(box_left, box_top, k_box_width, k_box_height),
77 paint);
78
79 // Now paint the favicon into the tile, leaving some room at the bottom for
80 // the caption.
81 gfx::ImageSkia icon_image(*icon_bitmap);
sky 2012/10/19 16:09:56 Maybe this should take an ImageSkia rather than Sk
benwells 2012/10/22 06:20:47 Done.
82 int left = (k_logo_width - icon_image.width()) / 2;
83 int top = (k_logo_height - k_caption_height - icon_image.height()) / 2;
84 canvas.DrawImageInt(icon_image, left, top);
85
86 SkBitmap logo_bitmap = canvas.ExtractImageRep().sk_bitmap();
87 std::vector<unsigned char> logo_png;
88 if (!gfx::PNGCodec::EncodeBGRASkBitmap(logo_bitmap, true, &logo_png))
89 return false;
90
91 return file_util::WriteFile(tile_path,
92 reinterpret_cast<char*>(&logo_png[0]),
93 logo_png.size()) > 0;
94 }
95
96 string16 GetLogoUrlString(const SkBitmap* favicon, const string16& tile_id) {
97 FilePath logo_dir;
98 DCHECK(PathService::Get(chrome::DIR_USER_DATA, &logo_dir));
99 logo_dir = logo_dir.Append(L"TileImages");
100 if (!file_util::DirectoryExists(logo_dir) &&
101 !file_util::CreateDirectory(logo_dir))
102 return string16();
103
104 string16 scheme(L"file:///");
105 if (favicon) {
106 FilePath logo_path = logo_dir.Append(tile_id)
107 .ReplaceExtension(L".png");
108 if (CreateLogoFromFavicon(favicon, logo_path))
109 return scheme.append(logo_path.value());
110 }
111
112 // Use default tile image. If it doesn't exist, copy it out of the install
113 // folder. The version in the install folder is not used as it may disappear
114 // after an upgrade, causing tiles to lose their images if Windows rebuilds
115 // its tile image cache.
116 static const wchar_t kDefaultLogoFileName[] = L"SecondaryTile.png";
117 FilePath logo_path = logo_dir.Append(kDefaultLogoFileName);
118 if (!file_util::PathExists(logo_path)) {
119 FilePath default_logo_path;
120 DCHECK(PathService::Get(base::DIR_MODULE, &default_logo_path));
121 default_logo_path = default_logo_path.Append(kDefaultLogoFileName);
122 if (!file_util::CopyFile(default_logo_path, logo_path))
sky 2012/10/19 16:09:56 What thread is this run on?
benwells 2012/10/22 06:20:47 This is all happening in the metro thread. I'll pu
123 return string16();
124 }
125
126 return scheme.append(logo_path.value());
37 } 127 }
38 128
39 BOOL IsPinnedToStartScreen(const string16& url_str) { 129 BOOL IsPinnedToStartScreen(const string16& url_str) {
40 mswr::ComPtr<winui::StartScreen::ISecondaryTileStatics> tile_statics; 130 mswr::ComPtr<winui::StartScreen::ISecondaryTileStatics> tile_statics;
41 HRESULT hr = winrt_utils::CreateActivationFactory( 131 HRESULT hr = winrt_utils::CreateActivationFactory(
42 RuntimeClass_Windows_UI_StartScreen_SecondaryTile, 132 RuntimeClass_Windows_UI_StartScreen_SecondaryTile,
43 tile_statics.GetAddressOf()); 133 tile_statics.GetAddressOf());
44 CheckHR(hr, "Failed to create instance of ISecondaryTileStatics"); 134 CheckHR(hr, "Failed to create instance of ISecondaryTileStatics");
45 135
46 boolean exists; 136 boolean exists;
(...skipping 23 matching lines...) Expand all
70 160
71 typedef winfoundtn::IAsyncOperationCompletedHandler<bool> RequestDoneType; 161 typedef winfoundtn::IAsyncOperationCompletedHandler<bool> RequestDoneType;
72 mswr::ComPtr<RequestDoneType> handler(mswr::Callback<RequestDoneType>( 162 mswr::ComPtr<RequestDoneType> handler(mswr::Callback<RequestDoneType>(
73 globals.view, &ChromeAppView::TileRequestCreateDone)); 163 globals.view, &ChromeAppView::TileRequestCreateDone));
74 DCHECK(handler.Get() != NULL); 164 DCHECK(handler.Get() != NULL);
75 hr = completion->put_Completed(handler.Get()); 165 hr = completion->put_Completed(handler.Get());
76 CheckHR(hr, "Failed to put_Completed"); 166 CheckHR(hr, "Failed to put_Completed");
77 } 167 }
78 168
79 void CreateTileOnStartScreen(const string16& title_str, 169 void CreateTileOnStartScreen(const string16& title_str,
80 const string16& url_str) { 170 const string16& url_str,
171 const SkBitmap* bitmap) {
81 VLOG(1) << __FUNCTION__; 172 VLOG(1) << __FUNCTION__;
173
82 mswr::ComPtr<winui::StartScreen::ISecondaryTileFactory> tile_factory; 174 mswr::ComPtr<winui::StartScreen::ISecondaryTileFactory> tile_factory;
83 HRESULT hr = winrt_utils::CreateActivationFactory( 175 HRESULT hr = winrt_utils::CreateActivationFactory(
84 RuntimeClass_Windows_UI_StartScreen_SecondaryTile, 176 RuntimeClass_Windows_UI_StartScreen_SecondaryTile,
85 tile_factory.GetAddressOf()); 177 tile_factory.GetAddressOf());
86 CheckHR(hr, "Failed to create instance of ISecondaryTileFactory"); 178 CheckHR(hr, "Failed to create instance of ISecondaryTileFactory");
87 179
88 winui::StartScreen::TileOptions options = 180 winui::StartScreen::TileOptions options =
89 winui::StartScreen::TileOptions_ShowNameOnLogo; 181 winui::StartScreen::TileOptions_ShowNameOnLogo;
90 mswrw::HString title; 182 mswrw::HString title;
91 title.Attach(MakeHString(title_str)); 183 title.Attach(MakeHString(title_str));
184
185 string16 id_str = GenerateTileId(url_str);
92 mswrw::HString id; 186 mswrw::HString id;
93 id.Attach(MakeHString(GenerateTileId(url_str))); 187 id.Attach(MakeHString(id_str));
188
94 mswrw::HString args; 189 mswrw::HString args;
95 // The url is just passed into the tile agruments as is. Metro and desktop 190 // The url is just passed into the tile agruments as is. Metro and desktop
96 // chrome will see the arguments as command line parameters. 191 // chrome will see the arguments as command line parameters.
97 // A GURL is used to ensure any spaces are properly escaped. 192 // A GURL is used to ensure any spaces are properly escaped.
98 GURL url(url_str); 193 GURL url(url_str);
99 args.Attach(MakeHString(UTF8ToUTF16(url.spec()))); 194 args.Attach(MakeHString(UTF8ToUTF16(url.spec())));
100 195
101 mswr::ComPtr<winfoundtn::IUriRuntimeClassFactory> uri_factory; 196 mswr::ComPtr<winfoundtn::IUriRuntimeClassFactory> uri_factory;
102 hr = winrt_utils::CreateActivationFactory( 197 hr = winrt_utils::CreateActivationFactory(
103 RuntimeClass_Windows_Foundation_Uri, 198 RuntimeClass_Windows_Foundation_Uri,
104 uri_factory.GetAddressOf()); 199 uri_factory.GetAddressOf());
105 CheckHR(hr, "Failed to create URIFactory"); 200 CheckHR(hr, "Failed to create URIFactory");
106 201
107 mswrw::HString logo_url; 202 mswrw::HString logo_url;
108 logo_url.Attach(MakeHString(GetLogoUrlString())); 203 logo_url.Attach(MakeHString(GetLogoUrlString(bitmap, id_str)));
109 mswr::ComPtr<winfoundtn::IUriRuntimeClass> uri; 204 mswr::ComPtr<winfoundtn::IUriRuntimeClass> uri;
110 hr = uri_factory->CreateUri(logo_url.Get(), &uri); 205 hr = uri_factory->CreateUri(logo_url.Get(), &uri);
111 CheckHR(hr, "Failed to create URI"); 206 CheckHR(hr, "Failed to create URI");
112 207
113 mswr::ComPtr<winui::StartScreen::ISecondaryTile> tile; 208 mswr::ComPtr<winui::StartScreen::ISecondaryTile> tile;
114 hr = tile_factory->CreateTile(id.Get(), 209 hr = tile_factory->CreateTile(id.Get(),
115 title.Get(), 210 title.Get(),
116 title.Get(), 211 title.Get(),
117 args.Get(), 212 args.Get(),
118 options, 213 options,
(...skipping 16 matching lines...) Expand all
135 CheckHR(hr, "Failed to put_Completed"); 230 CheckHR(hr, "Failed to put_Completed");
136 } 231 }
137 232
138 void TogglePinnedToStartScreen(const string16& title_str, 233 void TogglePinnedToStartScreen(const string16& title_str,
139 const string16& url_str) { 234 const string16& url_str) {
140 if (IsPinnedToStartScreen(url_str)) { 235 if (IsPinnedToStartScreen(url_str)) {
141 DeleteTileFromStartScreen(url_str); 236 DeleteTileFromStartScreen(url_str);
142 return; 237 return;
143 } 238 }
144 239
145 CreateTileOnStartScreen(title_str, url_str); 240 CreateTileOnStartScreen(title_str, url_str, NULL);
146 } 241 }
147 242
148 } // namespace 243 } // namespace
149 244
150 BOOL MetroIsPinnedToStartScreen(const string16& url) { 245 BOOL MetroIsPinnedToStartScreen(const string16& url) {
151 VLOG(1) << __FUNCTION__ << " url: " << url; 246 VLOG(1) << __FUNCTION__ << " url: " << url;
152 return IsPinnedToStartScreen(url); 247 return IsPinnedToStartScreen(url);
153 } 248 }
154 249
155 void MetroTogglePinnedToStartScreen(const string16& title, 250 void MetroTogglePinnedToStartScreen(const string16& title,
156 const string16& url) { 251 const string16& url) {
157 DVLOG(1) << __FUNCTION__ << " title:" << title << " url: " << url; 252 DVLOG(1) << __FUNCTION__ << " title:" << title << " url: " << url;
158 globals.appview_msg_loop->PostTask( 253 globals.appview_msg_loop->PostTask(
159 FROM_HERE, base::Bind(&TogglePinnedToStartScreen, title, url)); 254 FROM_HERE, base::Bind(&TogglePinnedToStartScreen, title, url));
160 } 255 }
256
257 void MetroUnPinFromStartScreen(const string16& url) {
258 globals.appview_msg_loop->PostTask(
259 FROM_HERE, base::Bind(&DeleteTileFromStartScreen, url));
260 }
261
262 void MetroPinToStartScreen(const string16& title,
263 const string16& url,
264 const SkBitmap* bitmap) {
265 globals.appview_msg_loop->PostTask(
266 FROM_HERE, base::Bind(&CreateTileOnStartScreen,
267 title,
268 url,
269 bitmap));
270 }
OLDNEW
« win8/metro_driver/chrome_app_view.cc ('K') | « win8/metro_driver/secondary_tile.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698