1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_POLICY_CLOUD_CLOUD_POLICY_INVALIDATOR_H_ 6 #define CHROME_BROWSER_POLICY_CLOUD_CLOUD_POLICY_INVALIDATOR_H_ 7 8 #include <string> 9 10 #include "base/basictypes.h" 11 #include "base/callback.h" 12 #include "base/memory/ref_counted.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/weak_ptr.h" 15 #include "base/threading/thread_checker.h" 16 #include "components/policy/core/common/cloud/cloud_policy_core.h" 17 #include "components/policy/core/common/cloud/cloud_policy_store.h" 18 #include "google/cacheinvalidation/include/types.h" 19 #include "sync/internal_api/public/base/invalidation.h" 20 #include "sync/notifier/invalidation_handler.h" 21 22 namespace base { 23 class Clock; 24 class SequencedTaskRunner; 25 } 26 27 namespace invalidation { 28 class InvalidationService; 29 } 30 31 namespace policy { 32 33 // Listens for and provides policy invalidations. 34 class CloudPolicyInvalidator : public syncer::InvalidationHandler, 35 public CloudPolicyCore::Observer, 36 public CloudPolicyStore::Observer { 37 public: 38 // The number of minutes to delay a policy refresh after receiving an 39 // invalidation with no payload. 40 static const int kMissingPayloadDelay; 41 42 // The default, min and max values for max_fetch_delay_. 43 static const int kMaxFetchDelayDefault; 44 static const int kMaxFetchDelayMin; 45 static const int kMaxFetchDelayMax; 46 47 // The grace period, in seconds, to allow for invalidations to be received 48 // once the invalidation service starts up. 49 static const int kInvalidationGracePeriod; 50 51 // Time, in seconds, for which unknown version invalidations are ignored after 52 // fetching a policy. 53 static const int kUnknownVersionIgnorePeriod; 54 55 // The max tolerated discrepancy, in seconds, between policy timestamps and 56 // invalidation timestamps when determining if an invalidation is expired. 57 static const int kMaxInvalidationTimeDelta; 58 59 // |core| is the cloud policy core which connects the various policy objects. 60 // It must remain valid until Shutdown is called. 61 // |task_runner| is used for scheduling delayed tasks. It must post tasks to 62 // the main policy thread. 63 // |clock| is used to get the current time. 64 CloudPolicyInvalidator( 65 CloudPolicyCore* core, 66 const scoped_refptr<base::SequencedTaskRunner>& task_runner, 67 scoped_ptr<base::Clock> clock); 68 virtual ~CloudPolicyInvalidator(); 69 70 // Initializes the invalidator. No invalidations will be generated before this 71 // method is called. This method must only be called once. 72 // |invalidation_service| is the invalidation service to use and must remain 73 // valid until Shutdown is called. 74 void Initialize(invalidation::InvalidationService* invalidation_service); 75 76 // Shuts down and disables invalidations. It must be called before the object 77 // is destroyed. 78 void Shutdown(); 79 80 // Whether the invalidator currently has the ability to receive invalidations. 81 bool invalidations_enabled() { 82 return invalidations_enabled_; 83 } 84 85 // syncer::InvalidationHandler: 86 virtual void OnInvalidatorStateChange( 87 syncer::InvalidatorState state) OVERRIDE; 88 virtual void OnIncomingInvalidation( 89 const syncer::ObjectIdInvalidationMap& invalidation_map) OVERRIDE; 90 virtual std::string GetOwnerName() const OVERRIDE; 91 92 // CloudPolicyCore::Observer: 93 virtual void OnCoreConnected(CloudPolicyCore* core) OVERRIDE; 94 virtual void OnRefreshSchedulerStarted(CloudPolicyCore* core) OVERRIDE; 95 virtual void OnCoreDisconnecting(CloudPolicyCore* core) OVERRIDE; 96 97 // CloudPolicyStore::Observer: 98 virtual void OnStoreLoaded(CloudPolicyStore* store) OVERRIDE; 99 virtual void OnStoreError(CloudPolicyStore* store) OVERRIDE; 100 101 private: 102 // Handle an invalidation to the policy. 103 void HandleInvalidation(const syncer::Invalidation& invalidation); 104 105 // Update object registration with the invalidation service based on the 106 // given policy data. 107 void UpdateRegistration(const enterprise_management::PolicyData* policy); 108 109 // Registers the given object with the invalidation service. 110 void Register(const invalidation::ObjectId& object_id); 111 112 // Unregisters the current object with the invalidation service. 113 void Unregister(); 114 115 // Update |max_fetch_delay_| based on the given policy map. 116 void UpdateMaxFetchDelay(const PolicyMap& policy_map); 117 void set_max_fetch_delay(int delay); 118 119 // Updates invalidations_enabled_ and calls the invalidation handler if the 120 // value changed. 121 void UpdateInvalidationsEnabled(); 122 123 // Refresh the policy. 124 // |is_missing_payload| is set to true if the callback is being invoked in 125 // response to an invalidation with a missing payload. 126 void RefreshPolicy(bool is_missing_payload); 127 128 // Acknowledge the latest invalidation. 129 void AcknowledgeInvalidation(); 130 131 // Determines if the given policy is different from the policy passed in the 132 // previous call. 133 bool IsPolicyChanged(const enterprise_management::PolicyData* policy); 134 135 // Determine if an invalidation has expired. 136 // |version| is the version of the invalidation, or zero for unknown. 137 bool IsInvalidationExpired(int64 version); 138 139 // Get the kMetricPolicyRefresh histogram metric which should be incremented 140 // when a policy is stored. 141 int GetPolicyRefreshMetric(bool policy_changed); 142 143 // Get the kMetricPolicyInvalidations histogram metric which should be 144 // incremented when an invalidation is received. 145 int GetInvalidationMetric(bool is_missing_payload, bool is_expired); 146 147 // Determine if invalidations have been enabled longer than the grace period. 148 bool GetInvalidationsEnabled(); 149 150 // The state of the object. 151 enum State { 152 UNINITIALIZED, 153 STOPPED, 154 STARTED, 155 SHUT_DOWN 156 }; 157 State state_; 158 159 // The cloud policy core. 160 CloudPolicyCore* core_; 161 162 // Schedules delayed tasks. 163 const scoped_refptr<base::SequencedTaskRunner> task_runner_; 164 165 // The clock. 166 scoped_ptr<base::Clock> clock_; 167 168 // The invalidation service. 169 invalidation::InvalidationService* invalidation_service_; 170 171 // Whether the invalidator currently has the ability to receive invalidations. 172 // This is true if the invalidation service is enabled and the invalidator 173 // has registered for a policy object. 174 bool invalidations_enabled_; 175 176 // The time that invalidations became enabled. 177 base::Time invalidations_enabled_time_; 178 179 // Whether the invalidation service is currently enabled. 180 bool invalidation_service_enabled_; 181 182 // Whether this object has registered for policy invalidations. 183 bool is_registered_; 184 185 // The object id representing the policy in the invalidation service. 186 invalidation::ObjectId object_id_; 187 188 // Whether the policy is current invalid. This is set to true when an 189 // invalidation is received and reset when the policy fetched due to the 190 // invalidation is stored. 191 bool invalid_; 192 193 // The version of the latest invalidation received. This is compared to 194 // the invalidation version of policy stored to determine when the 195 // invalidated policy is up-to-date. 196 int64 invalidation_version_; 197 198 // The number of invalidations with unknown version received. Since such 199 // invalidations do not provide a version number, this count is used to set 200 // invalidation_version_ when such invalidations occur. 201 int unknown_version_invalidation_count_; 202 203 // The most up to date invalidation. 204 scoped_ptr<syncer::Invalidation> invalidation_; 205 206 // WeakPtrFactory used to create callbacks to this object. 207 base::WeakPtrFactory<CloudPolicyInvalidator> weak_factory_; 208 209 // The maximum random delay, in ms, between receiving an invalidation and 210 // fetching the new policy. 211 int max_fetch_delay_; 212 213 // The hash value of the current policy. This is used to determine if a new 214 // policy is different from the current one. 215 uint32 policy_hash_value_; 216 217 // A thread checker to make sure that callbacks are invoked on the correct 218 // thread. 219 base::ThreadChecker thread_checker_; 220 221 DISALLOW_COPY_AND_ASSIGN(CloudPolicyInvalidator); 222 }; 223 224 } // namespace policy 225 226 #endif // CHROME_BROWSER_POLICY_CLOUD_CLOUD_POLICY_INVALIDATOR_H_ 227