blob: d0949191c6c68da8367052ad7a4c0f20a6d368a7 [file] [log] [blame]
// 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_DEMO_MODE_DEMO_SETUP_CONTROLLER_H_
#define CHROME_BROWSER_CHROMEOS_LOGIN_DEMO_MODE_DEMO_SETUP_CONTROLLER_H_
#include <string>
#include "base/callback_forward.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "chrome/browser/chromeos/login/demo_mode/demo_session.h"
#include "chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper.h"
#include "chrome/browser/chromeos/policy/enrollment_status_chromeos.h"
#include "chrome/browser/component_updater/cros_component_installer_chromeos.h"
#include "components/policy/core/common/cloud/cloud_policy_store.h"
class PrefRegistrySimple;
namespace policy {
class DeviceCloudPolicyManagerChromeOS;
}
namespace chromeos {
class DemoResources;
// Controlls enrollment flow for setting up Demo Mode.
class DemoSetupController
: public EnterpriseEnrollmentHelper::EnrollmentStatusConsumer,
public policy::CloudPolicyStore::Observer {
public:
// Contains information related to setup error.
class DemoSetupError {
public:
// Type of setup error.
enum class ErrorCode {
// Offline resources not available on device.
kNoOfflineResources,
// Cannot load or parse offline policy.
kOfflinePolicyError,
// Local account policy store error.
kOfflinePolicyStoreError,
// Cannot perform offline setup without online FRE check.
kOnlineFRECheckRequired,
// Cannot load online component.
kOnlineComponentError,
// Invalid request to DMServer.
kInvalidRequest,
// Request to DMServer failed, because of network error.
kRequestNetworkError,
// DMServer temporary unavailable.
kTemporaryUnavailable,
// DMServer returned abnormal response code.
kResponseError,
// DMServer response cannot be decoded.
kResponseDecodingError,
// Device management not supported for demo account.
kDemoAccountError,
// DMServer cannot find the device.
kDeviceNotFound,
// Invalid device management token.
kInvalidDMToken,
// Serial number invalid or unknown to DMServer,
kInvalidSerialNumber,
// Device id conflict.
kDeviceIdError,
// Not enough licenses or domain expired.
kLicenseError,
// Device was deprovisioned.ec
kDeviceDeprovisioned,
// Device belongs to different domain (FRE).
kDomainMismatch,
// Management request could not be signed by the client.
kSigningError,
// DMServer could not find policy for the device.
kPolicyNotFound,
// ARC disabled for demo domain.
kArcError,
// Cannot determine server-backed state keys.
kNoStateKeys,
// Failed to fetch robot account auth or refresh token.
kRobotFetchError,
// Failed to fetch robot account refresh token.
kRobotStoreError,
// Unsuppored device mode returned by the server.
kBadMode,
// Could not fetch registration cert,
kCertFetchError,
// Could not fetch the policy.
kPolicyFetchError,
// Policy validation failed.
kPolicyValidationError,
// Timeout during locking the device.
kLockTimeout,
// Error during locking the device.
kLockError,
// Device locked to different domain on mode.
kAlreadyLocked,
// Error while installing online policy.
kOnlineStoreError,
// Could not determine device model or serial number.
kMachineIdentificationError,
// Could not store DM token.
kDMTokenStoreError,
// Unexpected/fatal error.
kUnexpectedError,
};
// Type of recommended recovery from the setup error.
enum class RecoveryMethod {
// Retry demo setup.
kRetry,
// Reboot and retry demo setup.
kReboot,
// Powerwash and retry demo setup.
kPowerwash,
// Check network and retry demo setup.
kCheckNetwork,
// Cannot perform offline setup - online setup might work.
kOnlineOnly,
// Unknown recovery method.
kUnknown,
};
static DemoSetupError CreateFromEnrollmentStatus(
const policy::EnrollmentStatus& status);
static DemoSetupError CreateFromOtherEnrollmentError(
EnterpriseEnrollmentHelper::OtherError error);
static DemoSetupError CreateFromComponentError(
component_updater::CrOSComponentManager::Error error);
DemoSetupError(ErrorCode error_code, RecoveryMethod recovery_method);
DemoSetupError(ErrorCode error_code,
RecoveryMethod recovery_method,
const std::string& debug_message);
~DemoSetupError();
ErrorCode error_code() const { return error_code_; }
RecoveryMethod recovery_method() const { return recovery_method_; }
base::string16 GetLocalizedErrorMessage() const;
base::string16 GetLocalizedRecoveryMessage() const;
std::string GetDebugDescription() const;
private:
ErrorCode error_code_;
RecoveryMethod recovery_method_;
std::string debug_message_;
};
// Demo mode setup callbacks.
using OnSetupSuccess = base::OnceClosure;
using OnSetupError = base::OnceCallback<void(const DemoSetupError&)>;
using HasPreinstalledDemoResourcesCallback = base::OnceCallback<void(bool)>;
// Domain that demo mode devices are enrolled into.
static constexpr char kDemoModeDomain[] = "cros-demo-mode.com";
static void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
// Clears demo device enrollment requisition on the given |policy_manager| if
// it is set.
static void ClearDemoRequisition(
policy::DeviceCloudPolicyManagerChromeOS* policy_manager);
// Utility method that returns whether demo mode is allowed on the device.
static bool IsDemoModeAllowed();
// Utility method that returns whether offline demo mode is allowed on the
// device.
static bool IsOfflineDemoModeAllowed();
// Utility method that returns whether demo mode setup flow is in progress in
// OOBE.
static bool IsOobeDemoSetupFlowInProgress();
DemoSetupController();
~DemoSetupController() override;
// Sets demo mode config that will be used to setup the device. It has to be
// set before calling Enroll().
void set_demo_config(DemoSession::DemoModeConfig demo_config) {
demo_config_ = demo_config;
}
// Whether offline enrollment is used for setup.
bool IsOfflineEnrollment() const;
// Initiates enrollment that sets up the device in the demo mode domain. The
// |enrollment_type_| determines whether online or offline setup will be
// performed and it should be set with set_enrollment_type() before calling
// Enroll(). |on_setup_success| will be called when enrollment finishes
// successfully. |on_setup_error| will be called when enrollment finishes with
// an error.
void Enroll(OnSetupSuccess on_setup_success, OnSetupError on_setup_error);
// Tries to mount the preinstalled offline resources necessary for offline
// Demo Mode.
void TryMountPreinstalledDemoResources(
HasPreinstalledDemoResourcesCallback callback);
void OnDeviceEnrolled() override;
void OnEnrollmentError(policy::EnrollmentStatus status) override;
void OnAuthError(const GoogleServiceAuthError& error) override;
void OnOtherError(EnterpriseEnrollmentHelper::OtherError error) override;
void OnDeviceAttributeUploadCompleted(bool success) override;
void OnDeviceAttributeUpdatePermission(bool granted) override;
void OnMultipleLicensesAvailable(
const EnrollmentLicenseMap& licenses) override;
void OnRestoreAfterRollbackCompleted() override;
void SetCrOSComponentLoadErrorForTest(
component_updater::CrOSComponentManager::Error error);
void SetPreinstalledOfflineResourcesPathForTesting(
const base::FilePath& path);
void SetDeviceLocalAccountPolicyStoreForTest(policy::CloudPolicyStore* store);
void SetOfflineDataDirForTest(const base::FilePath& offline_dir);
private:
// Attempts to load the CrOS component with demo resources for online
// enrollment and passes the result to OnDemoResourcesCrOSComponentLoaded().
void LoadDemoResourcesCrOSComponent();
// Callback to initiate online enrollment once the CrOS component has loaded.
// If the component loaded successfully, registers and sets up the device in
// the demo mode domain. If the component couldn't be loaded, demo setup
// will fail.
void OnDemoResourcesCrOSComponentLoaded();
// Callback after attempting to load preinstalled demo resources. If the
// resources were loaded, offline Demo Mode should be available.
void OnPreinstalledDemoResourcesLoaded(
HasPreinstalledDemoResourcesCallback callback);
// Initiates offline enrollment that locks the device and sets up offline
// policies required by demo mode. It requires no network connectivity since
// all setup will be done locally. The policy files will be loaded from the
// |policy_dir|.
void EnrollOffline(const base::FilePath& policy_dir);
// Called when the checks of policy files for the offline demo mode is done.
void OnOfflinePolicyFilesExisted(std::string* message, bool ok);
// Called when the device local account policy for the offline demo mode is
// loaded.
void OnDeviceLocalAccountPolicyLoaded(base::Optional<std::string> blob);
// Called when device is marked as registered and the second part of OOBE flow
// is completed. This is the last step of demo mode setup flow.
void OnDeviceRegistered();
// Finish the flow with an error.
void SetupFailed(const DemoSetupError& error);
// Clears the internal state.
void Reset();
// policy::CloudPolicyStore::Observer:
void OnStoreLoaded(policy::CloudPolicyStore* store) override;
void OnStoreError(policy::CloudPolicyStore* store) override;
// Demo mode configuration type that will be setup when Enroll() is called.
// Should be set explicitly.
DemoSession::DemoModeConfig demo_config_ = DemoSession::DemoModeConfig::kNone;
// Error code to use when attempting to load the demo resources CrOS
// component.
component_updater::CrOSComponentManager::Error component_error_for_tests_ =
component_updater::CrOSComponentManager::Error::NONE;
// Path at which to mount preinstalled offline demo resources for tests.
base::FilePath preinstalled_offline_resources_path_for_tests_;
// Callback to call when enrollment finishes with an error.
OnSetupError on_setup_error_;
// Callback to call when enrollment finishes successfully.
OnSetupSuccess on_setup_success_;
// The directory which contains the policy blob files for the offline
// enrollment (i.e. device_policy and local_account_policy). Should be empty
// on the online enrollment.
base::FilePath policy_dir_;
// The directory containing policy blob files used for testing.
base::FilePath policy_dir_for_tests_;
// The CloudPolicyStore for the device local account for the offline policy.
policy::CloudPolicyStore* device_local_account_policy_store_ = nullptr;
std::unique_ptr<EnterpriseEnrollmentHelper> enrollment_helper_;
// The preinstalled Demo Mode Resources for offline Demo Mode.
std::unique_ptr<DemoResources> preinstalled_demo_resources_;
// The Demo Mode Resources CrOS Component downloaded for online Demo Mode.
std::unique_ptr<DemoResources> demo_resources_;
base::WeakPtrFactory<DemoSetupController> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(DemoSetupController);
};
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_LOGIN_DEMO_MODE_DEMO_SETUP_CONTROLLER_H_