1// Copyright (c) 2011 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#ifndef CHROME_BROWSER_POLICY_ASYNCHRONOUS_POLICY_LOADER_H_
6#define CHROME_BROWSER_POLICY_ASYNCHRONOUS_POLICY_LOADER_H_
7#pragma once
8
9#include "base/memory/ref_counted.h"
10#include "base/message_loop.h"
11#include "base/observer_list.h"
12#include "base/values.h"
13#include "chrome/browser/policy/asynchronous_policy_provider.h"
14#include "chrome/browser/policy/configuration_policy_provider.h"
15
16namespace policy {
17
18// Used by the implementation of asynchronous policy provider to manage the
19// tasks on the file thread that do the heavy lifting of loading policies.
20class AsynchronousPolicyLoader
21    : public base::RefCountedThreadSafe<AsynchronousPolicyLoader> {
22 public:
23  explicit AsynchronousPolicyLoader(
24      AsynchronousPolicyProvider::Delegate* delegate,
25      int reload_interval_minutes);
26
27  // Triggers initial policy load.
28  virtual void Init();
29
30  // Reloads policy, sending notification of changes if necessary. Must be
31  // called on the file thread.
32  virtual void Reload();
33
34  // Stops any pending reload tasks.
35  virtual void Stop();
36
37  void AddObserver(ConfigurationPolicyProvider::Observer* observer);
38  void RemoveObserver(ConfigurationPolicyProvider::Observer* observer);
39
40  const DictionaryValue* policy() const { return policy_.get(); }
41
42 protected:
43  friend class UpdatePolicyTask;
44
45  // AsynchronousPolicyLoader objects should only be deleted by
46  // RefCountedThreadSafe.
47  friend class base::RefCountedThreadSafe<AsynchronousPolicyLoader>;
48  virtual ~AsynchronousPolicyLoader();
49
50  // Schedules a call to UpdatePolicy on |origin_loop_|. Takes ownership of
51  // |new_policy|.
52  void PostUpdatePolicyTask(DictionaryValue* new_policy);
53
54  AsynchronousPolicyProvider::Delegate* delegate() {
55    return delegate_.get();
56  }
57
58  // Performs start operations that must be performed on the file thread.
59  virtual void InitOnFileThread();
60
61  // Performs stop operations that must be performed on the file thread.
62  virtual void StopOnFileThread();
63
64  // Schedules a reload task to run when |delay| expires. Must be called on the
65  // file thread.
66  void ScheduleReloadTask(const base::TimeDelta& delay);
67
68  // Schedules a reload task to run after the number of minutes specified
69  // in |reload_interval_minutes_|. Must be called on the file thread.
70  void ScheduleFallbackReloadTask();
71
72  void CancelReloadTask();
73
74  // Invoked from the reload task on the file thread.
75  void ReloadFromTask();
76
77 private:
78  friend class AsynchronousPolicyLoaderTest;
79
80  // Finishes loader initialization after the threading system has been fully
81  // intialized.
82  void InitAfterFileThreadAvailable();
83
84  // Replaces the existing policy to value map with a new one, sending
85  // notification to the observers if there is a policy change. Must be called
86  // on |origin_loop_| so that it's safe to call back into the provider, which
87  // is not thread-safe. Takes ownership of |new_policy|.
88  void UpdatePolicy(DictionaryValue* new_policy);
89
90  // Provides the low-level mechanics for loading policy.
91  scoped_ptr<AsynchronousPolicyProvider::Delegate> delegate_;
92
93  // Current policy.
94  scoped_ptr<DictionaryValue> policy_;
95
96  // The reload task. Access only on the file thread. Holds a reference to the
97  // currently posted task, so we can cancel and repost it if necessary.
98  CancelableTask* reload_task_;
99
100  // The interval at which a policy reload will be triggered as a fallback.
101  const base::TimeDelta  reload_interval_;
102
103  // The message loop on which this object was constructed. Recorded so that
104  // it's possible to call back into the non thread safe provider to fire the
105  // notification.
106  MessageLoop* origin_loop_;
107
108  // True if Stop has been called.
109  bool stopped_;
110
111  ObserverList<ConfigurationPolicyProvider::Observer, true> observer_list_;
112
113  DISALLOW_COPY_AND_ASSIGN(AsynchronousPolicyLoader);
114};
115
116}  // namespace policy
117
118#endif  // CHROME_BROWSER_POLICY_ASYNCHRONOUS_POLICY_LOADER_H_
119