910e62b5创建于 1月15日历史提交
// Copyright 2017 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/arc/arc_util.h"

#include <memory>

#include "ash/constants/ash_features.h"
#include "base/command_line.h"
#include "base/memory/raw_ptr.h"
#include "base/system/sys_info.h"
#include "base/test/icu_test_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_command_line.h"
#include "base/test/scoped_feature_list.h"
#include "base/values.h"
#include "chrome/browser/ash/arc/session/arc_session_manager.h"
#include "chrome/browser/ash/login/demo_mode/demo_session.h"
#include "chrome/browser/ash/login/oobe_configuration.h"
#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/ash/login/wizard_controller.h"
#include "chrome/browser/ash/profiles/profile_helper.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/ash/login/fake_login_display_host.h"
#include "chrome/browser/ui/webui/ash/login/consolidated_consent_screen_handler.h"
#include "chrome/browser/ui/webui/ash/login/demo_preferences_screen_handler.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "chromeos/ash/components/dbus/concierge/concierge_client.h"
#include "chromeos/ash/components/install_attributes/stub_install_attributes.h"
#include "chromeos/ash/components/settings/cros_settings.h"
#include "chromeos/ash/experiences/arc/arc_features.h"
#include "chromeos/ash/experiences/arc/arc_prefs.h"
#include "components/account_id/account_id.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/testing_pref_service.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "components/user_manager/known_user.h"
#include "components/user_manager/scoped_user_manager.h"
#include "components/user_manager/user_manager.h"
#include "components/user_manager/user_names.h"
#include "components/version_info/version_info.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_task_environment.h"
#include "google_apis/gaia/gaia_id.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace arc {
namespace util {

namespace {

constexpr char kTestProfileName[] = "user@gmail.com";
constexpr GaiaId::Literal kTestGaiaId("1234567890");

void SetProfileIsManagedForTesting(Profile* profile) {
  policy::ProfilePolicyConnector* const connector =
      profile->GetProfilePolicyConnector();
  connector->OverrideIsManagedForTesting(true);
}

void DisableDBusForProfileManager() {
  // Prevent access to DBus. This switch is reset in case set from test SetUp
  // due massive usage of InitFromArgv.
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (!command_line->HasSwitch(switches::kTestType))
    command_line->AppendSwitch(switches::kTestType);
}

class ScopedLogIn {
 public:
  ScopedLogIn(
      ash::FakeChromeUserManager* fake_user_manager,
      const AccountId& account_id,
      user_manager::UserType user_type = user_manager::UserType::kRegular)
      : ScopedLogIn(false, fake_user_manager, account_id, user_type) {}
  ScopedLogIn(
      bool isAffiliated,
      ash::FakeChromeUserManager* fake_user_manager,
      const AccountId& account_id,
      user_manager::UserType user_type = user_manager::UserType::kRegular)
      : fake_user_manager_(fake_user_manager), account_id_(account_id) {
    // Prevent access to DBus. This switch is reset in case set from test SetUp
    // due massive usage of InitFromArgv.
    base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
    if (!command_line.HasSwitch(switches::kTestType))
      command_line.AppendSwitch(switches::kTestType);

    switch (user_type) {
      case user_manager::UserType::kRegular:
        if (!isAffiliated)
          LogIn();
        else
          LogInWithAffiliatedAccount();
        break;
      case user_manager::UserType::kPublicAccount:
        LogInAsPublicAccount();
        break;
      default:
        NOTREACHED();
    }
  }

  ScopedLogIn(const ScopedLogIn&) = delete;
  ScopedLogIn& operator=(const ScopedLogIn&) = delete;

  ~ScopedLogIn() { fake_user_manager_->RemoveUserFromList(account_id_); }

 private:
  void LogIn() {
    fake_user_manager_->AddUser(account_id_);
    fake_user_manager_->LoginUser(account_id_);
  }

  void LogInAsPublicAccount() {
    fake_user_manager_->AddPublicAccountUser(account_id_);
    fake_user_manager_->LoginUser(account_id_);
  }

  void LogInWithAffiliatedAccount() {
    fake_user_manager_->AddUserWithAffiliation(account_id_, true);
    fake_user_manager_->LoginUser(account_id_);
  }

  raw_ptr<ash::FakeChromeUserManager> fake_user_manager_;
  const AccountId account_id_;
};

bool IsArcAllowedForProfileOnFirstCall(const Profile* profile) {
  ResetArcAllowedCheckForTesting(profile);
  return IsArcAllowedForProfile(profile);
}

}  // namespace

class ChromeArcUtilTest : public testing::Test {
 public:
  ChromeArcUtilTest() = default;

  ChromeArcUtilTest(const ChromeArcUtilTest&) = delete;
  ChromeArcUtilTest& operator=(const ChromeArcUtilTest&) = delete;

  ~ChromeArcUtilTest() override = default;

