Commit 514bc3e3 authored by Aga Wronska's avatar Aga Wronska Committed by Commit Bot

Add Demo Mode setup flow to OOBE WizardController.

Right now flow consists of:
* Demo preferences screen where user can select language related options
* Chrome OS Eula that has to be accepted
* Demo setup screen that shows progress and result of demo setup
More screens will be added later.

BUG=827376
TEST=Run tests in wizard_controller_browsertest.cc

Cq-Include-Trybots: luci.chromium.try:closure_compilation
Change-Id: Ifa4c86201a0ef7b0a6c41b5805ba0c3fde1d791a
Reviewed-on: https://chromium-review.googlesource.com/1108356
Commit-Queue: Aga Wronska <agawronska@chromium.org>
Reviewed-by: default avatarAlexander Alekseev <alemate@chromium.org>
Reviewed-by: default avatarMichael Giuffrida <michaelpg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#573489}
parent afc4e1a8
......@@ -7,6 +7,7 @@
#include "base/logging.h"
#include "chrome/browser/chromeos/login/screens/base_screen_delegate.h"
#include "chrome/browser/chromeos/login/screens/demo_preferences_screen_view.h"
#include "chrome/browser/chromeos/login/screens/screen_exit_code.h"
namespace chromeos {
......@@ -40,11 +41,9 @@ void DemoPreferencesScreen::Hide() {
void DemoPreferencesScreen::OnUserAction(const std::string& action_id) {
if (action_id == kUserActionContinue) {
// TODO(agawronska): Add continue action.
NOTIMPLEMENTED();
Finish(ScreenExitCode::DEMO_MODE_PREFERENCES_CONTINUED);
} else if (action_id == kUserActionClose) {
// TODO(agawronska): Add close action.
NOTIMPLEMENTED();
Finish(ScreenExitCode::DEMO_MODE_PREFERENCES_CANCELED);
} else {
BaseScreen::OnUserAction(action_id);
}
......
// Copyright 2018 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/chromeos/login/screens/mock_demo_preferences_screen.h"
using ::testing::AtLeast;
using ::testing::NotNull;
namespace chromeos {
MockDemoPreferencesScreen::MockDemoPreferencesScreen(
BaseScreenDelegate* base_screen_delegate,
DemoPreferencesScreenView* view)
: DemoPreferencesScreen(base_screen_delegate, view) {}
MockDemoPreferencesScreen::~MockDemoPreferencesScreen() = default;
MockDemoPreferencesScreenView::MockDemoPreferencesScreenView() {
EXPECT_CALL(*this, MockBind(NotNull())).Times(AtLeast(1));
}
MockDemoPreferencesScreenView::~MockDemoPreferencesScreenView() {
if (screen_)
screen_->OnViewDestroyed(this);
}
void MockDemoPreferencesScreenView::Bind(DemoPreferencesScreen* screen) {
screen_ = screen;
MockBind(screen);
}
} // namespace chromeos
// Copyright 2018 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_CHROMEOS_LOGIN_SCREENS_MOCK_DEMO_PREFERENCES_SCREEN_H_
#define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_MOCK_DEMO_PREFERENCES_SCREEN_H_
#include "base/macros.h"
#include "chrome/browser/chromeos/login/screens/demo_preferences_screen.h"
#include "chrome/browser/chromeos/login/screens/demo_preferences_screen_view.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace chromeos {
class MockDemoPreferencesScreen : public DemoPreferencesScreen {
public:
MockDemoPreferencesScreen(BaseScreenDelegate* base_screen_delegate,
DemoPreferencesScreenView* view);
~MockDemoPreferencesScreen() override;
private:
DISALLOW_COPY_AND_ASSIGN(MockDemoPreferencesScreen);
};
class MockDemoPreferencesScreenView : public DemoPreferencesScreenView {
public:
MockDemoPreferencesScreenView();
~MockDemoPreferencesScreenView() override;
MOCK_METHOD0(Show, void());
MOCK_METHOD0(Hide, void());
MOCK_METHOD1(MockBind, void(DemoPreferencesScreen* screen));
void Bind(DemoPreferencesScreen* screen) override;
private:
DemoPreferencesScreen* screen_;
DISALLOW_COPY_AND_ASSIGN(MockDemoPreferencesScreenView);
};
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_MOCK_DEMO_PREFERENCES_SCREEN_H_
......@@ -80,6 +80,10 @@ std::string ExitCodeToString(ScreenExitCode code) {
return "RECOMMEND_APPS_SKIPPED";
case ScreenExitCode::RECOMMEND_APPS_SELECTED:
return "RECOMMEND_APPS_SELECTED";
case ScreenExitCode::DEMO_MODE_PREFERENCES_CONTINUED:
return "DEMO_MODE_PREFERENCES_CONTINUED";
case ScreenExitCode::DEMO_MODE_PREFERENCES_CANCELED:
return "DEMO_MODE_PREFERENCES_CANCELED";
case ScreenExitCode::EXIT_CODES_COUNT:
default:
NOTREACHED();
......
......@@ -61,6 +61,8 @@ enum class ScreenExitCode {
DEMO_MODE_SETUP_CANCELED = 34,
RECOMMEND_APPS_SKIPPED = 35,
RECOMMEND_APPS_SELECTED = 36,
DEMO_MODE_PREFERENCES_CONTINUED = 37,
DEMO_MODE_PREFERENCES_CANCELED = 38,
EXIT_CODES_COUNT // not a real code, must be the last
};
......
......@@ -506,6 +506,11 @@ void WizardController::ShowLoginScreen(const LoginScreenContext& context) {
login_screen_started_ = true;
}
void WizardController::ShowPreviousScreen() {
DCHECK(previous_screen_);
SetCurrentScreen(previous_screen_);
}
void WizardController::ShowUserImageScreen() {
const user_manager::UserManager* user_manager =
user_manager::UserManager::Get();
......@@ -798,6 +803,11 @@ void WizardController::OnEulaAccepted() {
weak_factory_.GetWeakPtr()));
PerformPostEulaActions();
if (is_in_demo_setup_flow_) {
ShowDemoModeSetupScreen();
return;
}
if (skip_update_enroll_after_eula_) {
ShowAutoEnrollmentCheckScreen();
} else {
......@@ -805,6 +815,14 @@ void WizardController::OnEulaAccepted() {
}
}
void WizardController::OnEulaBack() {
if (is_in_demo_setup_flow_) {
ShowPreviousScreen();
} else {
ShowWelcomeScreen();
}
}
void WizardController::OnChangedMetricsReportingState(bool enabled) {
CrosSettings::Get()->SetBoolean(kStatsReportingPref, enabled);
if (!enabled)
......@@ -974,13 +992,27 @@ void WizardController::OnAutoEnrollmentCheckCompleted() {
}
void WizardController::OnDemoSetupFinished() {
DCHECK(is_in_demo_setup_flow_);
is_in_demo_setup_flow_ = false;
PerformOOBECompletedActions();
ShowLoginScreen(LoginScreenContext());
}
void WizardController::OnDemoSetupCanceled() {
DCHECK(previous_screen_);
SetCurrentScreen(previous_screen_);
DCHECK(is_in_demo_setup_flow_);
is_in_demo_setup_flow_ = false;
ShowWelcomeScreen();
}
void WizardController::OnDemoPreferencesContinued() {
DCHECK(is_in_demo_setup_flow_);
ShowEulaScreen();
}
void WizardController::OnDemoPreferencesCanceled() {
DCHECK(is_in_demo_setup_flow_);
is_in_demo_setup_flow_ = false;
ShowWelcomeScreen();
}
void WizardController::OnOobeFlowFinished() {
......@@ -1275,6 +1307,11 @@ void WizardController::AdvanceToScreen(OobeScreen screen) {
}
}
void WizardController::StartDemoModeSetup() {
is_in_demo_setup_flow_ = true;
ShowDemoModePreferencesScreen();
}
///////////////////////////////////////////////////////////////////////////////
// WizardController, BaseScreenDelegate overrides:
void WizardController::OnExit(BaseScreen& /* screen */,
......@@ -1318,7 +1355,7 @@ void WizardController::OnExit(BaseScreen& /* screen */,
OnEulaAccepted();
break;
case ScreenExitCode::EULA_BACK:
ShowWelcomeScreen();
OnEulaBack();
break;
case ScreenExitCode::ENABLE_DEBUGGING_CANCELED:
OnDeviceModificationCanceled();
......@@ -1393,6 +1430,12 @@ void WizardController::OnExit(BaseScreen& /* screen */,
case ScreenExitCode::DEMO_MODE_SETUP_CANCELED:
OnDemoSetupCanceled();
break;
case ScreenExitCode::DEMO_MODE_PREFERENCES_CONTINUED:
OnDemoPreferencesContinued();
break;
case ScreenExitCode::DEMO_MODE_PREFERENCES_CANCELED:
OnDemoPreferencesCanceled();
break;
default:
NOTREACHED();
}
......
......@@ -99,6 +99,13 @@ class WizardController : public BaseScreenDelegate,
// Advances to screen defined by |screen| and shows it.
void AdvanceToScreen(OobeScreen screen);
// Starts Demo Mode setup flow. The flow starts from network screen and reuses
// some of regular OOBE screens. It consists of the following screens:
// chromeos::OobeScreen::SCREEN_OOBE_DEMO_PREFERENCES
// chromeos::OobeScreen::SCREEN_OOBE_EULA
// chromeos::OobeScreen::SCREEN_OOBE_DEMO_SETUP
void StartDemoModeSetup();
// Advances to login/update screen. Should be used in for testing only.
void SkipToLoginForTesting(const LoginScreenContext& context);
void SkipToUpdateForTesting();
......@@ -169,12 +176,16 @@ class WizardController : public BaseScreenDelegate,
// Shows images login screen.
void ShowLoginScreen(const LoginScreenContext& context);
// Shows previous screen. Should only be called if previous screen exists.
void ShowPreviousScreen();
// Exit handlers:
void OnHIDDetectionCompleted();
void OnNetworkConnected();
void OnConnectionFailed();
void OnUpdateCompleted();
void OnEulaAccepted();
void OnEulaBack();
void OnUpdateErrorCheckingForUpdate();
void OnUpdateErrorUpdating(bool is_critical_update);
void OnUserImageSelected();
......@@ -197,6 +208,8 @@ class WizardController : public BaseScreenDelegate,
void OnAutoEnrollmentCheckCompleted();
void OnDemoSetupFinished();
void OnDemoSetupCanceled();
void OnDemoPreferencesContinued();
void OnDemoPreferencesCanceled();
void OnWaitForContainerReadyFinished();
void OnOobeFlowFinished();
......@@ -412,6 +425,9 @@ class WizardController : public BaseScreenDelegate,
bool is_in_session_oobe_ = false;
// Whether the currently presented flow is Demo Mode setup.
bool is_in_demo_setup_flow_ = false;
// Indicates that once image selection screen finishes we should return to
// a previous screen instead of proceeding with usual flow.
bool user_image_screen_return_to_previous_hack_ = false;
......@@ -424,11 +440,12 @@ class WizardController : public BaseScreenDelegate,
FRIEND_TEST_ALL_PREFIXES(WizardControllerDeviceStateTest,
ControlFlowNoForcedReEnrollmentOnFirstBoot);
friend class WizardControllerBrokenLocalStateTest;
friend class WizardControllerDemoSetupTest;
friend class WizardControllerDeviceStateTest;
friend class WizardControllerFlowTest;
friend class WizardControllerOobeConfigurationTest;
friend class WizardControllerOobeResumeTest;
friend class WizardInProcessBrowserTest;
friend class WizardControllerOobeConfigurationTest;
std::unique_ptr<AccessibilityStatusSubscription> accessibility_subscription_;
......
......@@ -27,6 +27,7 @@
#include "chrome/browser/chromeos/login/screens/device_disabled_screen.h"
#include "chrome/browser/chromeos/login/screens/error_screen.h"
#include "chrome/browser/chromeos/login/screens/hid_detection_screen.h"
#include "chrome/browser/chromeos/login/screens/mock_demo_preferences_screen.h"
#include "chrome/browser/chromeos/login/screens/mock_demo_setup_screen.h"
#include "chrome/browser/chromeos/login/screens/mock_device_disabled_screen_view.h"
#include "chrome/browser/chromeos/login/screens/mock_enable_debugging_screen.h"
......@@ -585,6 +586,9 @@ class WizardControllerFlowTest : public WizardControllerTest {
MockEnableDebuggingScreenView);
MOCK(mock_demo_setup_screen_, OobeScreen::SCREEN_OOBE_DEMO_SETUP,
MockDemoSetupScreen, MockDemoSetupScreenView);
MOCK(mock_demo_preferences_screen_,
OobeScreen::SCREEN_OOBE_DEMO_PREFERENCES, MockDemoPreferencesScreen,
MockDemoPreferencesScreenView);
device_disabled_screen_view_.reset(new MockDeviceDisabledScreenView);
wizard_controller->screen_manager()
->screens_[OobeScreen::SCREEN_DEVICE_DISABLED] =
......@@ -727,6 +731,9 @@ class WizardControllerFlowTest : public WizardControllerTest {
mock_enable_debugging_screen_;
MockOutShowHide<MockDemoSetupScreen, MockDemoSetupScreenView>*
mock_demo_setup_screen_;
MockOutShowHide<MockDemoPreferencesScreen, MockDemoPreferencesScreenView>*
mock_demo_preferences_screen_;
std::unique_ptr<MockDeviceDisabledScreenView> device_disabled_screen_view_;
private:
......@@ -2055,49 +2062,150 @@ class WizardControllerDemoSetupTest : public WizardControllerFlowTest {
command_line->AppendSwitch(chromeos::switches::kEnableDemoMode);
}
void SetUpOnMainThread() override {
WizardControllerFlowTest::SetUpOnMainThread();
testing::Mock::VerifyAndClearExpectations(mock_welcome_screen_);
}
bool IsInDemoSetupFlow() const {
return WizardController::default_controller()->is_in_demo_setup_flow_;
}
private:
DISALLOW_COPY_AND_ASSIGN(WizardControllerDemoSetupTest);
};
IN_PROC_BROWSER_TEST_F(WizardControllerDemoSetupTest, DemoSetupFinished) {
IN_PROC_BROWSER_TEST_F(WizardControllerDemoSetupTest, DemoSetupFlowFinished) {
CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME);
EXPECT_FALSE(IsInDemoSetupFlow());
WaitUntilJSIsReady();
EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1);
EXPECT_CALL(*mock_welcome_screen_, SetConfiguration(IsNull(), _)).Times(1);
EXPECT_CALL(*mock_demo_preferences_screen_, Show()).Times(1);
WizardController::default_controller()->StartDemoModeSetup();
CheckCurrentScreen(OobeScreen::SCREEN_OOBE_DEMO_PREFERENCES);
EXPECT_TRUE(IsInDemoSetupFlow());
EXPECT_CALL(*mock_demo_preferences_screen_, Hide()).Times(1);
EXPECT_CALL(*mock_eula_screen_, Show()).Times(1);
OnExit(*mock_demo_preferences_screen_,
ScreenExitCode::DEMO_MODE_PREFERENCES_CONTINUED);
CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA);
EXPECT_TRUE(IsInDemoSetupFlow());
EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1);
EXPECT_CALL(*mock_demo_setup_screen_, Show()).Times(1);
WizardController::default_controller()->AdvanceToScreen(
OobeScreen::SCREEN_OOBE_DEMO_SETUP);
OnExit(*mock_eula_screen_, ScreenExitCode::EULA_ACCEPTED);
CheckCurrentScreen(OobeScreen::SCREEN_OOBE_DEMO_SETUP);
EXPECT_TRUE(IsInDemoSetupFlow());
OnExit(*mock_demo_setup_screen_, ScreenExitCode::DEMO_MODE_SETUP_FINISHED);
EXPECT_TRUE(StartupUtils::IsOobeCompleted());
EXPECT_TRUE(ExistingUserController::current_controller());
EXPECT_FALSE(IsInDemoSetupFlow());
}
IN_PROC_BROWSER_TEST_F(WizardControllerDemoSetupTest, DemoSetupCanceled) {
CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME);
EXPECT_FALSE(IsInDemoSetupFlow());
WaitUntilJSIsReady();
EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1);
EXPECT_CALL(*mock_welcome_screen_, SetConfiguration(IsNull(), _)).Times(1);
EXPECT_CALL(*mock_demo_preferences_screen_, Show()).Times(1);
WizardController::default_controller()->StartDemoModeSetup();
CheckCurrentScreen(OobeScreen::SCREEN_OOBE_DEMO_PREFERENCES);
EXPECT_TRUE(IsInDemoSetupFlow());
EXPECT_CALL(*mock_demo_preferences_screen_, Hide()).Times(1);
EXPECT_CALL(*mock_eula_screen_, Show()).Times(1);
OnExit(*mock_demo_preferences_screen_,
ScreenExitCode::DEMO_MODE_PREFERENCES_CONTINUED);
CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA);
EXPECT_TRUE(IsInDemoSetupFlow());
EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1);
EXPECT_CALL(*mock_demo_setup_screen_, Show()).Times(1);
WizardController::default_controller()->AdvanceToScreen(
OobeScreen::SCREEN_OOBE_DEMO_SETUP);
OnExit(*mock_eula_screen_, ScreenExitCode::EULA_ACCEPTED);
CheckCurrentScreen(OobeScreen::SCREEN_OOBE_DEMO_SETUP);
EXPECT_TRUE(IsInDemoSetupFlow());
EXPECT_CALL(*mock_demo_setup_screen_, Hide()).Times(1);
EXPECT_CALL(*mock_welcome_screen_, SetConfiguration(NotNull(), _)).Times(1);
EXPECT_CALL(*mock_welcome_screen_, Show()).Times(1);
EXPECT_CALL(*mock_welcome_screen_, SetConfiguration(NotNull(), _)).Times(1);
OnExit(*mock_demo_setup_screen_, ScreenExitCode::DEMO_MODE_SETUP_CANCELED);
CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME);
EXPECT_FALSE(IsInDemoSetupFlow());
}
IN_PROC_BROWSER_TEST_F(WizardControllerDemoSetupTest, DemoPreferencesCanceled) {
CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME);
EXPECT_FALSE(IsInDemoSetupFlow());
WaitUntilJSIsReady();
EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1);
EXPECT_CALL(*mock_demo_preferences_screen_, Show()).Times(1);
WizardController::default_controller()->StartDemoModeSetup();
CheckCurrentScreen(OobeScreen::SCREEN_OOBE_DEMO_PREFERENCES);
EXPECT_TRUE(IsInDemoSetupFlow());
EXPECT_CALL(*mock_demo_preferences_screen_, Hide()).Times(1);
EXPECT_CALL(*mock_welcome_screen_, Show()).Times(1);
OnExit(*mock_demo_preferences_screen_,
ScreenExitCode::DEMO_MODE_PREFERENCES_CANCELED);
CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME);
EXPECT_FALSE(IsInDemoSetupFlow());
}
IN_PROC_BROWSER_TEST_F(WizardControllerDemoSetupTest, EulaBackPressed) {
CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME);
EXPECT_FALSE(IsInDemoSetupFlow());
WaitUntilJSIsReady();
EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1);
EXPECT_CALL(*mock_demo_preferences_screen_, Show()).Times(1);
WizardController::default_controller()->StartDemoModeSetup();
CheckCurrentScreen(OobeScreen::SCREEN_OOBE_DEMO_PREFERENCES);
EXPECT_TRUE(IsInDemoSetupFlow());
EXPECT_CALL(*mock_demo_preferences_screen_, Hide()).Times(1);
EXPECT_CALL(*mock_eula_screen_, Show()).Times(1);
OnExit(*mock_demo_preferences_screen_,
ScreenExitCode::DEMO_MODE_PREFERENCES_CONTINUED);
CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA);
EXPECT_TRUE(IsInDemoSetupFlow());
EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1);
EXPECT_CALL(*mock_demo_preferences_screen_, Show()).Times(1);
OnExit(*mock_eula_screen_, ScreenExitCode::EULA_BACK);
CheckCurrentScreen(OobeScreen::SCREEN_OOBE_DEMO_PREFERENCES);
EXPECT_TRUE(IsInDemoSetupFlow());
}
class WizardControllerOobeResumeTest : public WizardControllerTest {
......@@ -2260,7 +2368,7 @@ IN_PROC_BROWSER_TEST_F(WizardControllerOobeConfigurationTest,
// TODO(alemate): Add tests for Sync Consent UI.
// TODO(rsgingerrs): Add tests for Recommend Apps UI.
static_assert(static_cast<int>(ScreenExitCode::EXIT_CODES_COUNT) == 37,
static_assert(static_cast<int>(ScreenExitCode::EXIT_CODES_COUNT) == 39,
"tests for new control flow are missing");
} // namespace chromeos
<iron-iconset-svg name="demo-setup-32" size="32">
<svg>
<defs>
......
......@@ -648,7 +648,7 @@ void CoreOobeHandler::GetPrimaryDisplayNameCallback(
void CoreOobeHandler::HandleSetupDemoMode() {
WizardController* wizard_controller = WizardController::default_controller();
if (wizard_controller && !wizard_controller->login_screen_started()) {
wizard_controller->AdvanceToScreen(OobeScreen::SCREEN_OOBE_DEMO_SETUP);
wizard_controller->StartDemoModeSetup();
}
}
......
......@@ -1629,6 +1629,8 @@ test("browser_tests") {
"../browser/chromeos/login/resource_loader_browsertest.cc",
"../browser/chromeos/login/saml/saml_browsertest.cc",
"../browser/chromeos/login/screens/hid_detection_screen_browsertest.cc",
"../browser/chromeos/login/screens/mock_demo_preferences_screen.cc",
"../browser/chromeos/login/screens/mock_demo_preferences_screen.h",
"../browser/chromeos/login/screens/mock_demo_setup_screen.cc",
"../browser/chromeos/login/screens/mock_demo_setup_screen.h",
"../browser/chromeos/login/screens/mock_enable_debugging_screen.cc",
......
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