1a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// found in the LICENSE file. 4a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/policy/cloud/cloud_policy_invalidator.h" 6a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 7a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/bind.h" 858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/hash.h" 9a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/location.h" 10a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/metrics/histogram.h" 11a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/rand_util.h" 12a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/sequenced_task_runner.h" 13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/time/clock.h" 14a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/time/time.h" 15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/values.h" 160de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "components/invalidation/invalidation_service.h" 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/invalidation/object_id_invalidation_map.h" 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_client.h" 19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h" 20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/enterprise_metrics.h" 21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "policy/policy_constants.h" 22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace policy { 24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 25a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const int CloudPolicyInvalidator::kMissingPayloadDelay = 5; 2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const int CloudPolicyInvalidator::kMaxFetchDelayDefault = 10000; 27a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const int CloudPolicyInvalidator::kMaxFetchDelayMin = 1000; 28a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const int CloudPolicyInvalidator::kMaxFetchDelayMax = 300000; 29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst int CloudPolicyInvalidator::kInvalidationGracePeriod = 10; 30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst int CloudPolicyInvalidator::kUnknownVersionIgnorePeriod = 30; 31c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst int CloudPolicyInvalidator::kMaxInvalidationTimeDelta = 300; 32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)CloudPolicyInvalidator::CloudPolicyInvalidator( 346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) enterprise_management::DeviceRegisterRequest::Type type, 3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CloudPolicyCore* core, 36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const scoped_refptr<base::SequencedTaskRunner>& task_runner, 376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<base::Clock> clock, 386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int64 highest_handled_invalidation_version) 3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) : state_(UNINITIALIZED), 406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) type_(type), 4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) core_(core), 42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) task_runner_(task_runner), 43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch clock_(clock.Pass()), 44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_(NULL), 45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidations_enabled_(false), 46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_enabled_(false), 47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch is_registered_(false), 48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalid_(false), 49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_version_(0), 50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) unknown_version_invalidation_count_(0), 516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) highest_handled_invalidation_version_( 526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) highest_handled_invalidation_version), 5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) max_fetch_delay_(kMaxFetchDelayDefault), 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci policy_hash_value_(0), 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_(this) { 5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(core); 57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(task_runner.get()); 586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // |highest_handled_invalidation_version_| indicates the highest actual 596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // invalidation version handled. Since actual invalidations can have only 606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // positive versions, this member may be zero (no versioned invalidation 616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // handled yet) or positive. Negative values are not allowed: 626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // 636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Negative version numbers are used internally by CloudPolicyInvalidator to 646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // keep track of unversioned invalidations. When such an invalidation is 656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // handled, |highest_handled_invalidation_version_| remains unchanged and does 666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // not become negative. 676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK_LE(0, highest_handled_invalidation_version_); 68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)CloudPolicyInvalidator::~CloudPolicyInvalidator() { 7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(state_ == SHUT_DOWN); 72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void CloudPolicyInvalidator::Initialize( 75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation::InvalidationService* invalidation_service) { 7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(state_ == UNINITIALIZED); 7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(invalidation_service); 79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_ = invalidation_service; 8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) state_ = STOPPED; 8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) core_->AddObserver(this); 8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (core_->refresh_scheduler()) 8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) OnRefreshSchedulerStarted(core_); 84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::Shutdown() { 8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(state_ != SHUT_DOWN); 8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (state_ == STARTED) { 90c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (is_registered_) 91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_->UnregisterInvalidationHandler(this); 9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) core_->store()->RemoveObserver(this); 9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) weak_factory_.InvalidateWeakPtrs(); 94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (state_ != UNINITIALIZED) 9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) core_->RemoveObserver(this); 9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) state_ = SHUT_DOWN; 98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::OnInvalidatorStateChange( 101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) syncer::InvalidatorState state) { 10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(state_ == STARTED); 103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_enabled_ = state == syncer::INVALIDATIONS_ENABLED; 105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UpdateInvalidationsEnabled(); 106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::OnIncomingInvalidation( 109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const syncer::ObjectIdInvalidationMap& invalidation_map) { 11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(state_ == STARTED); 111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const syncer::SingleObjectInvalidationSet& list = 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) invalidation_map.ForObject(object_id_); 1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (list.IsEmpty()) { 115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOTREACHED(); 116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Acknowledge all except the invalidation with the highest version. 120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) syncer::SingleObjectInvalidationSet::const_reverse_iterator it = 121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) list.rbegin(); 122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ++it; 123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for ( ; it != list.rend(); ++it) { 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it->Acknowledge(); 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Handle the highest version invalidation. 1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) HandleInvalidation(list.back()); 129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)std::string CloudPolicyInvalidator::GetOwnerName() const { return "Cloud"; } 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void CloudPolicyInvalidator::OnCoreConnected(CloudPolicyCore* core) {} 13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void CloudPolicyInvalidator::OnRefreshSchedulerStarted(CloudPolicyCore* core) { 13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(state_ == STOPPED); 13758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) state_ = STARTED; 13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) OnStoreLoaded(core_->store()); 14058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) core_->store()->AddObserver(this); 14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void CloudPolicyInvalidator::OnCoreDisconnecting(CloudPolicyCore* core) { 14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(state_ == STARTED || state_ == STOPPED); 14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (state_ == STARTED) { 14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Unregister(); 14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) core_->store()->RemoveObserver(this); 14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) state_ = STOPPED; 15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 153a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::OnStoreLoaded(CloudPolicyStore* store) { 15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(state_ == STARTED); 155a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool policy_changed = IsPolicyChanged(store->policy()); 15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (is_registered_) { 1596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Update the kMetricDevicePolicyRefresh/kMetricUserPolicyRefresh histogram. 1606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (type_ == enterprise_management::DeviceRegisterRequest::DEVICE) { 1616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION(kMetricDevicePolicyRefresh, 1626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) GetPolicyRefreshMetric(policy_changed), 1636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) METRIC_POLICY_REFRESH_SIZE); 1646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } else { 1656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION(kMetricUserPolicyRefresh, 1666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) GetPolicyRefreshMetric(policy_changed), 1676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) METRIC_POLICY_REFRESH_SIZE); 1686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const int64 store_invalidation_version = store->invalidation_version(); 171a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 172a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // If the policy was invalid and the version stored matches the latest 173a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // invalidation version, acknowledge the latest invalidation. 1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (invalid_ && store_invalidation_version == invalidation_version_) 175a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) AcknowledgeInvalidation(); 1766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Update the highest invalidation version that was handled already. 1786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (store_invalidation_version > highest_handled_invalidation_version_) 1796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) highest_handled_invalidation_version_ = store_invalidation_version; 180a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 181a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 182a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UpdateRegistration(store->policy()); 183a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UpdateMaxFetchDelay(store->policy_map()); 184a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 185a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 186a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::OnStoreError(CloudPolicyStore* store) {} 187a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 188a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::HandleInvalidation( 189a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const syncer::Invalidation& invalidation) { 190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Ignore old invalidations. 191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (invalid_ && 192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) !invalidation.is_unknown_version() && 193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) invalidation.version() <= invalidation_version_) { 194a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 196a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!invalidation.is_unknown_version() && 1986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) invalidation.version() <= highest_handled_invalidation_version_) { 1996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // If this invalidation version was handled already, acknowledge the 2006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // invalidation but ignore it otherwise. 2016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) invalidation.Acknowledge(); 2026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return; 2036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 2046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 205a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // If there is still a pending invalidation, acknowledge it, since we only 206a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // care about the latest invalidation. 207a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (invalid_) 208a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) AcknowledgeInvalidation(); 209a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 210c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Get the version and payload from the invalidation. 211a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // When an invalidation with unknown version is received, use negative 212a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // numbers based on the number of such invalidations received. This 213a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // ensures that the version numbers do not collide with "real" versions 214a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // (which are positive) or previous invalidations with unknown version. 215c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int64 version; 216c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::string payload; 2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (invalidation.is_unknown_version()) { 218c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch version = -(++unknown_version_invalidation_count_); 2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 220c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch version = invalidation.version(); 221c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch payload = invalidation.payload(); 222c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 223c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 224c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Ignore the invalidation if it is expired. 225c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool is_expired = IsInvalidationExpired(version); 2266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (type_ == enterprise_management::DeviceRegisterRequest::DEVICE) { 2286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION( 2296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) kMetricDevicePolicyInvalidations, 2306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) GetInvalidationMetric(payload.empty(), is_expired), 2316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) POLICY_INVALIDATION_TYPE_SIZE); 2326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } else { 2336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION( 2346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) kMetricUserPolicyInvalidations, 2356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) GetInvalidationMetric(payload.empty(), is_expired), 2366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) POLICY_INVALIDATION_TYPE_SIZE); 2376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 238c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (is_expired) { 239c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch invalidation.Acknowledge(); 240c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 242a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 243c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Update invalidation state. 244c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch invalid_ = true; 245c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch invalidation_.reset(new syncer::Invalidation(invalidation)); 246c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch invalidation_version_ = version; 247c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 248a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // In order to prevent the cloud policy server from becoming overwhelmed when 249a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // a policy with many users is modified, delay for a random period of time 250a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // before fetching the policy. Delay for at least 20ms so that if multiple 251a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // invalidations are received in quick succession, only one fetch will be 252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // performed. 253a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::TimeDelta delay = base::TimeDelta::FromMilliseconds( 254a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::RandInt(20, max_fetch_delay_)); 255a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 25658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // If there is a payload, the policy can be refreshed at any time, so set 25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // the version and payload on the client immediately. Otherwise, the refresh 258a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // must only run after at least kMissingPayloadDelay minutes. 2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!payload.empty()) 260c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch core_->client()->SetInvalidationInfo(version, payload); 261a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) else 262a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) delay += base::TimeDelta::FromMinutes(kMissingPayloadDelay); 263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Schedule the policy to be refreshed. 265a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) task_runner_->PostDelayedTask( 266a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FROM_HERE, 267a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind( 26858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &CloudPolicyInvalidator::RefreshPolicy, 269a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) weak_factory_.GetWeakPtr(), 270a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) payload.empty() /* is_missing_payload */), 271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) delay); 272a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::UpdateRegistration( 275a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const enterprise_management::PolicyData* policy) { 276a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Create the ObjectId based on the policy data. 277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // If the policy does not specify an the ObjectId, then unregister. 278a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!policy || 279a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) !policy->has_invalidation_source() || 280a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) !policy->has_invalidation_name()) { 281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Unregister(); 282a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 283a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 284a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation::ObjectId object_id( 285a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) policy->invalidation_source(), 286a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) policy->invalidation_name()); 287a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 288a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // If the policy object id in the policy data is different from the currently 289a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // registered object id, update the object registration. 290c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!is_registered_ || !(object_id == object_id_)) 291c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Register(object_id); 292a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 293a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 294c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid CloudPolicyInvalidator::Register(const invalidation::ObjectId& object_id) { 295a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Register this handler with the invalidation service if needed. 296c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!is_registered_) { 297a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) OnInvalidatorStateChange(invalidation_service_->GetInvalidatorState()); 298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_->RegisterInvalidationHandler(this); 299a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 300a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 301a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Update internal state. 302a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (invalid_) 303a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) AcknowledgeInvalidation(); 304c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch is_registered_ = true; 305a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) object_id_ = object_id; 306a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UpdateInvalidationsEnabled(); 307a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 308a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Update registration with the invalidation service. 309a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) syncer::ObjectIdSet ids; 310a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ids.insert(object_id); 311a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_->UpdateRegisteredInvalidationIds(this, ids); 312a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 313a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 314a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::Unregister() { 315c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (is_registered_) { 316a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (invalid_) 317a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) AcknowledgeInvalidation(); 318a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_->UpdateRegisteredInvalidationIds( 319a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) this, 320a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) syncer::ObjectIdSet()); 321a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_->UnregisterInvalidationHandler(this); 322c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch is_registered_ = false; 323a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UpdateInvalidationsEnabled(); 324a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 325a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 326a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 327a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::UpdateMaxFetchDelay(const PolicyMap& policy_map) { 328a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int delay; 329a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 330a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Try reading the delay from the policy. 331a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const base::Value* delay_policy_value = 332a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) policy_map.GetValue(key::kMaxInvalidationFetchDelay); 333a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (delay_policy_value && delay_policy_value->GetAsInteger(&delay)) { 334a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) set_max_fetch_delay(delay); 335a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 336a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 337a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 338a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) set_max_fetch_delay(kMaxFetchDelayDefault); 339a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 340a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 341a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::set_max_fetch_delay(int delay) { 342a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (delay < kMaxFetchDelayMin) 343a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) max_fetch_delay_ = kMaxFetchDelayMin; 344a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) else if (delay > kMaxFetchDelayMax) 345a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) max_fetch_delay_ = kMaxFetchDelayMax; 346a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) else 347a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) max_fetch_delay_ = delay; 348a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 349a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 350a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::UpdateInvalidationsEnabled() { 351c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool invalidations_enabled = invalidation_service_enabled_ && is_registered_; 352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (invalidations_enabled_ != invalidations_enabled) { 353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidations_enabled_ = invalidations_enabled; 354c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (invalidations_enabled) 355c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch invalidations_enabled_time_ = clock_->Now(); 35658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) core_->refresh_scheduler()->SetInvalidationServiceAvailability( 35758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) invalidations_enabled); 358a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 359a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 360a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 36158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void CloudPolicyInvalidator::RefreshPolicy(bool is_missing_payload) { 362a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 363a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // In the missing payload case, the invalidation version has not been set on 364a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // the client yet, so set it now that the required time has elapsed. 36558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (is_missing_payload) 36658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) core_->client()->SetInvalidationInfo(invalidation_version_, std::string()); 36758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) core_->refresh_scheduler()->RefreshSoon(); 368a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 369a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 370a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::AcknowledgeInvalidation() { 371a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(invalid_); 372a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalid_ = false; 37358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) core_->client()->SetInvalidationInfo(0, std::string()); 374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) invalidation_->Acknowledge(); 375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) invalidation_.reset(); 37658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Cancel any scheduled policy refreshes. 377a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) weak_factory_.InvalidateWeakPtrs(); 378a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 379a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 38058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool CloudPolicyInvalidator::IsPolicyChanged( 38158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const enterprise_management::PolicyData* policy) { 38258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Determine if the policy changed by comparing its hash value to the 38358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // previous policy's hash value. 38458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) uint32 new_hash_value = 0; 38558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (policy && policy->has_policy_value()) 38658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) new_hash_value = base::Hash(policy->policy_value()); 38758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool changed = new_hash_value != policy_hash_value_; 38858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) policy_hash_value_ = new_hash_value; 38958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return changed; 39058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 39158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 392c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool CloudPolicyInvalidator::IsInvalidationExpired(int64 version) { 393c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Time last_fetch_time = base::Time::UnixEpoch() + 394c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::TimeDelta::FromMilliseconds(core_->store()->policy()->timestamp()); 395c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 396c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // If the version is unknown, consider the invalidation invalid if the 397c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // policy was fetched very recently. 398c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (version < 0) { 399c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::TimeDelta elapsed = clock_->Now() - last_fetch_time; 400c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return elapsed.InSeconds() < kUnknownVersionIgnorePeriod; 401c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 402c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 403c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // The invalidation version is the timestamp in microseconds. If the 404c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // invalidation occurred before the last policy fetch, then the invalidation 405c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // is expired. Time is added to the invalidation to err on the side of not 406c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // expired. 407c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Time invalidation_time = base::Time::UnixEpoch() + 408c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::TimeDelta::FromMicroseconds(version) + 409c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::TimeDelta::FromSeconds(kMaxInvalidationTimeDelta); 410c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return invalidation_time < last_fetch_time; 411c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 412c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 41358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)int CloudPolicyInvalidator::GetPolicyRefreshMetric(bool policy_changed) { 41458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (policy_changed) { 415a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (invalid_) 416a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return METRIC_POLICY_REFRESH_INVALIDATED_CHANGED; 417c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (GetInvalidationsEnabled()) 418a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return METRIC_POLICY_REFRESH_CHANGED; 419a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return METRIC_POLICY_REFRESH_CHANGED_NO_INVALIDATIONS; 420a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 421a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (invalid_) 422a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return METRIC_POLICY_REFRESH_INVALIDATED_UNCHANGED; 423a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return METRIC_POLICY_REFRESH_UNCHANGED; 424a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 425a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 426c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochint CloudPolicyInvalidator::GetInvalidationMetric(bool is_missing_payload, 427c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool is_expired) { 428c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (is_expired) { 429c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (is_missing_payload) 430c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return POLICY_INVALIDATION_TYPE_NO_PAYLOAD_EXPIRED; 431c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return POLICY_INVALIDATION_TYPE_EXPIRED; 432c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 433c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (is_missing_payload) 434c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return POLICY_INVALIDATION_TYPE_NO_PAYLOAD; 435c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return POLICY_INVALIDATION_TYPE_NORMAL; 436c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 437c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 438c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool CloudPolicyInvalidator::GetInvalidationsEnabled() { 439c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!invalidations_enabled_) 440c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return false; 441c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // If invalidations have been enabled for less than the grace period, then 442c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // consider invalidations to be disabled for metrics reporting. 443c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::TimeDelta elapsed = clock_->Now() - invalidations_enabled_time_; 444c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return elapsed.InSeconds() >= kInvalidationGracePeriod; 445c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 446c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 447a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} // namespace policy 448