  void SetUp() override {
    command_line_ = std::make_unique<base::test::ScopedCommandLine>();

    fake_user_manager_.Reset(std::make_unique<ash::FakeChromeUserManager>());

    ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
    profile_manager_ = std::make_unique<TestingProfileManager>(
        TestingBrowserProcess::GetGlobal());
    ASSERT_TRUE(profile_manager_->SetUp());

    profile_ = profile_manager_->CreateTestingProfile(kTestProfileName);
  }

  void TearDown() override {
    // Avoid retries, let the next test start safely.
    ResetArcAllowedCheckForTesting(profile_);
    SetArcvmDlcImageStatusForTesting(
        /*arcvm dlc image availability=*/std::nullopt);
    profile_manager_->DeleteTestingProfile(kTestProfileName);
    profile_ = nullptr;
    profile_manager_.reset();
    fake_user_manager_.Reset();
    command_line_.reset();
  }

  TestingProfile* profile() { return profile_; }

  ash::FakeChromeUserManager* GetFakeUserManager() const {
    return fake_user_manager_.Get();
  }

  void LogIn() {
    const auto account_id = AccountId::FromUserEmailGaiaId(
        profile()->GetProfileUserName(), kTestGaiaId);
    fake_user_manager_->AddUser(account_id);
    fake_user_manager_->LoginUser(account_id);
  }

 protected:
  ash::ScopedCrosSettingsTestHelper cros_settings_test_helper_;

 private:
  std::unique_ptr<base::test::ScopedCommandLine> command_line_;
  content::BrowserTaskEnvironment task_environment_;
  base::ScopedTempDir data_dir_;
  user_manager::TypedScopedUserManager<ash::FakeChromeUserManager>
      fake_user_manager_;
  std::unique_ptr<TestingProfileManager> profile_manager_;
  // Owned by |profile_manager_|
  raw_ptr<TestingProfile, DanglingUntriaged> profile_ = nullptr;
};

TEST_F(ChromeArcUtilTest, IsArcAllowedForProfile) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  ScopedLogIn login(GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  EXPECT_TRUE(IsArcAllowedForProfileOnFirstCall(profile()));

  // false for nullptr.
  EXPECT_FALSE(IsArcAllowedForProfileOnFirstCall(nullptr));

  // false for incognito mode profile.
  EXPECT_FALSE(IsArcAllowedForProfileOnFirstCall(
      profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true)));
}

TEST_F(ChromeArcUtilTest, IsArcAllowedForProfileLegacy) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv({"", "--enable-arc"});
  ScopedLogIn login(GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  EXPECT_TRUE(IsArcAllowedForProfileOnFirstCall(profile()));

  // false for nullptr.
  EXPECT_FALSE(IsArcAllowedForProfileOnFirstCall(nullptr));

  // false for incognito mode profile.
  EXPECT_FALSE(IsArcAllowedForProfileOnFirstCall(
      profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true)));
}

TEST_F(ChromeArcUtilTest, IsArcAllowedForProfile_DisableArc) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv({""});
  ScopedLogIn login(GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  EXPECT_FALSE(IsArcAllowedForProfileOnFirstCall(profile()));
}

TEST_F(ChromeArcUtilTest, IsArcAllowedForProfile_NonPrimaryProfile) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  ScopedLogIn login2(
      GetFakeUserManager(),
      AccountId::FromUserEmailGaiaId("user2@gmail.com", GaiaId("0123456789")));
  ScopedLogIn login(GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  EXPECT_FALSE(IsArcAllowedForProfileOnFirstCall(profile()));
}

// User without GAIA account.
TEST_F(ChromeArcUtilTest, IsArcAllowedForProfile_PublicAccount) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  ScopedLogIn login(GetFakeUserManager(),
                    AccountId::FromUserEmail("public_user@gmail.com"),
                    user_manager::UserType::kPublicAccount);
  EXPECT_TRUE(IsArcAllowedForProfile(profile()));
}

// Guest account is interpreted as EphemeralDataUser.
TEST_F(ChromeArcUtilTest, IsArcAllowedForProfile_GuestAccount) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  ScopedLogIn login(GetFakeUserManager(), user_manager::GuestAccountId());
  EXPECT_TRUE(IsArcAllowedForProfileOnFirstCall(profile()));
}

// The reven devices without the ARCVM DLC image is not allowed to
// use arc.
TEST_F(ChromeArcUtilTest, IsArcAllowedForProfile_NoArcvmDlcImage_Reven) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported", "--reven-branding"});
  SetArcvmDlcImageStatusForTesting(/*arcvm dlc image availability=*/false);
  EXPECT_FALSE(IsArcAllowedForProfileOnFirstCall(profile()));
}

// Unmanaged account on managed device is not allowed to
// use arc on reven board.
TEST_F(ChromeArcUtilTest, IsArcAllowedForProfile_UnmanagedAccount_Reven) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported", "--reven-branding"});
  SetArcvmDlcImageStatusForTesting(/*arcvm dlc image availability=*/true);
  cros_settings_test_helper_.InstallAttributes()->SetCloudManaged(
      "example.com", "fake-device-id");
  EXPECT_FALSE(IsArcAllowedForProfileOnFirstCall(profile()));
}

