| Index: chrome/browser/policy/asynchronous_policy_loader.cc
|
| diff --git a/chrome/browser/policy/asynchronous_policy_loader.cc b/chrome/browser/policy/asynchronous_policy_loader.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8a1402d4c181331cbba8e21bc770b2c4f9df6ce5
|
| --- /dev/null
|
| +++ b/chrome/browser/policy/asynchronous_policy_loader.cc
|
| @@ -0,0 +1,122 @@
|
| +// Copyright (c) 2010 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/asynchronous_policy_loader.h"
|
| +
|
| +#include "base/message_loop.h"
|
| +#include "base/task.h"
|
| +#include "chrome/browser/browser_thread.h"
|
| +
|
| +namespace policy {
|
| +
|
| +AsynchronousPolicyLoader::AsynchronousPolicyLoader(
|
| + base::WeakPtr<ConfigurationPolicyProvider> provider,
|
| + AsynchronousPolicyProvider::Delegate* delegate,
|
| + int reload_interval_minutes)
|
| + : provider_(provider),
|
| + delegate_(delegate),
|
| + origin_loop_(MessageLoop::current()),
|
| + reload_task_(NULL),
|
| + reload_interval_minutes_(reload_interval_minutes) {
|
| +}
|
| +
|
| +void AsynchronousPolicyLoader::Init() {
|
| + // Force an initial load, so GetPolicy() works.
|
| + policy_.reset(delegate_->Load());
|
| + DCHECK(policy_.get());
|
| + ScheduleFallbackReloadTask();
|
| +}
|
| +
|
| +DictionaryValue* AsynchronousPolicyLoader::GetPolicy() {
|
| + AutoLock lock(lock_);
|
| + return static_cast<DictionaryValue*>(policy_->DeepCopy());
|
| +}
|
| +
|
| +void AsynchronousPolicyLoader::Reload() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| + // Check the directory time in order to see whether a reload is required.
|
| + base::TimeDelta delay;
|
| + base::Time now = base::Time::Now();
|
| + if (!delegate_->IsSafeToReloadPolicy(now, &delay)) {
|
| + ScheduleReloadTask(delay);
|
| + return;
|
| + }
|
| +
|
| + // Load the policy definitions.
|
| + scoped_ptr<DictionaryValue> new_policy(delegate_->Load());
|
| +
|
| + // Check again in case the directory has changed while reading it.
|
| + if (!delegate_->IsSafeToReloadPolicy(now, &delay)) {
|
| + ScheduleReloadTask(delay);
|
| + return;
|
| + }
|
| +
|
| + // Replace policy definition.
|
| + bool changed = false;
|
| + {
|
| + AutoLock lock(lock_);
|
| + changed = !policy_->Equals(new_policy.get());
|
| + policy_.reset(new_policy.release());
|
| + }
|
| +
|
| + // There's a change, report it!
|
| + if (changed) {
|
| + origin_loop_->PostTask(FROM_HERE,
|
| + NewRunnableMethod(this,
|
| + &AsynchronousPolicyLoader::NotifyPolicyChanged));
|
| + }
|
| +
|
| + ScheduleFallbackReloadTask();
|
| +}
|
| +
|
| +void AsynchronousPolicyLoader::Stop() {
|
| + if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) {
|
| + BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
|
| + NewRunnableMethod(this, &AsynchronousPolicyLoader::Stop));
|
| + return;
|
| + }
|
| +
|
| + if (reload_task_) {
|
| + reload_task_->Cancel();
|
| + reload_task_ = NULL;
|
| + }
|
| +}
|
| +
|
| +void AsynchronousPolicyLoader::ScheduleReloadTask(
|
| + const base::TimeDelta& delay) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| +
|
| + if (reload_task_)
|
| + reload_task_->Cancel();
|
| +
|
| + reload_task_ =
|
| + NewRunnableMethod(this, &AsynchronousPolicyLoader::ReloadFromTask);
|
| + BrowserThread::PostDelayedTask(BrowserThread::FILE, FROM_HERE, reload_task_,
|
| + delay.InMilliseconds());
|
| +}
|
| +
|
| +void AsynchronousPolicyLoader::ScheduleFallbackReloadTask() {
|
| + // As a safeguard in case that the load delegate failed to timely notice a
|
| + // change in policy, schedule a reload task that'll make us recheck after a
|
| + // reasonable interval.
|
| + ScheduleReloadTask(base::TimeDelta::FromMinutes(reload_interval_minutes_));
|
| +}
|
| +
|
| +void AsynchronousPolicyLoader::ReloadFromTask() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| +
|
| + // Drop the reference to the reload task, since the task might be the only
|
| + // referer that keeps us alive, so we should not Cancel() it.
|
| + reload_task_ = NULL;
|
| +
|
| + Reload();
|
| +}
|
| +
|
| +void AsynchronousPolicyLoader::NotifyPolicyChanged() {
|
| + DCHECK_EQ(origin_loop_, MessageLoop::current());
|
| + if (provider_)
|
| + provider_->NotifyStoreOfPolicyChange();
|
| +}
|
| +
|
| +} // namespace policy
|
|
|