Chromium Code Reviews| 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 |