// Managed account on unmanaged device is not allowed to
// use arc on reven board.
TEST_F(ChromeArcUtilTest, IsArcAllowedForProfile_UnmanagedDevice_Reven) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported", "--reven-branding"});
  SetArcvmDlcImageStatusForTesting(/*arcvm dlc image availability=*/true);
  ScopedLogIn login(GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  SetProfileIsManagedForTesting(profile());
  EXPECT_FALSE(IsArcAllowedForProfileOnFirstCall(profile()));
}

// Managed account on managed device is allowed to use arc
// on reven board.
TEST_F(ChromeArcUtilTest, IsArcAllowedForProfile_ManagedDeviceAccount_Reven) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported", "--reven-branding"});
  SetArcvmDlcImageStatusForTesting(/*arcvm dlc image availability=*/true);
  ScopedLogIn login(GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  SetProfileIsManagedForTesting(profile());
  cros_settings_test_helper_.InstallAttributes()->SetCloudManaged(
      "example.com", "fake-device-id");
  EXPECT_TRUE(IsArcAllowedForProfileOnFirstCall(profile()));
}

// Demo account is interpreted as EphemeralDataUser.
TEST_F(ChromeArcUtilTest, IsArcAllowedForProfile_DemoAccount) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  ScopedLogIn login(GetFakeUserManager(), user_manager::DemoAccountId());
  EXPECT_TRUE(IsArcAllowedForProfileOnFirstCall(profile()));
}

TEST_F(ChromeArcUtilTest, IsArcBlockedDueToIncompatibleFileSystem) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  SetArcBlockedDueToIncompatibleFileSystemForTesting(true);

  const AccountId user_id(AccountId::FromUserEmailGaiaId(
      profile()->GetProfileUserName(), kTestGaiaId));
  const AccountId robot_id(
      AccountId::FromUserEmail(profile()->GetProfileUserName()));

  // Blocked for a regular user.
  {
    ScopedLogIn login(GetFakeUserManager(), user_id,
                      user_manager::UserType::kRegular);
    EXPECT_TRUE(IsArcBlockedDueToIncompatibleFileSystem(profile()));
  }

  // Never blocked for a public session.
  {
    ScopedLogIn login(GetFakeUserManager(), robot_id,
                      user_manager::UserType::kPublicAccount);
    EXPECT_FALSE(IsArcBlockedDueToIncompatibleFileSystem(profile()));
  }
}

TEST_F(ChromeArcUtilTest, IsArcCompatibleFileSystemUsedForProfile) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});

  const AccountId id(AccountId::FromUserEmailGaiaId(
      profile()->GetProfileUserName(), kTestGaiaId));
  ScopedLogIn login(GetFakeUserManager(), id);
  const user_manager::User* user =
      ash::ProfileHelper::Get()->GetUserByProfile(profile());

  // Unconfirmed
  EXPECT_TRUE(IsArcCompatibleFileSystemUsedForUser(user));

  user_manager::KnownUser known_user(g_browser_process->local_state());
  // Old FS
  known_user.SetIntegerPref(id, prefs::kArcCompatibleFilesystemChosen,
                            kFileSystemIncompatible);
  EXPECT_FALSE(IsArcCompatibleFileSystemUsedForUser(user));

  // New FS
  known_user.SetIntegerPref(id, prefs::kArcCompatibleFilesystemChosen,
                            kFileSystemCompatible);
  EXPECT_TRUE(IsArcCompatibleFileSystemUsedForUser(user));

  // New FS (User notified)
  known_user.SetIntegerPref(id, prefs::kArcCompatibleFilesystemChosen,
                            kFileSystemCompatibleAndNotifiedDeprecated);
  EXPECT_TRUE(IsArcCompatibleFileSystemUsedForUser(user));
}

TEST_F(ChromeArcUtilTest, ArcPlayStoreEnabledForProfile) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  // Ensure IsAllowedForProfile() true.
  ScopedLogIn login(GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  ASSERT_TRUE(IsArcAllowedForProfileOnFirstCall(profile()));

  // By default, Google Play Store is disabled.
  EXPECT_FALSE(IsArcPlayStoreEnabledForProfile(profile()));

  // Enable Google Play Store.
  SetArcPlayStoreEnabledForProfile(profile(), true);
  EXPECT_TRUE(IsArcPlayStoreEnabledForProfile(profile()));

  // Disable Google Play Store.
  SetArcPlayStoreEnabledForProfile(profile(), false);
  EXPECT_FALSE(IsArcPlayStoreEnabledForProfile(profile()));
}

TEST_F(ChromeArcUtilTest, ArcPlayStoreEnabledForProfile_NotAllowed) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  ASSERT_FALSE(IsArcAllowedForProfileOnFirstCall(profile()));

  // If ARC is not allowed for the profile, always return false.
  EXPECT_FALSE(IsArcPlayStoreEnabledForProfile(profile()));

  // Directly set the preference value, to avoid DCHECK in
  // SetArcPlayStoreEnabledForProfile().
  profile()->GetPrefs()->SetBoolean(prefs::kArcEnabled, true);
  EXPECT_FALSE(IsArcPlayStoreEnabledForProfile(profile()));
}

