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 |