1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
|
// 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.
#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_HANDLER_H_
#define CHROME_BROWSER_ASH_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_HANDLER_H_
#include <memory>
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/scoped_observation.h"
#include "base/time/time.h"
#include "base/timer/wall_clock_timer.h"
#include "base/version.h"
#include "chrome/browser/upgrade_detector/build_state_observer.h"
#include "chromeos/ash/components/dbus/update_engine/update_engine_client.h"
#include "chromeos/ash/components/network/network_state_handler_observer.h"
#include "chromeos/ash/components/settings/cros_settings.h"
class PrefRegistrySimple;
namespace ash {
class NetworkStateHandler;
class UpdateRequiredNotification;
} // namespace ash
namespace base {
class Clock;
class Time;
} // namespace base
namespace policy {
// This class observes the device setting |kDeviceMinimumVersion|, and
// checks if respective requirement is met. If an update is not required, all
// running timers are reset. If an update is required, it calculates the
// deadline using the warning period in the policy and restarts the timer. It
// also calls UpdateRequiredNotification to show in-session notifications if an
// update is required but it cannot be downloaded due to network limitations or
// Auto Update Expiration.
class MinimumVersionPolicyHandler : public BuildStateObserver,
public ash::NetworkStateHandlerObserver,
public ash::UpdateEngineClient::Observer {
public:
static const char kRequirements[];
static const char kChromeOsVersion[];
static const char kWarningPeriod[];
static const char kEolWarningPeriod[];
static const char kUnmanagedUserRestricted[];
class Observer {
public:
virtual void OnMinimumVersionStateChanged() = 0;
virtual ~Observer() = default;
};
// Delegate of MinimumVersionPolicyHandler to handle the external
// dependencies.
class Delegate {
public:
virtual ~Delegate() = default;
// Checks if the user is logged in as any kiosk app or this is an
// auto-launch kiosk device.
virtual bool IsKioskMode() const = 0;
// Checks if the device is enterprise managed.
virtual bool IsDeviceEnterpriseManaged() const = 0;
// Checks if a user is logged in.
virtual bool IsUserLoggedIn() const = 0;
// Checks if the user logged in is managed and not a child user.
virtual bool IsUserEnterpriseManaged() const = 0;
// Checks if we are currently on the login screen.
virtual bool IsLoginSessionState() const = 0;
// Checks if login is in progress before starting user session.
virtual bool IsLoginInProgress() const = 0;
// Shows the update required screen.
virtual void ShowUpdateRequiredScreen() = 0;
// Terminates the current session and restarts Chrome to show the login
// screen.
virtual void RestartToLoginScreen() = 0;
// Hides update required screen and shows the login screen.
virtual void HideUpdateRequiredScreenIfShown() = 0;
virtual base::Version GetCurrentVersion() const = 0;
};
class MinimumVersionRequirement {
public:
MinimumVersionRequirement(const base::Version version,
const base::TimeDelta warning,
const base::TimeDelta eol_warning);
MinimumVersionRequirement(const MinimumVersionRequirement&) = delete;
// Method used to create an instance of MinimumVersionRequirement from
// dictionary if it contains valid version string.
static std::unique_ptr<MinimumVersionRequirement> CreateInstanceIfValid(
const base::Value::Dict& dict);
// This is used to compare two MinimumVersionRequirement objects
// and returns 1 if the first object has version or warning time
// or eol warning time greater than that the second, -1 if the
// its version or warning time or eol warning time is less than the second,
// else 0.
int Compare(const MinimumVersionRequirement* other) const;
base::Version version() const { return minimum_version_; }
base::TimeDelta warning() const { return warning_time_; }
base::TimeDelta eol_warning() const { return eol_warning_time_; }
private:
base::Version minimum_version_;
base::TimeDelta warning_time_;
base::TimeDelta eol_warning_time_;
};
enum class NetworkStatus { kAllowed, kMetered, kOffline };
enum class NotificationType {
kMeteredConnection,
kNoConnection,
kEolReached
};
explicit MinimumVersionPolicyHandler(Delegate* delegate,
ash::CrosSettings* cros_settings);
MinimumVersionPolicyHandler(const MinimumVersionPolicyHandler&) = delete;
MinimumVersionPolicyHandler& operator=(const MinimumVersionPolicyHandler&) =
delete;
~MinimumVersionPolicyHandler() override;
// BuildStateObserver:
void OnUpdate(const BuildState* build_state) override;
// NetworkStateHandlerObserver:
void DefaultNetworkChanged(const ash::NetworkState* network) override;
void OnShuttingDown() override;
// UpdateEngineClient::Observer:
void UpdateStatusChanged(const update_engine::StatusResult& status) override;
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
bool RequirementsAreSatisfied() const { return GetState() == nullptr; }
const MinimumVersionRequirement* GetState() const { return state_.get(); }
bool DeadlineReached() { return deadline_reached_; }
static void RegisterPrefs(PrefRegistrySimple* registry);
// Show notification on login if the user is managed or
// |unmanaged_user_restricted_| is set to true if it is the last day to
// deadline.
void MaybeShowNotificationOnLogin();
// Whether banner to return back the device should be visible in Settings. It
// is true when an update is required on a device that has reached End Of Life
// (Auto Update Expiration) and the currently signed in user is enterprise
// managed or an unmanaged user restricted by DeviceMinimumVersion policy.
bool ShouldShowUpdateRequiredEolBanner() const;
// Returns the number of days to deadline if update is required and deadline
// has not been reached. Returns null if update is not required.
std::optional<int> GetTimeRemainingInDays();
// Callback used in tests and invoked after end-of-life status has been
// fetched from the update_engine.
void set_fetch_eol_callback_for_testing(base::OnceClosure callback) {
fetch_eol_callback_ = std::move(callback);
}
base::Time update_required_deadline_for_testing() const {
return update_required_deadline_;
}
bool IsDeadlineTimerRunningForTesting() const;
private:
// Returns |true| if the current version satisfies the given requirement.
bool CurrentVersionSatisfies(
const MinimumVersionRequirement& requirement) const;
// Whether the current user should receive update required notifications and
// force signed out on reaching the deadline. Retuns true if the user is
// enterprise managed or |unmanaged_user_restricted_| is true.
bool IsPolicyRestrictionAppliedForUser() const;
void OnPolicyChanged();
bool IsPolicyApplicable();
void Reset();
// Handles post update completed actions like reset timers, hide update
// required notification and stop observing build state.
void ResetOnUpdateCompleted();
// Handles the state when update is required as per the policy. If on the
// login screen, update required screen is shown, else the user is logged out
// if the device is not updated within the given |warning_time|. The
// |warning_time| is supplied by the policy.
void HandleUpdateRequired(base::TimeDelta warning_time);
void HandleUpdateNotRequired();
// Invokes update_engine_client to fetch the end-of-life status of the device.
void FetchEolInfo();
// Callback after fetching end-of-life info from the update_engine_client.
void OnFetchEolInfo(ash::UpdateEngineClient::EolInfo info);
// Called when the warning time to apply updates has expired. If the user on
// the login screen, the update required screen is shown else the current user
// session is terminated to bring the user back to the login screen.
void OnDeadlineReached();
// Starts the timer to expire when |deadline| is reached.
void StartDeadlineTimer(base::Time deadline);
// Starts observing the BuildState for any updates in Chrome OS and resets the
// state if new version satisfies the minimum version requirement.
void StartObservingUpdate();
// Shows notification for a managed logged in user if update is required and
// the device can not be updated due to end-of-life or network limitations.
void MaybeShowNotification(base::TimeDelta warning);
// Shows notification if required and starts a timer to expire when the next
// notification is to be shown.
void ShowAndScheduleNotification(base::Time deadline);
void HideNotification() const;
void StopObservingNetwork();
// Start updating over metered network as user has given consent through
// notification click.
void UpdateOverMeteredPermssionGranted();
// Tells whether starting an update check succeeded or not.
void OnUpdateCheckStarted(ash::UpdateEngineClient::UpdateCheckResult result);
// Callback from UpdateEngineClient::SetUpdateOverCellularOneTimePermission().
void OnSetUpdateOverCellularOneTimePermission(bool success);
// Updates pref |kUpdateRequiredWarningPeriod| in local state to
// |warning_time|. If |kUpdateRequiredTimerStartTime| is not null, it means
// update is already required and hence, the timer start time should not be
// updated.
void UpdateLocalState(base::TimeDelta warning_time);
// Resets the local state prefs to default values.
void ResetLocalState();
// This delegate instance is owned by the owner of
// MinimumVersionPolicyHandler. The owner is responsible to make sure that the
// delegate lives throughout the life of the policy handler.
raw_ptr<Delegate> delegate_;
// This represents the current minimum version requirement.
// It is chosen as one of the configurations specified in the policy. It is
// set to nullptr if the current version is higher than the minimum required
// version in all the configurations.
std::unique_ptr<MinimumVersionRequirement> state_;
// If this flag is true, unmanaged user sessions receive update required
// notifications and are force logged out when deadline is reached.
bool unmanaged_user_restricted_ = false;
bool eol_reached_ = false;
// If this flag is true, user should restricted to use the session by logging
// out and/or showing update required screen.
bool deadline_reached_ = false;
// Time when the policy is applied and with respect to which the deadline to
// update the device is calculated.
base::Time update_required_time_;
// Deadline for updating the device post which the user is restricted from
// using the session by force log out if a session is active and then blocking
// sign in at the login screen.
base::Time update_required_deadline_;
// Fires when the deadline to update the device has reached or passed.
base::WallClockTimer update_required_deadline_timer_;
// Fires when next update required notification is to be shown.
base::WallClockTimer notification_timer_;
// Non-owning reference to CrosSettings. This class have shorter lifetime than
// CrosSettings.
raw_ptr<ash::CrosSettings> cros_settings_;
const raw_ptr<base::Clock> clock_;
base::OnceClosure fetch_eol_callback_;
base::CallbackListSubscription policy_subscription_;
// Handles showing in-session update required notifications on the basis of
// current network and time to reach the deadline.
std::unique_ptr<ash::UpdateRequiredNotification> notification_handler_;
base::ScopedObservation<ash::NetworkStateHandler,
ash::NetworkStateHandlerObserver>
network_state_handler_observer_{this};
// List of registered observers.
base::ObserverList<Observer>::Unchecked observers_;
base::WeakPtrFactory<MinimumVersionPolicyHandler> weak_factory_{this};
};
} // namespace policy
#endif // CHROME_BROWSER_ASH_POLICY_HANDLERS_MINIMUM_VERSION_POLICY_HANDLER_H_
|