Home | History | Annotate | Download | only in common
      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/basictypes.h"
     11 #include "base/compiler_specific.h"
     12 #include "base/memory/ref_counted.h"
     13 #include "base/observer_list.h"
     14 #include "base/threading/non_thread_safe.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 : public base::NonThreadSafe {
     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.
     40     virtual void OnSchemaRegistryReady() = 0;
     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 
     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 SetReady(PolicyDomain domain);
     78 
     79   void AddObserver(Observer* observer);
     80   void RemoveObserver(Observer* observer);
     81 
     82   void AddInternalObserver(InternalObserver* observer);
     83   void RemoveInternalObserver(InternalObserver* observer);
     84 
     85  protected:
     86   void Notify(bool has_new_schemas);
     87 
     88   scoped_refptr<SchemaMap> schema_map_;
     89 
     90  private:
     91   ObserverList<Observer, true> observers_;
     92   ObserverList<InternalObserver, true> internal_observers_;
     93   bool domains_ready_[POLICY_DOMAIN_SIZE];
     94 
     95   DISALLOW_COPY_AND_ASSIGN(SchemaRegistry);
     96 };
     97 
     98 // A registry that combines the maps of other registries.
     99 class POLICY_EXPORT CombinedSchemaRegistry
    100     : public SchemaRegistry,
    101       public SchemaRegistry::Observer,
    102       public SchemaRegistry::InternalObserver {
    103  public:
    104   CombinedSchemaRegistry();
    105   virtual ~CombinedSchemaRegistry();
    106 
    107   void Track(SchemaRegistry* registry);
    108 
    109   // SchemaRegistry:
    110   virtual void RegisterComponents(PolicyDomain domain,
    111                                   const ComponentMap& components) OVERRIDE;
    112   virtual void UnregisterComponent(const PolicyNamespace& ns) OVERRIDE;
    113 
    114   // SchemaRegistry::Observer:
    115   virtual void OnSchemaRegistryUpdated(bool has_new_schemas) OVERRIDE;
    116   virtual void OnSchemaRegistryReady() OVERRIDE;
    117 
    118   // SchemaRegistry::InternalObserver:
    119   virtual void OnSchemaRegistryShuttingDown(SchemaRegistry* registry) OVERRIDE;
    120 
    121  private:
    122   void Combine(bool has_new_schemas);
    123 
    124   std::set<SchemaRegistry*> registries_;
    125   scoped_refptr<SchemaMap> own_schema_map_;
    126 
    127   DISALLOW_COPY_AND_ASSIGN(CombinedSchemaRegistry);
    128 };
    129 
    130 // A registry that wraps another schema registry.
    131 class POLICY_EXPORT ForwardingSchemaRegistry
    132     : public SchemaRegistry,
    133       public SchemaRegistry::Observer,
    134       public SchemaRegistry::InternalObserver {
    135  public:
    136   // This registry will stop updating its SchemaMap when |wrapped| is
    137   // destroyed.
    138   explicit ForwardingSchemaRegistry(SchemaRegistry* wrapped);
    139   virtual ~ForwardingSchemaRegistry();
    140 
    141   // SchemaRegistry:
    142   virtual void RegisterComponents(PolicyDomain domain,
    143                                   const ComponentMap& components) OVERRIDE;
    144   virtual void UnregisterComponent(const PolicyNamespace& ns) OVERRIDE;
    145 
    146   // SchemaRegistry::Observer:
    147   virtual void OnSchemaRegistryUpdated(bool has_new_schemas) OVERRIDE;
    148   virtual void OnSchemaRegistryReady() OVERRIDE;
    149 
    150   // SchemaRegistry::InternalObserver:
    151   virtual void OnSchemaRegistryShuttingDown(SchemaRegistry* registry) OVERRIDE;
    152 
    153  private:
    154   SchemaRegistry* wrapped_;
    155 
    156   DISALLOW_COPY_AND_ASSIGN(ForwardingSchemaRegistry);
    157 };
    158 
    159 }  // namespace policy
    160 
    161 #endif  // COMPONENTS_POLICY_CORE_COMMON_SCHEMA_REGISTRY_H_
    162