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

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

Issue 899443002: Create bookmark apps at the end of the process. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Feedback Created 5 years, 10 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/bookmark_app_helper.h" 5 #include "chrome/browser/extensions/bookmark_app_helper.h"
6 6
7 #include <cctype> 7 #include <cctype>
8 8
9 #include "base/prefs/pref_service.h"
9 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/extensions/crx_installer.h" 12 #include "chrome/browser/extensions/crx_installer.h"
11 #include "chrome/browser/extensions/extension_service.h" 13 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/extensions/favicon_downloader.h" 14 #include "chrome/browser/extensions/favicon_downloader.h"
15 #include "chrome/browser/extensions/launch_util.h"
13 #include "chrome/browser/extensions/tab_helper.h" 16 #include "chrome/browser/extensions/tab_helper.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/ui/app_list/app_list_service.h"
19 #include "chrome/browser/ui/app_list/app_list_util.h"
20 #include "chrome/browser/ui/browser_finder.h"
21 #include "chrome/browser/ui/browser_window.h"
22 #include "chrome/browser/ui/host_desktop.h"
14 #include "chrome/common/extensions/extension_constants.h" 23 #include "chrome/common/extensions/extension_constants.h"
15 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" 24 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
25 #include "chrome/common/url_constants.h"
16 #include "content/public/browser/notification_service.h" 26 #include "content/public/browser/notification_service.h"
17 #include "content/public/browser/notification_source.h" 27 #include "content/public/browser/notification_source.h"
18 #include "content/public/browser/web_contents.h" 28 #include "content/public/browser/web_contents.h"
29 #include "extensions/browser/extension_system.h"
19 #include "extensions/browser/image_loader.h" 30 #include "extensions/browser/image_loader.h"
20 #include "extensions/browser/notification_types.h" 31 #include "extensions/browser/notification_types.h"
32 #include "extensions/browser/pref_names.h"
21 #include "extensions/common/constants.h" 33 #include "extensions/common/constants.h"
22 #include "extensions/common/extension.h" 34 #include "extensions/common/extension.h"
23 #include "extensions/common/manifest_handlers/icons_handler.h" 35 #include "extensions/common/manifest_handlers/icons_handler.h"
24 #include "extensions/common/url_pattern.h" 36 #include "extensions/common/url_pattern.h"
25 #include "grit/platform_locale_settings.h" 37 #include "grit/platform_locale_settings.h"
26 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" 38 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
27 #include "skia/ext/image_operations.h" 39 #include "skia/ext/image_operations.h"
28 #include "skia/ext/platform_canvas.h" 40 #include "skia/ext/platform_canvas.h"
29 #include "third_party/skia/include/core/SkBitmap.h" 41 #include "third_party/skia/include/core/SkBitmap.h"
30 #include "ui/base/l10n/l10n_util.h" 42 #include "ui/base/l10n/l10n_util.h"
31 #include "ui/gfx/canvas.h" 43 #include "ui/gfx/canvas.h"
32 #include "ui/gfx/color_analysis.h" 44 #include "ui/gfx/color_analysis.h"
33 #include "ui/gfx/color_utils.h" 45 #include "ui/gfx/color_utils.h"
34 #include "ui/gfx/font.h" 46 #include "ui/gfx/font.h"
35 #include "ui/gfx/font_list.h" 47 #include "ui/gfx/font_list.h"
36 #include "ui/gfx/geometry/rect.h" 48 #include "ui/gfx/geometry/rect.h"
37 #include "ui/gfx/image/canvas_image_source.h" 49 #include "ui/gfx/image/canvas_image_source.h"
38 #include "ui/gfx/image/image.h" 50 #include "ui/gfx/image/image.h"
39 #include "ui/gfx/image/image_family.h" 51 #include "ui/gfx/image/image_family.h"
40 52
53 #if defined(OS_MACOSX)
54 #include "base/command_line.h"
55 #include "chrome/browser/web_applications/web_app_mac.h"
56 #include "chrome/common/chrome_switches.h"
57 #endif
58
59 #if defined(USE_ASH)
60 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
61 #endif
62
41 namespace { 63 namespace {
42 64
43 // Overlays a shortcut icon over the bottom left corner of a given image. 65 // Overlays a shortcut icon over the bottom left corner of a given image.
44 class GeneratedIconImageSource : public gfx::CanvasImageSource { 66 class GeneratedIconImageSource : public gfx::CanvasImageSource {
45 public: 67 public:
46 explicit GeneratedIconImageSource(char letter, SkColor color, int output_size) 68 explicit GeneratedIconImageSource(char letter, SkColor color, int output_size)
47 : gfx::CanvasImageSource(gfx::Size(output_size, output_size), false), 69 : gfx::CanvasImageSource(gfx::Size(output_size, output_size), false),
48 letter_(letter), 70 letter_(letter),
49 color_(color), 71 color_(color),
50 output_size_(output_size) {} 72 output_size_(output_size) {}
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 // Do nothing if there is already an icon of |output_size|. 233 // Do nothing if there is already an icon of |output_size|.
212 if (bitmaps->count(output_size)) 234 if (bitmaps->count(output_size))
213 return; 235 return;
214 236
215 gfx::ImageSkia icon_image( 237 gfx::ImageSkia icon_image(
216 new GeneratedIconImageSource(letter, color, output_size), 238 new GeneratedIconImageSource(letter, color, output_size),
217 gfx::Size(output_size, output_size)); 239 gfx::Size(output_size, output_size));
218 icon_image.bitmap()->deepCopyTo(&(*bitmaps)[output_size]); 240 icon_image.bitmap()->deepCopyTo(&(*bitmaps)[output_size]);
219 } 241 }
220 242
221 BookmarkAppHelper::BookmarkAppHelper(ExtensionService* service, 243 BookmarkAppHelper::BookmarkAppHelper(Profile* profile,
222 WebApplicationInfo web_app_info, 244 WebApplicationInfo web_app_info,
223 content::WebContents* contents) 245 content::WebContents* contents)
224 : contents_(contents), 246 : profile_(profile),
247 contents_(contents),
225 web_app_info_(web_app_info), 248 web_app_info_(web_app_info),
226 crx_installer_(extensions::CrxInstaller::CreateSilent(service)) { 249 crx_installer_(extensions::CrxInstaller::CreateSilent(
250 ExtensionSystem::Get(profile)->extension_service())) {
251 web_app_info_.open_as_window =
252 profile_->GetPrefs()->GetInteger(
253 extensions::pref_names::kBookmarkAppCreationLaunchType) ==
254 extensions::LAUNCH_TYPE_WINDOW;
255
227 registrar_.Add(this, 256 registrar_.Add(this,
228 extensions::NOTIFICATION_CRX_INSTALLER_DONE, 257 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
229 content::Source<CrxInstaller>(crx_installer_.get())); 258 content::Source<CrxInstaller>(crx_installer_.get()));
230 259
231 registrar_.Add(this, 260 registrar_.Add(this,
232 extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR, 261 extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR,
233 content::Source<CrxInstaller>(crx_installer_.get())); 262 content::Source<CrxInstaller>(crx_installer_.get()));
234 263
235 crx_installer_->set_error_on_unsupported_requirements(true); 264 crx_installer_->set_error_on_unsupported_requirements(true);
236 } 265 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 favicon_downloader_->Start(); 301 favicon_downloader_->Start();
273 } 302 }
274 303
275 void BookmarkAppHelper::OnIconsDownloaded( 304 void BookmarkAppHelper::OnIconsDownloaded(
276 bool success, 305 bool success,
277 const std::map<GURL, std::vector<SkBitmap> >& bitmaps) { 306 const std::map<GURL, std::vector<SkBitmap> >& bitmaps) {
278 // The tab has navigated away during the icon download. Cancel the bookmark 307 // The tab has navigated away during the icon download. Cancel the bookmark
279 // app creation. 308 // app creation.
280 if (!success) { 309 if (!success) {
281 favicon_downloader_.reset(); 310 favicon_downloader_.reset();
282 callback_.Run(NULL, web_app_info_); 311 callback_.Run(nullptr, web_app_info_);
283 return; 312 return;
284 } 313 }
285 314
286 std::vector<SkBitmap> downloaded_icons; 315 std::vector<SkBitmap> downloaded_icons;
287 for (FaviconDownloader::FaviconMap::const_iterator map_it = bitmaps.begin(); 316 for (FaviconDownloader::FaviconMap::const_iterator map_it = bitmaps.begin();
288 map_it != bitmaps.end(); 317 map_it != bitmaps.end();
289 ++map_it) { 318 ++map_it) {
290 for (std::vector<SkBitmap>::const_iterator bitmap_it = 319 for (std::vector<SkBitmap>::const_iterator bitmap_it =
291 map_it->second.begin(); 320 map_it->second.begin();
292 bitmap_it != map_it->second.end(); 321 bitmap_it != map_it->second.end();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 357
329 std::map<int, SkBitmap> generated_icons; 358 std::map<int, SkBitmap> generated_icons;
330 // Icons are always generated, replacing the icons that were downloaded. This 359 // Icons are always generated, replacing the icons that were downloaded. This
331 // is done so that the icons are consistent across machines. 360 // is done so that the icons are consistent across machines.
332 // TODO(benwells): Use blob sync once it is available to sync the downloaded 361 // TODO(benwells): Use blob sync once it is available to sync the downloaded
333 // icons, and then only generate when there are required sizes missing. 362 // icons, and then only generate when there are required sizes missing.
334 GenerateIcons(generate_sizes, web_app_info_.app_url, 363 GenerateIcons(generate_sizes, web_app_info_.app_url,
335 web_app_info_.generated_icon_color, &generated_icons); 364 web_app_info_.generated_icon_color, &generated_icons);
336 365
337 ReplaceWebAppIcons(generated_icons, &web_app_info_); 366 ReplaceWebAppIcons(generated_icons, &web_app_info_);
367 favicon_downloader_.reset();
338 368
339 // Install the app. 369 if (!contents_) {
340 crx_installer_->InstallWebApp(web_app_info_); 370 // The web contents can be null in tests.
341 favicon_downloader_.reset(); 371 OnBubbleCompleted(true, web_app_info_);
372 return;
373 }
374
375 Browser* browser = chrome::FindBrowserWithWebContents(contents_);
376 if (!browser) {
377 // The browser can be null in tests.
378 OnBubbleCompleted(true, web_app_info_);
379 return;
380 }
381 browser->window()->ShowBookmarkAppBubble(
382 web_app_info_, base::Bind(&BookmarkAppHelper::OnBubbleCompleted,
383 base::Unretained(this)));
384 }
385
386 void BookmarkAppHelper::OnBubbleCompleted(
387 bool user_accepted,
388 const WebApplicationInfo& web_app_info) {
389 if (user_accepted) {
390 web_app_info_ = web_app_info;
391 crx_installer_->InstallWebApp(web_app_info_);
392 } else {
393 callback_.Run(nullptr, web_app_info_);
394 }
395 }
396
397 void BookmarkAppHelper::FinishInstallation(const Extension* extension) {
398 // Set the default 'open as' preference for use next time the dialog is
399 // shown.
400 extensions::LaunchType launch_type = web_app_info_.open_as_window
401 ? extensions::LAUNCH_TYPE_WINDOW
402 : extensions::LAUNCH_TYPE_REGULAR;
403 profile_->GetPrefs()->SetInteger(
404 extensions::pref_names::kBookmarkAppCreationLaunchType, launch_type);
405
406 // Set the launcher type for the app.
407 extensions::SetLaunchType(profile_, extension->id(), launch_type);
408
409 if (!contents_) {
410 // The web contents can be null in tests.
411 callback_.Run(extension, web_app_info_);
412 return;
413 }
414
415 Browser* browser = chrome::FindBrowserWithWebContents(contents_);
416 if (!browser) {
417 // The browser can be null in tests.
418 callback_.Run(extension, web_app_info_);
419 return;
420 }
421
422 // Pin the app to the shelf on Ash.
423 chrome::HostDesktopType desktop = browser->host_desktop_type();
424 #if defined(USE_ASH)
425 if (desktop == chrome::HOST_DESKTOP_TYPE_ASH)
426 ChromeLauncherController::instance()->PinAppWithID(extension->id());
427 #endif
428
429 // Show the newly installed app in the app launcher, in finder (on Mac) or
430 // chrome://apps.
431 Profile* current_profile = profile_->GetOriginalProfile();
432 if (IsAppLauncherEnabled()) {
433 AppListService::Get(desktop)
434 ->ShowForAppInstall(current_profile, extension->id(), false);
435 #if defined(OS_MACOSX)
436 } else if (base::CommandLine::ForCurrentProcess()->HasSwitch(
437 switches::kEnableHostedAppShimCreation)) {
438 web_app::RevealAppShimInFinderForApp(profile_, extension);
439 #endif
440 } else {
441 chrome::NavigateParams params(current_profile,
442 GURL(chrome::kChromeUIAppsURL),
443 ui::PAGE_TRANSITION_LINK);
444 params.disposition = SINGLETON_TAB;
445 chrome::Navigate(&params);
446
447 content::NotificationService::current()->Notify(
448 chrome::NOTIFICATION_APP_INSTALLED_TO_NTP,
449 content::Source<content::WebContents>(params.target_contents),
450 content::Details<const std::string>(&extension->id()));
451 }
452
453 callback_.Run(extension, web_app_info_);
342 } 454 }
343 455
344 void BookmarkAppHelper::Observe(int type, 456 void BookmarkAppHelper::Observe(int type,
345 const content::NotificationSource& source, 457 const content::NotificationSource& source,
346 const content::NotificationDetails& details) { 458 const content::NotificationDetails& details) {
347 switch (type) { 459 switch (type) {
348 case extensions::NOTIFICATION_CRX_INSTALLER_DONE: { 460 case extensions::NOTIFICATION_CRX_INSTALLER_DONE: {
349 const Extension* extension = 461 const Extension* extension =
350 content::Details<const Extension>(details).ptr(); 462 content::Details<const Extension>(details).ptr();
351 DCHECK(extension); 463 DCHECK(extension);
352 DCHECK_EQ(AppLaunchInfo::GetLaunchWebURL(extension), 464 DCHECK_EQ(AppLaunchInfo::GetLaunchWebURL(extension),
353 web_app_info_.app_url); 465 web_app_info_.app_url);
354 callback_.Run(extension, web_app_info_); 466 FinishInstallation(extension);
355 break; 467 break;
356 } 468 }
357 case extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR: 469 case extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR:
358 callback_.Run(NULL, web_app_info_); 470 callback_.Run(nullptr, web_app_info_);
359 break; 471 break;
360 default: 472 default:
361 NOTREACHED(); 473 NOTREACHED();
362 break; 474 break;
363 } 475 }
364 } 476 }
365 477
366 void CreateOrUpdateBookmarkApp(ExtensionService* service, 478 void CreateOrUpdateBookmarkApp(ExtensionService* service,
367 WebApplicationInfo* web_app_info) { 479 WebApplicationInfo* web_app_info) {
368 scoped_refptr<extensions::CrxInstaller> installer( 480 scoped_refptr<extensions::CrxInstaller> installer(
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 extension, info_list, base::Bind(&OnIconsLoaded, web_app_info, callback)); 523 extension, info_list, base::Bind(&OnIconsLoaded, web_app_info, callback));
412 } 524 }
413 525
414 bool IsValidBookmarkAppUrl(const GURL& url) { 526 bool IsValidBookmarkAppUrl(const GURL& url) {
415 URLPattern origin_only_pattern(Extension::kValidWebExtentSchemes); 527 URLPattern origin_only_pattern(Extension::kValidWebExtentSchemes);
416 origin_only_pattern.SetMatchAllURLs(true); 528 origin_only_pattern.SetMatchAllURLs(true);
417 return url.is_valid() && origin_only_pattern.MatchesURL(url); 529 return url.is_valid() && origin_only_pattern.MatchesURL(url);
418 } 530 }
419 531
420 } // namespace extensions 532 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/bookmark_app_helper.h ('k') | chrome/browser/extensions/bookmark_app_helper_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698