Commit b930f6e9 authored by tmartino's avatar tmartino Committed by Commit bot

Refactoring startup logic for upcoming FRE changes (non-Win 10).

Refactor goals (in descending order):
1. Consolidate the various places throughout startup where onboarding and other special-case tabs are added.
2. Reduce the massive number of branches, spaghetti calls, and seemingly-redundant checks into a manageable, linear flow.
3. Offload all policy logic (e.g., "Should we show the Welcome page?") for FRE to the more-appropriate first_run directory.
4. Where possible, consolidate code into testable units.

BUG=618454, 248883, 517248

Review-Url: https://codereview.chromium.org/2164033002
Cr-Commit-Position: refs/heads/master@{#423636}
parent d7cbf7cc
......@@ -89,6 +89,11 @@ uint16_t g_auto_import_state = first_run::AUTO_IMPORT_NONE;
bool g_should_show_welcome_page = false;
bool g_should_do_autofill_personal_data_manager_first_run = false;
// Indicates whether this is first run. Populated when IsChromeFirstRun
// is invoked, then used as a cache on subsequent calls.
first_run::internal::FirstRunState g_first_run =
first_run::internal::FIRST_RUN_UNKNOWN;
// This class acts as an observer for the ImporterProgressObserver::ImportEnded
// callback. When the import process is started, certain errors may cause
// ImportEnded() to be called synchronously, but the typical case is that
......@@ -495,8 +500,6 @@ void ProcessDefaultBrowserPolicy(bool make_chrome_default_for_user) {
namespace first_run {
namespace internal {
FirstRunState g_first_run = FIRST_RUN_UNKNOWN;
void SetupMasterPrefsFromInstallPrefs(
const installer::MasterPreferences& install_prefs,
MasterPrefs* out_prefs) {
......@@ -617,6 +620,14 @@ bool IsOrganicFirstRun() {
}
#endif
FirstRunState DetermineFirstRunState(bool has_sentinel,
bool force_first_run,
bool no_first_run) {
return (force_first_run || (!has_sentinel && !no_first_run))
? FIRST_RUN_TRUE
: FIRST_RUN_FALSE;
}
} // namespace internal
MasterPrefs::MasterPrefs()
......@@ -632,17 +643,15 @@ MasterPrefs::MasterPrefs()
MasterPrefs::~MasterPrefs() {}
bool IsChromeFirstRun() {
if (internal::g_first_run == internal::FIRST_RUN_UNKNOWN) {
internal::g_first_run = internal::FIRST_RUN_FALSE;
if (g_first_run == internal::FIRST_RUN_UNKNOWN) {
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kForceFirstRun) ||
(!command_line->HasSwitch(switches::kNoFirstRun) &&
!internal::IsFirstRunSentinelPresent())) {
internal::g_first_run = internal::FIRST_RUN_TRUE;
}
g_first_run = internal::DetermineFirstRunState(
internal::IsFirstRunSentinelPresent(),
command_line->HasSwitch(switches::kForceFirstRun),
command_line->HasSwitch(switches::kNoFirstRun));
}
return internal::g_first_run == internal::FIRST_RUN_TRUE;
return g_first_run == internal::FIRST_RUN_TRUE;
}
#if defined(OS_MACOSX)
......
......@@ -87,7 +87,8 @@ struct MasterPrefs {
std::string suppress_default_browser_prompt_for_version;
};
// Returns true if this is the first time chrome is run for this user.
// Returns true if Chrome should behave as if this is the first time Chrome is
// run for this user.
bool IsChromeFirstRun();
#if defined(OS_MACOSX)
......@@ -135,6 +136,10 @@ void SetShouldShowWelcomePage();
// SetShouldShowWelcomePage() is called.
bool ShouldShowWelcomePage();
// Iterates over the given tabs, replacing "magic words" designated for
// use in Master Preferences files with corresponding URLs.
std::vector<GURL> ProcessMasterPrefsTabs(const std::vector<GURL>& tabs);
// Sets a flag that will cause ShouldDoPersonalDataManagerFirstRun()
// to return true exactly once, so that the browser loads
// PersonalDataManager once the main message loop gets going.
......
......@@ -5,7 +5,6 @@
#ifndef CHROME_BROWSER_FIRST_RUN_FIRST_RUN_INTERNAL_H_
#define CHROME_BROWSER_FIRST_RUN_FIRST_RUN_INTERNAL_H_
class MasterPrefs;
class Profile;
namespace base {
......@@ -18,6 +17,8 @@ class MasterPreferences;
namespace first_run {
struct MasterPrefs;
namespace internal {
enum FirstRunState {
......@@ -57,6 +58,11 @@ bool ShowPostInstallEULAIfNeeded(installer::MasterPreferences* install_prefs);
// Returns the path for the master preferences file.
base::FilePath MasterPrefsPath();
// Helper for IsChromeFirstRun. Exposed for testing.
FirstRunState DetermineFirstRunState(bool has_sentinel,
bool force_first_run,
bool no_first_run);
} // namespace internal
} // namespace first_run
......
......@@ -86,4 +86,44 @@ TEST_F(FirstRunTest,
EXPECT_FALSE(out_prefs.welcome_page_on_os_upgrade_enabled);
}
// No switches and no sentinel present. This is the standard case for first run.
TEST_F(FirstRunTest, DetermineFirstRunState_FirstRun) {
internal::FirstRunState result =
internal::DetermineFirstRunState(false, false, false);
EXPECT_EQ(internal::FIRST_RUN_TRUE, result);
}
// Force switch is present, overriding both sentinel and suppress switch.
TEST_F(FirstRunTest, DetermineFirstRunState_ForceSwitch) {
internal::FirstRunState result =
internal::DetermineFirstRunState(true, true, true);
EXPECT_EQ(internal::FIRST_RUN_TRUE, result);
result = internal::DetermineFirstRunState(true, true, false);
EXPECT_EQ(internal::FIRST_RUN_TRUE, result);
result = internal::DetermineFirstRunState(false, true, true);
EXPECT_EQ(internal::FIRST_RUN_TRUE, result);
result = internal::DetermineFirstRunState(false, true, false);
EXPECT_EQ(internal::FIRST_RUN_TRUE, result);
}
// No switches, but sentinel present. This is not a first run.
TEST_F(FirstRunTest, DetermineFirstRunState_NotFirstRun) {
internal::FirstRunState result =
internal::DetermineFirstRunState(true, false, false);
EXPECT_EQ(internal::FIRST_RUN_FALSE, result);
}
// Suppress switch is present, overriding sentinel state.
TEST_F(FirstRunTest, DetermineFirstRunState_SuppressSwitch) {
internal::FirstRunState result =
internal::DetermineFirstRunState(false, false, true);
EXPECT_EQ(internal::FIRST_RUN_FALSE, result);
result = internal::DetermineFirstRunState(true, false, true);
EXPECT_EQ(internal::FIRST_RUN_FALSE, result);
}
} // namespace first_run
......@@ -796,8 +796,12 @@ split_static_library("ui") {
"startup/startup_browser_creator.h",
"startup/startup_browser_creator_impl.cc",
"startup/startup_browser_creator_impl.h",
"startup/startup_features.cc",
"startup/startup_features.h",
"startup/startup_tab.cc",
"startup/startup_tab.h",
"startup/startup_tab_provider.cc",
"startup/startup_tab_provider.h",
"startup/startup_types.h",
"sync/browser_synced_window_delegate.cc",
"sync/browser_synced_window_delegate.h",
......
......@@ -108,6 +108,8 @@ class StartupBrowserCreator {
friend class CloudPrintProxyPolicyTest;
friend class CloudPrintProxyPolicyStartupTest;
friend class StartupBrowserCreatorImpl;
// TODO(crbug.com/642442): Remove this when first_run_tabs gets refactored.
friend class StartupTabProviderImpl;
FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest,
ReadingWasRestartedAfterNormalStart);
FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest,
......
......@@ -12,6 +12,7 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "chrome/browser/ui/startup/startup_tab.h"
#include "chrome/browser/ui/startup/startup_tab_provider.h"
#include "chrome/browser/ui/startup/startup_types.h"
#include "url/gurl.h"
......@@ -67,6 +68,15 @@ class StartupBrowserCreatorImpl {
private:
FRIEND_TEST_ALL_PREFIXES(BrowserTest, RestorePinnedTabs);
FRIEND_TEST_ALL_PREFIXES(BrowserTest, AppIdSwitch);
FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorImplTest, DetermineStartupTabs);
FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorImplTest,
DetermineStartupTabs_IncognitoOrCrash);
FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorImplTest,
DetermineStartupTabs_MasterPrefs);
FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorImplTest,
DetermineStartupTabs_CommandLine);
FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorImplTest,
DetermineStartupTabs_NewTabPage);
enum class WelcomeRunType {
NONE, // Do not inject the welcome page for this run.
......@@ -97,12 +107,44 @@ class StartupBrowserCreatorImpl {
// should open in a tab, do so.
bool OpenApplicationTab(Profile* profile);
// Determines the URLs to be shown at startup by way of various policies
// (onboarding, pinned tabs, etc.), determines whether a session restore
// is necessary, and opens the URLs in a new or restored browser accordingly.
void ProcessLaunchUrlsUsingConsolidatedFlow(
bool process_startup,
const std::vector<GURL>& cmd_line_urls);
// Returns the tabs to be shown on startup, based on the policy functions in
// the given StartupTabProvider, the given tabs passed by the command line,
// and the interactions between those policies.
StartupTabs DetermineStartupTabs(const StartupTabProvider& provider,
const StartupTabs& cmd_line_tabs,
bool is_incognito,
bool is_post_crash_launch);
// Adds a Tab to |tabs| for each url in |urls| that doesn't already exist
// in |tabs|.
void AddUniqueURLs(const std::vector<GURL>& urls, StartupTabs* tabs);
// Adds any startup infobars to the selected tab of the given browser.
void AddInfoBarsIfNecessary(
Browser* browser,
chrome::startup::IsProcessStartup is_process_startup);
// Records Rappor metrics on startup URLs.
void RecordRapporOnStartupURLs(const std::vector<GURL>& urls_to_open);
// TODO(crbug.com/651465): The following functions are deprecated. They will
// be removed once kUseConsolidatedStartupFlow is enabled by default.
// Invoked from Launch to handle processing of urls. This may do any of the
// following:
// . Invoke ProcessStartupURLs if |process_startup| is true.
// . If |process_startup| is false, restore the last session if necessary,
// or invoke ProcessSpecifiedURLs.
// . Open the urls directly.
// Under the kUseConsolidatedStartupFlow feature, this is replaced by
// ProcessLaunchUrlsUsingConsolidatedFlow().
void ProcessLaunchURLs(bool process_startup,
const std::vector<GURL>& urls_to_open);
......@@ -128,15 +170,6 @@ class StartupBrowserCreatorImpl {
// Otherwise null is returned and the caller must create a new browser.
Browser* ProcessSpecifiedURLs(const std::vector<GURL>& urls_to_open);
// Adds a Tab to |tabs| for each url in |urls| that doesn't already exist
// in |tabs|.
void AddUniqueURLs(const std::vector<GURL>& urls, StartupTabs* tabs);
// Adds any startup infobars to the selected tab of the given browser.
void AddInfoBarsIfNecessary(
Browser* browser,
chrome::startup::IsProcessStartup is_process_startup);
// Adds additional startup URLs to the specified vector.
void AddStartupURLs(std::vector<GURL>* startup_urls) const;
......@@ -149,9 +182,6 @@ class StartupBrowserCreatorImpl {
// suppress injecting the welcome page for future launches.
void InitializeWelcomeRunType(const std::vector<GURL>& urls_to_open);
// Record Rappor metrics on startup URLs.
void RecordRapporOnStartupURLs(const std::vector<GURL>& urls_to_open);
// Checks whether |profile_| has a reset trigger set.
bool ProfileHasResetTrigger() const;
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/startup/startup_browser_creator_impl.h"
#include "base/command_line.h"
#include "chrome/browser/ui/startup/startup_tab_provider.h"
#include "chrome/common/url_constants.cc"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
// Bits for FakeStartupTabProvider options.
constexpr uint32_t kOnboardingTabs = 0x01;
constexpr uint32_t kDistributionFirstRunTabs = 0x02;
constexpr uint32_t kResetTriggerTabs = 0x04;
constexpr uint32_t kPinnedTabs = 0x08;
constexpr uint32_t kPreferencesTabs = 0x10;
class FakeStartupTabProvider : public StartupTabProvider {
public:
// For each option passed, the corresponding adder below will add a sentinel
// tab and return true. For options not passed, the adder will return false.
explicit FakeStartupTabProvider(uint32_t options) : options_(options) {}
StartupTabs GetOnboardingTabs() const override {
StartupTabs tabs;
if (options_ & kOnboardingTabs)
tabs.emplace_back(GURL("https://onboarding"), false);
return tabs;
}
StartupTabs GetDistributionFirstRunTabs(
StartupBrowserCreator* browser_creator) const override {
StartupTabs tabs;
if (options_ & kDistributionFirstRunTabs)
tabs.emplace_back(GURL("https://distribution"), false);
return tabs;
}
StartupTabs GetResetTriggerTabs(Profile* profile) const override {
StartupTabs tabs;
if (options_ & kResetTriggerTabs)
tabs.emplace_back(GURL("https://reset-trigger"), false);
return tabs;
}
StartupTabs GetPinnedTabs() const override {
StartupTabs tabs;
if (options_ & kPinnedTabs)
tabs.emplace_back(GURL("https://pinned"), true);
return tabs;
}
StartupTabs GetPreferencesTabs() const override {
StartupTabs tabs;
if (options_ & kPreferencesTabs)
tabs.emplace_back(GURL("https://prefs"), false);
return tabs;
}
private:
const uint32_t options_;
};
} // namespace
// "Standard" case: Tabs specified in onboarding, reset trigger, pinned tabs, or
// preferences shouldn't interfere with each other. Nothing specified on the
// command line. Reset trigger always appears first.
TEST(StartupBrowserCreatorImplTest, DetermineStartupTabs) {
FakeStartupTabProvider provider(kOnboardingTabs | kResetTriggerTabs |
kPinnedTabs | kPreferencesTabs);
StartupBrowserCreatorImpl impl(
base::FilePath(), base::CommandLine(base::CommandLine::NO_PROGRAM),
chrome::startup::IS_FIRST_RUN);
StartupTabs output =
impl.DetermineStartupTabs(provider, StartupTabs(), false, false);
ASSERT_EQ(4U, output.size());
EXPECT_EQ("reset-trigger", output[0].url.host());
EXPECT_EQ("onboarding", output[1].url.host());
EXPECT_EQ("prefs", output[2].url.host());
EXPECT_EQ("pinned", output[3].url.host());
}
// All content is blocked in Incognito mode, or when recovering from a crash.
// Only the New Tab Page should appear in either case.
TEST(StartupBrowserCreatorImplTest, DetermineStartupTabs_IncognitoOrCrash) {
FakeStartupTabProvider provider(kOnboardingTabs | kDistributionFirstRunTabs |
kResetTriggerTabs | kPinnedTabs |
kPreferencesTabs);
StartupBrowserCreatorImpl impl(
base::FilePath(), base::CommandLine(base::CommandLine::NO_PROGRAM),
chrome::startup::IS_FIRST_RUN);
// Incognito case:
StartupTabs output =
impl.DetermineStartupTabs(provider, StartupTabs(), true, false);
ASSERT_EQ(1U, output.size());
EXPECT_EQ(GURL(chrome::kChromeUINewTabURL), output[0].url);
// Crash Recovery case:
output = impl.DetermineStartupTabs(provider, StartupTabs(), false, true);
ASSERT_EQ(1U, output.size());
EXPECT_EQ(GURL(chrome::kChromeUINewTabURL), output[0].url);
}
// If Master Preferences specifies content, this should block all other
// policies. The only exception is command line URLs, tested below.
TEST(StartupBrowserCreatorImplTest, DetermineStartupTabs_MasterPrefs) {
FakeStartupTabProvider provider(kOnboardingTabs | kDistributionFirstRunTabs |
kResetTriggerTabs | kPinnedTabs |
kPreferencesTabs);
StartupBrowserCreatorImpl impl(
base::FilePath(), base::CommandLine(base::CommandLine::NO_PROGRAM),
chrome::startup::IS_FIRST_RUN);
StartupTabs output =
impl.DetermineStartupTabs(provider, StartupTabs(), false, false);
ASSERT_EQ(1U, output.size());
EXPECT_EQ("distribution", output[0].url.host());
}
// URLs specified on the command line should always appear, and should block
// all other tabs except the Reset Trigger tab.
TEST(StartupBrowserCreatorImplTest, DetermineStartupTabs_CommandLine) {
FakeStartupTabProvider provider(kOnboardingTabs | kDistributionFirstRunTabs |
kResetTriggerTabs | kPinnedTabs |
kPreferencesTabs);
StartupBrowserCreatorImpl impl(
base::FilePath(), base::CommandLine(base::CommandLine::NO_PROGRAM),
chrome::startup::IS_FIRST_RUN);
StartupTabs cmd_line_tabs = {StartupTab(GURL("https://cmd-line"), false)};
StartupTabs output =
impl.DetermineStartupTabs(provider, cmd_line_tabs, false, false);
ASSERT_EQ(2U, output.size());
EXPECT_EQ("reset-trigger", output[0].url.host());
EXPECT_EQ("cmd-line", output[1].url.host());
// Also test that both incognito and crash recovery don't interfere with
// command line tabs.
// Incognito
output = impl.DetermineStartupTabs(provider, cmd_line_tabs, true, false);
ASSERT_EQ(1U, output.size());
EXPECT_EQ("cmd-line", output[0].url.host());
// Crash Recovery
output = impl.DetermineStartupTabs(provider, cmd_line_tabs, false, true);
ASSERT_EQ(1U, output.size());
EXPECT_EQ("cmd-line", output[0].url.host());
}
// New Tab Page should appear alongside pinned tabs and the reset trigger, but
// should be superseded by onboarding tabs and by tabs specified in preferences.
TEST(StartupBrowserCreatorImplTest, DetermineStartupTabs_NewTabPage) {
FakeStartupTabProvider provider_allows_ntp(kPinnedTabs | kResetTriggerTabs);
StartupBrowserCreatorImpl impl(
base::FilePath(), base::CommandLine(base::CommandLine::NO_PROGRAM),
chrome::startup::IS_FIRST_RUN);
StartupTabs output = impl.DetermineStartupTabs(provider_allows_ntp,
StartupTabs(), false, false);
ASSERT_EQ(3U, output.size());
EXPECT_EQ("reset-trigger", output[0].url.host());
EXPECT_EQ(GURL(chrome::kChromeUINewTabURL), output[1].url);
EXPECT_EQ("pinned", output[2].url.host());
}
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/startup/startup_features.h"
namespace features {
const base::Feature kUseConsolidatedStartupFlow{
"UseConsolidatedStartupFlow", base::FEATURE_DISABLED_BY_DEFAULT};
} // namespace features
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_STARTUP_STARTUP_FEATURES_H_
#define CHROME_BROWSER_UI_STARTUP_STARTUP_FEATURES_H_
#include "base/feature_list.h"
namespace features {
extern const base::Feature kUseConsolidatedStartupFlow;
} // namespace features
#endif // CHROME_BROWSER_UI_STARTUP_STARTUP_FEATURES_H_
......@@ -8,5 +8,8 @@ StartupTab::StartupTab()
: is_pinned(true) {
}
StartupTab::StartupTab(const GURL& url, bool is_pinned)
: url(url), is_pinned(is_pinned) {}
StartupTab::~StartupTab() {
}
......@@ -5,7 +5,6 @@
#ifndef CHROME_BROWSER_UI_STARTUP_STARTUP_TAB_H_
#define CHROME_BROWSER_UI_STARTUP_STARTUP_TAB_H_
#include <string>
#include <vector>
#include "url/gurl.h"
......@@ -13,6 +12,7 @@
// Represents tab data at startup.
struct StartupTab {
StartupTab();
StartupTab(const GURL& url, bool is_pinned);
~StartupTab();
// The url to load.
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/startup/startup_tab_provider.h"
#include "build/build_config.h"
#include "chrome/browser/first_run/first_run.h"
#include "chrome/browser/profile_resetter/triggered_profile_resetter.h"
#include "chrome/browser/profile_resetter/triggered_profile_resetter_factory.h"
#include "chrome/browser/ui/chrome_pages.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/locale_settings.h"
#include "ui/base/l10n/l10n_util.h"
#if defined(OS_WIN)
#include "base/win/windows_version.h"
#endif
StartupTabs StartupTabProviderImpl::GetOnboardingTabs() const {
#if defined(OS_WIN)
// Windows 10 has unique onboarding policies and content.
if (base::win::GetVersion() >= base::win::VERSION_WIN10) {
// TODO(tmartino): * Add a function, GetWin10SystemState, which gathers
// system state relevant to Win10 Onboarding and returns
// a struct.
// * Add a function, CheckWin10OnboardingTabPolicy, which
// takes such a struct as input and returns StartupTabs.
return StartupTabs();
}
#endif
return CheckStandardOnboardingTabPolicy(first_run::IsChromeFirstRun());
}
StartupTabs StartupTabProviderImpl::GetDistributionFirstRunTabs(
StartupBrowserCreator* browser_creator) const {
if (!browser_creator)
return StartupTabs();
StartupTabs tabs = CheckMasterPrefsTabPolicy(
first_run::IsChromeFirstRun(), browser_creator->first_run_tabs_);
browser_creator->first_run_tabs_.clear();
return tabs;
}
StartupTabs StartupTabProviderImpl::GetResetTriggerTabs(
Profile* profile) const {
auto* triggered_profile_resetter =
TriggeredProfileResetterFactory::GetForBrowserContext(profile);
bool has_reset_trigger = triggered_profile_resetter &&
triggered_profile_resetter->HasResetTrigger();
return CheckResetTriggerTabPolicy(has_reset_trigger);
}
StartupTabs StartupTabProviderImpl::GetPinnedTabs() const {
// TODO(tmartino): Copy/clean up logic from
// StartupBrowserCreatorImpl::ProcessSpecifiedUrls.
return StartupTabs();
}
StartupTabs StartupTabProviderImpl::GetPreferencesTabs() const {
// TODO(tmartino): Copy/clean up logic from
// StartupBrowserCreatorImpl::ProcessStartupUrls.
return StartupTabs();
}
// static
StartupTabs StartupTabProviderImpl::CheckStandardOnboardingTabPolicy(
bool is_first_run) {
StartupTabs tabs;
if (is_first_run)
tabs.emplace_back(GetWelcomePageUrl(), false);
return tabs;
}
// static
StartupTabs StartupTabProviderImpl::CheckMasterPrefsTabPolicy(
bool is_first_run,
const std::vector<GURL>& first_run_tabs) {
// Constants: Magic words used by Master Preferences files in place of a URL
// host to indicate that internal pages should appear on first run.
constexpr char kNewTabUrlHost[] = "new_tab_page";
constexpr char kWelcomePageUrlHost[] = "welcome_page";
StartupTabs tabs;
if (is_first_run) {
tabs.reserve(first_run_tabs.size());
for (GURL url : first_run_tabs) {
if (url.host() == kNewTabUrlHost)
url = GURL(chrome::kChromeUINewTabURL);
else if (url.host() == kWelcomePageUrlHost)
url = GetWelcomePageUrl();
tabs.emplace_back(url, false);
}
}
return tabs;
}
// static
StartupTabs StartupTabProviderImpl::CheckResetTriggerTabPolicy(
bool profile_has_trigger) {
StartupTabs tabs;
if (profile_has_trigger)
tabs.emplace_back(GetTriggeredResetSettingsUrl(), false);
return tabs;
}
// static
GURL StartupTabProviderImpl::GetWelcomePageUrl() {
return GURL(chrome::kChromeUIWelcomeURL);
}
// static
GURL StartupTabProviderImpl::GetTriggeredResetSettingsUrl() {
return GURL(
chrome::GetSettingsUrl(chrome::kTriggeredResetProfileSettingsSubPage));
}
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_STARTUP_STARTUP_TAB_PROVIDER_H_
#define CHROME_BROWSER_UI_STARTUP_STARTUP_TAB_PROVIDER_H_
#include <vector>
#include "base/gtest_prod_util.h"
#include "chrome/browser/first_run/first_run.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/startup/startup_browser_creator.h"
#include "chrome/browser/ui/startup/startup_tab.h"
#include "url/gurl.h"
// Provides the sets of tabs to be shown at startup for given sets of policy.
// For instance, this class answers the question, "which tabs, if any, need to
// be shown for first run/onboarding?" Provided as a virtual interface to allow
// faking in unit tests.
class StartupTabProvider {
public:
// Gathers relevant system state and returns any tabs which should be
// shown according to onboarding/first run policy.
virtual StartupTabs GetOnboardingTabs() const = 0;
// Gathers URLs from a Master Preferences file indicating first run logic
// specific to this distribution. Transforms any such URLs per policy and
// returns them. Also clears the value of first_run_urls_ in the provided
// BrowserCreator.
virtual StartupTabs GetDistributionFirstRunTabs(
StartupBrowserCreator* browser_creator) const = 0;
// Checks for the presence of a trigger indicating the need to offer a Profile
// Reset on this profile. Returns any tabs which should be shown accordingly.
virtual StartupTabs GetResetTriggerTabs(Profile* profile) const = 0;
// Returns the user's pinned tabs.
virtual StartupTabs GetPinnedTabs() const = 0;
// Returns tabs, if any, specified in the user's preferences as the default
// content for a new window.
virtual StartupTabs GetPreferencesTabs() const = 0;
};
class StartupTabProviderImpl : public StartupTabProvider {
public:
StartupTabProviderImpl() = default;
// The static Check*TabPolicy methods below enforce the policies relevant to
// the respective Get*Tabs methods, but do not gather or interact with any
// system state relating to making those policy decisions.
// Determines which tabs which should be shown according to onboarding/first
// run policy.
static StartupTabs CheckStandardOnboardingTabPolicy(bool is_first_run);
// Processes first run URLs specified in Master Preferences file, replacing
// any "magic word" URL hosts with appropriate URLs.
static StartupTabs CheckMasterPrefsTabPolicy(
bool is_first_run,
const std::vector<GURL>& first_run_tabs);
// Determines which tabs should be shown as a result of the presence/absence
// of a Reset Trigger on this profile.
static StartupTabs CheckResetTriggerTabPolicy(bool profile_has_trigger);
// Gets the URL for the "Welcome to Chrome" page.
static GURL GetWelcomePageUrl();
// Gets the URL for the page which offers to reset the user's profile
// settings.
static GURL GetTriggeredResetSettingsUrl();
// StartupTabProvider:
StartupTabs GetOnboardingTabs() const override;
StartupTabs GetDistributionFirstRunTabs(
StartupBrowserCreator* browser_creator) const override;
StartupTabs GetResetTriggerTabs(Profile* profile) const override;
StartupTabs GetPinnedTabs() const override;
StartupTabs GetPreferencesTabs() const override;
private:
DISALLOW_COPY_AND_ASSIGN(StartupTabProviderImpl);
};
#endif // CHROME_BROWSER_UI_STARTUP_STARTUP_TAB_PROVIDER_H_
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/startup/startup_tab_provider.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/url_constants.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
TEST(StartupTabProviderTest, CheckStandardOnboardingTabPolicy) {
StartupTabs output =
StartupTabProviderImpl::CheckStandardOnboardingTabPolicy(true);
ASSERT_EQ(1U, output.size());
EXPECT_EQ(StartupTabProviderImpl::GetWelcomePageUrl(), output[0].url);
EXPECT_FALSE(output[0].is_pinned);
}
TEST(StartupTabProviderTest, CheckStandardOnboardingTabPolicy_FirstRunOnly) {
StartupTabs output =
StartupTabProviderImpl::CheckStandardOnboardingTabPolicy(false);
EXPECT_TRUE(output.empty());
}
TEST(StartupTabProviderTest, CheckMasterPrefsTabPolicy) {
std::vector<GURL> input = {GURL(base::ASCIIToUTF16("https://new_tab_page")),
GURL(base::ASCIIToUTF16("https://www.google.com")),
GURL(base::ASCIIToUTF16("https://welcome_page"))};
StartupTabs output =
StartupTabProviderImpl::CheckMasterPrefsTabPolicy(true, input);
ASSERT_EQ(3U, output.size());
EXPECT_EQ(GURL(chrome::kChromeUINewTabURL), output[0].url);
EXPECT_FALSE(output[0].is_pinned);
EXPECT_EQ(input[1], output[1].url);
EXPECT_FALSE(output[1].is_pinned);
EXPECT_EQ(StartupTabProviderImpl::GetWelcomePageUrl(), output[2].url);
EXPECT_FALSE(output[2].is_pinned);
}
TEST(StartupTabProviderTest, CheckMasterPrefsTabPolicy_FirstRunOnly) {
std::vector<GURL> input = {
GURL(base::ASCIIToUTF16("https://www.google.com"))};
StartupTabs output =
StartupTabProviderImpl::CheckMasterPrefsTabPolicy(false, input);
EXPECT_TRUE(output.empty());
}
TEST(StartupTabProviderTest, CheckResetTriggerTabPolicy) {
StartupTabs output = StartupTabProviderImpl::CheckResetTriggerTabPolicy(true);
ASSERT_EQ(1U, output.size());
EXPECT_EQ(StartupTabProviderImpl::GetTriggeredResetSettingsUrl(),
output[0].url);
EXPECT_FALSE(output[0].is_pinned);
}
TEST(StartupTabProviderTest, CheckResetTriggerTabPolicy_Negative) {
StartupTabs output =
StartupTabProviderImpl::CheckResetTriggerTabPolicy(false);
ASSERT_TRUE(output.empty());
}
......@@ -4072,6 +4072,8 @@ test("unit_tests") {
"//chrome/browser/profiles/profile_list_desktop_unittest.cc",
"//chrome/browser/profiles/profile_statistics_unittest.cc",
"//chrome/browser/ui/startup/default_browser_infobar_delegate_unittest.cc",
"//chrome/browser/ui/startup/startup_browser_creator_impl_unittest.cc",
"//chrome/browser/ui/startup/startup_tab_provider_unittest.cc",
]
}
if (use_gio) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment