1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifndef COMPONENTS_POLICY_CORE_COMMON_SCHEMA_REGISTRY_H_
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define COMPONENTS_POLICY_CORE_COMMON_SCHEMA_REGISTRY_H_
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <set>
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/basictypes.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/compiler_specific.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/memory/ref_counted.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/observer_list.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/threading/non_thread_safe.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_namespace.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/schema.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/schema_map.h"
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/policy_export.h"
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace policy {
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class SchemaMap;
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Holds the main reference to the current SchemaMap, and allows a list of
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// observers to get notified whenever it is updated.
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// This object is not thread safe and must be used from the owner's thread,
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// usually UI.
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class POLICY_EXPORT SchemaRegistry : public base::NonThreadSafe {
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  class POLICY_EXPORT Observer {
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   public:
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Invoked whenever schemas are registered or unregistered.
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // |has_new_schemas| is true if a new component has been registered since
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // the last update; this allows observers to ignore updates when
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // components are unregistered but still get a handle to the current map
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // (e.g. for periodic reloads).
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    virtual void OnSchemaRegistryUpdated(bool has_new_schemas) = 0;
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Invoked when all policy domains become ready.
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    virtual void OnSchemaRegistryReady() = 0;
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   protected:
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    virtual ~Observer();
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  };
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // This observer is only meant to be used by subclasses.
476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  class POLICY_EXPORT InternalObserver {
486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)   public:
496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Invoked when |registry| is about to be destroyed.
506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    virtual void OnSchemaRegistryShuttingDown(SchemaRegistry* registry) = 0;
516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)   protected:
536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    virtual ~InternalObserver();
546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  };
556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SchemaRegistry();
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~SchemaRegistry();
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const scoped_refptr<SchemaMap>& schema_map() const { return schema_map_; }
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Register a single component.
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void RegisterComponent(const PolicyNamespace& ns,
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         const Schema& schema);
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Register a list of components for a given domain.
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void RegisterComponents(PolicyDomain domain,
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  const ComponentMap& components);
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void UnregisterComponent(const PolicyNamespace& ns);
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Returns true if all domains have registered the initial components.
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool IsReady() const;
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // This indicates that the initial components for |domain| have all been
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // registered. It must be invoked at least once for each policy domain;
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // subsequent calls for the same domain are ignored.
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void SetReady(PolicyDomain domain);
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void AddObserver(Observer* observer);
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void RemoveObserver(Observer* observer);
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  void AddInternalObserver(InternalObserver* observer);
836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  void RemoveInternalObserver(InternalObserver* observer);
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) protected:
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Notify(bool has_new_schemas);
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<SchemaMap> schema_map_;
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ObserverList<Observer, true> observers_;
926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ObserverList<InternalObserver, true> internal_observers_;
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool domains_ready_[POLICY_DOMAIN_SIZE];
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SchemaRegistry);
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// A registry that combines the maps of other registries.
996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)class POLICY_EXPORT CombinedSchemaRegistry
1006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    : public SchemaRegistry,
1016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      public SchemaRegistry::Observer,
1026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      public SchemaRegistry::InternalObserver {
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CombinedSchemaRegistry();
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~CombinedSchemaRegistry();
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Track(SchemaRegistry* registry);
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // SchemaRegistry:
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void RegisterComponents(PolicyDomain domain,
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  const ComponentMap& components) OVERRIDE;
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void UnregisterComponent(const PolicyNamespace& ns) OVERRIDE;
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // SchemaRegistry::Observer:
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void OnSchemaRegistryUpdated(bool has_new_schemas) OVERRIDE;
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void OnSchemaRegistryReady() OVERRIDE;
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // SchemaRegistry::InternalObserver:
1196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  virtual void OnSchemaRegistryShuttingDown(SchemaRegistry* registry) OVERRIDE;
1206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Combine(bool has_new_schemas);
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::set<SchemaRegistry*> registries_;
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<SchemaMap> own_schema_map_;
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CombinedSchemaRegistry);
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// A registry that wraps another schema registry.
1316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)class POLICY_EXPORT ForwardingSchemaRegistry
1326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    : public SchemaRegistry,
1336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      public SchemaRegistry::Observer,
1346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      public SchemaRegistry::InternalObserver {
1356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) public:
1366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // This registry will stop updating its SchemaMap when |wrapped| is
1376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // destroyed.
1386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  explicit ForwardingSchemaRegistry(SchemaRegistry* wrapped);
1396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  virtual ~ForwardingSchemaRegistry();
1406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // SchemaRegistry:
1426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  virtual void RegisterComponents(PolicyDomain domain,
1436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                  const ComponentMap& components) OVERRIDE;
1446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  virtual void UnregisterComponent(const PolicyNamespace& ns) OVERRIDE;
1456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // SchemaRegistry::Observer:
1476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  virtual void OnSchemaRegistryUpdated(bool has_new_schemas) OVERRIDE;
1486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  virtual void OnSchemaRegistryReady() OVERRIDE;
1496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // SchemaRegistry::InternalObserver:
1516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  virtual void OnSchemaRegistryShuttingDown(SchemaRegistry* registry) OVERRIDE;
1526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) private:
1546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  SchemaRegistry* wrapped_;
1556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ForwardingSchemaRegistry);
1576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
1586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace policy
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif  // COMPONENTS_POLICY_CORE_COMMON_SCHEMA_REGISTRY_H_
162