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

Side by Side Diff: chrome/browser/ui/startup/startup_browser_creator_impl.cc

Issue 2457653003: Completing refactor of startup_browser_creator_impl (Closed)
Patch Set: Addressing pkasting comments Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/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 <iterator>
11 #include <memory> 12 #include <memory>
12 #include <vector> 13 #include <vector>
13 14
14 #include "apps/app_restore_service.h" 15 #include "apps/app_restore_service.h"
15 #include "apps/app_restore_service_factory.h" 16 #include "apps/app_restore_service_factory.h"
17 #include "base/auto_reset.h"
16 #include "base/bind.h" 18 #include "base/bind.h"
17 #include "base/bind_helpers.h" 19 #include "base/bind_helpers.h"
18 #include "base/command_line.h" 20 #include "base/command_line.h"
19 #include "base/compiler_specific.h" 21 #include "base/compiler_specific.h"
20 #include "base/environment.h" 22 #include "base/environment.h"
21 #include "base/feature_list.h" 23 #include "base/feature_list.h"
22 #include "base/lazy_instance.h" 24 #include "base/lazy_instance.h"
23 #include "base/metrics/histogram_macros.h" 25 #include "base/metrics/histogram_macros.h"
24 #include "base/metrics/statistics_recorder.h" 26 #include "base/metrics/statistics_recorder.h"
25 #include "base/strings/string_number_conversions.h" 27 #include "base/strings/string_number_conversions.h"
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 185
184 void UrlsToTabs(const std::vector<GURL>& urls, StartupTabs* tabs) { 186 void UrlsToTabs(const std::vector<GURL>& urls, StartupTabs* tabs) {
185 for (size_t i = 0; i < urls.size(); ++i) { 187 for (size_t i = 0; i < urls.size(); ++i) {
186 StartupTab tab; 188 StartupTab tab;
187 tab.is_pinned = false; 189 tab.is_pinned = false;
188 tab.url = urls[i]; 190 tab.url = urls[i];
189 tabs->push_back(tab); 191 tabs->push_back(tab);
190 } 192 }
191 } 193 }
192 194
195 std::vector<GURL> TabsToUrls(const StartupTabs& tabs) {
196 std::vector<GURL> urls;
197 urls.reserve(tabs.size());
198 std::transform(tabs.begin(), tabs.end(), std::back_inserter(urls),
199 [](const StartupTab& tab) { return tab.url; });
200 return urls;
201 }
202
193 // Return true if the command line option --app-id is used. Set 203 // Return true if the command line option --app-id is used. Set
194 // |out_extension| to the app to open, and |out_launch_container| 204 // |out_extension| to the app to open, and |out_launch_container|
195 // to the type of window into which the app should be open. 205 // to the type of window into which the app should be open.
196 bool GetAppLaunchContainer( 206 bool GetAppLaunchContainer(
197 Profile* profile, 207 Profile* profile,
198 const std::string& app_id, 208 const std::string& app_id,
199 const Extension** out_extension, 209 const Extension** out_extension,
200 extensions::LaunchContainer* out_launch_container) { 210 extensions::LaunchContainer* out_launch_container) {
201 211
202 const Extension* extension = extensions::ExtensionRegistry::Get( 212 const Extension* extension = extensions::ExtensionRegistry::Get(
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 extension_id, extensions::ExtensionRegistry::EVERYTHING); 271 extension_id, extensions::ExtensionRegistry::EVERYTHING);
262 return extension && extension->is_platform_app() ? extension : NULL; 272 return extension && extension->is_platform_app() ? extension : NULL;
263 } 273 }
264 274
265 // Appends the contents of |from| to the end of |to|. 275 // Appends the contents of |from| to the end of |to|.
266 void AppendTabs(const StartupTabs& from, StartupTabs* to) { 276 void AppendTabs(const StartupTabs& from, StartupTabs* to) {
267 if (!from.empty()) 277 if (!from.empty())
268 to->insert(to->end(), from.begin(), from.end()); 278 to->insert(to->end(), from.begin(), from.end());
269 } 279 }
270 280
281 // Determines whether the Consolidated startup flow should be used, based on
282 // OS, OS version, and the kUseConsolidatedStartupFlow Feature.
283 bool UseConsolidatedFlow() {
284 #if defined(OS_WIN)
285 // TODO(tmartino): Enable for Windows 10+ once relevant Win 10-specific logic
286 // is added to StartupTabProvider.
287 if (base::win::GetVersion() >= base::win::VERSION_WIN10)
288 return false;
289 #endif // defined(OS_WIN)
290 return base::FeatureList::IsEnabled(features::kUseConsolidatedStartupFlow);
291 }
292
271 } // namespace 293 } // namespace
272 294
273 namespace internals { 295 namespace internals {
274 296
275 GURL GetTriggeredResetSettingsURL() { 297 GURL GetTriggeredResetSettingsURL() {
276 return GURL( 298 return GURL(
277 chrome::GetSettingsUrl(chrome::kTriggeredResetProfileSettingsSubPage)); 299 chrome::GetSettingsUrl(chrome::kTriggeredResetProfileSettingsSubPage));
278 } 300 }
279 301
280 GURL GetWelcomePageURL() { 302 GURL GetWelcomePageURL() {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 // URLs in that case. The user should see the window as an app, 369 // URLs in that case. The user should see the window as an app,
348 // not as chrome. 370 // not as chrome.
349 // Special case is when app switches are passed but we do want to restore 371 // Special case is when app switches are passed but we do want to restore
350 // session. In that case open app window + focus it after session is restored. 372 // session. In that case open app window + focus it after session is restored.
351 if (OpenApplicationWindow(profile)) { 373 if (OpenApplicationWindow(profile)) {
352 RecordLaunchModeHistogram(LM_AS_WEBAPP); 374 RecordLaunchModeHistogram(LM_AS_WEBAPP);
353 } else { 375 } else {
354 RecordLaunchModeHistogram(urls_to_open.empty() ? 376 RecordLaunchModeHistogram(urls_to_open.empty() ?
355 LM_TO_BE_DECIDED : LM_WITH_URLS); 377 LM_TO_BE_DECIDED : LM_WITH_URLS);
356 378
357 if (base::FeatureList::IsEnabled(features::kUseConsolidatedStartupFlow)) 379 if (UseConsolidatedFlow())
358 ProcessLaunchUrlsUsingConsolidatedFlow(process_startup, urls_to_open); 380 ProcessLaunchUrlsUsingConsolidatedFlow(process_startup, urls_to_open);
359 else 381 else
360 ProcessLaunchURLs(process_startup, urls_to_open); 382 ProcessLaunchURLs(process_startup, urls_to_open);
361 383
362 if (command_line_.HasSwitch(switches::kInstallChromeApp)) { 384 if (command_line_.HasSwitch(switches::kInstallChromeApp)) {
363 install_chrome_app::InstallChromeApp( 385 install_chrome_app::InstallChromeApp(
364 command_line_.GetSwitchValueASCII(switches::kInstallChromeApp)); 386 command_line_.GetSwitchValueASCII(switches::kInstallChromeApp));
365 } 387 }
366 388
367 // If this is an app launch, but we didn't open an app window, it may 389 // If this is an app launch, but we didn't open an app window, it may
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 void StartupBrowserCreatorImpl::ProcessLaunchUrlsUsingConsolidatedFlow( 611 void StartupBrowserCreatorImpl::ProcessLaunchUrlsUsingConsolidatedFlow(
590 bool process_startup, 612 bool process_startup,
591 const std::vector<GURL>& cmd_line_urls) { 613 const std::vector<GURL>& cmd_line_urls) {
592 // Don't open any browser windows if starting up in "background mode". 614 // Don't open any browser windows if starting up in "background mode".
593 if (process_startup && command_line_.HasSwitch(switches::kNoStartupWindow)) 615 if (process_startup && command_line_.HasSwitch(switches::kNoStartupWindow))
594 return; 616 return;
595 617
596 StartupTabs cmd_line_tabs; 618 StartupTabs cmd_line_tabs;
597 UrlsToTabs(cmd_line_urls, &cmd_line_tabs); 619 UrlsToTabs(cmd_line_urls, &cmd_line_tabs);
598 620
599 bool is_incognito = IncognitoModePrefs::ShouldLaunchIncognito( 621 bool is_ephemeral_profile =
600 command_line_, profile_->GetPrefs()); 622 profile_->GetProfileType() != Profile::ProfileType::REGULAR_PROFILE;
601 bool is_post_crash_launch = HasPendingUncleanExit(profile_); 623 bool is_post_crash_launch = HasPendingUncleanExit(profile_);
602 StartupTabs tabs = 624 StartupTabs tabs =
603 DetermineStartupTabs(StartupTabProviderImpl(), cmd_line_tabs, 625 DetermineStartupTabs(StartupTabProviderImpl(), cmd_line_tabs,
604 is_incognito, is_post_crash_launch); 626 is_ephemeral_profile, is_post_crash_launch);
605 627
606 // TODO(tmartino): If this is not process startup, attempt to restore 628 // Return immediately if we start an async restore, since the remainder of
607 // asynchronously and return here. This logic is self-contained in 629 // that process is self-contained.
608 // SessionService and therefore can't be combined with the other Browser 630 if (MaybeAsyncRestore(tabs, process_startup, is_post_crash_launch))
609 // creation logic. 631 return;
610 632
611 // TODO(tmartino): Function which determines what behavior of session 633 BrowserOpenBehavior behavior = DetermineBrowserOpenBehavior(
612 // restore, if any, is necessary, and passes the result to a new function 634 StartupBrowserCreator::GetSessionStartupPref(command_line_, profile_),
613 // which opens tabs in a restored or newly-created Browser accordingly. 635 process_startup, is_post_crash_launch,
614 // Incorporates code from ProcessStartupUrls. 636 command_line_.HasSwitch(switches::kRestoreLastSession),
637 command_line_.HasSwitch(switches::kOpenInNewWindow),
638 !cmd_line_tabs.empty());
615 639
616 Browser* browser = OpenTabsInBrowser(nullptr, process_startup, tabs); 640 uint32_t restore_options = 0;
641 if (behavior == BrowserOpenBehavior::SYNCHRONOUS_RESTORE) {
642 #if defined(OS_MACOSX)
643 bool was_mac_login_or_resume = base::mac::WasLaunchedAsLoginOrResumeItem();
644 #else
645 bool was_mac_login_or_resume = false;
646 #endif
647 restore_options = DetermineSynchronousRestoreOptions(
648 browser_defaults::kAlwaysCreateTabbedBrowserOnSessionRestore,
649 base::CommandLine::ForCurrentProcess()->HasSwitch(
650 switches::kCreateBrowserOnStartupForTests),
651 was_mac_login_or_resume);
652 }
653
654 Browser* browser = RestoreOrCreateBrowser(
655 tabs, behavior, restore_options, process_startup, is_post_crash_launch);
617 656
618 // Finally, add info bars. 657 // Finally, add info bars.
619 AddInfoBarsIfNecessary( 658 AddInfoBarsIfNecessary(
620 browser, process_startup ? chrome::startup::IS_PROCESS_STARTUP 659 browser, process_startup ? chrome::startup::IS_PROCESS_STARTUP
621 : chrome::startup::IS_NOT_PROCESS_STARTUP); 660 : chrome::startup::IS_NOT_PROCESS_STARTUP);
622 } 661 }
623 662
624 StartupTabs StartupBrowserCreatorImpl::DetermineStartupTabs( 663 StartupTabs StartupBrowserCreatorImpl::DetermineStartupTabs(
625 const StartupTabProvider& provider, 664 const StartupTabProvider& provider,
626 const StartupTabs& cmd_line_tabs, 665 const StartupTabs& cmd_line_tabs,
627 bool is_incognito, 666 bool is_ephemeral_profile,
628 bool is_post_crash_launch) { 667 bool is_post_crash_launch) {
629 // Only the New Tab Page or command line URLs may be shown in incognito mode. 668 // 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 669 // A similar policy exists for crash recovery launches, to prevent getting the
631 // user stuck in a crash loop. 670 // user stuck in a crash loop.
632 if (is_incognito || is_post_crash_launch) { 671 if (is_ephemeral_profile || is_post_crash_launch) {
633 if (cmd_line_tabs.empty()) 672 if (cmd_line_tabs.empty())
634 return StartupTabs({StartupTab(GURL(chrome::kChromeUINewTabURL), false)}); 673 return StartupTabs({StartupTab(GURL(chrome::kChromeUINewTabURL), false)});
635 return cmd_line_tabs; 674 return cmd_line_tabs;
636 } 675 }
637 676
638 // A trigger on a profile may indicate that we should show a tab which 677 // 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 678 // offers to reset the user's settings. When this appears, it is first, and
640 // may be shown alongside command-line tabs. 679 // may be shown alongside command-line tabs.
641 StartupTabs tabs = provider.GetResetTriggerTabs(profile_); 680 StartupTabs tabs = provider.GetResetTriggerTabs(profile_);
642 681
(...skipping 15 matching lines...) Expand all
658 // including OS and whether or not this is First Run. 697 // including OS and whether or not this is First Run.
659 StartupTabs onboarding_tabs = provider.GetOnboardingTabs(); 698 StartupTabs onboarding_tabs = provider.GetOnboardingTabs();
660 AppendTabs(onboarding_tabs, &tabs); 699 AppendTabs(onboarding_tabs, &tabs);
661 700
662 // If the user has set the preference indicating URLs to show on opening, 701 // If the user has set the preference indicating URLs to show on opening,
663 // read and add those. 702 // read and add those.
664 StartupTabs prefs_tabs = provider.GetPreferencesTabs(command_line_, profile_); 703 StartupTabs prefs_tabs = provider.GetPreferencesTabs(command_line_, profile_);
665 AppendTabs(prefs_tabs, &tabs); 704 AppendTabs(prefs_tabs, &tabs);
666 705
667 // Potentially add the New Tab Page. Onboarding content is designed to 706 // Potentially add the New Tab Page. Onboarding content is designed to
668 // replace (and eventually funnel the user to) the NTP. Likewise, URLs read 707 // replace (and eventually funnel the user to) the NTP. Likewise, URLs
669 // from preferences are explicitly meant to override showing the NTP. 708 // from preferences are explicitly meant to override showing the NTP.
670 if (onboarding_tabs.empty() && prefs_tabs.empty()) 709 if (onboarding_tabs.empty() && prefs_tabs.empty())
671 tabs.emplace_back(GURL(chrome::kChromeUINewTabURL), false); 710 AppendTabs(provider.GetNewTabPageTabs(command_line_, profile_), &tabs);
672 711
673 // Add any tabs which the user has previously pinned. 712 // Maybe add any tabs which the user has previously pinned.
674 AppendTabs(provider.GetPinnedTabs(profile_), &tabs); 713 AppendTabs(provider.GetPinnedTabs(command_line_, profile_), &tabs);
675 714
676 return tabs; 715 return tabs;
677 } 716 }
678 717
718 bool StartupBrowserCreatorImpl::MaybeAsyncRestore(const StartupTabs& tabs,
719 bool process_startup,
720 bool is_post_crash_launch) {
721 // Restore is performed synchronously on startup, and is never performed when
722 // launching after crashing.
723 if (process_startup || is_post_crash_launch)
724 return false;
725
726 // Note: there's no session service in incognito or guest mode.
727 SessionService* service =
728 SessionServiceFactory::GetForProfileForSessionRestore(profile_);
729
730 return service && service->RestoreIfNecessary(TabsToUrls(tabs));
731 }
732
733 Browser* StartupBrowserCreatorImpl::RestoreOrCreateBrowser(
734 const StartupTabs& tabs,
735 BrowserOpenBehavior behavior,
736 uint32_t restore_options,
737 bool process_startup,
738 bool is_post_crash_launch) {
739 Browser* browser = nullptr;
740 if (behavior == BrowserOpenBehavior::SYNCHRONOUS_RESTORE) {
741 browser = SessionRestore::RestoreSession(profile_, nullptr, restore_options,
742 TabsToUrls(tabs));
743 if (browser)
744 return browser;
745 } else if (behavior == BrowserOpenBehavior::USE_EXISTING) {
746 browser = chrome::FindTabbedBrowser(profile_, process_startup);
747 }
748
749 base::AutoReset<bool> synchronous_launch_resetter(
750 &StartupBrowserCreator::in_synchronous_profile_launch_, true);
751
752 // OpenTabsInBrowser requires at least one tab be passed. As a fallback to
753 // prevent a crash, use the NTP if |tabs| is empty.
754 browser = OpenTabsInBrowser(
755 browser, process_startup,
756 (tabs.empty()
757 ? StartupTabs({StartupTab(GURL(chrome::kChromeUINewTabURL), false)})
758 : tabs));
759
760 // Now that a restore is no longer possible, it is safe to clear DOM storage,
761 // unless this is a crash recovery.
762 if (!is_post_crash_launch) {
763 content::BrowserContext::GetDefaultStoragePartition(profile_)
764 ->GetDOMStorageContext()
765 ->StartScavengingUnusedSessionStorage();
766 }
767
768 return browser;
769 }
770
679 void StartupBrowserCreatorImpl::AddUniqueURLs(const std::vector<GURL>& urls, 771 void StartupBrowserCreatorImpl::AddUniqueURLs(const std::vector<GURL>& urls,
680 StartupTabs* tabs) { 772 StartupTabs* tabs) {
681 size_t num_existing_tabs = tabs->size(); 773 size_t num_existing_tabs = tabs->size();
682 for (size_t i = 0; i < urls.size(); ++i) { 774 for (size_t i = 0; i < urls.size(); ++i) {
683 bool in_tabs = false; 775 bool in_tabs = false;
684 for (size_t j = 0; j < num_existing_tabs; ++j) { 776 for (size_t j = 0; j < num_existing_tabs; ++j) {
685 if (urls[i] == (*tabs)[j].url) { 777 if (urls[i] == (*tabs)[j].url) {
686 in_tabs = true; 778 in_tabs = true;
687 break; 779 break;
688 } 780 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 } 826 }
735 827
736 void StartupBrowserCreatorImpl::RecordRapporOnStartupURLs( 828 void StartupBrowserCreatorImpl::RecordRapporOnStartupURLs(
737 const std::vector<GURL>& urls_to_open) { 829 const std::vector<GURL>& urls_to_open) {
738 for (const GURL& url : urls_to_open) { 830 for (const GURL& url : urls_to_open) {
739 rappor::SampleDomainAndRegistryFromGURL(g_browser_process->rappor_service(), 831 rappor::SampleDomainAndRegistryFromGURL(g_browser_process->rappor_service(),
740 "Startup.BrowserLaunchURL", url); 832 "Startup.BrowserLaunchURL", url);
741 } 833 }
742 } 834 }
743 835
836 // static
837 StartupBrowserCreatorImpl::BrowserOpenBehavior
838 StartupBrowserCreatorImpl::DetermineBrowserOpenBehavior(
839 const SessionStartupPref& pref,
840 bool process_startup,
841 bool is_post_crash_launch,
842 bool has_restore_switch,
843 bool has_new_window_switch,
844 bool has_cmd_line_tabs) {
845 if (!process_startup) {
846 // For existing processes, restore would have happened before invoking this
847 // function. If Chrome was launched with passed URLs, assume these should
848 // be appended to an existing window if possible, unless overridden by a
849 // switch.
850 return (has_cmd_line_tabs && !has_new_window_switch)
851 ? BrowserOpenBehavior::USE_EXISTING
852 : BrowserOpenBehavior::NEW;
853 }
854
855 if (pref.type == SessionStartupPref::LAST) {
856 // Don't perform a session restore on a post-crash launch, as this could
857 // cause a crash loop. These checks can be overridden by a switch.
858 // TODO(crbug.com/647851): Group this check with the logic in
859 // GetSessionStartupPref.
860 if (!is_post_crash_launch || has_restore_switch)
861 return BrowserOpenBehavior::SYNCHRONOUS_RESTORE;
862 }
863
864 return BrowserOpenBehavior::NEW;
865 }
866
867 // static
868 uint32_t StartupBrowserCreatorImpl::DetermineSynchronousRestoreOptions(
869 bool has_create_browser_default,
870 bool has_create_browser_switch,
871 bool was_mac_login_or_resume) {
872 uint32_t options = SessionRestore::SYNCHRONOUS;
873
874 // Suppress the creation of a new window on Mac when restoring with no windows
875 // if launching Chrome via a login item or the resume feature in OS 10.7+.
876 if (!was_mac_login_or_resume &&
877 (has_create_browser_default || has_create_browser_switch))
878 options |= SessionRestore::ALWAYS_CREATE_TABBED_BROWSER;
879
880 return options;
881 }
882
744 void StartupBrowserCreatorImpl::ProcessLaunchURLs( 883 void StartupBrowserCreatorImpl::ProcessLaunchURLs(
745 bool process_startup, 884 bool process_startup,
746 const std::vector<GURL>& urls_to_open) { 885 const std::vector<GURL>& urls_to_open) {
747 // Don't open any browser windows if we're starting up in "background mode". 886 // Don't open any browser windows if we're starting up in "background mode".
748 if (process_startup && command_line_.HasSwitch(switches::kNoStartupWindow)) 887 if (process_startup && command_line_.HasSwitch(switches::kNoStartupWindow))
749 return; 888 return;
750 889
751 // Determine whether or not this launch must include the welcome page. 890 // Determine whether or not this launch must include the welcome page.
752 InitializeWelcomeRunType(urls_to_open); 891 InitializeWelcomeRunType(urls_to_open);
753 892
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 #if defined(OS_WIN) 1221 #if defined(OS_WIN)
1083 TriggeredProfileResetter* triggered_profile_resetter = 1222 TriggeredProfileResetter* triggered_profile_resetter =
1084 TriggeredProfileResetterFactory::GetForBrowserContext(profile_); 1223 TriggeredProfileResetterFactory::GetForBrowserContext(profile_);
1085 // TriggeredProfileResetter instance will be nullptr for incognito profiles. 1224 // TriggeredProfileResetter instance will be nullptr for incognito profiles.
1086 if (triggered_profile_resetter) { 1225 if (triggered_profile_resetter) {
1087 has_reset_trigger = triggered_profile_resetter->HasResetTrigger(); 1226 has_reset_trigger = triggered_profile_resetter->HasResetTrigger();
1088 } 1227 }
1089 #endif // defined(OS_WIN) 1228 #endif // defined(OS_WIN)
1090 return has_reset_trigger; 1229 return has_reset_trigger;
1091 } 1230 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698