blob: abdc81797946e358dd844dc1d1e6724cd59663f9 [file] [log] [blame]
// Copyright 2020 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 <string>
#include "ash/constants/ash_features.h"
#include "ash/constants/ash_switches.h"
#include "ash/public/cpp/login_screen_test_api.h"
#include "ash/public/cpp/system_tray_test_api.h"
#include "base/json/json_writer.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/system/sys_info.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/default_clock.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chrome/browser/ash/login/existing_user_controller.h"
#include "chrome/browser/ash/login/login_manager_test.h"
#include "chrome/browser/ash/login/login_wizard.h"
#include "chrome/browser/ash/login/test/device_state_mixin.h"
#include "chrome/browser/ash/login/test/fake_gaia_mixin.h"
#include "chrome/browser/ash/login/test/login_manager_mixin.h"
#include "chrome/browser/ash/login/test/oobe_base_test.h"
#include "chrome/browser/ash/login/test/oobe_screen_exit_waiter.h"
#include "chrome/browser/ash/login/test/oobe_screen_waiter.h"
#include "chrome/browser/ash/login/test/user_policy_mixin.h"
#include "chrome/browser/ash/login/ui/login_display_host.h"
#include "chrome/browser/ash/login/wizard_controller.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_process_platform_part.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
#include "chrome/browser/chromeos/policy/minimum_version_policy_handler.h"
#include "chrome/browser/chromeos/policy/minimum_version_policy_handler_delegate_impl.h"
#include "chrome/browser/chromeos/policy/minimum_version_policy_test_helpers.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/notifications/notification_display_service_tester.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h"
#include "chrome/browser/ui/webui/chromeos/login/update_required_screen_handler.h"
#include "chrome/browser/upgrade_detector/upgrade_detector.h"
#include "chrome/common/pref_names.h"
#include "chromeos/dbus/constants/dbus_switches.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_update_engine_client.h"
#include "chromeos/dbus/shill/shill_service_client.h"
#include "chromeos/network/network_state_test_helper.h"
#include "chromeos/settings/cros_settings_names.h"
#include "components/policy/proto/chrome_device_policy.pb.h"
#include "components/prefs/pref_service.h"
#include "components/user_manager/user_type.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace em = enterprise_management;
namespace policy {
namespace {
const char kNewVersion[] = "13335.4.2";
const char kUpdatedVersion[] = "13340.0.0";
const char kCurrentVersion[] = "13332.0.25";
const int kNoWarning = 0;
const int kLastDayWarningInDays = 1;
const int kShortWarningInDays = 2;
const int kLongWarningInDays = 10;
const int kVeryLongWarningInDays = 100;
constexpr base::TimeDelta kShortWarning =
base::TimeDelta::FromDays(kShortWarningInDays);
constexpr base::TimeDelta kLongWarning =
base::TimeDelta::FromDays(kLongWarningInDays);
constexpr base::TimeDelta kVeryLongWarning =
base::TimeDelta::FromDays(kVeryLongWarningInDays);
const char kPublicSessionId[] = "demo@example.com";
const char kManagedUserId[] = "user@example.com";
const char kManagedUserGaiaId[] = "11111";
const char kUpdateRequiredNotificationId[] = "policy.update_required";
const char kWifiServicePath[] = "/service/wifi2";
const char kCellularServicePath[] = "/service/cellular1";
// This is a randomly chosen long delay in milliseconds to make sure that the
// timer keeps running for a long time in case it is started.
const int kAutoLoginLoginDelayMilliseconds = 500000;
policy::MinimumVersionPolicyHandler* GetMinimumVersionPolicyHandler() {
return g_browser_process->platform_part()
->browser_policy_connector_chromeos()
->GetMinimumVersionPolicyHandler();
}
void SetPlatformVersion(const std::string& platform_version) {
const std::string lsb_release = base::StringPrintf(
"CHROMEOS_RELEASE_VERSION=%s", platform_version.c_str());
base::SysInfo::SetChromeOSVersionInfoForTest(lsb_release, base::Time::Now());
}
} // namespace
class MinimumVersionPolicyTestBase : public chromeos::LoginManagerTest {
public:
MinimumVersionPolicyTestBase();
~MinimumVersionPolicyTestBase() override = default;
void SetUpInProcessBrowserTestFixture() override {
LoginManagerTest::SetUpInProcessBrowserTestFixture();
auto fake_update_engine_client =
std::make_unique<chromeos::FakeUpdateEngineClient>();
fake_update_engine_client_ = fake_update_engine_client.get();
chromeos::DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
std::move(fake_update_engine_client));
SetPlatformVersion(kCurrentVersion);
}
// Set new value for policy and wait till setting is changed.
void SetDevicePolicyAndWaitForSettingChange(const base::Value& value);
// Set new value for policy.
void SetAndRefreshMinimumChromeVersionPolicy(const base::Value& value);
void SetUpdateEngineStatus(update_engine::Operation operation);
protected:
void SetMinimumChromeVersionPolicy(const base::Value& value);
DevicePolicyCrosTestHelper helper_;
base::test::ScopedFeatureList feature_list_;
chromeos::FakeUpdateEngineClient* fake_update_engine_client_ = nullptr;
chromeos::DeviceStateMixin device_state_{
&mixin_host_,
chromeos::DeviceStateMixin::State::OOBE_COMPLETED_CLOUD_ENROLLED};
};
MinimumVersionPolicyTestBase::MinimumVersionPolicyTestBase() {
feature_list_.InitAndEnableFeature(chromeos::features::kMinimumChromeVersion);
}
void MinimumVersionPolicyTestBase::SetMinimumChromeVersionPolicy(
const base::Value& value) {
policy::DevicePolicyBuilder* const device_policy(helper_.device_policy());
em::ChromeDeviceSettingsProto& proto(device_policy->payload());
std::string policy_value;
EXPECT_TRUE(base::JSONWriter::Write(value, &policy_value));
proto.mutable_device_minimum_version()->set_value(policy_value);
}
void MinimumVersionPolicyTestBase::SetDevicePolicyAndWaitForSettingChange(
const base::Value& value) {
SetMinimumChromeVersionPolicy(value);
helper_.RefreshPolicyAndWaitUntilDeviceSettingsUpdated(
{chromeos::kDeviceMinimumVersion});
}
void MinimumVersionPolicyTestBase::SetAndRefreshMinimumChromeVersionPolicy(
const base::Value& value) {
SetMinimumChromeVersionPolicy(value);
helper_.RefreshDevicePolicy();
}
void MinimumVersionPolicyTestBase::SetUpdateEngineStatus(
update_engine::Operation operation) {
update_engine::StatusResult status;
status.set_current_operation(operation);
if (operation == update_engine::Operation::UPDATED_NEED_REBOOT)
status.set_new_version(kUpdatedVersion);
fake_update_engine_client_->NotifyObserversThatStatusChanged(status);
}
class MinimumVersionPolicyTest : public MinimumVersionPolicyTestBase {
public:
MinimumVersionPolicyTest() { login_manager_.AppendRegularUsers(1); }
~MinimumVersionPolicyTest() override = default;
void SetUpCommandLine(base::CommandLine* command_line) override {
MinimumVersionPolicyTestBase::SetUpCommandLine(command_line);
command_line->AppendSwitchASCII(chromeos::switches::kShillStub,
"clear=1,cellular=0,wifi=1");
}
void SetUpOnMainThread() override {
MinimumVersionPolicyTestBase::SetUpOnMainThread();
display_service_tester_ =
std::make_unique<NotificationDisplayServiceTester>(nullptr /*profile*/);
network_state_test_helper_ =
std::make_unique<chromeos::NetworkStateTestHelper>(
false /*use_default_devices_and_services*/);
network_state_test_helper_->manager_test()->SetupDefaultEnvironment();
tray_test_api_ = ash::SystemTrayTestApi::Create();
}
void TearDownOnMainThread() override {
network_state_test_helper_.reset();
MinimumVersionPolicyTestBase::TearDownOnMainThread();
}
void DisconectAllNetworks() { network_state_test_helper_->ClearServices(); }
void ConnectCellularNetwork() {
network_state_test_helper_->service_test()->AddService(
kCellularServicePath, kCellularServicePath,
kCellularServicePath /* name */, shill::kTypeCellular,
shill::kStateOnline, true /* visible */);
}
void LoginManagedUser();
void LoginUnmanagedUser();
protected:
const chromeos::LoginManagerMixin::TestUserInfo managed_user{
AccountId::FromUserEmailGaiaId(kManagedUserId, kManagedUserGaiaId)};
chromeos::UserPolicyMixin user_policy_mixin_{&mixin_host_,
managed_user.account_id};
chromeos::LoginManagerMixin login_manager_{&mixin_host_, {managed_user}};
std::unique_ptr<chromeos::NetworkStateTestHelper> network_state_test_helper_;
std::unique_ptr<NotificationDisplayServiceTester> display_service_tester_;
std::unique_ptr<ash::SystemTrayTestApi> tray_test_api_;
};
void MinimumVersionPolicyTest::LoginManagedUser() {
user_policy_mixin_.RequestPolicyUpdate();
EXPECT_EQ(user_manager::UserManager::Get()->GetLoggedInUsers().size(), 0u);
EXPECT_EQ(session_manager::SessionManager::Get()->session_state(),
session_manager::SessionState::LOGIN_PRIMARY);
auto context =
chromeos::LoginManagerMixin::CreateDefaultUserContext(managed_user);
login_manager_.LoginAndWaitForActiveSession(context);
EXPECT_EQ(user_manager::UserManager::Get()->GetLoggedInUsers().size(), 1u);
EXPECT_EQ(session_manager::SessionManager::Get()->session_state(),
session_manager::SessionState::ACTIVE);
}
void MinimumVersionPolicyTest::LoginUnmanagedUser() {
const auto& users = login_manager_.users();
EXPECT_EQ(user_manager::UserManager::Get()->GetLoggedInUsers().size(), 0u);
EXPECT_EQ(session_manager::SessionManager::Get()->session_state(),
session_manager::SessionState::LOGIN_PRIMARY);
LoginUser(users[1].account_id);
EXPECT_EQ(user_manager::UserManager::Get()->GetLoggedInUsers().size(), 1u);
EXPECT_EQ(session_manager::SessionManager::Get()->session_state(),
session_manager::SessionState::ACTIVE);
}
IN_PROC_BROWSER_TEST_F(MinimumVersionPolicyTest, CriticalUpdateOnLoginScreen) {
EXPECT_EQ(ash::LoginScreenTestApi::GetUsersCount(), 2);
EXPECT_FALSE(ash::LoginScreenTestApi::IsOobeDialogVisible());
// Set new value for policy and check update required screen is shown on the
// login screen.
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kNoWarning, kNoWarning,
false /* unmanaged_user_restricted */));
chromeos::OobeScreenWaiter(chromeos::UpdateRequiredView::kScreenId).Wait();
EXPECT_TRUE(ash::LoginScreenTestApi::IsOobeDialogVisible());
// Revoke policy and check update required screen is hidden.
base::Value empty_policy(base::Value::Type::DICTIONARY);
SetDevicePolicyAndWaitForSettingChange(empty_policy);
chromeos::OobeScreenExitWaiter(chromeos::UpdateRequiredView::kScreenId)
.Wait();
EXPECT_FALSE(ash::LoginScreenTestApi::IsOobeDialogVisible());
}
IN_PROC_BROWSER_TEST_F(MinimumVersionPolicyTest, PRE_CriticalUpdateInSession) {
// Login the user into the session and mark as managed.
LoginManagedUser();
// Create waiter to observe termination notification.
content::WindowedNotificationObserver termination_waiter(
chrome::NOTIFICATION_APP_TERMINATING,
content::NotificationService::AllSources());
// Set new value for policy and check that user is logged out of the session.
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kNoWarning, kNoWarning,
false /* unmanaged_user_restricted */));
termination_waiter.Wait();
EXPECT_TRUE(chrome::IsAttemptingShutdown());
}
IN_PROC_BROWSER_TEST_F(MinimumVersionPolicyTest, CriticalUpdateInSession) {
// Check login screen is shown post chrome restart due to critical update
// required in session.
EXPECT_EQ(session_manager::SessionManager::Get()->session_state(),
session_manager::SessionState::LOGIN_PRIMARY);
EXPECT_EQ(ash::LoginScreenTestApi::GetUsersCount(), 2);
// TODO(https://crbug.com/1048607): Show update required screen after user is
// logged out of session due to critical update required by policy.
EXPECT_FALSE(ash::LoginScreenTestApi::IsOobeDialogVisible());
EXPECT_EQ(user_manager::UserManager::Get()->GetLoggedInUsers().size(), 0u);
}
IN_PROC_BROWSER_TEST_F(MinimumVersionPolicyTest, NonCriticalUpdateGoodNetwork) {
// Login the user into the session.
LoginManagedUser();
// Check deadline timer is not running and local state is not set.
PrefService* prefs = g_browser_process->local_state();
base::Time timer_start_time =
prefs->GetTime(prefs::kUpdateRequiredTimerStartTime);
EXPECT_TRUE(timer_start_time.is_null());
EXPECT_FALSE(
GetMinimumVersionPolicyHandler()->IsDeadlineTimerRunningForTesting());
// Create and set policy value with short warning time.
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kShortWarningInDays, kShortWarningInDays,
false /* unmanaged_user_restricted */));
// Policy handler sets the local state and starts the deadline timer.
timer_start_time = prefs->GetTime(prefs::kUpdateRequiredTimerStartTime);
EXPECT_FALSE(timer_start_time.is_null());
EXPECT_EQ(prefs->GetTimeDelta(prefs::kUpdateRequiredWarningPeriod),
kShortWarning);
EXPECT_TRUE(
GetMinimumVersionPolicyHandler()->IsDeadlineTimerRunningForTesting());
EXPECT_FALSE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
// Create and set policy value with long warning time.
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kLongWarningInDays, kLongWarningInDays,
false /* unmanaged_user_restricted */));
// Warning time is increased but timer start time does not change.
EXPECT_EQ(prefs->GetTime(prefs::kUpdateRequiredTimerStartTime),
timer_start_time);
EXPECT_EQ(prefs->GetTimeDelta(prefs::kUpdateRequiredWarningPeriod),
kLongWarning);
EXPECT_FALSE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
// Create and set policy value with no warning time.
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kNoWarning, kNoWarning,
false /* unmanaged_user_restricted */));
// Warning time is not reduced as policy does not allow to reduce deadline.
EXPECT_EQ(prefs->GetTime(prefs::kUpdateRequiredTimerStartTime),
timer_start_time);
EXPECT_EQ(prefs->GetTimeDelta(prefs::kUpdateRequiredWarningPeriod),
kLongWarning);
EXPECT_FALSE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
EXPECT_TRUE(
GetMinimumVersionPolicyHandler()->IsDeadlineTimerRunningForTesting());
EXPECT_TRUE(GetMinimumVersionPolicyHandler()->GetState());
// Simulate update installed from update_engine_client and check that timer
// is reset but local state is not.
SetUpdateEngineStatus(update_engine::Operation::UPDATED_NEED_REBOOT);
EXPECT_FALSE(
GetMinimumVersionPolicyHandler()->IsDeadlineTimerRunningForTesting());
EXPECT_TRUE(GetMinimumVersionPolicyHandler()->GetState());
EXPECT_FALSE(prefs->GetTime(prefs::kUpdateRequiredTimerStartTime).is_null());
// New policy after update is downloaded does not restart the timer but just
// updates the local state with longer warning period.
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kVeryLongWarningInDays, kNoWarning,
false /* unmanaged_user_restricted */));
EXPECT_EQ(prefs->GetTime(prefs::kUpdateRequiredTimerStartTime),
timer_start_time);
EXPECT_EQ(prefs->GetTimeDelta(prefs::kUpdateRequiredWarningPeriod),
kVeryLongWarning);
EXPECT_FALSE(
GetMinimumVersionPolicyHandler()->IsDeadlineTimerRunningForTesting());
EXPECT_TRUE(GetMinimumVersionPolicyHandler()->GetState());
}
IN_PROC_BROWSER_TEST_F(MinimumVersionPolicyTest, DeviceUpdateStatusChange) {
// Login the user into the session.
LoginUnmanagedUser();
// Set policy value with warning time and check timer is started.
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kShortWarningInDays, kShortWarningInDays,
false /* unmanaged_user_restricted */));
EXPECT_TRUE(
GetMinimumVersionPolicyHandler()->IsDeadlineTimerRunningForTesting());
EXPECT_TRUE(GetMinimumVersionPolicyHandler()->GetState());
// Simulate channel switch rollback from update_engine_client and check that
// timer is not reset.
update_engine::StatusResult rollback_status;
rollback_status.set_current_operation(
update_engine::Operation::UPDATED_NEED_REBOOT);
rollback_status.set_will_powerwash_after_reboot(true);
fake_update_engine_client_->set_default_status(rollback_status);
fake_update_engine_client_->NotifyObserversThatStatusChanged(rollback_status);
EXPECT_TRUE(
GetMinimumVersionPolicyHandler()->IsDeadlineTimerRunningForTesting());
EXPECT_TRUE(GetMinimumVersionPolicyHandler()->GetState());
// Simulate enterprise rollback from update_engine_client and check that timer
// is not reset.
rollback_status.set_is_enterprise_rollback(true);
fake_update_engine_client_->set_default_status(rollback_status);
fake_update_engine_client_->NotifyObserversThatStatusChanged(rollback_status);
EXPECT_TRUE(
GetMinimumVersionPolicyHandler()->IsDeadlineTimerRunningForTesting());
EXPECT_TRUE(GetMinimumVersionPolicyHandler()->GetState());
// Simulate update installed from update_engine_client and check that timer is
// reset.
SetUpdateEngineStatus(update_engine::Operation::UPDATED_NEED_REBOOT);
EXPECT_FALSE(
GetMinimumVersionPolicyHandler()->IsDeadlineTimerRunningForTesting());
EXPECT_TRUE(GetMinimumVersionPolicyHandler()->GetState());
}
IN_PROC_BROWSER_TEST_F(MinimumVersionPolicyTest,
CriticalUpdateInSessionUnmanagedUser) {
// Login the user into the session.
LoginUnmanagedUser();
// Set new value for pref and check that user session is not terminated.
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kNoWarning, kNoWarning,
false /* unmanaged_user_restricted */));
EXPECT_FALSE(chrome::IsAttemptingShutdown());
}
IN_PROC_BROWSER_TEST_F(MinimumVersionPolicyTest,
CriticalUpdateInSessionUnmanagedUserEnabled) {
LoginUnmanagedUser();
// Create and set policy value.
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kNoWarning, kNoWarning,
true /* unmanaged_user_restricted */));
EXPECT_TRUE(chrome::IsAttemptingShutdown());
}
IN_PROC_BROWSER_TEST_F(MinimumVersionPolicyTest, NoNetworkNotificationClick) {
// Login the user into the session.
DisconectAllNetworks();
LoginManagedUser();
EXPECT_FALSE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
EXPECT_FALSE(tray_test_api_->IsTrayBubbleOpen());
// Set new policy value and check that update required notification is shown.
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kShortWarningInDays, kShortWarningInDays,
false /* unmanaged_user_restricted */));
EXPECT_TRUE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
// Clicking on notification button opens the network settings and hides the
// notification.
display_service_tester_->SimulateClick(NotificationHandler::Type::TRANSIENT,
kUpdateRequiredNotificationId,
0 /*action_index*/, base::nullopt);
EXPECT_FALSE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
EXPECT_TRUE(tray_test_api_->IsTrayBubbleOpen());
}
IN_PROC_BROWSER_TEST_F(MinimumVersionPolicyTest,
HideNotificationOnGoodNetwork) {
// Login the user into the session.
DisconectAllNetworks();
LoginManagedUser();
EXPECT_FALSE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
// Set new policy value and check that update required notification is shown.
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kShortWarningInDays, kShortWarningInDays,
false /* unmanaged_user_restricted */));
EXPECT_TRUE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
// Connecting to WiFi should hide the update required notification.
base::RunLoop run_loop;
display_service_tester_->SetNotificationClosedClosure(run_loop.QuitClosure());
network_state_test_helper_->service_test()->AddService(
kWifiServicePath, kWifiServicePath, kWifiServicePath /* name */,
shill::kTypeWifi, shill::kStateOnline, true /* visible */);
run_loop.Run();
EXPECT_FALSE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
}
IN_PROC_BROWSER_TEST_F(MinimumVersionPolicyTest, LastDayNotificationOnLogin) {
DisconectAllNetworks();
EXPECT_FALSE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kLastDayWarningInDays, kShortWarningInDays,
false /* unmanaged_user_restricted */));
// Login the user into the session and check that notification is shown.
LoginManagedUser();
EXPECT_TRUE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
EXPECT_FALSE(tray_test_api_->IsTrayBubbleOpen());
// Clicking on the no network update required notification button opens the
// network settings and hides the notification.
display_service_tester_->SimulateClick(NotificationHandler::Type::TRANSIENT,
kUpdateRequiredNotificationId,
0 /*action_index*/, base::nullopt);
EXPECT_FALSE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
EXPECT_TRUE(tray_test_api_->IsTrayBubbleOpen());
}
IN_PROC_BROWSER_TEST_F(MinimumVersionPolicyTest,
LastDayNotificationOnLoginUnmanagedUser) {
DisconectAllNetworks();
EXPECT_FALSE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kLastDayWarningInDays, kShortWarningInDays,
false /* unmanaged_user_restricted */));
// Login the user into the session and check that notification is not shown
// for unmanaged user.
LoginUnmanagedUser();
EXPECT_FALSE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
}
IN_PROC_BROWSER_TEST_F(MinimumVersionPolicyTest,
NotificationOnUnmanagedUserEnabled) {
fake_update_engine_client_->set_eol_date(
base::DefaultClock::GetInstance()->Now() - base::TimeDelta::FromDays(1));
LoginUnmanagedUser();
EXPECT_FALSE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
// Set policy and check that notification is shown to unmanaged user as it has
// been set in the policy.
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kShortWarningInDays, kShortWarningInDays,
true /* unmanaged_user_restricted */));
EXPECT_TRUE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
EXPECT_TRUE(
GetMinimumVersionPolicyHandler()->ShouldShowUpdateRequiredEolBanner());
}
IN_PROC_BROWSER_TEST_F(MinimumVersionPolicyTest, NotificationsOnLogin) {
DisconectAllNetworks();
EXPECT_FALSE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kShortWarningInDays, kShortWarningInDays,
false /* unmanaged_user_restricted */));
// Login the user into the session and check that notification is not shown as
// it is not the last day to update device.
LoginManagedUser();
EXPECT_FALSE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
}
IN_PROC_BROWSER_TEST_F(MinimumVersionPolicyTest,
MeteredNetworkNotificationClick) {
// Connect to metered network and login as managed user.
DisconectAllNetworks();
ConnectCellularNetwork();
LoginManagedUser();
EXPECT_FALSE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
// Set new policy value and check that update required notification is shown.
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kShortWarningInDays, kShortWarningInDays,
false /* unmanaged_user_restricted */));
EXPECT_TRUE(
GetMinimumVersionPolicyHandler()->IsDeadlineTimerRunningForTesting());
EXPECT_TRUE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
// Clicking on notification button starts update and hides the notification.
display_service_tester_->SimulateClick(NotificationHandler::Type::TRANSIENT,
kUpdateRequiredNotificationId,
0 /*action_index*/, base::nullopt);
EXPECT_FALSE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
// Verify that the DUT checks for an update.
EXPECT_EQ(fake_update_engine_client_->request_update_check_call_count(), 1);
EXPECT_EQ(fake_update_engine_client_
->update_over_cellular_one_time_permission_count(),
0);
// Simulate update over metered connection.
SetUpdateEngineStatus(update_engine::Operation::CHECKING_FOR_UPDATE);
SetUpdateEngineStatus(update_engine::Operation::UPDATE_AVAILABLE);
SetUpdateEngineStatus(update_engine::Operation::DOWNLOADING);
SetUpdateEngineStatus(update_engine::Operation::NEED_PERMISSION_TO_UPDATE);
EXPECT_GE(fake_update_engine_client_
->update_over_cellular_one_time_permission_count(),
1);
EXPECT_GT(fake_update_engine_client_->request_update_check_call_count(), 1);
SetUpdateEngineStatus(update_engine::Operation::UPDATED_NEED_REBOOT);
EXPECT_FALSE(
GetMinimumVersionPolicyHandler()->IsDeadlineTimerRunningForTesting());
EXPECT_TRUE(GetMinimumVersionPolicyHandler()->GetState());
}
IN_PROC_BROWSER_TEST_F(MinimumVersionPolicyTest, EolNotificationClick) {
// Mark device end of life and login as managed user.
fake_update_engine_client_->set_eol_date(
base::DefaultClock::GetInstance()->Now() - base::TimeDelta::FromDays(1));
LoginManagedUser();
EXPECT_FALSE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
// Set new policy value and check that update required notification is shown.
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kShortWarningInDays, kShortWarningInDays,
false /* unmanaged_user_restricted */));
EXPECT_TRUE(
GetMinimumVersionPolicyHandler()->IsDeadlineTimerRunningForTesting());
EXPECT_TRUE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
// Clicking on notification button opens settings page and hides notification.
display_service_tester_->SimulateClick(NotificationHandler::Type::TRANSIENT,
kUpdateRequiredNotificationId,
0 /*action_index*/, base::nullopt);
EXPECT_FALSE(
display_service_tester_->GetNotification(kUpdateRequiredNotificationId));
Browser* settings_browser = chrome::FindLastActive();
ASSERT_TRUE(settings_browser);
EXPECT_EQ(
settings_browser->tab_strip_model()->GetActiveWebContents()->GetURL(),
"chrome://management/");
}
IN_PROC_BROWSER_TEST_F(MinimumVersionPolicyTest, RelaunchNotificationOverride) {
LoginManagedUser();
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kShortWarningInDays, kShortWarningInDays,
false /* unmanaged_user_restricted */));
base::Time deadline =
GetMinimumVersionPolicyHandler()->update_required_deadline_for_testing();
// Simulate device updated.
SetUpdateEngineStatus(update_engine::Operation::UPDATED_NEED_REBOOT);
// Relaunch notifications are shown and the relaunch deadline is configured as
// per the policy deadline.
UpgradeDetector* upgrade_detector = UpgradeDetector::GetInstance();
EXPECT_EQ(upgrade_detector->upgrade_notification_stage(),
UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED);
EXPECT_EQ(upgrade_detector->GetHighAnnoyanceDeadline(), deadline);
// Revoking update required should reset the overridden the relaunch
// notifications.
SetDevicePolicyAndWaitForSettingChange(
base::Value(base::Value::Type::DICTIONARY));
EXPECT_NE(upgrade_detector->GetHighAnnoyanceDeadline(), deadline);
}
class MinimumVersionNoUsersLoginTest : public MinimumVersionPolicyTestBase {
public:
MinimumVersionNoUsersLoginTest() = default;
~MinimumVersionNoUsersLoginTest() override = default;
protected:
chromeos::LoginManagerMixin login_manager_{&mixin_host_};
};
IN_PROC_BROWSER_TEST_F(MinimumVersionNoUsersLoginTest,
CriticalUpdateOnLoginScreen) {
chromeos::OobeScreenWaiter(chromeos::OobeBaseTest::GetFirstSigninScreen())
.Wait();
EXPECT_EQ(ash::LoginScreenTestApi::GetUsersCount(), 0);
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kNoWarning, kNoWarning,
false /* unmanaged_user_restricted */));
// Check update required screen is shown on the login screen.
chromeos::OobeScreenWaiter(chromeos::UpdateRequiredView::kScreenId).Wait();
EXPECT_TRUE(ash::LoginScreenTestApi::IsOobeDialogVisible());
// Revoke policy and check update required screen is hidden and gaia screen is
// shown.
base::Value empty_policy(base::Value::Type::DICTIONARY);
SetDevicePolicyAndWaitForSettingChange(empty_policy);
chromeos::OobeScreenExitWaiter(chromeos::UpdateRequiredView::kScreenId)
.Wait();
chromeos::OobeScreenWaiter(chromeos::OobeBaseTest::GetFirstSigninScreen())
.Wait();
}
class MinimumVersionPolicyPresentTest : public MinimumVersionPolicyTestBase {
public:
MinimumVersionPolicyPresentTest() {}
~MinimumVersionPolicyPresentTest() override = default;
void SetUpInProcessBrowserTestFixture() override {
MinimumVersionPolicyTestBase::SetUpInProcessBrowserTestFixture();
// Create and set policy value.
SetAndRefreshMinimumChromeVersionPolicy(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kNoWarning, kNoWarning,
false /* unmanaged_user_restricted */));
}
};
IN_PROC_BROWSER_TEST_F(MinimumVersionPolicyPresentTest,
DeadlineReachedNoUsers) {
// Checks update required screen is shown at startup if there is no user in
// the device.
EXPECT_EQ(session_manager::SessionManager::Get()->session_state(),
session_manager::SessionState::LOGIN_PRIMARY);
chromeos::OobeScreenWaiter(chromeos::UpdateRequiredView::kScreenId).Wait();
EXPECT_TRUE(ash::LoginScreenTestApi::IsOobeDialogVisible());
}
class MinimumVersionExistingUserTest : public MinimumVersionPolicyPresentTest {
public:
MinimumVersionExistingUserTest() {
// Start with user pods.
login_mixin_.AppendManagedUsers(1);
}
protected:
chromeos::LoginManagerMixin login_mixin_{&mixin_host_};
};
IN_PROC_BROWSER_TEST_F(MinimumVersionExistingUserTest, DeadlineReached) {
// Checks update required screen is shown at startup if user is existing in
// the device.
EXPECT_EQ(session_manager::SessionManager::Get()->session_state(),
session_manager::SessionState::LOGIN_PRIMARY);
chromeos::OobeScreenWaiter(chromeos::UpdateRequiredView::kScreenId).Wait();
EXPECT_TRUE(ash::LoginScreenTestApi::IsOobeDialogVisible());
}
class MinimumVersionBeforeLoginHost : public MinimumVersionExistingUserTest {
public:
MinimumVersionBeforeLoginHost() {}
~MinimumVersionBeforeLoginHost() override = default;
bool SetUpUserDataDirectory() override {
// LoginManagerMixin sets up command line in the SetUpUserDataDirectory.
if (!MinimumVersionPolicyTestBase::SetUpUserDataDirectory())
return false;
// Postpone login host creation.
base::CommandLine::ForCurrentProcess()->RemoveSwitch(
chromeos::switches::kForceLoginManagerInTests);
return true;
}
};
IN_PROC_BROWSER_TEST_F(MinimumVersionBeforeLoginHost, DeadlineReached) {
// Checks update required screen is shown at startup if the policy handler is
// invoked before login display host is created.
EXPECT_EQ(chromeos::LoginDisplayHost::default_host(), nullptr);
EXPECT_TRUE(GetMinimumVersionPolicyHandler());
EXPECT_TRUE(GetMinimumVersionPolicyHandler()->DeadlineReached());
ShowLoginWizard(chromeos::OobeScreen::SCREEN_UNKNOWN);
EXPECT_EQ(session_manager::SessionManager::Get()->session_state(),
session_manager::SessionState::LOGIN_PRIMARY);
chromeos::OobeScreenWaiter(chromeos::UpdateRequiredView::kScreenId).Wait();
EXPECT_TRUE(ash::LoginScreenTestApi::IsOobeDialogVisible());
}
class MinimumVersionPublicSessionAutoLoginTest
: public MinimumVersionExistingUserTest {
public:
MinimumVersionPublicSessionAutoLoginTest() {}
~MinimumVersionPublicSessionAutoLoginTest() override = default;
void SetUpInProcessBrowserTestFixture() override {
MinimumVersionExistingUserTest::SetUpInProcessBrowserTestFixture();
AddPublicSessionToDevicePolicy(kPublicSessionId);
}
void AddPublicSessionToDevicePolicy(const std::string& user) {
em::ChromeDeviceSettingsProto& proto(helper_.device_policy()->payload());
DeviceLocalAccountTestHelper::AddPublicSession(&proto, user);
helper_.RefreshDevicePolicy();
em::DeviceLocalAccountsProto* device_local_accounts =
proto.mutable_device_local_accounts();
device_local_accounts->set_auto_login_id(user);
device_local_accounts->set_auto_login_delay(
kAutoLoginLoginDelayMilliseconds);
helper_.RefreshDevicePolicy();
}
};
IN_PROC_BROWSER_TEST_F(MinimumVersionPublicSessionAutoLoginTest,
BlockAutoLogin) {
// Checks public session auto login is blocked if update is required on
// reboot.
EXPECT_EQ(session_manager::SessionManager::Get()->session_state(),
session_manager::SessionState::LOGIN_PRIMARY);
chromeos::OobeScreenWaiter(chromeos::UpdateRequiredView::kScreenId).Wait();
EXPECT_TRUE(ash::LoginScreenTestApi::IsOobeDialogVisible());
EXPECT_FALSE(chromeos::ExistingUserController::current_controller()
->IsSigninInProgress());
EXPECT_FALSE(chromeos::ExistingUserController::current_controller()
->IsAutoLoginTimerRunningForTesting());
}
class MinimumVersionTimerExpiredOnLogin
: public MinimumVersionPolicyTestBase,
public chromeos::LocalStateMixin::Delegate {
public:
MinimumVersionTimerExpiredOnLogin() = default;
~MinimumVersionTimerExpiredOnLogin() override = default;
// chromeos::LocalStateMixin::Delegate:
void SetUpLocalState() override {
// Set up local state to reflect that update required deadline has passed
// when device is rebooted.
const base::TimeDelta delta = base::TimeDelta::FromDays(5);
PrefService* prefs = g_browser_process->local_state();
prefs->SetTime(prefs::kUpdateRequiredTimerStartTime,
base::Time::Now() - delta);
prefs->SetTimeDelta(prefs::kUpdateRequiredWarningPeriod, kShortWarning);
}
// MinimumVersionPolicyTestBase:
void SetUpInProcessBrowserTestFixture() override {
MinimumVersionPolicyTestBase::SetUpInProcessBrowserTestFixture();
SetAndRefreshMinimumChromeVersionPolicy(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kShortWarningInDays, kShortWarningInDays,
false /* unmanaged_user_restricted */));
}
private:
chromeos::LocalStateMixin local_state_mixin_{&mixin_host_, this};
};
IN_PROC_BROWSER_TEST_F(MinimumVersionTimerExpiredOnLogin, DeadlinePassed) {
// Show update required screen as deadline to update the device has passed.
EXPECT_EQ(session_manager::SessionManager::Get()->session_state(),
session_manager::SessionState::LOGIN_PRIMARY);
chromeos::OobeScreenWaiter(chromeos::UpdateRequiredView::kScreenId).Wait();
EXPECT_TRUE(ash::LoginScreenTestApi::IsOobeDialogVisible());
}
class MinimumVersionPolicyChildUser : public MinimumVersionPolicyTestBase {
public:
MinimumVersionPolicyChildUser() = default;
~MinimumVersionPolicyChildUser() override = default;
void LoginChildUser() {
chromeos::WizardController::SkipPostLoginScreensForTesting();
user_policy_mixin_.RequestPolicyUpdate();
login_manager_.LoginAsNewChildUser();
login_manager_.WaitForActiveSession();
EXPECT_EQ(user_manager::UserManager::Get()->GetLoggedInUsers().size(), 1u);
EXPECT_EQ(user_manager::UserManager::Get()->GetActiveUser()->GetType(),
user_manager::USER_TYPE_CHILD);
EXPECT_EQ(session_manager::SessionManager::Get()->session_state(),
session_manager::SessionState::ACTIVE);
}
private:
const chromeos::LoginManagerMixin::TestUserInfo child_user{
AccountId::FromUserEmailGaiaId(chromeos::test::kTestEmail,
chromeos::test::kTestGaiaId)};
chromeos::UserPolicyMixin user_policy_mixin_{&mixin_host_,
child_user.account_id};
chromeos::FakeGaiaMixin fake_gaia_{&mixin_host_, embedded_test_server()};
chromeos::LoginManagerMixin login_manager_{&mixin_host_, {}, &fake_gaia_};
};
IN_PROC_BROWSER_TEST_F(MinimumVersionPolicyChildUser,
CriticalUpdateInSessionChild) {
LoginChildUser();
// Child user is not enterprise managed and should not be signed out as
// unmanaged users are not restricted by policy.
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kNoWarning, kNoWarning,
false /* unmanaged_user_restricted */));
EXPECT_FALSE(chrome::IsAttemptingShutdown());
// Reset the policy so that it can be applied again.
base::Value empty_policy(base::Value::Type::DICTIONARY);
SetDevicePolicyAndWaitForSettingChange(empty_policy);
// Child user should be signout out as policy now restricts unmanaged users.
SetDevicePolicyAndWaitForSettingChange(
CreateMinimumVersionSingleRequirementPolicyValue(
kNewVersion, kNoWarning, kNoWarning,
true /* unmanaged_user_restricted */));
EXPECT_TRUE(chrome::IsAttemptingShutdown());
}
} // namespace policy