chromium/chrome/browser/ash/policy/enrollment/enrollment_requisition_manager.cc

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ash/policy/enrollment/enrollment_requisition_manager.h"

#include <string_view>

#include "base/logging.h"
#include "build/chromeos_buildflags.h"
#include "build/config/chromebox_for_meetings/buildflags.h"
#include "build/config/cuttlefish/buildflags.h"
#include "chrome/browser/ash/login/demo_mode/demo_setup_controller.h"
#include "chrome/browser/ash/login/startup_utils.h"
#include "chrome/browser/browser_process.h"
#include "chrome/common/pref_names.h"
#include "chromeos/ash/components/system/statistics_provider.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"

namespace policy {

using ::ash::system::StatisticsProvider;

// static
const char EnrollmentRequisitionManager::kNoRequisition[] = "none";
const char EnrollmentRequisitionManager::kRemoraRequisition[] = "remora";
const char EnrollmentRequisitionManager::kSharkRequisition[] = "shark";
const char EnrollmentRequisitionManager::kDemoRequisition[] = "cros-demo-mode";
const char EnrollmentRequisitionManager::kCuttlefishRequisition[] =
    "cuttlefish";

// static
void EnrollmentRequisitionManager::Initialize() {
  // OEM statistics are only loaded when OOBE is not completed.
  if (ash::StartupUtils::IsOobeCompleted())
    return;

  // Demo requisition may have been set in a prior enrollment attempt that was
  // interrupted.
  ash::DemoSetupController::ClearDemoRequisition();
  auto* local_state = g_browser_process->local_state();
  auto* provider = StatisticsProvider::GetInstance();
  const PrefService::Preference* pref =
      local_state->FindPreference(prefs::kDeviceEnrollmentRequisition);
  if (pref->IsDefaultValue()) {
    const std::optional<std::string_view> requisition =
        provider->GetMachineStatistic(ash::system::kOemDeviceRequisitionKey);

    if (requisition && !requisition->empty()) {
      local_state->SetString(prefs::kDeviceEnrollmentRequisition,
                             requisition.value());
      if (requisition == kRemoraRequisition ||
          requisition == kSharkRequisition) {
        SetDeviceEnrollmentAutoStart();
      } else {
        const bool auto_start = StatisticsProvider::FlagValueToBool(
            provider->GetMachineFlag(ash::system::kOemIsEnterpriseManagedKey),
            /*default_value=*/false);
        local_state->SetBoolean(prefs::kDeviceEnrollmentAutoStart, auto_start);
        const bool can_exit = StatisticsProvider::FlagValueToBool(
            provider->GetMachineFlag(
                ash::system::kOemCanExitEnterpriseEnrollmentKey),
            /*default_value=*/false);
        local_state->SetBoolean(prefs::kDeviceEnrollmentCanExit, can_exit);
      }
    }
  }
}

// static
std::string EnrollmentRequisitionManager::GetDeviceRequisition() {
  const PrefService::Preference* pref =
      g_browser_process->local_state()->FindPreference(
          prefs::kDeviceEnrollmentRequisition);
  std::string requisition;
  if (!pref->IsDefaultValue() && pref->GetValue()->is_string())
    requisition = pref->GetValue()->GetString();

  if (requisition == kNoRequisition)
    requisition.clear();

  return requisition;
}

// static
void EnrollmentRequisitionManager::SetDeviceRequisition(
    const std::string& requisition) {
  // TODO(crbug.com/40805389): Logging as "WARNING" to make sure it's preserved
  // in the logs.
  LOG(WARNING) << "SetDeviceRequisition " << requisition;

  auto* local_state = g_browser_process->local_state();
  if (requisition.empty()) {
    local_state->ClearPref(prefs::kDeviceEnrollmentRequisition);
    local_state->ClearPref(prefs::kDeviceEnrollmentAutoStart);
    local_state->ClearPref(prefs::kDeviceEnrollmentCanExit);
  } else {
    local_state->SetString(prefs::kDeviceEnrollmentRequisition, requisition);
    if (requisition == kNoRequisition) {
      local_state->ClearPref(prefs::kDeviceEnrollmentAutoStart);
      local_state->ClearPref(prefs::kDeviceEnrollmentCanExit);
    } else {
      SetDeviceEnrollmentAutoStart();
    }
  }
}

// static
bool EnrollmentRequisitionManager::IsRemoraRequisition() {
  return GetDeviceRequisition() == kRemoraRequisition;
}

// static
bool EnrollmentRequisitionManager::IsSharkRequisition() {
  return GetDeviceRequisition() == kSharkRequisition;
}

bool EnrollmentRequisitionManager::IsMeetDevice() {
#if BUILDFLAG(PLATFORM_CFM)
  return true;
#else
  return IsRemoraRequisition();
#endif  // BUILDFLAG(PLATFORM_CFM)
}

bool EnrollmentRequisitionManager::IsCuttlefishDevice() {
#if BUILDFLAG(PLATFORM_CUTTLEFISH)
  return true;
#else
  return false;
#endif  // BUILDFLAG(PLATFORM_CUTTLEFISH)
}

// static
std::string EnrollmentRequisitionManager::GetSubOrganization() {
  const PrefService::Preference* pref =
      g_browser_process->local_state()->FindPreference(
          prefs::kDeviceEnrollmentSubOrganization);
  if (!pref->IsDefaultValue() && pref->GetValue()->is_string())
    return pref->GetValue()->GetString();
  return std::string();
}

// static
void EnrollmentRequisitionManager::SetSubOrganization(
    const std::string& sub_organization) {
  if (sub_organization.empty())
    g_browser_process->local_state()->ClearPref(
        prefs::kDeviceEnrollmentSubOrganization);
  else
    g_browser_process->local_state()->SetString(
        prefs::kDeviceEnrollmentSubOrganization, sub_organization);
}

// static
void EnrollmentRequisitionManager::SetDeviceEnrollmentAutoStart() {
  g_browser_process->local_state()->SetBoolean(
      prefs::kDeviceEnrollmentAutoStart, true);
  g_browser_process->local_state()->SetBoolean(prefs::kDeviceEnrollmentCanExit,
                                               false);
}

// static
void EnrollmentRequisitionManager::RegisterPrefs(PrefRegistrySimple* registry) {
  registry->RegisterStringPref(prefs::kDeviceEnrollmentRequisition,
                               std::string());
  registry->RegisterStringPref(prefs::kDeviceEnrollmentSubOrganization,
                               std::string());
  registry->RegisterBooleanPref(prefs::kDeviceEnrollmentAutoStart, false);
  registry->RegisterBooleanPref(prefs::kDeviceEnrollmentCanExit, true);
  registry->RegisterStringPref(prefs::kEnrollmentVersionOS, std::string());
  registry->RegisterStringPref(prefs::kEnrollmentVersionBrowser, std::string());
}

}  // namespace policy