TEST_F(ChromeArcUtilTest, ArcPlayStoreEnabledForProfile_Managed) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  // Ensure IsAllowedForProfile() true.
  ScopedLogIn login(GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  ASSERT_TRUE(IsArcAllowedForProfileOnFirstCall(profile()));

  // By default it is not managed.
  EXPECT_FALSE(IsArcPlayStoreEnabledPreferenceManagedForProfile(profile()));
  EXPECT_FALSE(IsArcPlayStoreEnabledForProfile(profile()));

  // 1) Set managed preference to true, then try to set the value to false
  // via SetArcPlayStoreEnabledForProfile().
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcEnabled, std::make_unique<base::Value>(true));
  EXPECT_TRUE(IsArcPlayStoreEnabledPreferenceManagedForProfile(profile()));
  EXPECT_TRUE(IsArcPlayStoreEnabledForProfile(profile()));
  SetArcPlayStoreEnabledForProfile(profile(), false);
  EXPECT_TRUE(IsArcPlayStoreEnabledPreferenceManagedForProfile(profile()));
  EXPECT_TRUE(IsArcPlayStoreEnabledForProfile(profile()));

  // Remove managed state.
  profile()->GetTestingPrefService()->RemoveManagedPref(prefs::kArcEnabled);
  EXPECT_FALSE(IsArcPlayStoreEnabledPreferenceManagedForProfile(profile()));

  // 2) Set managed preference to false, then try to set the value to true
  // via SetArcPlayStoreEnabledForProfile().
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcEnabled, std::make_unique<base::Value>(false));
  EXPECT_TRUE(IsArcPlayStoreEnabledPreferenceManagedForProfile(profile()));
  EXPECT_FALSE(IsArcPlayStoreEnabledForProfile(profile()));
  SetArcPlayStoreEnabledForProfile(profile(), true);
  EXPECT_TRUE(IsArcPlayStoreEnabledPreferenceManagedForProfile(profile()));
  EXPECT_FALSE(IsArcPlayStoreEnabledForProfile(profile()));

  // Remove managed state.
  profile()->GetTestingPrefService()->RemoveManagedPref(prefs::kArcEnabled);
  EXPECT_FALSE(IsArcPlayStoreEnabledPreferenceManagedForProfile(profile()));
}

// Test the AreArcAllOptInPreferencesIgnorableForProfile() function.
TEST_F(ChromeArcUtilTest, AreArcAllOptInPreferencesIgnorableForProfile) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  // OptIn prefs are unset, the function returns false.
  EXPECT_FALSE(AreArcAllOptInPreferencesIgnorableForProfile(profile()));

  // OptIn prefs are set to unmanaged/OFF values, and the function returns
  // false.
  profile()->GetPrefs()->SetBoolean(prefs::kArcBackupRestoreEnabled, false);
  profile()->GetPrefs()->SetBoolean(prefs::kArcLocationServiceEnabled, false);
  EXPECT_FALSE(AreArcAllOptInPreferencesIgnorableForProfile(profile()));

  // OptIn prefs are set to unmanaged/ON values, and the function returns false.
  profile()->GetPrefs()->SetBoolean(prefs::kArcBackupRestoreEnabled, true);
  profile()->GetPrefs()->SetBoolean(prefs::kArcLocationServiceEnabled, true);
  EXPECT_FALSE(AreArcAllOptInPreferencesIgnorableForProfile(profile()));

  // Backup-restore pref is managed/OFF, while location-service is unmanaged,
  // and the function returns false.
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcBackupRestoreEnabled, std::make_unique<base::Value>(false));
  profile()->GetPrefs()->SetBoolean(prefs::kArcLocationServiceEnabled, false);
  // When PrivacyHubLocation is enabled, the location setting is no longer
  // ARC++ specific, but ChromeOS system setting. Thus we only check the
  // Backup-restore pref.
  EXPECT_EQ(ash::features::IsCrosPrivacyHubLocationEnabled(),
            AreArcAllOptInPreferencesIgnorableForProfile(profile()));

  // Location-service pref is managed/OFF, while backup-restore is unmanaged,
  // and the function returns false.
  profile()->GetTestingPrefService()->RemoveManagedPref(
      prefs::kArcBackupRestoreEnabled);
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcLocationServiceEnabled, std::make_unique<base::Value>(false));
  EXPECT_FALSE(AreArcAllOptInPreferencesIgnorableForProfile(profile()));

  // Both OptIn prefs are set to managed/OFF values, and the function returns
  // true.
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcBackupRestoreEnabled, std::make_unique<base::Value>(false));
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcLocationServiceEnabled, std::make_unique<base::Value>(false));
  EXPECT_TRUE(AreArcAllOptInPreferencesIgnorableForProfile(profile()));

  // Backup-restore pref is set to managed/ON, while location-service pref is
  // set to managed/OFF, and the function returns true.
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcBackupRestoreEnabled, std::make_unique<base::Value>(true));
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcLocationServiceEnabled, std::make_unique<base::Value>(false));
  EXPECT_TRUE(AreArcAllOptInPreferencesIgnorableForProfile(profile()));

  // Location-service pref is set to managed/ON, while location-service pref is
  // set to managed/OFF, and the function returns true.
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcBackupRestoreEnabled, std::make_unique<base::Value>(false));
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcLocationServiceEnabled, std::make_unique<base::Value>(true));
  EXPECT_TRUE(AreArcAllOptInPreferencesIgnorableForProfile(profile()));

  // Both OptIn prefs are set to managed/ON values, and the function returns
  // true.
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcBackupRestoreEnabled, std::make_unique<base::Value>(true));
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcLocationServiceEnabled, std::make_unique<base::Value>(true));
  EXPECT_TRUE(AreArcAllOptInPreferencesIgnorableForProfile(profile()));
}

