Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4622)

Unified Diff: chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.cc

Issue 109743002: Move policy code into components/policy. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: moar fixes Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.cc
diff --git a/chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.cc b/chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.cc
deleted file mode 100644
index aaf1c2964cedccb87ee6c9ad13f3124f0d6a44cf..0000000000000000000000000000000000000000
--- a/chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.cc
+++ /dev/null
@@ -1,375 +0,0 @@
-// Copyright (c) 2012 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 "chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.h"
-
-#include <algorithm>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/command_line.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/metrics/histogram.h"
-#include "base/sequenced_task_runner.h"
-#include "base/time/default_tick_clock.h"
-#include "base/time/tick_clock.h"
-#include "chrome/browser/policy/cloud/cloud_policy_constants.h"
-#include "components/policy/core/common/policy_switches.h"
-
-namespace policy {
-
-namespace {
-
-// The maximum rate at which to refresh policies.
-const size_t kMaxRefreshesPerHour = 5;
-
-// The maximum time to wait for the invalidations service to become available
-// before starting to issue requests.
-const int kWaitForInvalidationsTimeoutSeconds = 5;
-
-} // namespace
-
-#if defined(OS_ANDROID)
-
-const int64 CloudPolicyRefreshScheduler::kDefaultRefreshDelayMs =
- 24 * 60 * 60 * 1000; // 1 day.
-const int64 CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs =
- 24 * 60 * 60 * 1000; // 1 day.
-// Delay for periodic refreshes when the invalidations service is available,
-// in milliseconds.
-// TODO(joaodasilva): increase this value once we're confident that the
-// invalidations channel works as expected.
-const int64 CloudPolicyRefreshScheduler::kWithInvalidationsRefreshDelayMs =
- 24 * 60 * 60 * 1000; // 1 day.
-const int64 CloudPolicyRefreshScheduler::kInitialErrorRetryDelayMs =
- 5 * 60 * 1000; // 5 minutes.
-const int64 CloudPolicyRefreshScheduler::kRefreshDelayMinMs =
- 30 * 60 * 1000; // 30 minutes.
-const int64 CloudPolicyRefreshScheduler::kRefreshDelayMaxMs =
- 7 * 24 * 60 * 60 * 1000; // 1 week.
-
-#else
-
-const int64 CloudPolicyRefreshScheduler::kDefaultRefreshDelayMs =
- 3 * 60 * 60 * 1000; // 3 hours.
-const int64 CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs =
- 24 * 60 * 60 * 1000; // 1 day.
-// Delay for periodic refreshes when the invalidations service is available,
-// in milliseconds.
-// TODO(joaodasilva): increase this value once we're confident that the
-// invalidations channel works as expected.
-const int64 CloudPolicyRefreshScheduler::kWithInvalidationsRefreshDelayMs =
- 3 * 60 * 60 * 1000; // 3 hours.
-const int64 CloudPolicyRefreshScheduler::kInitialErrorRetryDelayMs =
- 5 * 60 * 1000; // 5 minutes.
-const int64 CloudPolicyRefreshScheduler::kRefreshDelayMinMs =
- 30 * 60 * 1000; // 30 minutes.
-const int64 CloudPolicyRefreshScheduler::kRefreshDelayMaxMs =
- 24 * 60 * 60 * 1000; // 1 day.
-
-#endif
-
-CloudPolicyRefreshScheduler::CloudPolicyRefreshScheduler(
- CloudPolicyClient* client,
- CloudPolicyStore* store,
- const scoped_refptr<base::SequencedTaskRunner>& task_runner)
- : client_(client),
- store_(store),
- task_runner_(task_runner),
- error_retry_delay_ms_(kInitialErrorRetryDelayMs),
- refresh_delay_ms_(kDefaultRefreshDelayMs),
- rate_limiter_(kMaxRefreshesPerHour,
- base::TimeDelta::FromHours(1),
- base::Bind(&CloudPolicyRefreshScheduler::RefreshNow,
- base::Unretained(this)),
- task_runner_,
- scoped_ptr<base::TickClock>(new base::DefaultTickClock())),
- invalidations_available_(false),
- creation_time_(base::Time::NowFromSystemTime()) {
- client_->AddObserver(this);
- store_->AddObserver(this);
- net::NetworkChangeNotifier::AddIPAddressObserver(this);
-
- UpdateLastRefreshFromPolicy();
-
- // Give some time for the invalidation service to become available before the
- // first refresh if there is already policy present.
- if (store->has_policy())
- WaitForInvalidationService();
- else
- ScheduleRefresh();
-}
-
-CloudPolicyRefreshScheduler::~CloudPolicyRefreshScheduler() {
- store_->RemoveObserver(this);
- client_->RemoveObserver(this);
- net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
-}
-
-void CloudPolicyRefreshScheduler::SetRefreshDelay(int64 refresh_delay) {
- refresh_delay_ms_ = std::min(std::max(refresh_delay, kRefreshDelayMinMs),
- kRefreshDelayMaxMs);
- ScheduleRefresh();
-}
-
-void CloudPolicyRefreshScheduler::RefreshSoon() {
- // An external consumer needs a policy update now (e.g. a new extension, or
- // the InvalidationService received a policy invalidation), so don't wait
- // before fetching anymore.
- wait_for_invalidations_timeout_callback_.Cancel();
- rate_limiter_.PostRequest();
-}
-
-void CloudPolicyRefreshScheduler::SetInvalidationServiceAvailability(
- bool is_available) {
- if (!creation_time_.is_null()) {
- base::TimeDelta elapsed = base::Time::NowFromSystemTime() - creation_time_;
- UMA_HISTOGRAM_MEDIUM_TIMES("Enterprise.PolicyInvalidationsStartupTime",
- elapsed);
- creation_time_ = base::Time();
- }
-
- if (is_available == invalidations_available_) {
- // No change in state. If we're currently WaitingForInvalidationService
- // then the timeout task will eventually execute and trigger a reschedule;
- // let the InvalidationService keep retrying until that happens.
- return;
- }
-
- wait_for_invalidations_timeout_callback_.Cancel();
- invalidations_available_ = is_available;
-
- // Schedule a refresh since the refresh delay has been updated; however, allow
- // some time for the invalidation service to update. If it is now online, the
- // wait allows pending invalidations to be delivered. If it is now offline,
- // then the wait allows for the service to recover from transient failure
- // before falling back on the polling behavior.
- WaitForInvalidationService();
-}
-
-void CloudPolicyRefreshScheduler::OnPolicyFetched(CloudPolicyClient* client) {
- error_retry_delay_ms_ = kInitialErrorRetryDelayMs;
-
- // Schedule the next refresh.
- last_refresh_ = base::Time::NowFromSystemTime();
- ScheduleRefresh();
-}
-
-void CloudPolicyRefreshScheduler::OnRegistrationStateChanged(
- CloudPolicyClient* client) {
- error_retry_delay_ms_ = kInitialErrorRetryDelayMs;
-
- // The client might have registered, so trigger an immediate refresh.
- RefreshNow();
-}
-
-void CloudPolicyRefreshScheduler::OnClientError(CloudPolicyClient* client) {
- // Save the status for below.
- DeviceManagementStatus status = client_->status();
-
- // Schedule an error retry if applicable.
- last_refresh_ = base::Time::NowFromSystemTime();
- ScheduleRefresh();
-
- // Update the retry delay.
- if (client->is_registered() &&
- (status == DM_STATUS_REQUEST_FAILED ||
- status == DM_STATUS_TEMPORARY_UNAVAILABLE)) {
- error_retry_delay_ms_ = std::min(error_retry_delay_ms_ * 2,
- refresh_delay_ms_);
- } else {
- error_retry_delay_ms_ = kInitialErrorRetryDelayMs;
- }
-}
-
-void CloudPolicyRefreshScheduler::OnStoreLoaded(CloudPolicyStore* store) {
- UpdateLastRefreshFromPolicy();
-
- // Re-schedule the next refresh in case the is_managed bit changed.
- ScheduleRefresh();
-}
-
-void CloudPolicyRefreshScheduler::OnStoreError(CloudPolicyStore* store) {
- // If |store_| fails, the is_managed bit that it provides may become stale.
- // The best guess in that situation is to assume is_managed didn't change and
- // continue using the stale information. Thus, no specific response to a store
- // error is required. NB: Changes to is_managed fire OnStoreLoaded().
-}
-
-void CloudPolicyRefreshScheduler::OnIPAddressChanged() {
- if (client_->status() == DM_STATUS_REQUEST_FAILED)
- RefreshSoon();
-}
-
-void CloudPolicyRefreshScheduler::UpdateLastRefreshFromPolicy() {
- if (!last_refresh_.is_null())
- return;
-
- // If the client has already fetched policy, assume that happened recently. If
- // that assumption ever breaks, the proper thing to do probably is to move the
- // |last_refresh_| bookkeeping to CloudPolicyClient.
- if (!client_->responses().empty()) {
- last_refresh_ = base::Time::NowFromSystemTime();
- return;
- }
-
-#if defined(OS_ANDROID)
- // Refreshing on Android:
- // - if no user is signed-in then the |client_| is never registered and
- // nothing happens here.
- // - if the user is signed-in but isn't enterprise then the |client_| is
- // never registered and nothing happens here.
- // - if the user is signed-in but isn't registered for policy yet then the
- // |client_| isn't registered either; the UserPolicySigninService will try
- // to register, and OnRegistrationStateChanged() will be invoked later.
- // - if the client is signed-in and has policy then its timestamp is used to
- // determine when to perform the next fetch, which will be once the cached
- // version is considered "old enough".
- //
- // If there is an old policy cache then a fetch will be performed "soon"; if
- // that fetch fails then a retry is attempted after a delay, with exponential
- // backoff. If those fetches keep failing then the cached timestamp is *not*
- // updated, and another fetch (and subsequent retries) will be attempted
- // again on the next startup.
- //
- // But if the cached policy is considered fresh enough then we try to avoid
- // fetching again on startup; the Android logic differs from the desktop in
- // this aspect.
- if (store_->has_policy() && store_->policy()->has_timestamp()) {
- last_refresh_ =
- base::Time::UnixEpoch() +
- base::TimeDelta::FromMilliseconds(store_->policy()->timestamp());
- }
-#else
- // If there is a cached non-managed response, make sure to only re-query the
- // server after kUnmanagedRefreshDelayMs. NB: For existing policy, an
- // immediate refresh is intentional.
- if (store_->has_policy() && store_->policy()->has_timestamp() &&
- !store_->is_managed()) {
- last_refresh_ =
- base::Time::UnixEpoch() +
- base::TimeDelta::FromMilliseconds(store_->policy()->timestamp());
- }
-#endif
-}
-
-void CloudPolicyRefreshScheduler::RefreshNow() {
- last_refresh_ = base::Time();
- ScheduleRefresh();
-}
-
-void CloudPolicyRefreshScheduler::ScheduleRefresh() {
- // If the client isn't registered, there is nothing to do.
- if (!client_->is_registered()) {
- refresh_callback_.Cancel();
- return;
- }
-
- // Don't schedule anything yet if we're still waiting for the invalidations
- // service.
- if (WaitingForInvalidationService())
- return;
-
- // If policy invalidations are available then periodic updates are done at
- // a much lower rate; otherwise use the |refresh_delay_ms_| value.
- int64 refresh_delay_ms =
- invalidations_available_ ? kWithInvalidationsRefreshDelayMs
- : refresh_delay_ms_;
-
- // If there is a registration, go by the client's status. That will tell us
- // what the appropriate refresh delay should be.
- switch (client_->status()) {
- case DM_STATUS_SUCCESS:
- if (store_->is_managed())
- RefreshAfter(refresh_delay_ms);
- else
- RefreshAfter(kUnmanagedRefreshDelayMs);
- return;
- case DM_STATUS_SERVICE_ACTIVATION_PENDING:
- case DM_STATUS_SERVICE_POLICY_NOT_FOUND:
- RefreshAfter(refresh_delay_ms);
- return;
- case DM_STATUS_REQUEST_FAILED:
- case DM_STATUS_TEMPORARY_UNAVAILABLE:
- RefreshAfter(error_retry_delay_ms_);
- return;
- case DM_STATUS_REQUEST_INVALID:
- case DM_STATUS_HTTP_STATUS_ERROR:
- case DM_STATUS_RESPONSE_DECODING_ERROR:
- case DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED:
- RefreshAfter(kUnmanagedRefreshDelayMs);
- return;
- case DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID:
- case DM_STATUS_SERVICE_DEVICE_NOT_FOUND:
- case DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER:
- case DM_STATUS_SERVICE_DEVICE_ID_CONFLICT:
- case DM_STATUS_SERVICE_MISSING_LICENSES:
- // Need a re-registration, no use in retrying.
- refresh_callback_.Cancel();
- return;
- }
-
- NOTREACHED() << "Invalid client status " << client_->status();
- RefreshAfter(kUnmanagedRefreshDelayMs);
-}
-
-void CloudPolicyRefreshScheduler::PerformRefresh() {
- if (client_->is_registered()) {
- // Update |last_refresh_| so another fetch isn't triggered inadvertently.
- last_refresh_ = base::Time::NowFromSystemTime();
-
- // The result of this operation will be reported through a callback, at
- // which point the next refresh will be scheduled.
- client_->FetchPolicy();
- return;
- }
-
- // This should never happen, as the registration change should have been
- // handled via OnRegistrationStateChanged().
- NOTREACHED();
-}
-
-void CloudPolicyRefreshScheduler::RefreshAfter(int delta_ms) {
- base::TimeDelta delta(base::TimeDelta::FromMilliseconds(delta_ms));
- refresh_callback_.Cancel();
-
- // Schedule the callback.
- base::TimeDelta delay =
- std::max((last_refresh_ + delta) - base::Time::NowFromSystemTime(),
- base::TimeDelta());
- refresh_callback_.Reset(
- base::Bind(&CloudPolicyRefreshScheduler::PerformRefresh,
- base::Unretained(this)));
- task_runner_->PostDelayedTask(FROM_HERE, refresh_callback_.callback(), delay);
-}
-
-void CloudPolicyRefreshScheduler::WaitForInvalidationService() {
- DCHECK(!WaitingForInvalidationService());
- wait_for_invalidations_timeout_callback_.Reset(
- base::Bind(
- &CloudPolicyRefreshScheduler::OnWaitForInvalidationServiceTimeout,
- base::Unretained(this)));
- base::TimeDelta delay =
- base::TimeDelta::FromSeconds(kWaitForInvalidationsTimeoutSeconds);
- // Do not wait for the invalidation service if the feature is disabled.
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableCloudPolicyPush)) {
- delay = base::TimeDelta();
- }
- task_runner_->PostDelayedTask(
- FROM_HERE,
- wait_for_invalidations_timeout_callback_.callback(),
- delay);
-}
-
-void CloudPolicyRefreshScheduler::OnWaitForInvalidationServiceTimeout() {
- wait_for_invalidations_timeout_callback_.Cancel();
- ScheduleRefresh();
-}
-
-bool CloudPolicyRefreshScheduler::WaitingForInvalidationService() const {
- return !wait_for_invalidations_timeout_callback_.IsCancelled();
-}
-
-} // namespace policy

Powered by Google App Engine
This is Rietveld 408576698