Commit 919287d0 authored by Wenzhao Zang's avatar Wenzhao Zang Committed by Commit Bot

cros: Show Powerwash button in case of a fatal demo setup error

Bug: 871412
Change-Id: I5bf054ed6ef4c927253fbad4fe09ec674cc58d39
Reviewed-on: https://chromium-review.googlesource.com/c/1310559Reviewed-by: default avatarAga Wronska <agawronska@chromium.org>
Reviewed-by: default avatarAlexander Alekseev <alemate@chromium.org>
Commit-Queue: Wenzhao (Colin) Zang <wzang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#605256}
parent 8bc8d513
...@@ -229,12 +229,38 @@ TEST_F(DemoSetupControllerTest, OfflineInvalidDeviceLocalAccountPolicyBlob) { ...@@ -229,12 +229,38 @@ TEST_F(DemoSetupControllerTest, OfflineInvalidDeviceLocalAccountPolicyBlob) {
EXPECT_EQ("", GetDeviceRequisition()); EXPECT_EQ("", GetDeviceRequisition());
} }
TEST_F(DemoSetupControllerTest, OfflineError) { TEST_F(DemoSetupControllerTest, OfflineErrorDefault) {
base::ScopedTempDir temp_dir; base::ScopedTempDir temp_dir;
ASSERT_TRUE(SetupDummyOfflinePolicyDir("test", &temp_dir)); ASSERT_TRUE(SetupDummyOfflinePolicyDir("test", &temp_dir));
EnterpriseEnrollmentHelper::SetupEnrollmentHelperMock( EnterpriseEnrollmentHelper::SetupEnrollmentHelperMock(
&MockDemoModeOfflineEnrollmentHelperCreator<DemoModeSetupResult::ERROR>); &MockDemoModeOfflineEnrollmentHelperCreator<
DemoModeSetupResult::ERROR_DEFAULT>);
policy::MockCloudPolicyStore mock_store;
EXPECT_CALL(mock_store, Store(_)).Times(0);
tested_controller_->SetDeviceLocalAccountPolicyStoreForTest(&mock_store);
tested_controller_->set_demo_config(DemoSession::DemoModeConfig::kOffline);
tested_controller_->SetOfflineDataDirForTest(temp_dir.GetPath());
tested_controller_->Enroll(
base::BindOnce(&DemoSetupControllerTestHelper::OnSetupSuccess,
base::Unretained(helper_.get())),
base::BindOnce(&DemoSetupControllerTestHelper::OnSetupError,
base::Unretained(helper_.get())));
EXPECT_TRUE(helper_->WaitResult(false));
EXPECT_FALSE(helper_->RequiresPowerwash());
EXPECT_EQ("", GetDeviceRequisition());
}
TEST_F(DemoSetupControllerTest, OfflineErrorPowerwashRequired) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(SetupDummyOfflinePolicyDir("test", &temp_dir));
EnterpriseEnrollmentHelper::SetupEnrollmentHelperMock(
&MockDemoModeOfflineEnrollmentHelperCreator<
DemoModeSetupResult::ERROR_POWERWASH_REQUIRED>);
policy::MockCloudPolicyStore mock_store; policy::MockCloudPolicyStore mock_store;
EXPECT_CALL(mock_store, Store(_)).Times(0); EXPECT_CALL(mock_store, Store(_)).Times(0);
...@@ -268,9 +294,10 @@ TEST_F(DemoSetupControllerTest, OnlineSuccess) { ...@@ -268,9 +294,10 @@ TEST_F(DemoSetupControllerTest, OnlineSuccess) {
EXPECT_EQ("", GetDeviceRequisition()); EXPECT_EQ("", GetDeviceRequisition());
} }
TEST_F(DemoSetupControllerTest, OnlineError) { TEST_F(DemoSetupControllerTest, OnlineErrorDefault) {
EnterpriseEnrollmentHelper::SetupEnrollmentHelperMock( EnterpriseEnrollmentHelper::SetupEnrollmentHelperMock(
&MockDemoModeOnlineEnrollmentHelperCreator<DemoModeSetupResult::ERROR>); &MockDemoModeOnlineEnrollmentHelperCreator<
DemoModeSetupResult::ERROR_DEFAULT>);
tested_controller_->set_demo_config(DemoSession::DemoModeConfig::kOnline); tested_controller_->set_demo_config(DemoSession::DemoModeConfig::kOnline);
tested_controller_->Enroll( tested_controller_->Enroll(
...@@ -284,6 +311,23 @@ TEST_F(DemoSetupControllerTest, OnlineError) { ...@@ -284,6 +311,23 @@ TEST_F(DemoSetupControllerTest, OnlineError) {
EXPECT_EQ("", GetDeviceRequisition()); EXPECT_EQ("", GetDeviceRequisition());
} }
TEST_F(DemoSetupControllerTest, OnlineErrorPowerwashRequired) {
EnterpriseEnrollmentHelper::SetupEnrollmentHelperMock(
&MockDemoModeOnlineEnrollmentHelperCreator<
DemoModeSetupResult::ERROR_POWERWASH_REQUIRED>);
tested_controller_->set_demo_config(DemoSession::DemoModeConfig::kOnline);
tested_controller_->Enroll(
base::BindOnce(&DemoSetupControllerTestHelper::OnSetupSuccess,
base::Unretained(helper_.get())),
base::BindOnce(&DemoSetupControllerTestHelper::OnSetupError,
base::Unretained(helper_.get())));
EXPECT_TRUE(helper_->WaitResult(false));
EXPECT_TRUE(helper_->RequiresPowerwash());
EXPECT_EQ("", GetDeviceRequisition());
}
TEST_F(DemoSetupControllerTest, OnlineComponentError) { TEST_F(DemoSetupControllerTest, OnlineComponentError) {
EnterpriseEnrollmentHelper::SetupEnrollmentHelperMock( EnterpriseEnrollmentHelper::SetupEnrollmentHelperMock(
&MockDemoModeOnlineEnrollmentHelperCreator<DemoModeSetupResult::SUCCESS>); &MockDemoModeOnlineEnrollmentHelperCreator<DemoModeSetupResult::SUCCESS>);
...@@ -305,7 +349,8 @@ TEST_F(DemoSetupControllerTest, OnlineComponentError) { ...@@ -305,7 +349,8 @@ TEST_F(DemoSetupControllerTest, OnlineComponentError) {
TEST_F(DemoSetupControllerTest, EnrollTwice) { TEST_F(DemoSetupControllerTest, EnrollTwice) {
EnterpriseEnrollmentHelper::SetupEnrollmentHelperMock( EnterpriseEnrollmentHelper::SetupEnrollmentHelperMock(
&MockDemoModeOnlineEnrollmentHelperCreator<DemoModeSetupResult::ERROR>); &MockDemoModeOnlineEnrollmentHelperCreator<
DemoModeSetupResult::ERROR_DEFAULT>);
tested_controller_->set_demo_config(DemoSession::DemoModeConfig::kOnline); tested_controller_->set_demo_config(DemoSession::DemoModeConfig::kOnline);
tested_controller_->Enroll( tested_controller_->Enroll(
......
...@@ -22,7 +22,12 @@ namespace chromeos { ...@@ -22,7 +22,12 @@ namespace chromeos {
namespace test { namespace test {
// Result of Demo Mode setup. // Result of Demo Mode setup.
enum class DemoModeSetupResult { SUCCESS, ERROR }; // TODO(agawronska, wzang): Test more error types.
enum class DemoModeSetupResult {
SUCCESS,
ERROR_DEFAULT,
ERROR_POWERWASH_REQUIRED
};
// Helper method that mocks EnterpriseEnrollmentHelper for online Demo Mode // Helper method that mocks EnterpriseEnrollmentHelper for online Demo Mode
// setup. It simulates specified Demo Mode enrollment |result|. // setup. It simulates specified Demo Mode enrollment |result|.
...@@ -37,14 +42,23 @@ EnterpriseEnrollmentHelper* MockDemoModeOnlineEnrollmentHelperCreator( ...@@ -37,14 +42,23 @@ EnterpriseEnrollmentHelper* MockDemoModeOnlineEnrollmentHelperCreator(
EXPECT_EQ(enrollment_config.mode, policy::EnrollmentConfig::MODE_ATTESTATION); EXPECT_EQ(enrollment_config.mode, policy::EnrollmentConfig::MODE_ATTESTATION);
EXPECT_CALL(*mock, EnrollUsingAttestation()) EXPECT_CALL(*mock, EnrollUsingAttestation())
.WillRepeatedly(testing::Invoke([mock]() { .WillRepeatedly(testing::Invoke([mock]() {
if (result == DemoModeSetupResult::SUCCESS) { switch (result) {
mock->status_consumer()->OnDeviceEnrolled(""); case DemoModeSetupResult::SUCCESS:
} else { mock->status_consumer()->OnDeviceEnrolled("");
// TODO(agawronska): Test different error types. break;
mock->status_consumer()->OnEnrollmentError( case DemoModeSetupResult::ERROR_POWERWASH_REQUIRED:
policy::EnrollmentStatus::ForRegistrationError( mock->status_consumer()->OnEnrollmentError(
policy::DeviceManagementStatus:: policy::EnrollmentStatus::ForLockError(
DM_STATUS_TEMPORARY_UNAVAILABLE)); chromeos::InstallAttributes::LOCK_ALREADY_LOCKED));
break;
case DemoModeSetupResult::ERROR_DEFAULT:
mock->status_consumer()->OnEnrollmentError(
policy::EnrollmentStatus::ForRegistrationError(
policy::DeviceManagementStatus::
DM_STATUS_TEMPORARY_UNAVAILABLE));
break;
default:
NOTREACHED();
} }
})); }));
return mock; return mock;
...@@ -64,13 +78,22 @@ EnterpriseEnrollmentHelper* MockDemoModeOfflineEnrollmentHelperCreator( ...@@ -64,13 +78,22 @@ EnterpriseEnrollmentHelper* MockDemoModeOfflineEnrollmentHelperCreator(
policy::EnrollmentConfig::MODE_OFFLINE_DEMO); policy::EnrollmentConfig::MODE_OFFLINE_DEMO);
EXPECT_CALL(*mock, EnrollForOfflineDemo()) EXPECT_CALL(*mock, EnrollForOfflineDemo())
.WillRepeatedly(testing::Invoke([mock]() { .WillRepeatedly(testing::Invoke([mock]() {
if (result == DemoModeSetupResult::SUCCESS) { switch (result) {
mock->status_consumer()->OnDeviceEnrolled(""); case DemoModeSetupResult::SUCCESS:
} else { mock->status_consumer()->OnDeviceEnrolled("");
// TODO(agawronska): Test different error types. break;
mock->status_consumer()->OnEnrollmentError( case DemoModeSetupResult::ERROR_POWERWASH_REQUIRED:
policy::EnrollmentStatus::ForLockError( mock->status_consumer()->OnEnrollmentError(
chromeos::InstallAttributes::LOCK_READBACK_ERROR)); policy::EnrollmentStatus::ForLockError(
chromeos::InstallAttributes::LOCK_READBACK_ERROR));
break;
case DemoModeSetupResult::ERROR_DEFAULT:
mock->status_consumer()->OnEnrollmentError(
policy::EnrollmentStatus::ForStatus(
policy::EnrollmentStatus::OFFLINE_POLICY_DECODING_FAILED));
break;
default:
NOTREACHED();
} }
})); }));
return mock; return mock;
......
...@@ -8,11 +8,14 @@ ...@@ -8,11 +8,14 @@
#include "chrome/browser/chromeos/login/screens/base_screen_delegate.h" #include "chrome/browser/chromeos/login/screens/base_screen_delegate.h"
#include "chrome/browser/chromeos/login/screens/demo_setup_screen_view.h" #include "chrome/browser/chromeos/login/screens/demo_setup_screen_view.h"
#include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/session_manager_client.h"
namespace { namespace {
constexpr char kUserActionStartSetup[] = "start-setup"; constexpr char kUserActionStartSetup[] = "start-setup";
constexpr char kUserActionClose[] = "close-setup"; constexpr char kUserActionClose[] = "close-setup";
constexpr char kUserActionPowerwash[] = "powerwash";
} // namespace } // namespace
...@@ -47,6 +50,10 @@ void DemoSetupScreen::OnUserAction(const std::string& action_id) { ...@@ -47,6 +50,10 @@ void DemoSetupScreen::OnUserAction(const std::string& action_id) {
StartEnrollment(); StartEnrollment();
} else if (action_id == kUserActionClose) { } else if (action_id == kUserActionClose) {
Finish(ScreenExitCode::DEMO_MODE_SETUP_CANCELED); Finish(ScreenExitCode::DEMO_MODE_SETUP_CANCELED);
} else if (action_id == kUserActionPowerwash) {
chromeos::DBusThreadManager::Get()
->GetSessionManagerClient()
->StartDeviceWipe();
} else { } else {
BaseScreen::OnUserAction(action_id); BaseScreen::OnUserAction(action_id);
} }
......
...@@ -51,12 +51,20 @@ ...@@ -51,12 +51,20 @@
images/alert-illustration_2x.svg 2x"> images/alert-illustration_2x.svg 2x">
</div> </div>
<div slot="bottom-buttons" class="layout horizontal justified"> <div slot="bottom-buttons" class="layout horizontal justified">
<oobe-back-button inverse on-tap="onCloseClicked_"></oobe-back-button> <oobe-back-button inverse on-tap="onCloseClicked_"
<oobe-text-button inverse on-tap="onRetryClicked_"> disabled="[[isPowerwashRequired_]]"></oobe-back-button>
<oobe-text-button id="retryButton" on-tap="onRetryClicked_"
inverse hidden="[[isPowerwashRequired_]]">
<div> <div>
[[i18nDynamic(locale, 'demoSetupErrorScreenRetryButtonLabel')]] [[i18nDynamic(locale, 'demoSetupErrorScreenRetryButtonLabel')]]
</div> </div>
</oobe-text-button> </oobe-text-button>
<oobe-text-button id="powerwashButton" on-tap="onPowerwashClicked_"
inverse hidden="[[!isPowerwashRequired_]]">
<div>
[[i18nDynamic(locale, 'demoSetupErrorScreenPowerwashButtonLabel')]]
</div>
</oobe-text-button>
</div> </div>
</oobe-dialog> </oobe-dialog>
......
...@@ -19,6 +19,12 @@ Polymer({ ...@@ -19,6 +19,12 @@ Polymer({
value: '', value: '',
}, },
/** Whether powerwash is required in case of a setup error. */
isPowerwashRequired_: {
type: Boolean,
value: false,
},
/** Ordered array of screen ids that are a part of demo setup flow. */ /** Ordered array of screen ids that are a part of demo setup flow. */
screens_: { screens_: {
type: Array, type: Array,
...@@ -48,9 +54,12 @@ Polymer({ ...@@ -48,9 +54,12 @@ Polymer({
/** /**
* Called when demo mode setup failed. * Called when demo mode setup failed.
* @param {string} message Error message to be displayed to the user. * @param {string} message Error message to be displayed to the user.
* @param {boolean} isPowerwashRequired Whether powerwash is required to
* recover from the error.
*/ */
onSetupFailed: function(message) { onSetupFailed: function(message, isPowerwashRequired) {
this.errorMessage_ = message; this.errorMessage_ = message;
this.isPowerwashRequired_ = isPowerwashRequired;
this.showScreen_('demoSetupErrorDialog'); this.showScreen_('demoSetupErrorDialog');
}, },
...@@ -96,11 +105,22 @@ Polymer({ ...@@ -96,11 +105,22 @@ Polymer({
this.reset(); this.reset();
}, },
/**
* Powerwash button click handler.
* @private
*/
onPowerwashClicked_: function() {
chrome.send('login.DemoSetupScreen.userActed', ['powerwash']);
},
/** /**
* Close button click handler. * Close button click handler.
* @private * @private
*/ */
onCloseClicked_: function() { onCloseClicked_: function() {
// TODO(wzang): Remove this after crbug.com/900640 is fixed.
if (this.isPowerwashRequired_)
return;
chrome.send('login.DemoSetupScreen.userActed', ['close-setup']); chrome.send('login.DemoSetupScreen.userActed', ['close-setup']);
}, },
}); });
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
Attributes: Attributes:
'disabled' - button is disabled when the attribute is set. 'disabled' - button is disabled when the attribute is set.
(See crbug.com/900640)
'inverse' - makes text white and background blue. 'inverse' - makes text white and background blue.
'label-for-aria' - accessibility label. 'label-for-aria' - accessibility label.
'border' - adds border to the button. 'border' - adds border to the button.
...@@ -84,6 +85,7 @@ ...@@ -84,6 +85,7 @@
Attributes: Attributes:
'disabled' - button is disabled when the attribute is set. 'disabled' - button is disabled when the attribute is set.
(See crbug.com/900640)
'label-for-aria' - accessibility label. 'label-for-aria' - accessibility label.
--> -->
<dom-module id="oobe-back-button"> <dom-module id="oobe-back-button">
......
...@@ -45,9 +45,11 @@ login.createScreen('DemoSetupScreen', 'demo-setup', function() { ...@@ -45,9 +45,11 @@ login.createScreen('DemoSetupScreen', 'demo-setup', function() {
/** /**
* Called when demo mode setup failed. * Called when demo mode setup failed.
* @param {string} message Error message to be displayed to the user. * @param {string} message Error message to be displayed to the user.
* @param {boolean} isPowerwashRequired Whether powerwash is required to
* recover from the error.
*/ */
onSetupFailed: function(message) { onSetupFailed: function(message, isPowerwashRequired) {
this.demoSetupModule_.onSetupFailed(message); this.demoSetupModule_.onSetupFailed(message, isPowerwashRequired);
}, },
}; };
}); });
...@@ -43,10 +43,13 @@ void DemoSetupScreenHandler::Bind(DemoSetupScreen* screen) { ...@@ -43,10 +43,13 @@ void DemoSetupScreenHandler::Bind(DemoSetupScreen* screen) {
void DemoSetupScreenHandler::OnSetupFailed( void DemoSetupScreenHandler::OnSetupFailed(
const DemoSetupController::DemoSetupError& error) { const DemoSetupController::DemoSetupError& error) {
// TODO(wzang): Consider customization for RecoveryMethod::kReboot as well.
CallJS("onSetupFailed", CallJS("onSetupFailed",
base::JoinString({error.GetLocalizedErrorMessage(), base::JoinString({error.GetLocalizedErrorMessage(),
error.GetLocalizedRecoveryMessage()}, error.GetLocalizedRecoveryMessage()},
base::UTF8ToUTF16(" "))); base::UTF8ToUTF16(" ")),
error.recovery_method() ==
DemoSetupController::DemoSetupError::RecoveryMethod::kPowerwash);
} }
void DemoSetupScreenHandler::OnSetupSucceeded() { void DemoSetupScreenHandler::OnSetupSucceeded() {
...@@ -63,6 +66,8 @@ void DemoSetupScreenHandler::DeclareLocalizedValues( ...@@ -63,6 +66,8 @@ void DemoSetupScreenHandler::DeclareLocalizedValues(
IDS_OOBE_DEMO_SETUP_ERROR_SCREEN_TITLE); IDS_OOBE_DEMO_SETUP_ERROR_SCREEN_TITLE);
builder->Add("demoSetupErrorScreenRetryButtonLabel", builder->Add("demoSetupErrorScreenRetryButtonLabel",
IDS_OOBE_DEMO_SETUP_ERROR_SCREEN_RETRY_BUTTON_LABEL); IDS_OOBE_DEMO_SETUP_ERROR_SCREEN_RETRY_BUTTON_LABEL);
builder->Add("demoSetupErrorScreenPowerwashButtonLabel",
IDS_LOCAL_STATE_ERROR_POWERWASH_BUTTON);
} }
} // namespace chromeos } // namespace chromeos
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