Chromium Code Reviews| Index: chrome/browser/policy/file_based_policy_provider.cc |
| diff --git a/chrome/browser/policy/file_based_policy_provider.cc b/chrome/browser/policy/file_based_policy_provider.cc |
| index 578277d61d78f22ce4e529f8adb1f972b75cb4b8..c913c9d2801574830d816d1d663a290d5b129937 100644 |
| --- a/chrome/browser/policy/file_based_policy_provider.cc |
| +++ b/chrome/browser/policy/file_based_policy_provider.cc |
| @@ -14,146 +14,71 @@ |
| #include "chrome/browser/browser_thread.h" |
| #include "chrome/common/json_value_serializer.h" |
| -namespace policy { |
| +namespace { |
| // Amount of time we wait for the files on disk to settle before trying to load |
| // it. This alleviates the problem of reading partially written files and allows |
| // to batch quasi-simultaneous changes. |
| const int kSettleIntervalSeconds = 5; |
| -// The time interval for rechecking policy. This is our fallback in case the |
| -// file path watch fails or doesn't report a change. |
| -const int kReloadIntervalMinutes = 15; |
| - |
| -// FileBasedPolicyProvider implementation: |
| - |
| -FileBasedPolicyProvider::Delegate::~Delegate() { |
| -} |
| - |
| -FileBasedPolicyProvider::Delegate::Delegate(const FilePath& config_file_path) |
| - : config_file_path_(config_file_path) { |
| -} |
| - |
| -FileBasedPolicyProvider::FileBasedPolicyProvider( |
| - const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list, |
| - FileBasedPolicyProvider::Delegate* delegate) |
| - : ConfigurationPolicyProvider(policy_list) { |
| - loader_ = new FileBasedPolicyLoader(AsWeakPtr(), |
| - delegate, |
| - kSettleIntervalSeconds, |
| - kReloadIntervalMinutes); |
| - watcher_ = new FileBasedPolicyWatcher; |
| - watcher_->Init(loader_.get()); |
| -} |
| - |
| -FileBasedPolicyProvider::~FileBasedPolicyProvider() { |
| - loader_->Stop(); |
| -} |
| - |
| -bool FileBasedPolicyProvider::Provide( |
| - ConfigurationPolicyStoreInterface* store) { |
| - scoped_ptr<DictionaryValue> policy(loader_->GetPolicy()); |
| - DCHECK(policy.get()); |
| - DecodePolicyValueTree(policy.get(), store); |
| - return true; |
| -} |
| - |
| -// FileBasedPolicyLoader implementation: |
| - |
| -FileBasedPolicyLoader::FileBasedPolicyLoader( |
| - base::WeakPtr<ConfigurationPolicyProvider> provider, |
| - FileBasedPolicyProvider::Delegate* delegate, |
| - int settle_interval_seconds, |
| - int reload_interval_minutes) |
| - : delegate_(delegate), |
| - provider_(provider), |
| - origin_loop_(MessageLoop::current()), |
| - reload_task_(NULL), |
| - settle_interval_seconds_(settle_interval_seconds), |
| - reload_interval_minutes_(reload_interval_minutes) { |
| - // Force an initial load, so GetPolicy() works. |
| - policy_.reset(delegate_->Load()); |
| - DCHECK(policy_.get()); |
| } |
| -void FileBasedPolicyLoader::Stop() { |
| - if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) { |
| - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| - NewRunnableMethod(this, &FileBasedPolicyLoader::Stop)); |
| - return; |
| - } |
| +namespace policy { |
| - if (reload_task_) { |
| - reload_task_->Cancel(); |
| - reload_task_ = NULL; |
| - } |
| +FileBasedPolicyProvider::WatcherDelegate::WatcherDelegate( |
| + const FilePath& config_file_path, |
| + AsynchronousPolicyProvider::PolicyChangeObserver* observer) |
| + : config_file_path_(config_file_path), |
| + observer_(observer) { |
| } |
| -void FileBasedPolicyLoader::Reload() { |
| +void FileBasedPolicyProvider::WatcherDelegate::Init() { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| + watcher_.reset(new FilePathWatcher()); |
| + if (!config_file_path_.empty() && |
| + !watcher_->Watch(config_file_path_, this)) |
| + OnError(); |
| - // Check the directory time in order to see whether a reload is required. |
| - base::TimeDelta delay; |
| - base::Time now = base::Time::Now(); |
| - if (!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 (!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) { |
| - VLOG(0) << "Policy reload from " << config_file_path().value() |
| - << " succeeded."; |
| - origin_loop_->PostTask(FROM_HERE, |
| - NewRunnableMethod(this, &FileBasedPolicyLoader::NotifyPolicyChanged)); |
| - } |
| - |
| - // As a safeguard in case the file watcher fails, schedule a reload task |
| - // that'll make us recheck after a reasonable interval. |
| - ScheduleReloadTask(base::TimeDelta::FromMinutes(reload_interval_minutes_)); |
| + // There might have been changes to the directory in the time between |
| + // construction of the loader and initialization of the watcher. Call reload |
| + // to detect if that is the case. |
| + observer_->OnPolicyChange(); |
| } |
| -DictionaryValue* FileBasedPolicyLoader::GetPolicy() { |
| - AutoLock lock(lock_); |
| - return static_cast<DictionaryValue*>(policy_->DeepCopy()); |
| +void FileBasedPolicyProvider::WatcherDelegate::Stop() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| + watcher_.reset(NULL); |
| + observer_.reset(NULL); |
|
Mattias Nissler (ping if slow)
2010/12/02 18:16:00
No need to pass the NULL literal, you can just use
danno
2010/12/03 17:05:38
Done.
|
| } |
| -void FileBasedPolicyLoader::OnFilePathChanged(const FilePath& path) { |
| +void FileBasedPolicyProvider::WatcherDelegate::OnFilePathChanged( |
| + const FilePath& path) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| - Reload(); |
| + if (observer_.get()) |
| + observer_->OnPolicyChange(); |
| } |
| -void FileBasedPolicyLoader::OnError() { |
| - LOG(ERROR) << "FilePathWatcher on " << config_file_path().value() |
| +void FileBasedPolicyProvider::WatcherDelegate::OnError() { |
| + LOG(ERROR) << "FilePathWatcher on " << config_file_path_.value() |
| << " failed."; |
| } |
| -FileBasedPolicyLoader::~FileBasedPolicyLoader() { |
| +FileBasedPolicyProvider::ProviderDelegate::ProviderDelegate( |
| + const FilePath& config_file_path) |
| + : config_file_path_(config_file_path), |
| + settle_interval_seconds_(kSettleIntervalSeconds){ |
| } |
| -bool FileBasedPolicyLoader::IsSafeToReloadPolicy(const base::Time& now, |
| - base::TimeDelta* delay) { |
| +FileBasedPolicyProvider::ProviderDelegate::~ProviderDelegate() { |
| +} |
| + |
| +bool FileBasedPolicyProvider::ProviderDelegate::IsSafeToReloadPolicy( |
| + const base::Time& now, |
| + base::TimeDelta* delay) { |
| DCHECK(delay); |
| // A null modification time indicates there's no data. |
| - base::Time last_modification(delegate_->GetLastModification()); |
| + base::Time last_modification(GetLastModification()); |
| if (last_modification.is_null()) |
| return true; |
| @@ -177,68 +102,32 @@ bool FileBasedPolicyLoader::IsSafeToReloadPolicy(const base::Time& now, |
| return true; |
| } |
| -void FileBasedPolicyLoader::ScheduleReloadTask(const base::TimeDelta& delay) { |
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| - |
| - if (reload_task_) |
| - reload_task_->Cancel(); |
| - |
| - reload_task_ = |
| - NewRunnableMethod(this, &FileBasedPolicyLoader::ReloadFromTask); |
| - BrowserThread::PostDelayedTask(BrowserThread::FILE, FROM_HERE, reload_task_, |
| - delay.InMilliseconds()); |
| -} |
| - |
| -void FileBasedPolicyLoader::NotifyPolicyChanged() { |
| - DCHECK_EQ(origin_loop_, MessageLoop::current()); |
| - if (provider_) |
| - provider_->NotifyStoreOfPolicyChange(); |
| -} |
| - |
| -void FileBasedPolicyLoader::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(); |
| -} |
| - |
| -// FileBasedPolicyWatcher implementation: |
| +void FileBasedPolicyProvider::ProviderDelegate::Init( |
| + AsynchronousPolicyProvider::PolicyChangeObserver* observer) { |
| + watcher_delegate_ = new FileBasedPolicyProvider::WatcherDelegate( |
| + config_file_path_, |
| + observer); |
| -FileBasedPolicyWatcher::FileBasedPolicyWatcher() { |
| + // Initialization can happen early when the file thread is not |
| + // yet available. So post a task on the FILE thread which will run after |
| + // threading is up and schedule watch initialization on the file thread. |
| + BrowserThread::PostTask( |
| + BrowserThread::FILE, FROM_HERE, |
| + NewRunnableMethod(watcher_delegate_.get(), |
| + &FileBasedPolicyProvider::WatcherDelegate::Init)); |
| } |
| -void FileBasedPolicyWatcher::Init(FileBasedPolicyLoader* loader) { |
| - // Initialization can happen early when the file thread is not yet available. |
| - // So post a task to ourselves on the UI thread which will run after threading |
| - // is up and schedule watch initialization on the file thread. |
| - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| - NewRunnableMethod(this, |
| - &FileBasedPolicyWatcher::InitWatcher, |
| - scoped_refptr<FileBasedPolicyLoader>(loader))); |
| +void FileBasedPolicyProvider::ProviderDelegate::Stop() { |
| + BrowserThread::PostTask( |
| + BrowserThread::FILE, FROM_HERE, |
| + NewRunnableMethod(watcher_delegate_.get(), |
| + &FileBasedPolicyProvider::WatcherDelegate::Stop)); |
| } |
| -FileBasedPolicyWatcher::~FileBasedPolicyWatcher() { |
| -} |
| - |
| -void FileBasedPolicyWatcher::InitWatcher( |
| - const scoped_refptr<FileBasedPolicyLoader>& loader) { |
| - if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) { |
| - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| - NewRunnableMethod(this, &FileBasedPolicyWatcher::InitWatcher, loader)); |
| - return; |
| - } |
| - |
| - if (!loader->config_file_path().empty() && |
| - !watcher_.Watch(loader->config_file_path(), loader.get())) |
| - loader->OnError(); |
| - |
| - // There might have been changes to the directory in the time between |
| - // construction of the loader and initialization of the watcher. Call reload |
| - // to detect if that is the case. |
| - loader->Reload(); |
| +FileBasedPolicyProvider::FileBasedPolicyProvider( |
| + const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list, |
| + FileBasedPolicyProvider::ProviderDelegate* delegate) |
| + : AsynchronousPolicyProvider(policy_list, delegate) { |
| } |
| } // namespace policy |