• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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 COMPONENTS_POLICY_CORE_COMMON_SCHEMA_REGISTRY_H_
6 #define COMPONENTS_POLICY_CORE_COMMON_SCHEMA_REGISTRY_H_
7 
8 #include <set>
9 
10 #include "base/compiler_specific.h"
11 #include "base/macros.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/observer_list.h"
14 #include "base/sequence_checker.h"
15 #include "components/policy/core/common/policy_namespace.h"
16 #include "components/policy/core/common/schema.h"
17 #include "components/policy/core/common/schema_map.h"
18 #include "components/policy/policy_export.h"
19 
20 namespace policy {
21 
22 class SchemaMap;
23 
24 // Holds the main reference to the current SchemaMap, and allows a list of
25 // observers to get notified whenever it is updated.
26 // This object is not thread safe and must be used from the owner's thread,
27 // usually UI.
28 class POLICY_EXPORT SchemaRegistry {
29  public:
30   class POLICY_EXPORT Observer {
31    public:
32     // Invoked whenever schemas are registered or unregistered.
33     // |has_new_schemas| is true if a new component has been registered since
34     // the last update; this allows observers to ignore updates when
35     // components are unregistered but still get a handle to the current map
36     // (e.g. for periodic reloads).
37     virtual void OnSchemaRegistryUpdated(bool has_new_schemas) = 0;
38 
39     // Invoked when all policy domains become ready.
OnSchemaRegistryReady()40     virtual void OnSchemaRegistryReady() {}
41 
42    protected:
43     virtual ~Observer();
44   };
45 
46   // This observer is only meant to be used by subclasses.
47   class POLICY_EXPORT InternalObserver {
48    public:
49     // Invoked when |registry| is about to be destroyed.
50     virtual void OnSchemaRegistryShuttingDown(SchemaRegistry* registry) = 0;
51 
52    protected:
53     virtual ~InternalObserver();
54   };
55 
56   SchemaRegistry();
57   virtual ~SchemaRegistry();
58 
schema_map()59   const scoped_refptr<SchemaMap>& schema_map() const { return schema_map_; }
60 
61   // Register a single component.
62   void RegisterComponent(const PolicyNamespace& ns,
63                          const Schema& schema);
64 
65   // Register a list of components for a given domain.
66   virtual void RegisterComponents(PolicyDomain domain,
67                                   const ComponentMap& components);
68 
69   virtual void UnregisterComponent(const PolicyNamespace& ns);
70 
71   // Returns true if all domains have registered the initial components.
72   bool IsReady() const;
73 
74   // This indicates that the initial components for |domain| have all been
75   // registered. It must be invoked at least once for each policy domain;
76   // subsequent calls for the same domain are ignored.
77   void SetDomainReady(PolicyDomain domain);
78   // This is equivalent to calling |SetDomainReady| with each of the policy
79   // domains.
80   void SetAllDomainsReady();
81   // This is equivalent to calling |SetDomainReady| with each of the domains
82   // that correspond to policy for extensions.
83   void SetExtensionsDomainsReady();
84 
85   void AddObserver(Observer* observer);
86   void RemoveObserver(Observer* observer);
87 
88   void AddInternalObserver(InternalObserver* observer);
89   void RemoveInternalObserver(InternalObserver* observer);
90 
91  protected:
92   void Notify(bool has_new_schemas);
93 
94   SEQUENCE_CHECKER(sequence_checker_);
95 
96   scoped_refptr<SchemaMap> schema_map_;
97 
98  private:
99   base::ObserverList<Observer, true> observers_;
100   base::ObserverList<InternalObserver, true> internal_observers_;
101   bool domains_ready_[POLICY_DOMAIN_SIZE];
102 
103   DISALLOW_COPY_AND_ASSIGN(SchemaRegistry);
104 };
105 
106 // A registry that combines the maps of other registries.
107 class POLICY_EXPORT CombinedSchemaRegistry
108     : public SchemaRegistry,
109       public SchemaRegistry::Observer,
110       public SchemaRegistry::InternalObserver {
111  public:
112   CombinedSchemaRegistry();
113   ~CombinedSchemaRegistry() override;
114 
115   void Track(SchemaRegistry* registry);
116 
117   // SchemaRegistry:
118   void RegisterComponents(PolicyDomain domain,
119                           const ComponentMap& components) override;
120   void UnregisterComponent(const PolicyNamespace& ns) override;
121 
122   // SchemaRegistry::Observer:
123   void OnSchemaRegistryUpdated(bool has_new_schemas) override;
124 
125   // SchemaRegistry::InternalObserver:
126   void OnSchemaRegistryShuttingDown(SchemaRegistry* registry) override;
127 
128  private:
129   void Combine(bool has_new_schemas);
130 
131   std::set<SchemaRegistry*> registries_;
132   scoped_refptr<SchemaMap> own_schema_map_;
133 
134   DISALLOW_COPY_AND_ASSIGN(CombinedSchemaRegistry);
135 };
136 
137 // A registry that wraps another schema registry.
138 class POLICY_EXPORT ForwardingSchemaRegistry
139     : public SchemaRegistry,
140       public SchemaRegistry::Observer,
141       public SchemaRegistry::InternalObserver {
142  public:
143   // This registry will stop updating its SchemaMap when |wrapped| is
144   // destroyed.
145   explicit ForwardingSchemaRegistry(SchemaRegistry* wrapped);
146   ~ForwardingSchemaRegistry() override;
147 
148   // SchemaRegistry:
149   void RegisterComponents(PolicyDomain domain,
150                           const ComponentMap& components) override;
151   void UnregisterComponent(const PolicyNamespace& ns) override;
152 
153   // SchemaRegistry::Observer:
154   void OnSchemaRegistryUpdated(bool has_new_schemas) override;
155   void OnSchemaRegistryReady() override;
156 
157   // SchemaRegistry::InternalObserver:
158   void OnSchemaRegistryShuttingDown(SchemaRegistry* registry) override;
159 
160  private:
161   void UpdateReadiness();
162 
163   SchemaRegistry* wrapped_;
164 
165   DISALLOW_COPY_AND_ASSIGN(ForwardingSchemaRegistry);
166 };
167 
168 }  // namespace policy
169 
170 #endif  // COMPONENTS_POLICY_CORE_COMMON_SCHEMA_REGISTRY_H_
171