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

Unified Diff: chrome/browser/policy/cloud_policy_controller.cc

Issue 11946017: Remove old cloud policy code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address nits. Created 7 years, 11 months 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_policy_controller.cc
diff --git a/chrome/browser/policy/cloud_policy_controller.cc b/chrome/browser/policy/cloud_policy_controller.cc
deleted file mode 100644
index bd4b9b56d8095c935152072364fd163b60f6e603..0000000000000000000000000000000000000000
--- a/chrome/browser/policy/cloud_policy_controller.cc
+++ /dev/null
@@ -1,481 +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_policy_controller.h"
-
-#include <algorithm>
-#include <string>
-
-#include "base/bind.h"
-#include "base/guid.h"
-#include "base/logging.h"
-#include "base/metrics/histogram.h"
-#include "base/rand_util.h"
-#include "chrome/browser/policy/browser_policy_connector.h"
-#include "chrome/browser/policy/cloud_policy_cache_base.h"
-#include "chrome/browser/policy/cloud_policy_constants.h"
-#include "chrome/browser/policy/cloud_policy_subsystem.h"
-#include "chrome/browser/policy/delayed_work_scheduler.h"
-#include "chrome/browser/policy/device_management_service.h"
-#include "chrome/browser/policy/device_token_fetcher.h"
-#include "chrome/browser/policy/enterprise_metrics.h"
-#include "chrome/browser/policy/policy_notifier.h"
-
-namespace policy {
-
-namespace {
-
-// The maximum ratio in percent of the policy refresh rate we use for adjusting
-// the policy refresh time instant. The rationale is to avoid load spikes from
-// many devices that were set up in sync for some reason.
-const int kPolicyRefreshDeviationFactorPercent = 10;
-// Maximum deviation we are willing to accept.
-const int64 kPolicyRefreshDeviationMaxInMilliseconds = 30 * 60 * 1000;
-
-// These are the base values for delays before retrying after an error. They
-// will be doubled each time they are used.
-const int64 kPolicyRefreshErrorDelayInMilliseconds =
- 5 * 60 * 1000; // 5 minutes.
-
-// Default value for the policy refresh rate.
-const int kPolicyRefreshRateInMilliseconds = 3 * 60 * 60 * 1000; // 3 hours.
-
-// Records the UMA metric corresponding to |status|, if it represents an error.
-// Also records that a fetch response was received.
-void SampleErrorStatus(DeviceManagementStatus status) {
- UMA_HISTOGRAM_ENUMERATION(kMetricPolicy,
- kMetricPolicyFetchResponseReceived,
- kMetricPolicySize);
- int sample = -1;
- switch (status) {
- case DM_STATUS_SUCCESS:
- return;
- case DM_STATUS_SERVICE_POLICY_NOT_FOUND:
- sample = kMetricPolicyFetchNotFound;
- break;
- case DM_STATUS_SERVICE_DEVICE_NOT_FOUND:
- sample = kMetricPolicyFetchInvalidToken;
- break;
- case DM_STATUS_RESPONSE_DECODING_ERROR:
- sample = kMetricPolicyFetchBadResponse;
- break;
- case DM_STATUS_REQUEST_FAILED:
- case DM_STATUS_REQUEST_INVALID:
- case DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID:
- sample = kMetricPolicyFetchRequestFailed;
- break;
- case DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED:
- case DM_STATUS_SERVICE_DEVICE_ID_CONFLICT:
- case DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER:
- case DM_STATUS_TEMPORARY_UNAVAILABLE:
- case DM_STATUS_SERVICE_ACTIVATION_PENDING:
- case DM_STATUS_HTTP_STATUS_ERROR:
- case DM_STATUS_SERVICE_MISSING_LICENSES:
- sample = kMetricPolicyFetchServerFailed;
- break;
- }
- if (sample != -1)
- UMA_HISTOGRAM_ENUMERATION(kMetricPolicy, sample, kMetricPolicySize);
- else
- NOTREACHED();
-}
-
-} // namespace
-
-namespace em = enterprise_management;
-
-CloudPolicyController::CloudPolicyController(
- DeviceManagementService* service,
- CloudPolicyCacheBase* cache,
- DeviceTokenFetcher* token_fetcher,
- CloudPolicyDataStore* data_store,
- PolicyNotifier* notifier) {
- Initialize(service,
- cache,
- token_fetcher,
- data_store,
- notifier,
- new DelayedWorkScheduler);
-}
-
-CloudPolicyController::~CloudPolicyController() {
- data_store_->RemoveObserver(this);
- scheduler_->CancelDelayedWork();
-}
-
-void CloudPolicyController::SetRefreshRate(int64 refresh_rate_milliseconds) {
- policy_refresh_rate_ms_ = refresh_rate_milliseconds;
-
- // Reschedule the refresh task if necessary.
- if (state_ == STATE_POLICY_VALID) {
- scheduler_->CancelDelayedWork();
- base::Time now(base::Time::NowFromSystemTime());
- ScheduleDelayedWorkTask(
- (GetLastRefreshTime(now) + GetRefreshDelay()) - now);
- }
-}
-
-void CloudPolicyController::Retry() {
- scheduler_->CancelDelayedWork();
- DoWork();
-}
-
-void CloudPolicyController::Reset() {
- SetState(STATE_TOKEN_UNAVAILABLE);
-}
-
-void CloudPolicyController::RefreshPolicies(bool wait_for_auth_token) {
- // This call must eventually trigger a notification to the cache.
- if (data_store_->device_token().empty()) {
- // The DMToken has to be fetched.
- if (ReadyToFetchToken()) {
- SetState(STATE_TOKEN_UNAVAILABLE);
- } else if (!wait_for_auth_token) {
- // The controller doesn't have enough material to start a token fetch,
- // but observers of the cache are waiting for the refresh.
- SetState(STATE_TOKEN_UNMANAGED);
- }
- } else {
- // The token is valid, so the next step is to fetch policy.
- SetState(STATE_TOKEN_VALID);
- }
-}
-
-void CloudPolicyController::OnPolicyFetchCompleted(
- DeviceManagementStatus status,
- const em::DeviceManagementResponse& response) {
- if (status == DM_STATUS_SUCCESS && !response.has_policy_response()) {
- // Handled below.
- status = DM_STATUS_RESPONSE_DECODING_ERROR;
- }
-
- SampleErrorStatus(status);
-
- switch (status) {
- case DM_STATUS_SUCCESS: {
- const em::DevicePolicyResponse& policy_response(
- response.policy_response());
- if (policy_response.response_size() > 0) {
- if (policy_response.response_size() > 1) {
- LOG(WARNING) << "More than one policy in the response of the device "
- << "management server, discarding.";
- }
- const em::PolicyFetchResponse& fetch_response(
- policy_response.response(0));
- if (!fetch_response.has_error_code() ||
- fetch_response.error_code() == dm_protocol::POLICY_FETCH_SUCCESS) {
- if (cache_->SetPolicy(fetch_response))
- SetState(STATE_POLICY_VALID);
- else
- SetState(STATE_POLICY_ERROR);
- } else {
- UMA_HISTOGRAM_ENUMERATION(kMetricPolicy,
- kMetricPolicyFetchBadResponse,
- kMetricPolicySize);
- SetState(STATE_POLICY_UNAVAILABLE);
- }
- } else {
- UMA_HISTOGRAM_ENUMERATION(kMetricPolicy, kMetricPolicyFetchBadResponse,
- kMetricPolicySize);
- SetState(STATE_POLICY_UNAVAILABLE);
- }
- return;
- }
- case DM_STATUS_SERVICE_DEVICE_NOT_FOUND:
- case DM_STATUS_SERVICE_DEVICE_ID_CONFLICT:
- case DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID:
- LOG(WARNING) << "The device token was either invalid or unknown to the "
- << "device manager, re-registering device.";
- // Will retry fetching a token but gracefully backing off.
- SetState(STATE_TOKEN_ERROR);
- return;
- case DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER:
- VLOG(1) << "The device is no longer enlisted for the domain.";
- token_fetcher_->SetSerialNumberInvalidState();
- SetState(STATE_TOKEN_ERROR);
- return;
- case DM_STATUS_SERVICE_MISSING_LICENSES:
- VLOG(1) << "There are no valid licenses for this domain left.";
- token_fetcher_->SetMissingLicensesState();
- SetState(STATE_TOKEN_UNMANAGED);
- return;
- case DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED:
- VLOG(1) << "The device is no longer managed.";
- token_fetcher_->SetUnmanagedState();
- SetState(STATE_TOKEN_UNMANAGED);
- return;
- case DM_STATUS_SERVICE_POLICY_NOT_FOUND:
- case DM_STATUS_REQUEST_INVALID:
- case DM_STATUS_SERVICE_ACTIVATION_PENDING:
- case DM_STATUS_RESPONSE_DECODING_ERROR:
- case DM_STATUS_HTTP_STATUS_ERROR:
- VLOG(1) << "An error in the communication with the policy server occurred"
- << ", will retry in a few hours.";
- SetState(STATE_POLICY_UNAVAILABLE);
- return;
- case DM_STATUS_REQUEST_FAILED:
- case DM_STATUS_TEMPORARY_UNAVAILABLE:
- VLOG(1) << "A temporary error in the communication with the policy server"
- << " occurred.";
- // Will retry last operation but gracefully backing off.
- SetState(STATE_POLICY_ERROR);
- return;
- }
-
- NOTREACHED();
- SetState(STATE_POLICY_ERROR);
-}
-
-void CloudPolicyController::OnDeviceTokenChanged() {
- if (data_store_->device_token().empty()) {
- // Additionally clear the generated device id to ensure we don't reuse old
- // ids which could be potentially used for user tracking.
- data_store_->set_device_id(std::string());
- SetState(STATE_TOKEN_UNAVAILABLE);
- } else {
- SetState(STATE_TOKEN_VALID);
- }
-}
-
-void CloudPolicyController::OnCredentialsChanged() {
- // This notification is only interesting if we don't have a device token.
- // If we already have a device token, that must be matching the current
- // user, because (1) we always recreate the policy subsystem after user
- // login (2) tokens are cached per user.
- if (data_store_->device_token().empty()) {
- notifier_->Inform(CloudPolicySubsystem::UNENROLLED,
- CloudPolicySubsystem::NO_DETAILS,
- PolicyNotifier::POLICY_CONTROLLER);
- effective_policy_refresh_error_delay_ms_ =
- kPolicyRefreshErrorDelayInMilliseconds;
- SetState(STATE_TOKEN_UNAVAILABLE);
- }
-}
-
-CloudPolicyController::CloudPolicyController(
- DeviceManagementService* service,
- CloudPolicyCacheBase* cache,
- DeviceTokenFetcher* token_fetcher,
- CloudPolicyDataStore* data_store,
- PolicyNotifier* notifier,
- DelayedWorkScheduler* scheduler) {
- Initialize(service,
- cache,
- token_fetcher,
- data_store,
- notifier,
- scheduler);
-}
-
-void CloudPolicyController::Initialize(
- DeviceManagementService* service,
- CloudPolicyCacheBase* cache,
- DeviceTokenFetcher* token_fetcher,
- CloudPolicyDataStore* data_store,
- PolicyNotifier* notifier,
- DelayedWorkScheduler* scheduler) {
- DCHECK(cache);
-
- service_ = service;
- cache_ = cache;
- token_fetcher_ = token_fetcher;
- data_store_ = data_store;
- notifier_ = notifier;
- state_ = STATE_TOKEN_UNAVAILABLE;
- policy_refresh_rate_ms_ = kPolicyRefreshRateInMilliseconds;
- effective_policy_refresh_error_delay_ms_ =
- kPolicyRefreshErrorDelayInMilliseconds;
- scheduler_.reset(scheduler);
- data_store_->AddObserver(this);
- if (!data_store_->device_token().empty())
- SetState(STATE_TOKEN_VALID);
- else
- SetState(STATE_TOKEN_UNAVAILABLE);
-}
-
-bool CloudPolicyController::ReadyToFetchToken() {
- return data_store_->token_cache_loaded() &&
- !data_store_->user_name().empty() &&
- data_store_->has_auth_token();
-}
-
-void CloudPolicyController::FetchToken() {
- if (ReadyToFetchToken()) {
- if (BrowserPolicyConnector::IsNonEnterpriseUser(data_store_->user_name())) {
- SetState(STATE_TOKEN_UNMANAGED);
- } else {
- // Either use an already prepopulated id or generate a new random device
- // id. (It'll only be kept if registration succeeds.)
- if (data_store_->device_id().empty())
- data_store_->set_device_id(base::GenerateGUID());
- token_fetcher_->FetchToken();
- }
- } else {
- VLOG(1) << "Not ready to fetch DMToken yet, will try again later.";
- }
-}
-
-void CloudPolicyController::SendPolicyRequest() {
- DCHECK(!data_store_->device_token().empty());
-
- if (!data_store_->policy_fetching_enabled())
- return;
-
- request_job_.reset(
- service_->CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH));
- request_job_->SetDMToken(data_store_->device_token());
- request_job_->SetClientID(data_store_->device_id());
- request_job_->SetUserAffiliation(data_store_->user_affiliation());
-
- em::DeviceManagementRequest* request = request_job_->GetRequest();
- em::PolicyFetchRequest* fetch_request =
- request->mutable_policy_request()->add_request();
- fetch_request->set_signature_type(em::PolicyFetchRequest::SHA1_RSA);
- fetch_request->set_policy_type(data_store_->policy_type());
- if (cache_->machine_id_missing() && !data_store_->machine_id().empty())
- fetch_request->set_machine_id(data_store_->machine_id());
- if (!cache_->is_unmanaged() &&
- !cache_->last_policy_refresh_time().is_null()) {
- base::TimeDelta timestamp =
- cache_->last_policy_refresh_time() - base::Time::UnixEpoch();
- fetch_request->set_timestamp(timestamp.InMilliseconds());
- }
- int key_version = 0;
- if (cache_->GetPublicKeyVersion(&key_version))
- fetch_request->set_public_key_version(key_version);
-
-#if defined(OS_CHROMEOS)
- if (data_store_->device_status_collector()) {
- data_store_->device_status_collector()->GetStatus(
- request->mutable_device_status_report_request());
- }
-#endif
-
- request_job_->Start(base::Bind(&CloudPolicyController::OnPolicyFetchCompleted,
- base::Unretained(this)));
- UMA_HISTOGRAM_ENUMERATION(kMetricPolicy, kMetricPolicyFetchRequested,
- kMetricPolicySize);
-}
-
-void CloudPolicyController::DoWork() {
- switch (state_) {
- case STATE_TOKEN_UNAVAILABLE:
- case STATE_TOKEN_ERROR:
- FetchToken();
- return;
- case STATE_TOKEN_VALID:
- case STATE_POLICY_VALID:
- case STATE_POLICY_ERROR:
- case STATE_POLICY_UNAVAILABLE:
- SendPolicyRequest();
- return;
- case STATE_TOKEN_UNMANAGED:
- return;
- }
-
- NOTREACHED() << "Unhandled state" << state_;
-}
-
-void CloudPolicyController::SetState(
- CloudPolicyController::ControllerState new_state) {
- state_ = new_state;
-
- request_job_.reset(); // Stop any pending requests.
-
- base::Time now(base::Time::NowFromSystemTime());
- base::Time last_refresh(GetLastRefreshTime(now));
- base::Time refresh_at;
-
- // Determine when to take the next step.
- bool inform_notifier_done = false;
- switch (state_) {
- case STATE_TOKEN_UNMANAGED:
- notifier_->Inform(CloudPolicySubsystem::UNMANAGED,
- CloudPolicySubsystem::NO_DETAILS,
- PolicyNotifier::POLICY_CONTROLLER);
- break;
- case STATE_TOKEN_UNAVAILABLE:
- // The controller is not yet initialized and needs to immediately fetch
- // token and policy if present.
- case STATE_TOKEN_VALID:
- // Immediately try to fetch the token on initialization or policy after a
- // token update. Subsequent retries will respect the back-off strategy.
- refresh_at = now;
- // |notifier_| isn't informed about anything at this point, we wait for
- // the result of the next action first.
- break;
- case STATE_POLICY_VALID:
- // Delay is only reset if the policy fetch operation was successful. This
- // will ensure the server won't get overloaded with retries in case of
- // a bug on either side.
- effective_policy_refresh_error_delay_ms_ =
- kPolicyRefreshErrorDelayInMilliseconds;
- refresh_at = last_refresh + GetRefreshDelay();
- notifier_->Inform(CloudPolicySubsystem::SUCCESS,
- CloudPolicySubsystem::NO_DETAILS,
- PolicyNotifier::POLICY_CONTROLLER);
- break;
- case STATE_TOKEN_ERROR:
- notifier_->Inform(CloudPolicySubsystem::NETWORK_ERROR,
- CloudPolicySubsystem::BAD_DMTOKEN,
- PolicyNotifier::POLICY_CONTROLLER);
- inform_notifier_done = true;
- case STATE_POLICY_ERROR:
- if (!inform_notifier_done) {
- notifier_->Inform(CloudPolicySubsystem::NETWORK_ERROR,
- CloudPolicySubsystem::POLICY_NETWORK_ERROR,
- PolicyNotifier::POLICY_CONTROLLER);
- }
- refresh_at = now + base::TimeDelta::FromMilliseconds(
- effective_policy_refresh_error_delay_ms_);
- effective_policy_refresh_error_delay_ms_ =
- std::min(effective_policy_refresh_error_delay_ms_ * 2,
- policy_refresh_rate_ms_);
- break;
- case STATE_POLICY_UNAVAILABLE:
- effective_policy_refresh_error_delay_ms_ = policy_refresh_rate_ms_;
- refresh_at = now + base::TimeDelta::FromMilliseconds(
- effective_policy_refresh_error_delay_ms_);
- notifier_->Inform(CloudPolicySubsystem::NETWORK_ERROR,
- CloudPolicySubsystem::POLICY_NETWORK_ERROR,
- PolicyNotifier::POLICY_CONTROLLER);
- break;
- }
-
- // Update the delayed work task.
- scheduler_->CancelDelayedWork();
- if (!refresh_at.is_null())
- ScheduleDelayedWorkTask(refresh_at - now);
-
- // Inform the cache if a fetch attempt has completed. This happens if policy
- // has been succesfully fetched, or if token or policy fetching failed.
- if (state_ != STATE_TOKEN_UNAVAILABLE && state_ != STATE_TOKEN_VALID)
- cache_->SetFetchingDone();
-}
-
-base::TimeDelta CloudPolicyController::GetRefreshDelay() {
- int64 deviation = (kPolicyRefreshDeviationFactorPercent *
- policy_refresh_rate_ms_) / 100;
- deviation = std::min(deviation, kPolicyRefreshDeviationMaxInMilliseconds);
- return base::TimeDelta::FromMilliseconds(
- policy_refresh_rate_ms_ - base::RandGenerator(deviation + 1));
-}
-
-void CloudPolicyController::ScheduleDelayedWorkTask(
- const base::TimeDelta& delay) {
- int64 effective_delay = std::max<int64>(delay.InMilliseconds(), 0);
- scheduler_->PostDelayedWork(
- base::Bind(&CloudPolicyController::DoWork, base::Unretained(this)),
- effective_delay);
-}
-
-base::Time CloudPolicyController::GetLastRefreshTime(const base::Time& now) {
- base::Time last_refresh(cache_->last_policy_refresh_time());
- if (last_refresh.is_null())
- last_refresh = now;
-
- return last_refresh;
-}
-
-} // namespace policy
« no previous file with comments | « chrome/browser/policy/cloud_policy_controller.h ('k') | chrome/browser/policy/cloud_policy_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698