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

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: TabsToUrls optimizations 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"
16 #include "base/bind.h" 17 #include "base/bind.h"
17 #include "base/bind_helpers.h" 18 #include "base/bind_helpers.h"
18 #include "base/command_line.h" 19 #include "base/command_line.h"
19 #include "base/compiler_specific.h" 20 #include "base/compiler_specific.h"
20 #include "base/environment.h" 21 #include "base/environment.h"
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 184
184 void UrlsToTabs(const std::vector<GURL>& urls, StartupTabs* tabs) { 185 void UrlsToTabs(const std::vector<GURL>& urls, StartupTabs* tabs) {
185 for (size_t i = 0; i < urls.size(); ++i) { 186 for (size_t i = 0; i < urls.size(); ++i) {
186 StartupTab tab; 187 StartupTab tab;
187 tab.is_pinned = false; 188 tab.is_pinned = false;
188 tab.url = urls[i]; 189 tab.url = urls[i];
189 tabs->push_back(tab); 190 tabs->push_back(tab);
190 } 191 }
191 } 192 }
192 193
194 std::vector<GURL> TabsToUrls(const StartupTabs& tabs) {
195 std::vector<GURL> urls;
196 urls.reserve(tabs.size());
197 std::transform(tabs.begin(), tabs.end(), std::back_inserter(urls),
198 [](const StartupTab& tab) { return tab.url; });
199 return urls;
200 }
201
193 // Return true if the command line option --app-id is used. Set 202 // Return true if the command line option --app-id is used. Set
194 // |out_extension| to the app to open, and |out_launch_container| 203 // |out_extension| to the app to open, and |out_launch_container|
195 // to the type of window into which the app should be open. 204 // to the type of window into which the app should be open.
196 bool GetAppLaunchContainer( 205 bool GetAppLaunchContainer(
197 Profile* profile, 206 Profile* profile,
198 const std::string& app_id, 207 const std::string& app_id,
199 const Extension** out_extension, 208 const Extension** out_extension,
200 extensions::LaunchContainer* out_launch_container) { 209 extensions::LaunchContainer* out_launch_container) {
201 210
202 const Extension* extension = extensions::ExtensionRegistry::Get( 211 const Extension* extension = extensions::ExtensionRegistry::Get(
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 extension_id, extensions::ExtensionRegistry::EVERYTHING); 270 extension_id, extensions::ExtensionRegistry::EVERYTHING);
262 return extension && extension->is_platform_app() ? extension : NULL; 271 return extension && extension->is_platform_app() ? extension : NULL;
263 } 272 }
264 273
265 // Appends the contents of |from| to the end of |to|. 274 // Appends the contents of |from| to the end of |to|.
266 void AppendTabs(const StartupTabs& from, StartupTabs* to) { 275 void AppendTabs(const StartupTabs& from, StartupTabs* to) {
267 if (!from.empty()) 276 if (!from.empty())
268 to->insert(to->end(), from.begin(), from.end()); 277 to->insert(to->end(), from.begin(), from.end());
269 } 278 }
270 279
280 // Determines whether the Consolidated startup flow should be used, based on
281 // OS, OS version, and the kUseConsolidatedStartupFlow Feature.
282 bool UseConsolidatedFlow() {
283 #if defined(OS_WIN)
284 if (base::win::GetVersion() >= base::win::VERSION_WIN10)
Peter Kasting 2016/10/31 19:24:06 Nit: Should there be a comment here about why Win
tmartino 2016/11/02 16:33:59 Added TODO.
285 return false;
286 #endif // defined(OS_WIN)
287 return base::FeatureList::IsEnabled(features::kUseConsolidatedStartupFlow);
288 }
289
271 } // namespace 290 } // namespace
272 291
273 namespace internals { 292 namespace internals {
274 293
275 GURL GetTriggeredResetSettingsURL() { 294 GURL GetTriggeredResetSettingsURL() {
276 return GURL( 295 return GURL(
277 chrome::GetSettingsUrl(chrome::kTriggeredResetProfileSettingsSubPage)); 296 chrome::GetSettingsUrl(chrome::kTriggeredResetProfileSettingsSubPage));
278 } 297 }
279 298
280 GURL GetWelcomePageURL() { 299 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, 366 // URLs in that case. The user should see the window as an app,
348 // not as chrome. 367 // not as chrome.
349 // Special case is when app switches are passed but we do want to restore 368 // 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. 369 // session. In that case open app window + focus it after session is restored.
351 if (OpenApplicationWindow(profile)) { 370 if (OpenApplicationWindow(profile)) {
352 RecordLaunchModeHistogram(LM_AS_WEBAPP); 371 RecordLaunchModeHistogram(LM_AS_WEBAPP);
353 } else { 372 } else {
354 RecordLaunchModeHistogram(urls_to_open.empty() ? 373 RecordLaunchModeHistogram(urls_to_open.empty() ?
355 LM_TO_BE_DECIDED : LM_WITH_URLS); 374 LM_TO_BE_DECIDED : LM_WITH_URLS);
356 375
357 if (base::FeatureList::IsEnabled(features::kUseConsolidatedStartupFlow)) 376 if (UseConsolidatedFlow())
358 ProcessLaunchUrlsUsingConsolidatedFlow(process_startup, urls_to_open); 377 ProcessLaunchUrlsUsingConsolidatedFlow(process_startup, urls_to_open);
359 else 378 else
360 ProcessLaunchURLs(process_startup, urls_to_open); 379 ProcessLaunchURLs(process_startup, urls_to_open);
361 380
362 if (command_line_.HasSwitch(switches::kInstallChromeApp)) { 381 if (command_line_.HasSwitch(switches::kInstallChromeApp)) {
363 install_chrome_app::InstallChromeApp( 382 install_chrome_app::InstallChromeApp(
364 command_line_.GetSwitchValueASCII(switches::kInstallChromeApp)); 383 command_line_.GetSwitchValueASCII(switches::kInstallChromeApp));
365 } 384 }
366 385
367 // If this is an app launch, but we didn't open an app window, it may 386 // 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( 608 void StartupBrowserCreatorImpl::ProcessLaunchUrlsUsingConsolidatedFlow(
590 bool process_startup, 609 bool process_startup,
591 const std::vector<GURL>& cmd_line_urls) { 610 const std::vector<GURL>& cmd_line_urls) {
592 // Don't open any browser windows if starting up in "background mode". 611 // Don't open any browser windows if starting up in "background mode".
593 if (process_startup && command_line_.HasSwitch(switches::kNoStartupWindow)) 612 if (process_startup && command_line_.HasSwitch(switches::kNoStartupWindow))
594 return; 613 return;
595 614
596 StartupTabs cmd_line_tabs; 615 StartupTabs cmd_line_tabs;
597 UrlsToTabs(cmd_line_urls, &cmd_line_tabs); 616 UrlsToTabs(cmd_line_urls, &cmd_line_tabs);
598 617
599 bool is_incognito = IncognitoModePrefs::ShouldLaunchIncognito( 618 bool is_incognito_or_guest =
Peter Kasting 2016/10/31 19:24:06 Nit: Do you think it would be any clearer to rever
tmartino 2016/11/02 16:33:59 Definitely don't like "regular", but I'm OK with "
grt (UTC plus 2) 2016/11/03 09:43:33 Note that an "ephemeral profile" is a thing in and
tmartino 2016/11/03 18:39:24 Changing in forthcoming CL. I see the term "off t
Peter Kasting 2016/11/03 21:46:42 "off the record" is an archaic term for incognito.
grt (UTC plus 2) 2016/11/04 08:41:31 I'm not sure. I had a memory of hearing about "eph
600 command_line_, profile_->GetPrefs()); 619 profile_->GetProfileType() != Profile::ProfileType::REGULAR_PROFILE;
601 bool is_post_crash_launch = HasPendingUncleanExit(profile_); 620 bool is_post_crash_launch = HasPendingUncleanExit(profile_);
602 StartupTabs tabs = 621 StartupTabs tabs =
603 DetermineStartupTabs(StartupTabProviderImpl(), cmd_line_tabs, 622 DetermineStartupTabs(StartupTabProviderImpl(), cmd_line_tabs,
604 is_incognito, is_post_crash_launch); 623 is_incognito_or_guest, is_post_crash_launch);
605 624
606 // TODO(tmartino): If this is not process startup, attempt to restore 625 // If an async restore is necessary and is successfully kicked off, the
607 // asynchronously and return here. This logic is self-contained in 626 // remainder of the process is self-contained, so return.
Peter Kasting 2016/10/31 19:24:06 Nit: Passive voice; maybe "Return immediately if w
tmartino 2016/11/02 16:33:59 Done
608 // SessionService and therefore can't be combined with the other Browser 627 if (MaybeAsyncRestore(tabs, process_startup, is_post_crash_launch))
609 // creation logic. 628 return;
610 629
611 // TODO(tmartino): Function which determines what behavior of session 630 BrowserOpenBehavior behavior = DetermineBrowserOpenBehavior(
612 // restore, if any, is necessary, and passes the result to a new function 631 StartupBrowserCreator::GetSessionStartupPref(command_line_, profile_),
613 // which opens tabs in a restored or newly-created Browser accordingly. 632 process_startup, is_post_crash_launch,
614 // Incorporates code from ProcessStartupUrls. 633 command_line_.HasSwitch(switches::kRestoreLastSession),
634 command_line_.HasSwitch(switches::kOpenInNewWindow),
635 !cmd_line_tabs.empty());
615 636
616 Browser* browser = OpenTabsInBrowser(nullptr, process_startup, tabs); 637 uint32_t restore_options = 0;
638 if (behavior == BrowserOpenBehavior::SYNCHRONOUS_RESTORE) {
639 #if defined(OS_MACOSX)
640 bool was_mac_login_or_resume = base::mac::WasLaunchedAsLoginOrResumeItem();
641 #else
642 bool was_mac_login_or_resume = false;
643 #endif
644 restore_options = DetermineSynchronousRestoreOptions(
645 browser_defaults::kAlwaysCreateTabbedBrowserOnSessionRestore,
646 base::CommandLine::ForCurrentProcess()->HasSwitch(
647 switches::kCreateBrowserOnStartupForTests),
648 was_mac_login_or_resume);
649 }
650
651 Browser* browser = RestoreOrCreateBrowser(
652 tabs, behavior, restore_options, process_startup, is_post_crash_launch);
617 653
618 // Finally, add info bars. 654 // Finally, add info bars.
619 AddInfoBarsIfNecessary( 655 AddInfoBarsIfNecessary(
620 browser, process_startup ? chrome::startup::IS_PROCESS_STARTUP 656 browser, process_startup ? chrome::startup::IS_PROCESS_STARTUP
621 : chrome::startup::IS_NOT_PROCESS_STARTUP); 657 : chrome::startup::IS_NOT_PROCESS_STARTUP);
622 } 658 }
623 659
624 StartupTabs StartupBrowserCreatorImpl::DetermineStartupTabs( 660 StartupTabs StartupBrowserCreatorImpl::DetermineStartupTabs(
625 const StartupTabProvider& provider, 661 const StartupTabProvider& provider,
626 const StartupTabs& cmd_line_tabs, 662 const StartupTabs& cmd_line_tabs,
627 bool is_incognito, 663 bool is_incognito_or_guest,
628 bool is_post_crash_launch) { 664 bool is_post_crash_launch) {
629 // Only the New Tab Page or command line URLs may be shown in incognito mode. 665 // 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 666 // A similar policy exists for crash recovery launches, to prevent getting the
631 // user stuck in a crash loop. 667 // user stuck in a crash loop.
632 if (is_incognito || is_post_crash_launch) { 668 if (is_incognito_or_guest || is_post_crash_launch) {
633 if (cmd_line_tabs.empty()) 669 if (cmd_line_tabs.empty())
634 return StartupTabs({StartupTab(GURL(chrome::kChromeUINewTabURL), false)}); 670 return StartupTabs({StartupTab(GURL(chrome::kChromeUINewTabURL), false)});
635 return cmd_line_tabs; 671 return cmd_line_tabs;
636 } 672 }
637 673
638 // A trigger on a profile may indicate that we should show a tab which 674 // 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 675 // offers to reset the user's settings. When this appears, it is first, and
640 // may be shown alongside command-line tabs. 676 // may be shown alongside command-line tabs.
641 StartupTabs tabs = provider.GetResetTriggerTabs(profile_); 677 StartupTabs tabs = provider.GetResetTriggerTabs(profile_);
642 678
(...skipping 15 matching lines...) Expand all
658 // including OS and whether or not this is First Run. 694 // including OS and whether or not this is First Run.
659 StartupTabs onboarding_tabs = provider.GetOnboardingTabs(); 695 StartupTabs onboarding_tabs = provider.GetOnboardingTabs();
660 AppendTabs(onboarding_tabs, &tabs); 696 AppendTabs(onboarding_tabs, &tabs);
661 697
662 // If the user has set the preference indicating URLs to show on opening, 698 // If the user has set the preference indicating URLs to show on opening,
663 // read and add those. 699 // read and add those.
664 StartupTabs prefs_tabs = provider.GetPreferencesTabs(command_line_, profile_); 700 StartupTabs prefs_tabs = provider.GetPreferencesTabs(command_line_, profile_);
665 AppendTabs(prefs_tabs, &tabs); 701 AppendTabs(prefs_tabs, &tabs);
666 702
667 // Potentially add the New Tab Page. Onboarding content is designed to 703 // Potentially add the New Tab Page. Onboarding content is designed to
668 // replace (and eventually funnel the user to) the NTP. Likewise, URLs read 704 // replace (and eventually funnel the user to) the NTP. Likewise, URLs
669 // from preferences are explicitly meant to override showing the NTP. 705 // from preferences are explicitly meant to override showing the NTP.
670 if (onboarding_tabs.empty() && prefs_tabs.empty()) 706 if (onboarding_tabs.empty() && prefs_tabs.empty())
671 tabs.emplace_back(GURL(chrome::kChromeUINewTabURL), false); 707 AppendTabs(provider.GetNewTabPageTabs(command_line_, profile_), &tabs);
672 708
673 // Add any tabs which the user has previously pinned. 709 // Maybe add any tabs which the user has previously pinned.
674 AppendTabs(provider.GetPinnedTabs(profile_), &tabs); 710 AppendTabs(provider.GetPinnedTabs(command_line_, profile_), &tabs);
675 711
676 return tabs; 712 return tabs;
677 } 713 }
678 714
715 bool StartupBrowserCreatorImpl::MaybeAsyncRestore(const StartupTabs& tabs,
716 bool process_startup,
717 bool is_post_crash_launch) {
718 // Restore is performed synchronously on startup, and is never performed when
719 // launching after crashing.
720 if (process_startup || is_post_crash_launch)
721 return false;
722
723 SessionService* service =
724 SessionServiceFactory::GetForProfileForSessionRestore(profile_);
725
726 // Service will be null in incognito and guest mode.
Peter Kasting 2016/10/31 19:24:05 Nit: Service -> |service| Or: // Note: there's
tmartino 2016/11/02 16:33:59 Done (went for the middle option)
727 return (service && service->RestoreIfNecessary(TabsToUrls(tabs)));
Peter Kasting 2016/10/31 19:24:05 Nit: No need for outer ()
tmartino 2016/11/02 16:33:59 Done
728 }
729
730 Browser* StartupBrowserCreatorImpl::RestoreOrCreateBrowser(
731 const StartupTabs& tabs,
732 BrowserOpenBehavior behavior,
733 uint32_t restore_options,
734 bool process_startup,
735 bool is_post_crash_launch) {
736 Browser* browser = nullptr;
737
Peter Kasting 2016/10/31 19:24:06 Nit: I'd remove this blank, since the subsequent b
tmartino 2016/11/02 16:34:00 Done
738 if (behavior == BrowserOpenBehavior::SYNCHRONOUS_RESTORE) {
739 browser = SessionRestore::RestoreSession(profile_, nullptr, restore_options,
740 TabsToUrls(tabs));
741 if (browser)
742 return browser;
743 } else if (behavior == BrowserOpenBehavior::USE_EXISTING) {
744 browser = chrome::FindTabbedBrowser(profile_, process_startup);
745 }
746
747 StartupBrowserCreator::in_synchronous_profile_launch_ = true;
Peter Kasting 2016/10/31 19:24:05 Nit: I suggest using base::AutoReset to make clear
tmartino 2016/11/02 16:33:59 Done. And, yeah, I don't care for the structure o
grt (UTC plus 2) 2016/11/03 09:43:33 My favorite part of this class's "impl"-ness is th
748
749 // OpenTabsInBrowser requires at least one tab be passed. As a fallback to
750 // prevent a crash, use the NTP if |tabs| is empty.
Peter Kasting 2016/10/31 19:24:05 Nit: "As a fallback to prevent a crash" makes it s
tmartino 2016/11/02 16:33:59 It really *is* an error case. I had a comment earl
Peter Kasting 2016/11/02 17:00:46 Can we add this case to the comment here? For wei
tmartino 2016/11/02 17:36:52 Sorry for CQing before responding--I thought I had
751 browser = OpenTabsInBrowser(
752 browser, process_startup,
753 (tabs.empty()
754 ? StartupTabs({StartupTab(GURL(chrome::kChromeUINewTabURL), false)})
755 : tabs));
756
757 StartupBrowserCreator::in_synchronous_profile_launch_ = false;
758
759 // Now that a restore is no longer possible, it is safe to clear DOM storage,
760 // unless this is a crash recovery.
761 if (!is_post_crash_launch) {
762 content::BrowserContext::GetDefaultStoragePartition(profile_)
763 ->GetDOMStorageContext()
764 ->StartScavengingUnusedSessionStorage();
765 }
766
767 return browser;
768 }
769
770 // static
771 StartupBrowserCreatorImpl::BrowserOpenBehavior
772 StartupBrowserCreatorImpl::DetermineBrowserOpenBehavior(
773 const SessionStartupPref& pref,
774 bool process_startup,
775 bool is_post_crash_launch,
776 bool has_restore_switch,
777 bool has_new_window_switch,
778 bool has_cmd_line_tabs) {
779 if (!process_startup) {
780 // For existing processes, restore would have happened before invoking this
781 // function. If Chrome was launched with passed URLs, assume these should
782 // be appended to an existing window if possible, unless overridden by
Peter Kasting 2016/10/31 19:24:06 Nit: by -> by a?
tmartino 2016/11/02 16:33:59 Done
783 // switch.
784 return (has_cmd_line_tabs && !has_new_window_switch)
785 ? BrowserOpenBehavior::USE_EXISTING
786 : BrowserOpenBehavior::NEW;
787 }
788
789 if (pref.type == SessionStartupPref::LAST) {
790 // Don't perform a session restore on a post-crash launch, as this could
791 // cause a crash loop. These checks can be overridden by a switch.
792 // TODO(crbug.com/647851): Group this check with the logic in
793 // GetSessionStartupPref.
794 if (!is_post_crash_launch || has_restore_switch)
795 return BrowserOpenBehavior::SYNCHRONOUS_RESTORE;
796 }
797
798 return BrowserOpenBehavior::NEW;
799 }
800
801 // static
802 uint32_t StartupBrowserCreatorImpl::DetermineSynchronousRestoreOptions(
803 bool has_create_browser_default,
804 bool has_create_browser_switch,
805 bool was_mac_login_or_resume) {
806 uint32_t options = SessionRestore::SYNCHRONOUS;
807
808 // On Mac, when restoring a session with no windows, suppress the creation
809 // of a new window in the case where the system is launching Chrome via a
810 // login item or the resume feature in OS 10.7+.
Peter Kasting 2016/10/31 19:24:06 Nit: This sentence reads confusingly because the p
tmartino 2016/11/02 16:33:59 There are a lot of conditions to fit in, but I mov
811 if (!was_mac_login_or_resume &&
812 (has_create_browser_default || has_create_browser_switch)) {
Peter Kasting 2016/10/31 19:24:05 Nit: {} optional
tmartino 2016/11/02 16:33:59 Done
813 options |= SessionRestore::ALWAYS_CREATE_TABBED_BROWSER;
814 }
815
816 return options;
817 }
818
679 void StartupBrowserCreatorImpl::AddUniqueURLs(const std::vector<GURL>& urls, 819 void StartupBrowserCreatorImpl::AddUniqueURLs(const std::vector<GURL>& urls,
680 StartupTabs* tabs) { 820 StartupTabs* tabs) {
681 size_t num_existing_tabs = tabs->size(); 821 size_t num_existing_tabs = tabs->size();
682 for (size_t i = 0; i < urls.size(); ++i) { 822 for (size_t i = 0; i < urls.size(); ++i) {
683 bool in_tabs = false; 823 bool in_tabs = false;
684 for (size_t j = 0; j < num_existing_tabs; ++j) { 824 for (size_t j = 0; j < num_existing_tabs; ++j) {
685 if (urls[i] == (*tabs)[j].url) { 825 if (urls[i] == (*tabs)[j].url) {
686 in_tabs = true; 826 in_tabs = true;
687 break; 827 break;
688 } 828 }
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 #if defined(OS_WIN) 1222 #if defined(OS_WIN)
1083 TriggeredProfileResetter* triggered_profile_resetter = 1223 TriggeredProfileResetter* triggered_profile_resetter =
1084 TriggeredProfileResetterFactory::GetForBrowserContext(profile_); 1224 TriggeredProfileResetterFactory::GetForBrowserContext(profile_);
1085 // TriggeredProfileResetter instance will be nullptr for incognito profiles. 1225 // TriggeredProfileResetter instance will be nullptr for incognito profiles.
1086 if (triggered_profile_resetter) { 1226 if (triggered_profile_resetter) {
1087 has_reset_trigger = triggered_profile_resetter->HasResetTrigger(); 1227 has_reset_trigger = triggered_profile_resetter->HasResetTrigger();
1088 } 1228 }
1089 #endif // defined(OS_WIN) 1229 #endif // defined(OS_WIN)
1090 return has_reset_trigger; 1230 return has_reset_trigger;
1091 } 1231 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698