TEST_F(ChromeArcUtilTest, TermsOfServiceNegotiationNeededForAlreadyAccepted) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  DisableDBusForProfileManager();
  ScopedLogIn login(GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  EXPECT_TRUE(IsArcTermsOfServiceNegotiationNeeded(profile()));
  EXPECT_TRUE(IsArcTermsOfServiceOobeNegotiationNeeded());
  profile()->GetPrefs()->SetBoolean(prefs::kArcTermsAccepted, true);
  EXPECT_FALSE(IsArcTermsOfServiceNegotiationNeeded(profile()));
  EXPECT_FALSE(IsArcTermsOfServiceOobeNegotiationNeeded());
}

// For managed user, generally no opt-in dialog is shown.
// For OOBE user, see TermsOfServiceOobeNegotiationNeededForManagedUser test.
TEST_F(ChromeArcUtilTest, TermsOfServiceNegotiationNeededForManagedUser) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  DisableDBusForProfileManager();
  ScopedLogIn login(GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));

  EXPECT_TRUE(IsArcTermsOfServiceNegotiationNeeded(profile()));

  SetProfileIsManagedForTesting(profile());

  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcEnabled, std::make_unique<base::Value>(true));
  EXPECT_TRUE(ShouldStartArcSilentlyForManagedProfile(profile()));
  EXPECT_FALSE(IsArcTermsOfServiceNegotiationNeeded(profile()));
}

TEST_F(ChromeArcUtilTest, TermsOfServiceOobeNegotiationNeededNoLogin) {
  DisableDBusForProfileManager();
  EXPECT_FALSE(IsArcTermsOfServiceOobeNegotiationNeeded());
}

TEST_F(ChromeArcUtilTest,
       TermsOfServiceOobeNegotiationNeededNoArcAvailability) {
  DisableDBusForProfileManager();
  ScopedLogIn login(GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  EXPECT_FALSE(IsArcTermsOfServiceOobeNegotiationNeeded());
}

TEST_F(ChromeArcUtilTest, TermsOfServiceOobeNegotiationNeededNoPlayStore) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported",
       "--arc-start-mode=always-start-with-no-play-store"});
  DisableDBusForProfileManager();
  ScopedLogIn login(GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  EXPECT_FALSE(IsArcTermsOfServiceOobeNegotiationNeeded());
}

TEST_F(ChromeArcUtilTest, IsArcStatsReportingEnabled) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  ScopedLogIn login(GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  EXPECT_FALSE(IsArcStatsReportingEnabled());
}

TEST_F(ChromeArcUtilTest, IsArcStatsReportingEnabled_PublicAccount) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  ScopedLogIn login(GetFakeUserManager(),
                    AccountId::FromUserEmail("public_user@gmail.com"),
                    user_manager::UserType::kPublicAccount);
  EXPECT_FALSE(IsArcStatsReportingEnabled());
}

TEST_F(ChromeArcUtilTest, ArcStartModeDefault) {
  auto* command_line = base::CommandLine::ForCurrentProcess();
  command_line->InitFromArgv({"", "--arc-availability=installed"});
  EXPECT_TRUE(IsPlayStoreAvailable());
}

TEST_F(ChromeArcUtilTest, ArcStartModeDefaultPublicSession) {
  auto* command_line = base::CommandLine::ForCurrentProcess();
  command_line->InitFromArgv({"", "--arc-availability=installed"});
  ScopedLogIn login(GetFakeUserManager(),
                    AccountId::FromUserEmail("public_user@gmail.com"),
                    user_manager::UserType::kPublicAccount);
  EXPECT_FALSE(IsPlayStoreAvailable());
}

TEST_F(ChromeArcUtilTest, ArcStartModeDefaultDemoMode) {
  auto* command_line = base::CommandLine::ForCurrentProcess();
  command_line->InitFromArgv({"", "--arc-availability=installed"});
  cros_settings_test_helper_.InstallAttributes()->SetDemoMode();
  ScopedLogIn login(GetFakeUserManager(),
                    AccountId::FromUserEmail("public_user@gmail.com"),
                    user_manager::UserType::kPublicAccount);
  EXPECT_TRUE(IsPlayStoreAvailable());
}

