Commit 53a1b2e2 authored by bartfab@chromium.org's avatar bartfab@chromium.org

Pass highest handled invalidation version between invalidators

With this CL, device policy invalidation keeps track of the highest
invalidation version that has been handled (= policy has been reloaded
for this version already) when one invalidation is destroyed and another
created.

BUG=358699
TEST=WIP

Review URL: https://codereview.chromium.org/460573005

Cr-Commit-Position: refs/heads/master@{#289411}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289411 0039d316-1c4b-4281-b951-d872f2087c98
parent 4ea7f20b
......@@ -118,7 +118,8 @@ std::string DeviceCloudPolicyInvalidator::InvalidationServiceObserver::
}
DeviceCloudPolicyInvalidator::DeviceCloudPolicyInvalidator()
: invalidation_service_(NULL) {
: invalidation_service_(NULL),
highest_handled_invalidation_version_(0) {
// The DeviceCloudPolicyInvalidator should be created before any user
// Profiles.
DCHECK(g_browser_process->profile_manager()->GetLoadedProfiles().empty());
......@@ -251,18 +252,23 @@ void DeviceCloudPolicyInvalidator::TryToCreateInvalidator() {
void DeviceCloudPolicyInvalidator::CreateInvalidator(
invalidation::InvalidationService* invalidation_service) {
invalidation_service_ = invalidation_service;
DCHECK(!invalidator_);
invalidator_.reset(new CloudPolicyInvalidator(
enterprise_management::DeviceRegisterRequest::DEVICE,
g_browser_process->platform_part()->browser_policy_connector_chromeos()->
GetDeviceCloudPolicyManager()->core(),
base::MessageLoopProxy::current(),
scoped_ptr<base::Clock>(new base::DefaultClock())));
scoped_ptr<base::Clock>(new base::DefaultClock()),
highest_handled_invalidation_version_));
invalidator_->Initialize(invalidation_service);
}
void DeviceCloudPolicyInvalidator::DestroyInvalidator() {
if (invalidator_)
if (invalidator_) {
highest_handled_invalidation_version_ =
invalidator_->highest_handled_invalidation_version();
invalidator_->Shutdown();
}
invalidator_.reset();
invalidation_service_ = NULL;
}
......
......@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_CLOUD_POLICY_INVALIDATOR_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_CLOUD_POLICY_INVALIDATOR_H_
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
......@@ -88,6 +89,9 @@ class DeviceCloudPolicyInvalidator : public content::NotificationObserver {
// if no |CloudPolicyInvalidator| exists.
invalidation::InvalidationService* invalidation_service_;
// The highest invalidation version that was handled already.
int64 highest_handled_invalidation_version_;
// The current |CloudPolicyInvalidator|. NULL if no connected invalidation
// service is available.
scoped_ptr<CloudPolicyInvalidator> invalidator_;
......
......@@ -34,7 +34,8 @@ CloudPolicyInvalidator::CloudPolicyInvalidator(
enterprise_management::DeviceRegisterRequest::Type type,
CloudPolicyCore* core,
const scoped_refptr<base::SequencedTaskRunner>& task_runner,
scoped_ptr<base::Clock> clock)
scoped_ptr<base::Clock> clock,
int64 highest_handled_invalidation_version)
: state_(UNINITIALIZED),
type_(type),
core_(core),
......@@ -47,11 +48,23 @@ CloudPolicyInvalidator::CloudPolicyInvalidator(
invalid_(false),
invalidation_version_(0),
unknown_version_invalidation_count_(0),
highest_handled_invalidation_version_(
highest_handled_invalidation_version),
weak_factory_(this),
max_fetch_delay_(kMaxFetchDelayDefault),
policy_hash_value_(0) {
DCHECK(core);
DCHECK(task_runner.get());
// |highest_handled_invalidation_version_| indicates the highest actual
// invalidation version handled. Since actual invalidations can have only
// positive versions, this member may be zero (no versioned invalidation
// handled yet) or positive. Negative values are not allowed:
//
// Negative version numbers are used internally by CloudPolicyInvalidator to
// keep track of unversioned invalidations. When such an invalidation is
// handled, |highest_handled_invalidation_version_| remains unchanged and does
// not become negative.
DCHECK_LE(0, highest_handled_invalidation_version_);
}
CloudPolicyInvalidator::~CloudPolicyInvalidator() {
......@@ -154,10 +167,16 @@ void CloudPolicyInvalidator::OnStoreLoaded(CloudPolicyStore* store) {
METRIC_POLICY_REFRESH_SIZE);
}
const int64 store_invalidation_version = store->invalidation_version();
// If the policy was invalid and the version stored matches the latest
// invalidation version, acknowledge the latest invalidation.
if (invalid_ && store->invalidation_version() == invalidation_version_)
if (invalid_ && store_invalidation_version == invalidation_version_)
AcknowledgeInvalidation();
// Update the highest invalidation version that was handled already.
if (store_invalidation_version > highest_handled_invalidation_version_)
highest_handled_invalidation_version_ = store_invalidation_version;
}
UpdateRegistration(store->policy());
......@@ -175,6 +194,14 @@ void CloudPolicyInvalidator::HandleInvalidation(
return;
}
if (!invalidation.is_unknown_version() &&
invalidation.version() <= highest_handled_invalidation_version_) {
// If this invalidation version was handled already, acknowledge the
// invalidation but ignore it otherwise.
invalidation.Acknowledge();
return;
}
// If there is still a pending invalidation, acknowledge it, since we only
// care about the latest invalidation.
if (invalid_)
......
......@@ -64,11 +64,14 @@ class CloudPolicyInvalidator : public syncer::InvalidationHandler,
// |task_runner| is used for scheduling delayed tasks. It must post tasks to
// the main policy thread.
// |clock| is used to get the current time.
// |highest_handled_invalidation_version| is the highest invalidation version
// that was handled already before this invalidator was created.
CloudPolicyInvalidator(
enterprise_management::DeviceRegisterRequest::Type type,
CloudPolicyCore* core,
const scoped_refptr<base::SequencedTaskRunner>& task_runner,
scoped_ptr<base::Clock> clock);
scoped_ptr<base::Clock> clock,
int64 highest_handled_invalidation_version);
virtual ~CloudPolicyInvalidator();
// Initializes the invalidator. No invalidations will be generated before this
......@@ -86,6 +89,11 @@ class CloudPolicyInvalidator : public syncer::InvalidationHandler,
return invalidations_enabled_;
}
// The highest invalidation version that was handled already.
int64 highest_handled_invalidation_version() const {
return highest_handled_invalidation_version_;
}
// syncer::InvalidationHandler:
virtual void OnInvalidatorStateChange(
syncer::InvalidatorState state) OVERRIDE;
......@@ -207,6 +215,9 @@ class CloudPolicyInvalidator : public syncer::InvalidationHandler,
// invalidation_version_ when such invalidations occur.
int unknown_version_invalidation_count_;
// The highest invalidation version that was handled already.
int64 highest_handled_invalidation_version_;
// The most up to date invalidation.
scoped_ptr<syncer::Invalidation> invalidation_;
......
......@@ -22,7 +22,8 @@ UserCloudPolicyInvalidator::UserCloudPolicyInvalidator(
: CloudPolicyInvalidator(GetPolicyType(),
policy_manager->core(),
base::MessageLoopProxy::current(),
scoped_ptr<base::Clock>(new base::DefaultClock())),
scoped_ptr<base::Clock>(new base::DefaultClock()),
0 /* highest_handled_invalidation_version */),
profile_(profile) {
DCHECK(profile);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment