1 // Copyright 2015 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.
5 #ifndef REMOTING_HOST_POLICY_WATCHER_H_
6 #define REMOTING_HOST_POLICY_WATCHER_H_
8 #include "base/callback.h"
9 #include "base/macros.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/threading/non_thread_safe.h"
13 #include "components/policy/core/common/policy_service.h"
16 class DictionaryValue
;
17 class SingleThreadTaskRunner
;
21 class AsyncPolicyLoader
;
22 class ConfigurationPolicyProvider
;
28 // Watches for changes to the managed remote access host policies.
29 class PolicyWatcher
: public policy::PolicyService::Observer
,
30 public base::NonThreadSafe
{
32 // Called first with all policies, and subsequently with any changed policies.
33 typedef base::Callback
<void(scoped_ptr
<base::DictionaryValue
>)>
34 PolicyUpdatedCallback
;
36 // TODO(lukasza): PolicyErrorCallback never gets called by PolicyWatcher.
37 // Need to either 1) remove error-handling from PolicyWatcher or 2) add
38 // error-handling around PolicyService 2a) Add policy name/type validation via
39 // policy::Schema::Normalize. 2b) Consider exposing parsing errors from
40 // policy::ConfigDirPolicyLoader.
42 // Called after detecting malformed policies.
43 typedef base::Callback
<void()> PolicyErrorCallback
;
45 ~PolicyWatcher() override
;
47 // This guarantees that the |policy_updated_callback| is called at least once
48 // with the current policies. After that, |policy_updated_callback| will be
49 // called whenever a change to any policy is detected. It will then be called
50 // only with the changed policies.
52 // |policy_error_callback| will be called when malformed policies are detected
53 // (i.e. wrong type of policy value, or unparseable files under
54 // /etc/opt/chrome/policies/managed).
55 // When called, the |policy_error_callback| is responsible for mitigating the
56 // security risk of running with incorrectly formulated policies (by either
57 // shutting down or locking down the host).
58 // After calling |policy_error_callback| PolicyWatcher will continue watching
59 // for policy changes and will call |policy_updated_callback| when the error
60 // is recovered from and may call |policy_error_callback| when new errors are
62 virtual void StartWatching(
63 const PolicyUpdatedCallback
& policy_updated_callback
,
64 const PolicyErrorCallback
& policy_error_callback
);
66 // Specify a |policy_service| to borrow (on Chrome OS, from the browser
67 // process) or specify nullptr to internally construct and use a new
68 // PolicyService (on other OS-es). PolicyWatcher must be used on the thread on
69 // which it is created. |policy_service| is called on the same thread.
71 // When |policy_service| is null, then |file_task_runner| is used for reading
72 // the policy from files / registry / preferences (which are blocking
73 // operations). |file_task_runner| should be of TYPE_IO type.
75 // When |policy_service| is specified then |file_task_runner| argument is
76 // ignored and 1) BrowserThread::UI is used for PolicyUpdatedCallback and
77 // PolicyErrorCallback and 2) BrowserThread::FILE is used for reading the
78 // policy from files / registry / preferences (although (2) is just an
79 // implementation detail and should likely be ignored outside of
81 static scoped_ptr
<PolicyWatcher
> Create(
82 policy::PolicyService
* policy_service
,
83 const scoped_refptr
<base::SingleThreadTaskRunner
>& file_task_runner
);
86 friend class PolicyWatcherTest
;
88 // Takes the policy dictionary from the OS specific store and extracts the
90 void UpdatePolicies(const base::DictionaryValue
* new_policy
);
92 // Signals policy error to the registered |PolicyErrorCallback|.
93 void SignalPolicyError();
95 // Called whenever a transient error occurs during reading of policy files.
96 // This will increment a counter, and will trigger a call to
97 // SignalPolicyError() only after a threshold count is reached.
98 // The counter is reset whenever policy has been successfully read.
99 void SignalTransientPolicyError();
101 // |policy_service_task_runner| is the task runner where it is safe
102 // to call |policy_service_| methods and where we expect to get callbacks
103 // from |policy_service_|.
105 policy::PolicyService
* policy_service
,
106 scoped_ptr
<policy::PolicyService
> owned_policy_service
,
107 scoped_ptr
<policy::ConfigurationPolicyProvider
> owned_policy_provider
,
108 scoped_ptr
<policy::SchemaRegistry
> owned_schema_registry
);
110 // Creates PolicyWatcher that wraps the owned |async_policy_loader| with an
111 // appropriate PolicySchema.
113 // |policy_service_task_runner| is passed through to the constructor of
115 static scoped_ptr
<PolicyWatcher
> CreateFromPolicyLoader(
116 scoped_ptr
<policy::AsyncPolicyLoader
> async_policy_loader
);
118 // PolicyService::Observer interface.
119 void OnPolicyUpdated(const policy::PolicyNamespace
& ns
,
120 const policy::PolicyMap
& previous
,
121 const policy::PolicyMap
& current
) override
;
122 void OnPolicyServiceInitialized(policy::PolicyDomain domain
) override
;
124 PolicyUpdatedCallback policy_updated_callback_
;
125 PolicyErrorCallback policy_error_callback_
;
126 int transient_policy_error_retry_counter_
;
128 scoped_ptr
<base::DictionaryValue
> old_policies_
;
129 scoped_ptr
<base::DictionaryValue
> default_values_
;
130 scoped_ptr
<base::DictionaryValue
> bad_type_values_
;
132 policy::PolicyService
* policy_service_
;
134 // Order of fields below is important to ensure destruction takes object
135 // dependencies into account:
136 // - |owned_policy_service_| uses |owned_policy_provider_|
137 // - |owned_policy_provider_| uses |owned_schema_registry_|
138 scoped_ptr
<policy::SchemaRegistry
> owned_schema_registry_
;
139 scoped_ptr
<policy::ConfigurationPolicyProvider
> owned_policy_provider_
;
140 scoped_ptr
<policy::PolicyService
> owned_policy_service_
;
142 DISALLOW_COPY_AND_ASSIGN(PolicyWatcher
);
145 } // namespace remoting
147 #endif // REMOTING_HOST_POLICY_WATCHER_H_