TEST_F(ChromeArcUtilTest, ArcStartModeWithoutPlayStore) {
  auto* command_line = base::CommandLine::ForCurrentProcess();
  command_line->InitFromArgv(
      {"", "--arc-availability=installed",
       "--arc-start-mode=always-start-with-no-play-store"});
  EXPECT_FALSE(IsPlayStoreAvailable());
}

TEST_F(ChromeArcUtilTest, ArcUnmanagedToManagedTransition) {
  profile()->GetPrefs()->SetInteger(
      arc::prefs::kArcManagementTransition,
      static_cast<int>(arc::ArcManagementTransition::UNMANAGED_TO_MANAGED));

  EXPECT_EQ(GetManagementTransition(profile()),
            arc::ArcManagementTransition::UNMANAGED_TO_MANAGED);
}

class ArcOobeTest : public ChromeArcUtilTest,
                    public testing::WithParamInterface<bool> {
 public:
  ArcOobeTest() {
    if (GetParam()) {
      scoped_feature_list_.InitAndEnableFeature(ash::features::kCrosPrivacyHub);
    } else {
      scoped_feature_list_.InitAndDisableFeature(
          ash::features::kCrosPrivacyHub);
    }
    ash::ConciergeClient::InitializeFake(/*fake_cicerone_client=*/nullptr);
    oobe_configuration_ = std::make_unique<ash::OobeConfiguration>();
  }

  ArcOobeTest(const ArcOobeTest&) = delete;
  ArcOobeTest& operator=(const ArcOobeTest&) = delete;

  ~ArcOobeTest() override {
    // Fake display host have to be shut down first, as it may access
    // configuration.
    fake_login_display_host_.reset();
    oobe_configuration_.reset();
    ash::ConciergeClient::Shutdown();
  }

 protected:
  void CreateLoginDisplayHost() {
    fake_login_display_host_ = std::make_unique<ash::FakeLoginDisplayHost>();
  }

  ash::FakeLoginDisplayHost* login_display_host() {
    return fake_login_display_host_.get();
  }

  void CloseLoginDisplayHost() { fake_login_display_host_.reset(); }

 private:
  std::unique_ptr<ash::OobeConfiguration> oobe_configuration_;
  std::unique_ptr<ash::FakeLoginDisplayHost> fake_login_display_host_;
  base::test::ScopedFeatureList scoped_feature_list_;
};

// Testing both states of the `ash::features::kCrosPrivacyHub` feature.
INSTANTIATE_TEST_SUITE_P(All, ArcOobeTest, testing::Bool());

TEST_P(ArcOobeTest, TermsOfServiceOobeNegotiationNeededForManagedUser) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  DisableDBusForProfileManager();
  ScopedLogIn login(GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));

  CreateLoginDisplayHost();
  EXPECT_TRUE(IsArcOobeOptInActive());

  SetProfileIsManagedForTesting(profile());
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcEnabled, std::make_unique<base::Value>(true));
  EXPECT_TRUE(IsArcTermsOfServiceNegotiationNeeded(profile()));
  EXPECT_TRUE(IsArcTermsOfServiceOobeNegotiationNeeded());

  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcBackupRestoreEnabled, std::make_unique<base::Value>(false));
  // When PrivacyHubLocation is enabled, location setting is no longer ARC++
  // specific. `kArcBackupRestoreEnabled` is the only pref of interest.
  EXPECT_EQ(ash::features::IsCrosPrivacyHubLocationEnabled(),
            !IsArcTermsOfServiceNegotiationNeeded(profile()));
  EXPECT_EQ(ash::features::IsCrosPrivacyHubLocationEnabled(),
            !IsArcTermsOfServiceOobeNegotiationNeeded());

  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcLocationServiceEnabled, std::make_unique<base::Value>(false));
  EXPECT_FALSE(IsArcTermsOfServiceNegotiationNeeded(profile()));
  EXPECT_FALSE(IsArcTermsOfServiceOobeNegotiationNeeded());

  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcBackupRestoreEnabled, std::make_unique<base::Value>(true));
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcLocationServiceEnabled, std::make_unique<base::Value>(false));
  EXPECT_FALSE(IsArcTermsOfServiceNegotiationNeeded(profile()));
  EXPECT_FALSE(IsArcTermsOfServiceOobeNegotiationNeeded());

  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcBackupRestoreEnabled, std::make_unique<base::Value>(false));
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcLocationServiceEnabled, std::make_unique<base::Value>(true));
  EXPECT_FALSE(IsArcTermsOfServiceNegotiationNeeded(profile()));
  EXPECT_FALSE(IsArcTermsOfServiceOobeNegotiationNeeded());

  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcBackupRestoreEnabled, std::make_unique<base::Value>(true));
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcLocationServiceEnabled, std::make_unique<base::Value>(true));
  EXPECT_FALSE(IsArcTermsOfServiceNegotiationNeeded(profile()));
  EXPECT_FALSE(IsArcTermsOfServiceOobeNegotiationNeeded());
}

