Chromium Code Reviews| 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. |
|
Mattias Nissler (ping if slow)
2010/12/02 18:16:00
Outdated comment?
danno
2010/12/03 17:05:38
Done.
|
| + base::TimeDelta delay; |
| + base::Time now = base::Time::Now(); |
| + if (!delegate_->IsSafeToReloadPolicy(now, &delay)) { |
|
Mattias Nissler (ping if slow)
2010/12/02 18:16:00
Does IsSafeToReloadPolicy make sense for group pol
danno
2010/12/03 17:05:38
Done.
|
| + ScheduleReloadTask(delay); |
|
Mattias Nissler (ping if slow)
2010/12/02 18:16:00
Does the periodic reload task make sense for group
danno
2010/12/03 17:05:38
Done.
|
| + 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 |