Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: chrome/browser/policy/file_based_policy_loader.cc

Issue 5562002: Refactor FileBasedPolicyProvider, introduce AsynchronousPolicyProvider. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review feedback Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/policy/file_based_policy_loader.h"
6
7 namespace {
8
9 // Amount of time we wait for the files on disk to settle before trying to load
10 // it. This alleviates the problem of reading partially written files and allows
Mattias Nissler (ping if slow) 2010/12/06 10:26:20 s/it/them/
danno 2010/12/06 14:05:12 Done.
11 // to batch quasi-simultaneous changes.
12 const int kSettleIntervalSeconds = 5;
13
14 // The time interval for rechecking policy. This is our fallback in case the
15 // delegate never reports a change to the ReloadObserver.
16 const int kReloadIntervalMinutes = 15;
17
18 }
19
20 namespace policy {
21
22 FileBasedPolicyLoader::FileBasedPolicyLoader(
23 FileBasedPolicyProvider::ProviderDelegate* provider_delegate)
24 : AsynchronousPolicyLoader(provider_delegate),
25 provider_delegate_(provider_delegate),
26 config_file_path_(provider_delegate->config_file_path()),
27 reload_interval_(base::TimeDelta::FromMinutes(kReloadIntervalMinutes)),
28 settle_interval_(base::TimeDelta::FromSeconds(kSettleIntervalSeconds)) {
29 }
30
31 class FileBasedPolicyWatcherDelegate : public FilePathWatcher::Delegate {
32 public:
33 explicit FileBasedPolicyWatcherDelegate(
34 scoped_refptr<FileBasedPolicyLoader> loader)
35 : loader_(loader) {}
36 virtual ~FileBasedPolicyWatcherDelegate() {}
37
38 // FilePathWatcher::Delegate implementation:
39 void OnFilePathChanged(const FilePath& path) {
40 loader_->OnFilePathChanged(path);
41 }
42
43 void OnError() {
44 loader_->OnError();
45 }
46
47 private:
48 scoped_refptr<FileBasedPolicyLoader> loader_;
49 DISALLOW_COPY_AND_ASSIGN(FileBasedPolicyWatcherDelegate);
50 };
51
52 void FileBasedPolicyLoader::Init() {
53 AsynchronousPolicyLoader::Init();
54
55 // Initialization can happen early when the file thread is not
56 // yet available. So post a task on the FILE thread which will run after
57 // threading is up and schedule watch initialization on the file thread.
Mattias Nissler (ping if slow) 2010/12/06 10:26:20 Didn't we post on the UI thread before? That was i
danno 2010/12/06 14:05:12 Done.
58 BrowserThread::PostTask(
59 BrowserThread::FILE, FROM_HERE,
60 NewRunnableMethod(this, &FileBasedPolicyLoader::InitWatcher));
61
62 ScheduleFallbackReloadTask();
63 }
64
65 void FileBasedPolicyLoader::Stop() {
66 AsynchronousPolicyLoader::Stop();
67 BrowserThread::PostTask(
68 BrowserThread::FILE, FROM_HERE,
69 NewRunnableMethod(this, &FileBasedPolicyLoader::StopOnFileThread));
70 }
71
72 void FileBasedPolicyLoader::OnFilePathChanged(
73 const FilePath& path) {
74 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
75 Reload();
76 }
77
78 void FileBasedPolicyLoader::OnError() {
79 LOG(ERROR) << "FilePathWatcher on " << config_file_path().value()
80 << " failed.";
81 }
82
83 void FileBasedPolicyLoader::Reload() {
84 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
85 // Check the directory time in order to see whether a reload is required.
86 base::TimeDelta delay;
87 base::Time now = base::Time::Now();
88 if (!IsSafeToReloadPolicy(now, &delay)) {
89 ScheduleReloadTask(delay);
90 return;
91 }
92
93 // Load the policy definitions.
94 scoped_ptr<DictionaryValue> new_policy(delegate()->Load());
95
96 // Check again in case the directory has changed while reading it.
97 if (!IsSafeToReloadPolicy(now, &delay)) {
98 ScheduleReloadTask(delay);
99 return;
100 }
101
102 PostUpdatePolicyTask(new_policy.release());
103
104 ScheduleFallbackReloadTask();
105 }
106
107 void FileBasedPolicyLoader::InitWatcher() {
108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
109 watcher_.reset(new FilePathWatcher);
110 if (!config_file_path().empty() &&
111 !watcher_->Watch(config_file_path(),
112 new FileBasedPolicyWatcherDelegate(this)))
113 OnError();
Mattias Nissler (ping if slow) 2010/12/06 10:26:20 need curlies here.
danno 2010/12/06 14:05:12 Done.
114
115 // There might have been changes to the directory in the time between
116 // construction of the loader and initialization of the watcher. Call reload
117 // to detect if that is the case.
118 Reload();
119 }
120
121 void FileBasedPolicyLoader::StopOnFileThread() {
122 watcher_.reset();
123 if (reload_task_) {
124 reload_task_->Cancel();
125 reload_task_ = NULL;
126 }
127 }
128
129 void FileBasedPolicyLoader::ScheduleReloadTask(
130 const base::TimeDelta& delay) {
131 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
132
133 if (reload_task_)
134 reload_task_->Cancel();
135
136 reload_task_ =
137 NewRunnableMethod(this, &FileBasedPolicyLoader::ReloadFromTask);
138 BrowserThread::PostDelayedTask(BrowserThread::FILE, FROM_HERE, reload_task_,
139 delay.InMilliseconds());
140 }
141
142 void FileBasedPolicyLoader::ScheduleFallbackReloadTask() {
143 // As a safeguard in case that the load delegate failed to timely notice a
144 // change in policy, schedule a reload task that'll make us recheck after a
145 // reasonable interval.
146 ScheduleReloadTask(reload_interval_);
147 }
148
149 void FileBasedPolicyLoader::ReloadFromTask() {
150 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
151
152 // Drop the reference to the reload task, since the task might be the only
153 // referer that keeps us alive, so we should not Cancel() it.
154 reload_task_ = NULL;
155
156 Reload();
157 }
158
159 bool FileBasedPolicyLoader::IsSafeToReloadPolicy(
160 const base::Time& now,
161 base::TimeDelta* delay) {
162 DCHECK(delay);
163
164 // A null modification time indicates there's no data.
165 base::Time last_modification(provider_delegate_->GetLastModification());
166 if (last_modification.is_null())
167 return true;
168
169 // If there was a change since the last recorded modification, wait some more.
170 if (last_modification != last_modification_file_) {
171 last_modification_file_ = last_modification;
172 last_modification_clock_ = now;
173 *delay = settle_interval_;
174 return false;
175 }
176
177 // Check whether the settle interval has elapsed.
178 base::TimeDelta age = now - last_modification_clock_;
179 if (age < settle_interval_) {
180 *delay = settle_interval_ - age;
181 return false;
182 }
183
184 return true;
185 }
186
187 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698