| 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
|
| index e78c9aaf82c26fc01a3e94fb81f0e752bf5660a0..cf6706629e407e4de1806dc41c734c2476387003 100644
|
| --- a/chrome/browser/policy/asynchronous_policy_loader.cc
|
| +++ b/chrome/browser/policy/asynchronous_policy_loader.cc
|
| @@ -6,21 +6,43 @@
|
|
|
| #include "base/message_loop.h"
|
| #include "base/task.h"
|
| +#include "chrome/browser/browser_thread.h"
|
|
|
| namespace policy {
|
|
|
| AsynchronousPolicyLoader::AsynchronousPolicyLoader(
|
| - AsynchronousPolicyProvider::Delegate* delegate)
|
| + AsynchronousPolicyProvider::Delegate* delegate,
|
| + int reload_interval_minutes)
|
| : delegate_(delegate),
|
| provider_(NULL),
|
| - origin_loop_(MessageLoop::current()) {}
|
| + reload_task_(NULL),
|
| + reload_interval_(base::TimeDelta::FromMinutes(reload_interval_minutes)),
|
| + origin_loop_(MessageLoop::current()),
|
| + stopped_(false) {}
|
|
|
| void AsynchronousPolicyLoader::Init() {
|
| policy_.reset(delegate_->Load());
|
| + // Initialization can happen early when the file thread is not yet available,
|
| + // but the subclass of the loader must do some of their initialization on the
|
| + // file thread. Posting to the file thread directly before it is initialized
|
| + // will cause the task to be forgotten. Instead, post a task to the ui thread
|
| + // to delay the remainder of initialization until threading is fully
|
| + // initialized.
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + NewRunnableMethod(
|
| + this,
|
| + &AsynchronousPolicyLoader::InitAfterFileThreadAvailable));
|
| }
|
|
|
| void AsynchronousPolicyLoader::Stop() {
|
| - delegate_.reset();
|
| + if (!stopped_) {
|
| + stopped_ = true;
|
| + delegate_.reset();
|
| + BrowserThread::PostTask(
|
| + BrowserThread::FILE, FROM_HERE,
|
| + NewRunnableMethod(this, &AsynchronousPolicyLoader::StopOnFileThread));
|
| + }
|
| }
|
|
|
| void AsynchronousPolicyLoader::SetProvider(
|
| @@ -57,6 +79,54 @@ void AsynchronousPolicyLoader::Reload() {
|
| }
|
| }
|
|
|
| +void AsynchronousPolicyLoader::CancelReloadTask() {
|
| + if (reload_task_) {
|
| + // Only check the thread if there's still a reload task. During
|
| + // destruction of unit tests, the message loop destruction can
|
| + // call this method when the file thread is no longer around,
|
| + // but in that case reload_task_ is NULL.
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| + reload_task_->Cancel();
|
| + reload_task_ = NULL;
|
| + }
|
| +}
|
| +
|
| +void AsynchronousPolicyLoader::ScheduleReloadTask(
|
| + const base::TimeDelta& delay) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| +
|
| + CancelReloadTask();
|
| +
|
| + 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(reload_interval_);
|
| +}
|
| +
|
| +void AsynchronousPolicyLoader::ReloadFromTask() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| +
|
| + // Drop the reference to the reload task, since the task might be the only
|
| + // referrer that keeps us alive, so we should not Cancel() it.
|
| + reload_task_ = NULL;
|
| +
|
| + Reload();
|
| +}
|
| +
|
| +void AsynchronousPolicyLoader::InitOnFileThread() {
|
| +}
|
| +
|
| +void AsynchronousPolicyLoader::StopOnFileThread() {
|
| + CancelReloadTask();
|
| +}
|
| +
|
| void AsynchronousPolicyLoader::PostUpdatePolicyTask(
|
| DictionaryValue* new_policy) {
|
| origin_loop_->PostTask(FROM_HERE, new UpdatePolicyTask(this, new_policy));
|
| @@ -75,4 +145,12 @@ void AsynchronousPolicyLoader::UpdatePolicy(DictionaryValue* new_policy_raw) {
|
| }
|
| }
|
|
|
| +void AsynchronousPolicyLoader::InitAfterFileThreadAvailable() {
|
| + if (!stopped_) {
|
| + BrowserThread::PostTask(
|
| + BrowserThread::FILE, FROM_HERE,
|
| + NewRunnableMethod(this, &AsynchronousPolicyLoader::InitOnFileThread));
|
| + }
|
| +}
|
| +
|
| } // namespace policy
|
|
|