OLD | NEW |
---|---|
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/startup/startup_browser_creator_impl.h" | 5 #include "chrome/browser/ui/startup/startup_browser_creator_impl.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
11 #include <memory> | 11 #include <memory> |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 #include "apps/app_restore_service.h" | 14 #include "apps/app_restore_service.h" |
15 #include "apps/app_restore_service_factory.h" | 15 #include "apps/app_restore_service_factory.h" |
16 #include "base/bind.h" | 16 #include "base/bind.h" |
17 #include "base/bind_helpers.h" | 17 #include "base/bind_helpers.h" |
18 #include "base/command_line.h" | 18 #include "base/command_line.h" |
19 #include "base/compiler_specific.h" | 19 #include "base/compiler_specific.h" |
20 #include "base/environment.h" | 20 #include "base/environment.h" |
21 #include "base/feature_list.h" | |
21 #include "base/lazy_instance.h" | 22 #include "base/lazy_instance.h" |
22 #include "base/metrics/histogram_macros.h" | 23 #include "base/metrics/histogram_macros.h" |
23 #include "base/metrics/statistics_recorder.h" | 24 #include "base/metrics/statistics_recorder.h" |
24 #include "base/strings/string_number_conversions.h" | 25 #include "base/strings/string_number_conversions.h" |
25 #include "base/strings/string_split.h" | 26 #include "base/strings/string_split.h" |
26 #include "base/strings/string_util.h" | 27 #include "base/strings/string_util.h" |
27 #include "base/strings/stringprintf.h" | 28 #include "base/strings/stringprintf.h" |
28 #include "base/strings/utf_string_conversions.h" | 29 #include "base/strings/utf_string_conversions.h" |
29 #include "base/threading/thread_restrictions.h" | 30 #include "base/threading/thread_restrictions.h" |
30 #include "build/build_config.h" | 31 #include "build/build_config.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
63 #include "chrome/browser/ui/chrome_pages.h" | 64 #include "chrome/browser/ui/chrome_pages.h" |
64 #include "chrome/browser/ui/extensions/app_launch_params.h" | 65 #include "chrome/browser/ui/extensions/app_launch_params.h" |
65 #include "chrome/browser/ui/extensions/application_launch.h" | 66 #include "chrome/browser/ui/extensions/application_launch.h" |
66 #include "chrome/browser/ui/session_crashed_bubble.h" | 67 #include "chrome/browser/ui/session_crashed_bubble.h" |
67 #include "chrome/browser/ui/startup/bad_flags_prompt.h" | 68 #include "chrome/browser/ui/startup/bad_flags_prompt.h" |
68 #include "chrome/browser/ui/startup/default_browser_prompt.h" | 69 #include "chrome/browser/ui/startup/default_browser_prompt.h" |
69 #include "chrome/browser/ui/startup/google_api_keys_infobar_delegate.h" | 70 #include "chrome/browser/ui/startup/google_api_keys_infobar_delegate.h" |
70 #include "chrome/browser/ui/startup/obsolete_system_infobar_delegate.h" | 71 #include "chrome/browser/ui/startup/obsolete_system_infobar_delegate.h" |
71 #include "chrome/browser/ui/startup/session_crashed_infobar_delegate.h" | 72 #include "chrome/browser/ui/startup/session_crashed_infobar_delegate.h" |
72 #include "chrome/browser/ui/startup/startup_browser_creator.h" | 73 #include "chrome/browser/ui/startup/startup_browser_creator.h" |
74 #include "chrome/browser/ui/startup/startup_features.h" | |
73 #include "chrome/browser/ui/tabs/pinned_tab_codec.h" | 75 #include "chrome/browser/ui/tabs/pinned_tab_codec.h" |
74 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 76 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
75 #include "chrome/common/chrome_constants.h" | 77 #include "chrome/common/chrome_constants.h" |
76 #include "chrome/common/chrome_paths.h" | 78 #include "chrome/common/chrome_paths.h" |
77 #include "chrome/common/chrome_result_codes.h" | 79 #include "chrome/common/chrome_result_codes.h" |
78 #include "chrome/common/chrome_switches.h" | 80 #include "chrome/common/chrome_switches.h" |
79 #include "chrome/common/extensions/extension_constants.h" | 81 #include "chrome/common/extensions/extension_constants.h" |
80 #include "chrome/common/extensions/extension_metrics.h" | 82 #include "chrome/common/extensions/extension_metrics.h" |
81 #include "chrome/common/pref_names.h" | 83 #include "chrome/common/pref_names.h" |
82 #include "chrome/common/url_constants.h" | 84 #include "chrome/common/url_constants.h" |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
253 | 255 |
254 // TODO(koz): Consolidate this function and remove the special casing. | 256 // TODO(koz): Consolidate this function and remove the special casing. |
255 const Extension* GetPlatformApp(Profile* profile, | 257 const Extension* GetPlatformApp(Profile* profile, |
256 const std::string& extension_id) { | 258 const std::string& extension_id) { |
257 const Extension* extension = | 259 const Extension* extension = |
258 extensions::ExtensionRegistry::Get(profile)->GetExtensionById( | 260 extensions::ExtensionRegistry::Get(profile)->GetExtensionById( |
259 extension_id, extensions::ExtensionRegistry::EVERYTHING); | 261 extension_id, extensions::ExtensionRegistry::EVERYTHING); |
260 return extension && extension->is_platform_app() ? extension : NULL; | 262 return extension && extension->is_platform_app() ? extension : NULL; |
261 } | 263 } |
262 | 264 |
265 // Appends the contents of |from| to the end of |to|. | |
266 void AppendTabs(const StartupTabs& from, StartupTabs* to) { | |
267 if (!from.empty()) | |
268 to->insert(to->end(), from.begin(), from.end()); | |
269 } | |
270 | |
263 } // namespace | 271 } // namespace |
264 | 272 |
265 namespace internals { | 273 namespace internals { |
266 | 274 |
267 GURL GetTriggeredResetSettingsURL() { | 275 GURL GetTriggeredResetSettingsURL() { |
268 return GURL( | 276 return GURL( |
269 chrome::GetSettingsUrl(chrome::kTriggeredResetProfileSettingsSubPage)); | 277 chrome::GetSettingsUrl(chrome::kTriggeredResetProfileSettingsSubPage)); |
270 } | 278 } |
271 | 279 |
272 GURL GetWelcomePageURL() { | 280 GURL GetWelcomePageURL() { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
339 // URLs in that case. The user should see the window as an app, | 347 // URLs in that case. The user should see the window as an app, |
340 // not as chrome. | 348 // not as chrome. |
341 // Special case is when app switches are passed but we do want to restore | 349 // Special case is when app switches are passed but we do want to restore |
342 // session. In that case open app window + focus it after session is restored. | 350 // session. In that case open app window + focus it after session is restored. |
343 if (OpenApplicationWindow(profile)) { | 351 if (OpenApplicationWindow(profile)) { |
344 RecordLaunchModeHistogram(LM_AS_WEBAPP); | 352 RecordLaunchModeHistogram(LM_AS_WEBAPP); |
345 } else { | 353 } else { |
346 RecordLaunchModeHistogram(urls_to_open.empty() ? | 354 RecordLaunchModeHistogram(urls_to_open.empty() ? |
347 LM_TO_BE_DECIDED : LM_WITH_URLS); | 355 LM_TO_BE_DECIDED : LM_WITH_URLS); |
348 | 356 |
349 ProcessLaunchURLs(process_startup, urls_to_open); | 357 if (base::FeatureList::IsEnabled(features::kUseConsolidatedStartupFlow)) |
358 ProcessLaunchUrlsUsingConsolidatedFlow(process_startup, urls_to_open); | |
359 else | |
360 ProcessLaunchURLs(process_startup, urls_to_open); | |
350 | 361 |
351 if (command_line_.HasSwitch(switches::kInstallChromeApp)) { | 362 if (command_line_.HasSwitch(switches::kInstallChromeApp)) { |
352 install_chrome_app::InstallChromeApp( | 363 install_chrome_app::InstallChromeApp( |
353 command_line_.GetSwitchValueASCII(switches::kInstallChromeApp)); | 364 command_line_.GetSwitchValueASCII(switches::kInstallChromeApp)); |
354 } | 365 } |
355 | 366 |
356 // If this is an app launch, but we didn't open an app window, it may | 367 // If this is an app launch, but we didn't open an app window, it may |
357 // be an app tab. | 368 // be an app tab. |
358 OpenApplicationTab(profile); | 369 OpenApplicationTab(profile); |
359 | 370 |
(...skipping 22 matching lines...) Expand all Loading... | |
382 // TODO(gab): This could now run only during Active Setup (i.e. on explicit | 393 // TODO(gab): This could now run only during Active Setup (i.e. on explicit |
383 // Active Setup versioning and on OS upgrades) instead of every startup. | 394 // Active Setup versioning and on OS upgrades) instead of every startup. |
384 // http://crbug.com/577697 | 395 // http://crbug.com/577697 |
385 if (process_startup) | 396 if (process_startup) |
386 shell_integration::win::MigrateTaskbarPins(); | 397 shell_integration::win::MigrateTaskbarPins(); |
387 #endif // defined(OS_WIN) | 398 #endif // defined(OS_WIN) |
388 | 399 |
389 return true; | 400 return true; |
390 } | 401 } |
391 | 402 |
403 Browser* StartupBrowserCreatorImpl::OpenURLsInBrowser( | |
404 Browser* browser, | |
405 bool process_startup, | |
406 const std::vector<GURL>& urls) { | |
407 StartupTabs tabs; | |
408 UrlsToTabs(urls, &tabs); | |
409 return OpenTabsInBrowser(browser, process_startup, tabs); | |
410 } | |
411 | |
412 Browser* StartupBrowserCreatorImpl::OpenTabsInBrowser(Browser* browser, | |
413 bool process_startup, | |
414 const StartupTabs& tabs) { | |
415 DCHECK(!tabs.empty()); | |
416 | |
417 // If we don't yet have a profile, try to use the one we're given from | |
418 // |browser|. While we may not end up actually using |browser| (since it | |
419 // could be a popup window), we can at least use the profile. | |
420 if (!profile_ && browser) | |
421 profile_ = browser->profile(); | |
422 | |
423 if (!browser || !browser->is_type_tabbed()) | |
424 browser = new Browser(Browser::CreateParams(profile_)); | |
425 | |
426 bool first_tab = true; | |
427 ProtocolHandlerRegistry* registry = profile_ ? | |
428 ProtocolHandlerRegistryFactory::GetForBrowserContext(profile_) : NULL; | |
429 for (size_t i = 0; i < tabs.size(); ++i) { | |
430 // We skip URLs that we'd have to launch an external protocol handler for. | |
431 // This avoids us getting into an infinite loop asking ourselves to open | |
432 // a URL, should the handler be (incorrectly) configured to be us. Anyone | |
433 // asking us to open such a URL should really ask the handler directly. | |
434 bool handled_by_chrome = ProfileIOData::IsHandledURL(tabs[i].url) || | |
435 (registry && registry->IsHandledProtocol(tabs[i].url.scheme())); | |
436 if (!process_startup && !handled_by_chrome) | |
437 continue; | |
438 | |
439 int add_types = first_tab ? TabStripModel::ADD_ACTIVE : | |
440 TabStripModel::ADD_NONE; | |
441 add_types |= TabStripModel::ADD_FORCE_INDEX; | |
442 if (tabs[i].is_pinned) | |
443 add_types |= TabStripModel::ADD_PINNED; | |
444 | |
445 chrome::NavigateParams params(browser, tabs[i].url, | |
446 ui::PAGE_TRANSITION_AUTO_TOPLEVEL); | |
447 params.disposition = first_tab ? WindowOpenDisposition::NEW_FOREGROUND_TAB | |
448 : WindowOpenDisposition::NEW_BACKGROUND_TAB; | |
449 params.tabstrip_add_types = add_types; | |
450 | |
451 #if defined(ENABLE_RLZ) | |
452 if (process_startup && google_util::IsGoogleHomePageUrl(tabs[i].url)) { | |
453 params.extra_headers = rlz::RLZTracker::GetAccessPointHttpHeader( | |
454 rlz::RLZTracker::ChromeHomePage()); | |
455 } | |
456 #endif // defined(ENABLE_RLZ) | |
457 | |
458 chrome::Navigate(¶ms); | |
459 | |
460 first_tab = false; | |
461 } | |
462 if (!browser->tab_strip_model()->GetActiveWebContents()) { | |
463 // TODO(sky): this is a work around for 110909. Figure out why it's needed. | |
464 if (!browser->tab_strip_model()->count()) | |
465 chrome::AddTabAt(browser, GURL(), -1, true); | |
466 else | |
467 browser->tab_strip_model()->ActivateTabAt(0, false); | |
468 } | |
469 | |
470 // The default behavior is to show the window, as expressed by the default | |
471 // value of StartupBrowserCreated::show_main_browser_window_. If this was set | |
472 // to true ahead of this place, it means another task must have been spawned | |
473 // to take care of that. | |
474 if (!browser_creator_ || browser_creator_->show_main_browser_window()) | |
475 browser->window()->Show(); | |
476 | |
477 return browser; | |
478 } | |
479 | |
392 bool StartupBrowserCreatorImpl::IsAppLaunch(std::string* app_url, | 480 bool StartupBrowserCreatorImpl::IsAppLaunch(std::string* app_url, |
393 std::string* app_id) { | 481 std::string* app_id) { |
394 if (command_line_.HasSwitch(switches::kApp)) { | 482 if (command_line_.HasSwitch(switches::kApp)) { |
395 if (app_url) | 483 if (app_url) |
396 *app_url = command_line_.GetSwitchValueASCII(switches::kApp); | 484 *app_url = command_line_.GetSwitchValueASCII(switches::kApp); |
397 return true; | 485 return true; |
398 } | 486 } |
399 if (command_line_.HasSwitch(switches::kAppId)) { | 487 if (command_line_.HasSwitch(switches::kAppId)) { |
400 if (app_id) | 488 if (app_id) |
401 *app_id = command_line_.GetSwitchValueASCII(switches::kAppId); | 489 *app_id = command_line_.GetSwitchValueASCII(switches::kAppId); |
402 return true; | 490 return true; |
403 } | 491 } |
404 return false; | 492 return false; |
405 } | 493 } |
406 | 494 |
407 bool StartupBrowserCreatorImpl::OpenApplicationTab(Profile* profile) { | |
408 std::string app_id; | |
409 // App shortcuts to URLs always open in an app window. Because this | |
410 // function will open an app that should be in a tab, there is no need | |
411 // to look at the app URL. OpenApplicationWindow() will open app url | |
412 // shortcuts. | |
413 if (!IsAppLaunch(NULL, &app_id) || app_id.empty()) | |
414 return false; | |
415 | |
416 extensions::LaunchContainer launch_container; | |
417 const Extension* extension; | |
418 if (!GetAppLaunchContainer(profile, app_id, &extension, &launch_container)) | |
419 return false; | |
420 | |
421 // If the user doesn't want to open a tab, fail. | |
422 if (launch_container != extensions::LAUNCH_CONTAINER_TAB) | |
423 return false; | |
424 | |
425 RecordCmdLineAppHistogram(extension->GetType()); | |
426 | |
427 WebContents* app_tab = ::OpenApplication( | |
428 AppLaunchParams(profile, extension, extensions::LAUNCH_CONTAINER_TAB, | |
429 WindowOpenDisposition::NEW_FOREGROUND_TAB, | |
430 extensions::SOURCE_COMMAND_LINE)); | |
431 return (app_tab != NULL); | |
432 } | |
433 | |
434 bool StartupBrowserCreatorImpl::OpenApplicationWindow(Profile* profile) { | 495 bool StartupBrowserCreatorImpl::OpenApplicationWindow(Profile* profile) { |
435 std::string url_string, app_id; | 496 std::string url_string, app_id; |
436 if (!IsAppLaunch(&url_string, &app_id)) | 497 if (!IsAppLaunch(&url_string, &app_id)) |
437 return false; | 498 return false; |
438 | 499 |
439 // This can fail if the app_id is invalid. It can also fail if the | 500 // This can fail if the app_id is invalid. It can also fail if the |
440 // extension is external, and has not yet been installed. | 501 // extension is external, and has not yet been installed. |
441 // TODO(skerner): Do something reasonable here. Pop up a warning panel? | 502 // TODO(skerner): Do something reasonable here. Pop up a warning panel? |
442 // Open an URL to the gallery page of the extension id? | 503 // Open an URL to the gallery page of the extension id? |
443 if (!app_id.empty()) { | 504 if (!app_id.empty()) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
491 extensions::Manifest::TYPE_HOSTED_APP); | 552 extensions::Manifest::TYPE_HOSTED_APP); |
492 } | 553 } |
493 | 554 |
494 WebContents* app_tab = ::OpenAppShortcutWindow(profile, url); | 555 WebContents* app_tab = ::OpenAppShortcutWindow(profile, url); |
495 return (app_tab != NULL); | 556 return (app_tab != NULL); |
496 } | 557 } |
497 } | 558 } |
498 return false; | 559 return false; |
499 } | 560 } |
500 | 561 |
562 bool StartupBrowserCreatorImpl::OpenApplicationTab(Profile* profile) { | |
563 std::string app_id; | |
564 // App shortcuts to URLs always open in an app window. Because this | |
565 // function will open an app that should be in a tab, there is no need | |
566 // to look at the app URL. OpenApplicationWindow() will open app url | |
567 // shortcuts. | |
568 if (!IsAppLaunch(NULL, &app_id) || app_id.empty()) | |
569 return false; | |
570 | |
571 extensions::LaunchContainer launch_container; | |
572 const Extension* extension; | |
573 if (!GetAppLaunchContainer(profile, app_id, &extension, &launch_container)) | |
574 return false; | |
575 | |
576 // If the user doesn't want to open a tab, fail. | |
577 if (launch_container != extensions::LAUNCH_CONTAINER_TAB) | |
578 return false; | |
579 | |
580 RecordCmdLineAppHistogram(extension->GetType()); | |
581 | |
582 WebContents* app_tab = ::OpenApplication( | |
583 AppLaunchParams(profile, extension, extensions::LAUNCH_CONTAINER_TAB, | |
584 WindowOpenDisposition::NEW_FOREGROUND_TAB, | |
585 extensions::SOURCE_COMMAND_LINE)); | |
586 return (app_tab != NULL); | |
587 } | |
588 | |
589 void StartupBrowserCreatorImpl::ProcessLaunchUrlsUsingConsolidatedFlow( | |
590 bool process_startup, | |
591 const std::vector<GURL>& cmd_line_urls) { | |
592 // Don't open any browser windows if starting up in "background mode". | |
593 if (process_startup && command_line_.HasSwitch(switches::kNoStartupWindow)) | |
594 return; | |
595 | |
596 StartupTabs cmd_line_tabs; | |
597 UrlsToTabs(cmd_line_urls, &cmd_line_tabs); | |
598 | |
599 bool is_incognito = IncognitoModePrefs::ShouldLaunchIncognito( | |
600 command_line_, profile_->GetPrefs()); | |
601 bool is_post_crash_launch = HasPendingUncleanExit(profile_); | |
602 StartupTabs tabs = | |
603 DetermineStartupTabs(StartupTabProviderImpl(), cmd_line_tabs, | |
604 is_incognito, is_post_crash_launch); | |
605 | |
606 // TODO(tmartino): If this is not process startup, attempt to restore | |
607 // asynchronously and return here. This logic is self-contained in | |
608 // SessionService and therefore can't be combined with the other Browser | |
609 // creation logic. | |
610 | |
611 // TODO(tmartino): Function which determines what behavior of session | |
612 // restore, if any, is necessary, and passes the result to a new function | |
613 // which opens tabs in a restored or newly-created Browser accordingly. | |
614 // Incorporates code from ProcessStartupUrls. | |
615 | |
616 Browser* browser = OpenTabsInBrowser(nullptr, process_startup, tabs); | |
617 | |
618 // Finally, add info bars. | |
619 AddInfoBarsIfNecessary( | |
620 browser, process_startup ? chrome::startup::IS_PROCESS_STARTUP | |
621 : chrome::startup::IS_NOT_PROCESS_STARTUP); | |
622 } | |
623 | |
624 StartupTabs StartupBrowserCreatorImpl::DetermineStartupTabs( | |
625 const StartupTabProvider& provider, | |
626 const StartupTabs& cmd_line_tabs, | |
627 bool is_incognito, | |
628 bool is_post_crash_launch) { | |
629 // Only the New Tab Page or command line URLs may be shown in incognito mode. | |
630 // A similar policy exists for crash recovery launches, to prevent getting the | |
631 // user stuck in a crash loop. | |
632 if (is_incognito || is_post_crash_launch) { | |
633 if (cmd_line_tabs.empty()) | |
634 return StartupTabs({StartupTab(GURL(chrome::kChromeUINewTabURL), false)}); | |
635 return cmd_line_tabs; | |
636 } | |
637 | |
638 // A trigger on a profile may indicate that we should show a tab which | |
639 // offers to reset the user's settings. When this appears, it is first, and | |
640 // may be shown alongside command-line tabs. | |
641 StartupTabs tabs = provider.GetResetTriggerTabs(profile_); | |
642 | |
643 // URLs passed on the command line supersede all others. | |
644 AppendTabs(cmd_line_tabs, &tabs); | |
645 if (!cmd_line_tabs.empty()) | |
646 return tabs; | |
647 | |
648 // A Master Preferences file provided with this distribution may specify | |
649 // tabs to be displayed on first run, overriding all non-command-line tabs, | |
650 // including the profile reset tab. | |
651 StartupTabs distribution_tabs = | |
652 provider.GetDistributionFirstRunTabs(browser_creator_); | |
653 if (!distribution_tabs.empty()) | |
654 return distribution_tabs; | |
655 | |
656 // Policies for onboarding (e.g., first run) may show promotional and | |
657 // introductory content depending on a number of system status factors, | |
658 // including OS and whether or not this is First Run. | |
659 StartupTabs onboarding_tabs = provider.GetOnboardingTabs(); | |
660 AppendTabs(onboarding_tabs, &tabs); | |
661 | |
662 // If the user has set the preference indicating URLs to show on opening, | |
663 // read and add those. | |
664 StartupTabs prefs_tabs = provider.GetPreferencesTabs(); | |
665 AppendTabs(prefs_tabs, &tabs); | |
666 | |
667 // Potentially add the New Tab Page. Onboarding content is designed to | |
668 // replace (and eventually funnel the user to) the NTP. Likewise, URLs read | |
669 // from preferences are explicitly meant to override showing the NTP. | |
670 if (onboarding_tabs.empty() && prefs_tabs.empty()) | |
671 tabs.emplace_back(GURL(chrome::kChromeUINewTabURL), false); | |
672 | |
673 // Add any tabs which the user has previously pinned. | |
674 AppendTabs(provider.GetPinnedTabs(), &tabs); | |
675 | |
676 return tabs; | |
677 } | |
678 | |
679 void StartupBrowserCreatorImpl::AddUniqueURLs(const std::vector<GURL>& urls, | |
680 StartupTabs* tabs) { | |
681 size_t num_existing_tabs = tabs->size(); | |
682 for (size_t i = 0; i < urls.size(); ++i) { | |
grt (UTC plus 2)
2016/10/07 07:21:45
nit: this can be condensed a bit:
foreach (const
Peter Kasting
2016/10/10 23:50:29
Yep. And without spending much time thinking abou
| |
683 bool in_tabs = false; | |
684 for (size_t j = 0; j < num_existing_tabs; ++j) { | |
685 if (urls[i] == (*tabs)[j].url) { | |
686 in_tabs = true; | |
687 break; | |
688 } | |
689 } | |
690 if (!in_tabs) { | |
691 StartupTab tab; | |
692 tab.is_pinned = false; | |
693 tab.url = urls[i]; | |
694 tabs->push_back(tab); | |
695 } | |
696 } | |
697 } | |
698 | |
699 void StartupBrowserCreatorImpl::AddInfoBarsIfNecessary( | |
700 Browser* browser, | |
701 chrome::startup::IsProcessStartup is_process_startup) { | |
702 if (!browser || !profile_ || browser->tab_strip_model()->count() == 0) | |
703 return; | |
704 | |
705 if (HasPendingUncleanExit(browser->profile()) && | |
706 !SessionCrashedBubble::Show(browser)) { | |
707 SessionCrashedInfoBarDelegate::Create(browser); | |
708 } | |
709 | |
710 // The below info bars are only added to the first profile which is launched. | |
711 // Other profiles might be restoring the browsing sessions asynchronously, | |
712 // so we cannot add the info bars to the focused tabs here. | |
713 if (is_process_startup == chrome::startup::IS_PROCESS_STARTUP && | |
714 !command_line_.HasSwitch(switches::kTestType)) { | |
715 chrome::ShowBadFlagsPrompt(browser); | |
716 GoogleApiKeysInfoBarDelegate::Create(InfoBarService::FromWebContents( | |
717 browser->tab_strip_model()->GetActiveWebContents())); | |
718 ObsoleteSystemInfoBarDelegate::Create(InfoBarService::FromWebContents( | |
719 browser->tab_strip_model()->GetActiveWebContents())); | |
720 | |
721 #if !defined(OS_CHROMEOS) | |
722 if (!command_line_.HasSwitch(switches::kNoDefaultBrowserCheck)) { | |
723 // Generally, the default browser prompt should not be shown on first | |
724 // run. However, when the set-as-default dialog has been suppressed, we | |
725 // need to allow it. | |
726 if (!is_first_run_ || | |
727 (browser_creator_ && | |
728 browser_creator_->is_default_browser_dialog_suppressed())) { | |
729 chrome::ShowDefaultBrowserPrompt(profile_); | |
730 } | |
731 } | |
732 #endif | |
733 } | |
734 } | |
735 | |
736 void StartupBrowserCreatorImpl::RecordRapporOnStartupURLs( | |
737 const std::vector<GURL>& urls_to_open) { | |
738 for (const GURL& url : urls_to_open) { | |
739 rappor::SampleDomainAndRegistryFromGURL(g_browser_process->rappor_service(), | |
740 "Startup.BrowserLaunchURL", url); | |
741 } | |
742 } | |
743 | |
501 void StartupBrowserCreatorImpl::ProcessLaunchURLs( | 744 void StartupBrowserCreatorImpl::ProcessLaunchURLs( |
502 bool process_startup, | 745 bool process_startup, |
503 const std::vector<GURL>& urls_to_open) { | 746 const std::vector<GURL>& urls_to_open) { |
504 // Don't open any browser windows if we're starting up in "background mode". | 747 // Don't open any browser windows if we're starting up in "background mode". |
505 if (process_startup && command_line_.HasSwitch(switches::kNoStartupWindow)) | 748 if (process_startup && command_line_.HasSwitch(switches::kNoStartupWindow)) |
506 return; | 749 return; |
507 | 750 |
508 // Determine whether or not this launch must include the welcome page. | 751 // Determine whether or not this launch must include the welcome page. |
509 InitializeWelcomeRunType(urls_to_open); | 752 InitializeWelcomeRunType(urls_to_open); |
510 | 753 |
511 // TODO(tapted): Move this to startup_browser_creator_win.cc after refactor. | |
512 #if defined(OS_WIN) | |
513 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { | |
514 // See if there are apps for this profile that should be launched on startup | |
515 // due to a switch from Metro mode. | |
516 app_metro_launch::HandleAppLaunchForMetroRestart(profile_); | |
517 } | |
518 #endif | |
519 | |
520 if (process_startup && ProcessStartupURLs(urls_to_open)) { | 754 if (process_startup && ProcessStartupURLs(urls_to_open)) { |
521 // ProcessStartupURLs processed the urls, nothing else to do. | 755 // ProcessStartupURLs processed the urls, nothing else to do. |
522 return; | 756 return; |
523 } | 757 } |
524 | 758 |
525 chrome::startup::IsProcessStartup is_process_startup = process_startup ? | 759 chrome::startup::IsProcessStartup is_process_startup = process_startup ? |
526 chrome::startup::IS_PROCESS_STARTUP : | 760 chrome::startup::IS_PROCESS_STARTUP : |
527 chrome::startup::IS_NOT_PROCESS_STARTUP; | 761 chrome::startup::IS_NOT_PROCESS_STARTUP; |
528 if (!process_startup) { | 762 if (!process_startup) { |
529 // Even if we're not starting a new process, this may conceptually be | 763 // Even if we're not starting a new process, this may conceptually be |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
686 AddUniqueURLs(pref.urls, &tabs); | 920 AddUniqueURLs(pref.urls, &tabs); |
687 } | 921 } |
688 | 922 |
689 if (tabs.empty()) | 923 if (tabs.empty()) |
690 return NULL; | 924 return NULL; |
691 | 925 |
692 Browser* browser = OpenTabsInBrowser(NULL, true, tabs); | 926 Browser* browser = OpenTabsInBrowser(NULL, true, tabs); |
693 return browser; | 927 return browser; |
694 } | 928 } |
695 | 929 |
696 void StartupBrowserCreatorImpl::AddUniqueURLs(const std::vector<GURL>& urls, | |
697 StartupTabs* tabs) { | |
698 size_t num_existing_tabs = tabs->size(); | |
699 for (size_t i = 0; i < urls.size(); ++i) { | |
700 bool in_tabs = false; | |
701 for (size_t j = 0; j < num_existing_tabs; ++j) { | |
702 if (urls[i] == (*tabs)[j].url) { | |
703 in_tabs = true; | |
704 break; | |
705 } | |
706 } | |
707 if (!in_tabs) { | |
708 StartupTab tab; | |
709 tab.is_pinned = false; | |
710 tab.url = urls[i]; | |
711 tabs->push_back(tab); | |
712 } | |
713 } | |
714 } | |
715 | |
716 Browser* StartupBrowserCreatorImpl::OpenURLsInBrowser( | |
717 Browser* browser, | |
718 bool process_startup, | |
719 const std::vector<GURL>& urls) { | |
720 StartupTabs tabs; | |
721 UrlsToTabs(urls, &tabs); | |
722 return OpenTabsInBrowser(browser, process_startup, tabs); | |
723 } | |
724 | |
725 Browser* StartupBrowserCreatorImpl::OpenTabsInBrowser(Browser* browser, | |
726 bool process_startup, | |
727 const StartupTabs& tabs) { | |
728 DCHECK(!tabs.empty()); | |
729 | |
730 // If we don't yet have a profile, try to use the one we're given from | |
731 // |browser|. While we may not end up actually using |browser| (since it | |
732 // could be a popup window), we can at least use the profile. | |
733 if (!profile_ && browser) | |
734 profile_ = browser->profile(); | |
735 | |
736 if (!browser || !browser->is_type_tabbed()) | |
737 browser = new Browser(Browser::CreateParams(profile_)); | |
738 | |
739 bool first_tab = true; | |
740 ProtocolHandlerRegistry* registry = profile_ ? | |
741 ProtocolHandlerRegistryFactory::GetForBrowserContext(profile_) : NULL; | |
742 for (size_t i = 0; i < tabs.size(); ++i) { | |
743 // We skip URLs that we'd have to launch an external protocol handler for. | |
744 // This avoids us getting into an infinite loop asking ourselves to open | |
745 // a URL, should the handler be (incorrectly) configured to be us. Anyone | |
746 // asking us to open such a URL should really ask the handler directly. | |
747 bool handled_by_chrome = ProfileIOData::IsHandledURL(tabs[i].url) || | |
748 (registry && registry->IsHandledProtocol(tabs[i].url.scheme())); | |
749 if (!process_startup && !handled_by_chrome) | |
750 continue; | |
751 | |
752 int add_types = first_tab ? TabStripModel::ADD_ACTIVE : | |
753 TabStripModel::ADD_NONE; | |
754 add_types |= TabStripModel::ADD_FORCE_INDEX; | |
755 if (tabs[i].is_pinned) | |
756 add_types |= TabStripModel::ADD_PINNED; | |
757 | |
758 chrome::NavigateParams params(browser, tabs[i].url, | |
759 ui::PAGE_TRANSITION_AUTO_TOPLEVEL); | |
760 params.disposition = first_tab ? WindowOpenDisposition::NEW_FOREGROUND_TAB | |
761 : WindowOpenDisposition::NEW_BACKGROUND_TAB; | |
762 params.tabstrip_add_types = add_types; | |
763 | |
764 #if defined(ENABLE_RLZ) | |
765 if (process_startup && google_util::IsGoogleHomePageUrl(tabs[i].url)) { | |
766 params.extra_headers = rlz::RLZTracker::GetAccessPointHttpHeader( | |
767 rlz::RLZTracker::ChromeHomePage()); | |
768 } | |
769 #endif // defined(ENABLE_RLZ) | |
770 | |
771 chrome::Navigate(¶ms); | |
772 | |
773 first_tab = false; | |
774 } | |
775 if (!browser->tab_strip_model()->GetActiveWebContents()) { | |
776 // TODO(sky): this is a work around for 110909. Figure out why it's needed. | |
777 if (!browser->tab_strip_model()->count()) | |
778 chrome::AddTabAt(browser, GURL(), -1, true); | |
779 else | |
780 browser->tab_strip_model()->ActivateTabAt(0, false); | |
781 } | |
782 | |
783 // The default behavior is to show the window, as expressed by the default | |
784 // value of StartupBrowserCreated::show_main_browser_window_. If this was set | |
785 // to true ahead of this place, it means another task must have been spawned | |
786 // to take care of that. | |
787 if (!browser_creator_ || browser_creator_->show_main_browser_window()) | |
788 browser->window()->Show(); | |
789 | |
790 return browser; | |
791 } | |
792 | |
793 void StartupBrowserCreatorImpl::AddInfoBarsIfNecessary( | |
794 Browser* browser, | |
795 chrome::startup::IsProcessStartup is_process_startup) { | |
796 if (!browser || !profile_ || browser->tab_strip_model()->count() == 0) | |
797 return; | |
798 | |
799 if (HasPendingUncleanExit(browser->profile()) && | |
800 !SessionCrashedBubble::Show(browser)) { | |
801 SessionCrashedInfoBarDelegate::Create(browser); | |
802 } | |
803 | |
804 // The below info bars are only added to the first profile which is launched. | |
805 // Other profiles might be restoring the browsing sessions asynchronously, | |
806 // so we cannot add the info bars to the focused tabs here. | |
807 if (is_process_startup == chrome::startup::IS_PROCESS_STARTUP && | |
808 !command_line_.HasSwitch(switches::kTestType)) { | |
809 chrome::ShowBadFlagsPrompt(browser); | |
810 GoogleApiKeysInfoBarDelegate::Create(InfoBarService::FromWebContents( | |
811 browser->tab_strip_model()->GetActiveWebContents())); | |
812 ObsoleteSystemInfoBarDelegate::Create(InfoBarService::FromWebContents( | |
813 browser->tab_strip_model()->GetActiveWebContents())); | |
814 | |
815 #if !defined(OS_CHROMEOS) | |
816 if (!command_line_.HasSwitch(switches::kNoDefaultBrowserCheck)) { | |
817 // Generally, the default browser prompt should not be shown on first | |
818 // run. However, when the set-as-default dialog has been suppressed, we | |
819 // need to allow it. | |
820 if (!is_first_run_ || | |
821 (browser_creator_ && | |
822 browser_creator_->is_default_browser_dialog_suppressed())) { | |
823 chrome::ShowDefaultBrowserPrompt(profile_); | |
824 } | |
825 } | |
826 #endif | |
827 } | |
828 } | |
829 | |
830 void StartupBrowserCreatorImpl::AddStartupURLs( | 930 void StartupBrowserCreatorImpl::AddStartupURLs( |
831 std::vector<GURL>* startup_urls) const { | 931 std::vector<GURL>* startup_urls) const { |
832 // TODO(atwilson): Simplify the logic that decides which tabs to open on | |
833 // start-up and make it more consistent. http://crbug.com/248883 | |
834 | |
835 // If we have urls specified by the first run master preferences use them | 932 // If we have urls specified by the first run master preferences use them |
836 // and nothing else. | 933 // and nothing else. |
837 if (browser_creator_ && startup_urls->empty()) { | 934 if (browser_creator_ && startup_urls->empty()) { |
838 if (!browser_creator_->first_run_tabs_.empty()) { | 935 if (!browser_creator_->first_run_tabs_.empty()) { |
839 std::vector<GURL>::iterator it = | 936 std::vector<GURL>::iterator it = |
840 browser_creator_->first_run_tabs_.begin(); | 937 browser_creator_->first_run_tabs_.begin(); |
841 while (it != browser_creator_->first_run_tabs_.end()) { | 938 while (it != browser_creator_->first_run_tabs_.end()) { |
842 // Replace magic names for the actual urls. | 939 // Replace magic names for the actual urls. |
843 if (it->host() == "new_tab_page") { | 940 if (it->host() == "new_tab_page") { |
844 startup_urls->push_back(GURL(chrome::kChromeUINewTabURL)); | 941 startup_urls->push_back(GURL(chrome::kChromeUINewTabURL)); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
972 | 1069 |
973 // Remember that the welcome page was shown for this OS version. | 1070 // Remember that the welcome page was shown for this OS version. |
974 local_state->SetString(prefs::kLastWelcomedOSVersion, this_version); | 1071 local_state->SetString(prefs::kLastWelcomedOSVersion, this_version); |
975 #else // OS_WIN | 1072 #else // OS_WIN |
976 // Show the welcome page as the last tab only on first-run. | 1073 // Show the welcome page as the last tab only on first-run. |
977 if (first_run::ShouldShowWelcomePage()) | 1074 if (first_run::ShouldShowWelcomePage()) |
978 welcome_run_type_ = WelcomeRunType::FIRST_RUN_LAST_TAB; | 1075 welcome_run_type_ = WelcomeRunType::FIRST_RUN_LAST_TAB; |
979 #endif // !OS_WIN | 1076 #endif // !OS_WIN |
980 } | 1077 } |
981 | 1078 |
982 void StartupBrowserCreatorImpl::RecordRapporOnStartupURLs( | |
983 const std::vector<GURL>& urls_to_open) { | |
984 for (const GURL& url : urls_to_open) { | |
985 rappor::SampleDomainAndRegistryFromGURL(g_browser_process->rappor_service(), | |
986 "Startup.BrowserLaunchURL", url); | |
987 } | |
988 } | |
989 | |
990 bool StartupBrowserCreatorImpl::ProfileHasResetTrigger() const { | 1079 bool StartupBrowserCreatorImpl::ProfileHasResetTrigger() const { |
991 bool has_reset_trigger = false; | 1080 bool has_reset_trigger = false; |
992 #if defined(OS_WIN) | 1081 #if defined(OS_WIN) |
993 TriggeredProfileResetter* triggered_profile_resetter = | 1082 TriggeredProfileResetter* triggered_profile_resetter = |
994 TriggeredProfileResetterFactory::GetForBrowserContext(profile_); | 1083 TriggeredProfileResetterFactory::GetForBrowserContext(profile_); |
995 // TriggeredProfileResetter instance will be nullptr for incognito profiles. | 1084 // TriggeredProfileResetter instance will be nullptr for incognito profiles. |
996 if (triggered_profile_resetter) { | 1085 if (triggered_profile_resetter) { |
997 has_reset_trigger = triggered_profile_resetter->HasResetTrigger(); | 1086 has_reset_trigger = triggered_profile_resetter->HasResetTrigger(); |
998 } | 1087 } |
999 #endif // defined(OS_WIN) | 1088 #endif // defined(OS_WIN) |
1000 return has_reset_trigger; | 1089 return has_reset_trigger; |
1001 } | 1090 } |
OLD | NEW |