TEST_P(ArcOobeTest, ShouldStartArcSilentlyForManagedProfile) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  DisableDBusForProfileManager();
  ScopedLogIn login(GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));

  CreateLoginDisplayHost();
  EXPECT_TRUE(IsArcOobeOptInActive());

  SetProfileIsManagedForTesting(profile());
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcEnabled, std::make_unique<base::Value>(true));
  EXPECT_FALSE(ShouldStartArcSilentlyForManagedProfile(profile()));

  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcBackupRestoreEnabled, std::make_unique<base::Value>(false));
  // When PrivacyHubLocation is enabled, location setting is no longer ARC++
  // specific. `kArcBackupRestoreEnabled` is the only pref of interest.
  EXPECT_EQ(ash::features::IsCrosPrivacyHubLocationEnabled(),
            ShouldStartArcSilentlyForManagedProfile(profile()));

  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcLocationServiceEnabled, std::make_unique<base::Value>(false));
  EXPECT_TRUE(ShouldStartArcSilentlyForManagedProfile(profile()));

  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcBackupRestoreEnabled, std::make_unique<base::Value>(true));
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcLocationServiceEnabled, std::make_unique<base::Value>(false));
  EXPECT_TRUE(ShouldStartArcSilentlyForManagedProfile(profile()));

  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcBackupRestoreEnabled, std::make_unique<base::Value>(false));
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcLocationServiceEnabled, std::make_unique<base::Value>(true));
  EXPECT_TRUE(ShouldStartArcSilentlyForManagedProfile(profile()));

  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcBackupRestoreEnabled, std::make_unique<base::Value>(true));
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcLocationServiceEnabled, std::make_unique<base::Value>(true));
  EXPECT_TRUE(ShouldStartArcSilentlyForManagedProfile(profile()));
}

using ArcOobeOptInActiveInTest = ArcOobeTest;
INSTANTIATE_TEST_SUITE_P(All, ArcOobeOptInActiveInTest, testing::Bool());

TEST_P(ArcOobeOptInActiveInTest, OobeOptInActive) {
  // OOBE OptIn is active in case of OOBE controller is alive and the
  // Consolidated Consent screen is currently showing.
  LogIn();
  EXPECT_FALSE(IsArcOobeOptInActive());
  CreateLoginDisplayHost();

  const AccountId account_id = AccountId::FromUserEmailGaiaId(
      profile()->GetProfileUserName(), kTestGaiaId);

  // OOBE OptIn can only start if Onboarding is not completed yet.
  EXPECT_TRUE(IsArcOobeOptInActive());

  // Set a version for the Onboarding to indicate that the user completed the
  // onboarding flow.
  user_manager::KnownUser(g_browser_process->local_state())
      .SetOnboardingCompletedVersion(account_id, version_info::GetVersion());
  EXPECT_FALSE(IsArcOobeOptInActive());

  // Consolidated Consent wizard but Onboarding flow completed.
  login_display_host()->StartWizard(
      ash::ConsolidatedConsentScreenView::kScreenId);
  EXPECT_FALSE(IsArcOobeOptInActive());
}

using DemoSetupFlowArcOptInTest = ArcOobeTest;
INSTANTIATE_TEST_SUITE_P(All, DemoSetupFlowArcOptInTest, testing::Bool());

TEST_P(DemoSetupFlowArcOptInTest, NoTermsOfServiceOobeNegotiationNeeded) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  DisableDBusForProfileManager();
  CreateLoginDisplayHost();
  EXPECT_FALSE(IsArcDemoModeSetupFlow());
  EXPECT_FALSE(IsArcTermsOfServiceOobeNegotiationNeeded());
}

TEST_P(DemoSetupFlowArcOptInTest, TermsOfServiceOobeNegotiationNeeded) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  DisableDBusForProfileManager();
  CreateLoginDisplayHost();
  login_display_host()->StartWizard(ash::DemoPreferencesScreenView::kScreenId);
  login_display_host()
      ->GetWizardController()
      ->SimulateDemoModeSetupForTesting();
  EXPECT_TRUE(IsArcDemoModeSetupFlow());
  EXPECT_TRUE(IsArcTermsOfServiceOobeNegotiationNeeded());
}

TEST_P(DemoSetupFlowArcOptInTest,
       NoPlayStoreNoTermsOfServiceOobeNegotiationNeeded) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported",
       "--arc-start-mode=always-start-with-no-play-store"});
  DisableDBusForProfileManager();
  CreateLoginDisplayHost();
  login_display_host()->StartWizard(ash::DemoPreferencesScreenView::kScreenId);
  login_display_host()
      ->GetWizardController()
      ->SimulateDemoModeSetupForTesting();
  EXPECT_TRUE(IsArcDemoModeSetupFlow());
  EXPECT_FALSE(IsArcTermsOfServiceOobeNegotiationNeeded());
}

using ChromeUnaffiliatedDevicesArcRestrictionTest = ChromeArcUtilTest;

