summaryrefslogtreecommitdiffstats
path: root/chrome/browser/policy/file_based_policy_provider.h
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/policy/file_based_policy_provider.h')
-rw-r--r--chrome/browser/policy/file_based_policy_provider.h203
1 files changed, 203 insertions, 0 deletions
diff --git a/chrome/browser/policy/file_based_policy_provider.h b/chrome/browser/policy/file_based_policy_provider.h
new file mode 100644
index 0000000..49af11f
--- /dev/null
+++ b/chrome/browser/policy/file_based_policy_provider.h
@@ -0,0 +1,203 @@
+// 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.
+
+#ifndef CHROME_BROWSER_POLICY_FILE_BASED_POLICY_PROVIDER_H_
+#define CHROME_BROWSER_POLICY_FILE_BASED_POLICY_PROVIDER_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "base/file_path.h"
+#include "base/lock.h"
+#include "base/ref_counted.h"
+#include "base/scoped_ptr.h"
+#include "base/time.h"
+#include "base/weak_ptr.h"
+#include "chrome/browser/file_path_watcher.h"
+#include "chrome/browser/policy/configuration_policy_provider.h"
+
+class CancelableTask;
+class DictionaryValue;
+class MessageLoop;
+
+namespace policy {
+
+class FileBasedPolicyLoader;
+class FileBasedPolicyWatcher;
+
+// File based policy provider that coordinates watching and reloading policy
+// information from the configuration path. Actual logic for loading policy
+// information is handled by a delegate passed at construction time.
+class FileBasedPolicyProvider
+ : public ConfigurationPolicyProvider,
+ public base::SupportsWeakPtr<FileBasedPolicyProvider> {
+ public:
+ // Delegate interface for actual policy loading from the system.
+ class Delegate {
+ public:
+ virtual ~Delegate();
+
+ // Loads the policy information. Ownership of the return value is
+ // transferred to the caller.
+ virtual DictionaryValue* Load() = 0;
+
+ // Gets the last modification timestamp for the policy information from the
+ // filesystem. Returns base::Time() if the information is not present, in
+ // which case Load() should return an empty dictionary.
+ virtual base::Time GetLastModification() = 0;
+
+ const FilePath& config_file_path() { return config_file_path_; }
+
+ protected:
+ explicit Delegate(const FilePath& config_file_path);
+
+ private:
+ // The path at which we look for configuration files.
+ const FilePath config_file_path_;
+
+ DISALLOW_COPY_AND_ASSIGN(Delegate);
+ };
+
+ // Assumes ownership of |delegate|.
+ FileBasedPolicyProvider(const PolicyDefinitionList* policy_list,
+ Delegate* delegate);
+ virtual ~FileBasedPolicyProvider();
+
+ // ConfigurationPolicyProvider implementation.
+ virtual bool Provide(ConfigurationPolicyStoreInterface* store);
+
+ private:
+ // Decodes the value tree and writes the configuration to the given |store|.
+ void DecodePolicyValueTree(DictionaryValue* policies,
+ ConfigurationPolicyStoreInterface* store);
+
+ // Watches for changes to the configuration directory.
+ scoped_refptr<FileBasedPolicyWatcher> watcher_;
+
+ // The loader object we use internally.
+ scoped_refptr<FileBasedPolicyLoader> loader_;
+
+ DISALLOW_COPY_AND_ASSIGN(FileBasedPolicyProvider);
+};
+
+// FilePathWatcher delegate implementation that handles change notifications for
+// the configuration file or directory. It keeps the authorative version of the
+// currently effective policy dictionary and updates it as appropriate. The
+// actual loading logic is handled by a delegate.
+class FileBasedPolicyLoader : public FilePathWatcher::Delegate {
+ public:
+ // Creates a new loader that'll load its data from |config_file_path|.
+ // Assumes ownership of |delegate|, which provides the actual loading logic.
+ // The parameters |settle_interval_seconds| and |reload_interval_minutes|
+ // specify the time to wait before reading the file contents after a change
+ // and the period for checking |config_file_path| for changes, respectively.
+ FileBasedPolicyLoader(base::WeakPtr<ConfigurationPolicyProvider> provider,
+ FileBasedPolicyProvider::Delegate* delegate,
+ int settle_interval_seconds,
+ int reload_interval_minutes);
+
+ // Stops any pending reload tasks.
+ void Stop();
+
+ // Reloads the policies and sends out a notification, if appropriate. Must be
+ // called on the file thread.
+ void Reload();
+
+ // Gets the current dictionary value object. Ownership of the returned value
+ // is transferred to the caller.
+ DictionaryValue* GetPolicy();
+
+ const FilePath& config_file_path() { return delegate_->config_file_path(); }
+
+ // FilePathWatcher::Delegate implementation:
+ void OnFilePathChanged(const FilePath& path);
+ void OnError();
+
+ private:
+ // FileBasedPolicyLoader objects should only be deleted by
+ // RefCountedThreadSafe.
+ friend class base::RefCountedThreadSafe<FileBasedPolicyLoader>;
+ virtual ~FileBasedPolicyLoader();
+
+ // Checks whether reading policy information is safe to do. If not, returns
+ // false and the delay until it is considered safe to reload in |delay|.
+ bool IsSafeToReloadPolicy(const base::Time& now, base::TimeDelta* delay);
+
+ // Schedules a reload task to run when |delay| expires. Must be called on the
+ // file thread.
+ void ScheduleReloadTask(const base::TimeDelta& delay);
+
+ // Notifies the policy provider to send out a policy changed notification.
+ // Must be called on |origin_loop_|.
+ void NotifyPolicyChanged();
+
+ // Invoked from the reload task on the file thread.
+ void ReloadFromTask();
+
+ // The delegate.
+ scoped_ptr<FileBasedPolicyProvider::Delegate> delegate_;
+
+ // The provider this loader is associated with. Access only on the thread that
+ // called the constructor. See |origin_loop_| below.
+ base::WeakPtr<ConfigurationPolicyProvider> provider_;
+
+ // The message loop on which this object was constructed and |provider_|
+ // received on. Recorded so we can call back into the non thread safe provider
+ // to fire the notification.
+ MessageLoop* origin_loop_;
+
+ // Records last known modification timestamp of |config_file_path_|.
+ base::Time last_modification_file_;
+
+ // The wall clock time at which the last modification timestamp was recorded.
+ // It's better to not assume the file notification time and the wall clock
+ // times come from the same source, just in case there is some non-local
+ // filesystem involved.
+ base::Time last_modification_clock_;
+
+ // Protects |policy_|.
+ Lock lock_;
+
+ // The current policy definition.
+ scoped_ptr<DictionaryValue> policy_;
+
+ // The reload task. Access only on the file thread. Holds a reference to the
+ // currently posted task, so we can cancel and repost it if necessary.
+ CancelableTask* reload_task_;
+
+ // Settle and reload intervals.
+ const int settle_interval_seconds_;
+ const int reload_interval_minutes_;
+
+ DISALLOW_COPY_AND_ASSIGN(FileBasedPolicyLoader);
+};
+
+// Wraps a FilePathWatcher for the configuration path and takes care of
+// initializing the watcher object on the file thread.
+class FileBasedPolicyWatcher
+ : public base::RefCountedThreadSafe<FileBasedPolicyWatcher> {
+ public:
+ FileBasedPolicyWatcher();
+
+ // Runs initialization. This is in a separate method since we need to post a
+ // task (which cannot be done from the constructor).
+ void Init(FileBasedPolicyLoader* loader);
+
+ private:
+ // FileBasedPolicyWatcher objects should only be deleted by
+ // RefCountedThreadSafe.
+ friend class base::RefCountedThreadSafe<FileBasedPolicyWatcher>;
+ virtual ~FileBasedPolicyWatcher();
+
+ // Actually sets up the watch with the FilePathWatcher code.
+ void InitWatcher(const scoped_refptr<FileBasedPolicyLoader>& loader);
+
+ // Wrapped watcher that takes care of the actual watching.
+ FilePathWatcher watcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(FileBasedPolicyWatcher);
+};
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_POLICY_FILE_BASED_POLICY_PROVIDER_H_