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" 8a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/command_line.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" 13a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 14a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/time/time.h" 15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/values.h" 16a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/invalidation/invalidation_service.h" 17a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/invalidation/invalidation_service_factory.h" 18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/policy/cloud/enterprise_metrics.h" 19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "policy/policy_constants.h" 21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "sync/notifier/object_id_invalidation_map.h" 22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace policy { 24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 25a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const int CloudPolicyInvalidator::kMissingPayloadDelay = 5; 26a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const int CloudPolicyInvalidator::kMaxFetchDelayDefault = 5000; 27a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const int CloudPolicyInvalidator::kMaxFetchDelayMin = 1000; 28a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const int CloudPolicyInvalidator::kMaxFetchDelayMax = 300000; 29a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)CloudPolicyInvalidator::CloudPolicyInvalidator( 31a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CloudPolicyInvalidationHandler* invalidation_handler, 32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CloudPolicyStore* store, 33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const scoped_refptr<base::SequencedTaskRunner>& task_runner) 34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) : invalidation_handler_(invalidation_handler), 35a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) store_(store), 36a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) task_runner_(task_runner), 37a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) profile_(NULL), 38a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_(NULL), 39a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidations_enabled_(false), 40a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_enabled_(false), 41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) registered_timestamp_(0), 42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalid_(false), 43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_version_(0), 44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) unknown_version_invalidation_count_(0), 45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ack_handle_(syncer::AckHandle::InvalidAckHandle()), 46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) weak_factory_(this), 47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) max_fetch_delay_(kMaxFetchDelayDefault) { 48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(invalidation_handler); 49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(store); 50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(task_runner.get()); 51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(!IsInitialized()); 52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)CloudPolicyInvalidator::~CloudPolicyInvalidator() {} 55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::InitializeWithProfile(Profile* profile) { 57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(!IsInitialized()); 58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(profile); 59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) profile_ = profile; 60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Initialize(); 61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::InitializeWithService( 64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation::InvalidationService* invalidation_service) { 65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(!IsInitialized()); 66a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(invalidation_service); 67a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_ = invalidation_service; 68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Initialize(); 69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::Shutdown() { 72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (IsInitialized()) { 73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (registered_timestamp_) 74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_->UnregisterInvalidationHandler(this); 75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) store_->RemoveObserver(this); 76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::OnInvalidatorStateChange( 80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) syncer::InvalidatorState state) { 81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_enabled_ = state == syncer::INVALIDATIONS_ENABLED; 83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UpdateInvalidationsEnabled(); 84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::OnIncomingInvalidation( 87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const syncer::ObjectIdInvalidationMap& invalidation_map) { 88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const syncer::ObjectIdInvalidationMap::const_iterator invalidation = 90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_map.find(object_id_); 91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (invalidation == invalidation_map.end()) { 92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOTREACHED(); 93a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) HandleInvalidation(invalidation->second); 96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::OnStoreLoaded(CloudPolicyStore* store) { 99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(IsInitialized()); 100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (registered_timestamp_) { 102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Update the kMetricPolicyRefresh histogram. In some cases, this object can 103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // be constructed during an OnStoreLoaded callback, which causes 104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // OnStoreLoaded to be called twice at initialization time, so make sure 105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // that the timestamp does not match the timestamp at which registration 106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // occurred. We only measure changes which occur after registration. 107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!store->policy() || !store->policy()->has_timestamp() || 108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) store->policy()->timestamp() != registered_timestamp_) { 109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION( 110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) kMetricPolicyRefresh, 111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GetPolicyRefreshMetric(), 112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) METRIC_POLICY_REFRESH_SIZE); 113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // If the policy was invalid and the version stored matches the latest 116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // invalidation version, acknowledge the latest invalidation. 117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (invalid_ && store->invalidation_version() == invalidation_version_) 118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) AcknowledgeInvalidation(); 119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UpdateRegistration(store->policy()); 122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UpdateMaxFetchDelay(store->policy_map()); 123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::OnStoreError(CloudPolicyStore* store) {} 126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)base::WeakPtr<CloudPolicyInvalidator> CloudPolicyInvalidator::GetWeakPtr() { 128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(!IsInitialized()); 129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return weak_factory_.GetWeakPtr(); 130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::Initialize() { 133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) OnStoreLoaded(store_); 134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) store_->AddObserver(this); 135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 137a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool CloudPolicyInvalidator::IsInitialized() { 138a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Could have been initialized with a profile or invalidation service. 139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return profile_ || invalidation_service_; 140a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 141a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::HandleInvalidation( 143a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const syncer::Invalidation& invalidation) { 144a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // The invalidation service may send an invalidation more than once if there 145a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // is a delay in acknowledging it. Duplicate invalidations are ignored. 146a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (invalid_ && ack_handle_.Equals(invalidation.ack_handle)) 147a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // If there is still a pending invalidation, acknowledge it, since we only 150a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // care about the latest invalidation. 151a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (invalid_) 152a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) AcknowledgeInvalidation(); 153a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 154a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Update invalidation state. 155a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalid_ = true; 156a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ack_handle_ = invalidation.ack_handle; 157a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_version_ = invalidation.version; 158a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 159a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // When an invalidation with unknown version is received, use negative 160a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // numbers based on the number of such invalidations received. This 161a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // ensures that the version numbers do not collide with "real" versions 162a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // (which are positive) or previous invalidations with unknown version. 163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (invalidation_version_ == syncer::Invalidation::kUnknownVersion) 164a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_version_ = -(++unknown_version_invalidation_count_); 165a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 166a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // In order to prevent the cloud policy server from becoming overwhelmed when 167a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // a policy with many users is modified, delay for a random period of time 168a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // before fetching the policy. Delay for at least 20ms so that if multiple 169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // invalidations are received in quick succession, only one fetch will be 170a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // performed. 171a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::TimeDelta delay = base::TimeDelta::FromMilliseconds( 172a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::RandInt(20, max_fetch_delay_)); 173a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 174a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // If there is a payload, the invalidate callback can run at any time, so set 175a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // the version and payload on the client immediately. Otherwise, the callback 176a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // must only run after at least kMissingPayloadDelay minutes. 177a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& payload = invalidation.payload; 178a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!invalidation.payload.empty()) 179a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_handler_->SetInvalidationInfo(invalidation_version_, payload); 180a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) else 181a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) delay += base::TimeDelta::FromMinutes(kMissingPayloadDelay); 182a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 183a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Schedule the invalidate callback to run. 184a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) task_runner_->PostDelayedTask( 185a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FROM_HERE, 186a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind( 187a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) &CloudPolicyInvalidator::RunInvalidateCallback, 188a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) weak_factory_.GetWeakPtr(), 189a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) payload.empty() /* is_missing_payload */), 190a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) delay); 191a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 192a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Update the kMetricPolicyInvalidations histogram. 193a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UMA_HISTOGRAM_BOOLEAN(kMetricPolicyInvalidations, !payload.empty()); 194a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 195a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 196a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::UpdateRegistration( 197a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const enterprise_management::PolicyData* policy) { 198a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Create the ObjectId based on the policy data. 199a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // If the policy does not specify an the ObjectId, then unregister. 200a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!policy || 201a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) !policy->has_timestamp() || 202a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) !policy->has_invalidation_source() || 203a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) !policy->has_invalidation_name()) { 204a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Unregister(); 205a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 206a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 207a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation::ObjectId object_id( 208a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) policy->invalidation_source(), 209a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) policy->invalidation_name()); 210a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 211a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // If the policy object id in the policy data is different from the currently 212a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // registered object id, update the object registration. 213a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!registered_timestamp_ || !(object_id == object_id_)) 214a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Register(policy->timestamp(), object_id); 215a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 216a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 217a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::Register( 218a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int64 timestamp, 219a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const invalidation::ObjectId& object_id) { 220a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Get the invalidation service from the profile if needed. 221a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!invalidation_service_) { 222a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(profile_); 223a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_ = 224a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation::InvalidationServiceFactory::GetForProfile(profile_); 225a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!invalidation_service_) 226a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 227a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 228a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 229a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Register this handler with the invalidation service if needed. 230a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!registered_timestamp_) { 231a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) OnInvalidatorStateChange(invalidation_service_->GetInvalidatorState()); 232a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_->RegisterInvalidationHandler(this); 233a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Update internal state. 236a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (invalid_) 237a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) AcknowledgeInvalidation(); 238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) registered_timestamp_ = timestamp; 239a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) object_id_ = object_id; 240a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UpdateInvalidationsEnabled(); 241a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 242a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Update registration with the invalidation service. 243a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) syncer::ObjectIdSet ids; 244a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ids.insert(object_id); 245a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_->UpdateRegisteredInvalidationIds(this, ids); 246a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 247a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 248a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::Unregister() { 249a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (registered_timestamp_) { 250a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (invalid_) 251a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) AcknowledgeInvalidation(); 252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_->UpdateRegisteredInvalidationIds( 253a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) this, 254a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) syncer::ObjectIdSet()); 255a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_->UnregisterInvalidationHandler(this); 256a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) registered_timestamp_ = 0; 257a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UpdateInvalidationsEnabled(); 258a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 259a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 260a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 261a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::UpdateMaxFetchDelay(const PolicyMap& policy_map) { 262a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int delay; 263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 264a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Try reading the delay from the policy. 265a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const base::Value* delay_policy_value = 266a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) policy_map.GetValue(key::kMaxInvalidationFetchDelay); 267a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (delay_policy_value && delay_policy_value->GetAsInteger(&delay)) { 268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) set_max_fetch_delay(delay); 269a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 270a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 272a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Try reading the delay from the command line switch. 273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string delay_string = 274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 275a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) switches::kCloudPolicyInvalidationDelay); 276a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (base::StringToInt(delay_string, &delay)) { 277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) set_max_fetch_delay(delay); 278a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 279a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 280a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) set_max_fetch_delay(kMaxFetchDelayDefault); 282a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 283a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 284a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::set_max_fetch_delay(int delay) { 285a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (delay < kMaxFetchDelayMin) 286a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) max_fetch_delay_ = kMaxFetchDelayMin; 287a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) else if (delay > kMaxFetchDelayMax) 288a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) max_fetch_delay_ = kMaxFetchDelayMax; 289a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) else 290a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) max_fetch_delay_ = delay; 291a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 292a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 293a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::UpdateInvalidationsEnabled() { 294a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool invalidations_enabled = 295a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_enabled_ && registered_timestamp_; 296a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (invalidations_enabled_ != invalidations_enabled) { 297a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidations_enabled_ = invalidations_enabled; 298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_handler_->OnInvalidatorStateChanged(invalidations_enabled); 299a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 300a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 301a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 302a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::RunInvalidateCallback(bool is_missing_payload) { 303a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 304a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // In the missing payload case, the invalidation version has not been set on 305a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // the client yet, so set it now that the required time has elapsed. 306a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (is_missing_payload) { 307a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_handler_->SetInvalidationInfo( 308a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_version_, 309a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string()); 310a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 311a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_handler_->InvalidatePolicy(); 312a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 313a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 314a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void CloudPolicyInvalidator::AcknowledgeInvalidation() { 315a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(invalid_); 316a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalid_ = false; 317a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_handler_->SetInvalidationInfo(0, std::string()); 318a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) invalidation_service_->AcknowledgeInvalidation(object_id_, ack_handle_); 319a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Cancel any scheduled invalidate callbacks. 320a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) weak_factory_.InvalidateWeakPtrs(); 321a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 322a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 323a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int CloudPolicyInvalidator::GetPolicyRefreshMetric() { 324a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (store_->policy_changed()) { 325a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (invalid_) 326a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return METRIC_POLICY_REFRESH_INVALIDATED_CHANGED; 327a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (invalidations_enabled_) 328a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return METRIC_POLICY_REFRESH_CHANGED; 329a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return METRIC_POLICY_REFRESH_CHANGED_NO_INVALIDATIONS; 330a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 331a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (invalid_) 332a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return METRIC_POLICY_REFRESH_INVALIDATED_UNCHANGED; 333a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return METRIC_POLICY_REFRESH_UNCHANGED; 334a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 335a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 336a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} // namespace policy 337