TEST_F(ChromeUnaffiliatedDevicesArcRestrictionTest,
       ArcAllowedForAffiliatedUser_WhenPolicyValueTrue) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  ScopedLogIn login(true, GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  SetProfileIsManagedForTesting(profile());
  profile()->GetPrefs()->SetBoolean(prefs::kUnaffiliatedDeviceArcAllowed,
                                    true);

  EXPECT_TRUE(IsArcAllowedForProfileOnFirstCall(profile()));
}

TEST_F(ChromeUnaffiliatedDevicesArcRestrictionTest,
       ArcAllowedForUnAffiliatedUser_WhenPolicyValueTrue) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  ScopedLogIn login(false, GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  SetProfileIsManagedForTesting(profile());
  profile()->GetPrefs()->SetBoolean(prefs::kUnaffiliatedDeviceArcAllowed,
                                    true);

  EXPECT_TRUE(IsArcAllowedForProfileOnFirstCall(profile()));
}

TEST_F(ChromeUnaffiliatedDevicesArcRestrictionTest,
       ArcAllowedForNonEnterpriseAccount_WhenPolicyValueTrue) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  ScopedLogIn login(false, GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  profile()->GetPrefs()->SetBoolean(prefs::kUnaffiliatedDeviceArcAllowed,
                                    true);

  EXPECT_TRUE(IsArcAllowedForProfileOnFirstCall(profile()));
}

TEST_F(ChromeUnaffiliatedDevicesArcRestrictionTest,
       ArcAllowedForAffiliatedUser_WhenPolicyValueFalse) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  ScopedLogIn login(true, GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  SetProfileIsManagedForTesting(profile());
  profile()->GetPrefs()->SetBoolean(prefs::kUnaffiliatedDeviceArcAllowed,
                                    false);

  EXPECT_TRUE(IsArcAllowedForProfileOnFirstCall(profile()));
}

TEST_F(ChromeUnaffiliatedDevicesArcRestrictionTest,
       ArcNotAllowedForUnAffiliatedUser_WhenPolicyValueFalse) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  ScopedLogIn login(false, GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  SetProfileIsManagedForTesting(profile());
  profile()->GetPrefs()->SetBoolean(prefs::kUnaffiliatedDeviceArcAllowed,
                                    false);

  EXPECT_FALSE(IsArcAllowedForProfileOnFirstCall(profile()));
}

TEST_F(ChromeUnaffiliatedDevicesArcRestrictionTest,
       ArcAllowedForNonEnterpriseAccount_WhenPolicyValueFalse) {
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  ScopedLogIn login(false, GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  profile()->GetPrefs()->SetBoolean(prefs::kUnaffiliatedDeviceArcAllowed,
                                    false);

  EXPECT_TRUE(IsArcAllowedForProfileOnFirstCall(profile()));
}

TEST_F(ChromeUnaffiliatedDevicesArcRestrictionTest,
       ReportArcAllowedForAffiliatedUser_WhenPolicyValueFalse) {
  base::HistogramTester tester;
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  ScopedLogIn login(true, GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  SetProfileIsManagedForTesting(profile());
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcEnabled, std::make_unique<base::Value>(true));
  profile()->GetPrefs()->SetBoolean(prefs::kUnaffiliatedDeviceArcAllowed,
                                    false);

  RecordArcStatusBasedOnDeviceAffiliationUMA(profile());
  tester.ExpectBucketCount("Arc.Provisioning.DeviceAffiliationAction", 0, 1);
}

TEST_F(ChromeUnaffiliatedDevicesArcRestrictionTest,
       ReportArcAllowedForUnAffiliatedUser_WhenPolicyValueTrue) {
  base::HistogramTester tester;
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  ScopedLogIn login(false, GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  SetProfileIsManagedForTesting(profile());
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcEnabled, std::make_unique<base::Value>(true));
  profile()->GetPrefs()->SetBoolean(prefs::kUnaffiliatedDeviceArcAllowed, true);
  RecordArcStatusBasedOnDeviceAffiliationUMA(profile());
  tester.ExpectBucketCount("Arc.Provisioning.DeviceAffiliationAction", 1, 1);
}

TEST_F(ChromeUnaffiliatedDevicesArcRestrictionTest,
       ReportArcNotAllowedForUnAffiliatedUser_WhenPolicyValueFalse) {
  base::HistogramTester tester;
  base::CommandLine::ForCurrentProcess()->InitFromArgv(
      {"", "--arc-availability=officially-supported"});
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcEnabled, std::make_unique<base::Value>(true));
  ScopedLogIn login(false, GetFakeUserManager(),
                    AccountId::FromUserEmailGaiaId(
                        profile()->GetProfileUserName(), kTestGaiaId));
  SetProfileIsManagedForTesting(profile());
  profile()->GetTestingPrefService()->SetManagedPref(
      prefs::kArcEnabled, std::make_unique<base::Value>(true));
  profile()->GetPrefs()->SetBoolean(prefs::kUnaffiliatedDeviceArcAllowed,
                                    false);
  RecordArcStatusBasedOnDeviceAffiliationUMA(profile());
  tester.ExpectBucketCount("Arc.Provisioning.DeviceAffiliationAction", 2, 1);
}

}  // namespace util
}  // namespace arc