summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjoaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-20 17:14:15 +0000
committerjoaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-20 17:14:15 +0000
commit80bfae1142d44fa37e51d9bec0610c3010796642 (patch)
tree2e7c1e6dfc789051c996fd9e2f3a879ac1d47452
parent68a31b1b3ed40a9146d45cd0e262a0d939275c48 (diff)
downloadchromium_src-80bfae1142d44fa37e51d9bec0610c3010796642.zip
chromium_src-80bfae1142d44fa37e51d9bec0610c3010796642.tar.gz
chromium_src-80bfae1142d44fa37e51d9bec0610c3010796642.tar.bz2
Decoupled the SchemaRegistryService from SchemaRegistry.
The service is not a SchemaRegistry anymore but owns one instead. This enables the service to own subclasses of SchemaRegistry. Also added a ForwardingSchemaRegisy, which wraps another SchemaRegistry. This will be used in a future CL. R=bartfab@chromium.org TBR=kalman@chromium.org BUG=224596 Review URL: https://codereview.chromium.org/349643002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@278735 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.cc3
-rw-r--r--chrome/browser/extensions/api/storage/managed_value_store_cache.cc6
-rw-r--r--chrome/browser/extensions/api/storage/settings_apitest.cc2
-rw-r--r--chrome/browser/policy/cloud/user_cloud_policy_manager_factory.cc3
-rw-r--r--chrome/browser/policy/profile_policy_connector_factory.cc3
-rw-r--r--chrome/browser/policy/schema_registry_service.cc25
-rw-r--r--chrome/browser/policy/schema_registry_service.h22
-rw-r--r--chrome/browser/policy/schema_registry_service_factory.cc9
-rw-r--r--chrome/browser/ui/webui/policy_ui.cc2
-rw-r--r--components/policy/core/common/schema_registry.cc92
-rw-r--r--components/policy/core/common/schema_registry.h57
-rw-r--r--components/policy/core/common/schema_registry_unittest.cc93
12 files changed, 236 insertions, 81 deletions
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.cc b/chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.cc
index ba317a7..6b0e11c 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.cc
@@ -209,7 +209,8 @@ scoped_ptr<UserCloudPolicyManagerChromeOS>
manager->EnableWildcardLoginCheck(username);
}
- manager->Init(SchemaRegistryServiceFactory::GetForContext(profile));
+ manager->Init(
+ SchemaRegistryServiceFactory::GetForContext(profile)->registry());
manager->Connect(g_browser_process->local_state(),
device_management_service,
g_browser_process->system_request_context(),
diff --git a/chrome/browser/extensions/api/storage/managed_value_store_cache.cc b/chrome/browser/extensions/api/storage/managed_value_store_cache.cc
index 92451c4..75387a9 100644
--- a/chrome/browser/extensions/api/storage/managed_value_store_cache.cc
+++ b/chrome/browser/extensions/api/storage/managed_value_store_cache.cc
@@ -107,8 +107,8 @@ class ManagedValueStoreCache::ExtensionTracker
ManagedValueStoreCache::ExtensionTracker::ExtensionTracker(Profile* profile)
: profile_(profile),
extension_registry_observer_(this),
- schema_registry_(
- policy::SchemaRegistryServiceFactory::GetForContext(profile)),
+ schema_registry_(policy::SchemaRegistryServiceFactory::GetForContext(
+ profile)->registry()),
weak_factory_(this) {
extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
// Load schemas when the extension system is ready. It might be ready now.
@@ -291,7 +291,7 @@ void ManagedValueStoreCache::OnPolicyServiceInitialized(
// The PolicyService now has all the initial policies ready. Send policy
// for all the managed extensions to their backing stores now.
policy::SchemaRegistry* registry =
- policy::SchemaRegistryServiceFactory::GetForContext(profile_);
+ policy::SchemaRegistryServiceFactory::GetForContext(profile_)->registry();
const policy::ComponentMap* map = registry->schema_map()->GetComponents(
policy::POLICY_DOMAIN_EXTENSIONS);
if (!map)
diff --git a/chrome/browser/extensions/api/storage/settings_apitest.cc b/chrome/browser/extensions/api/storage/settings_apitest.cc
index 7efa0c1..98a36fc 100644
--- a/chrome/browser/extensions/api/storage/settings_apitest.cc
+++ b/chrome/browser/extensions/api/storage/settings_apitest.cc
@@ -432,7 +432,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, ExtensionsSchemas) {
message_.clear();
policy::SchemaRegistry* registry =
- policy::SchemaRegistryServiceFactory::GetForContext(profile);
+ policy::SchemaRegistryServiceFactory::GetForContext(profile)->registry();
ASSERT_TRUE(registry);
EXPECT_FALSE(registry->schema_map()->GetSchema(policy::PolicyNamespace(
policy::POLICY_DOMAIN_EXTENSIONS, kManagedStorageExtensionId)));
diff --git a/chrome/browser/policy/cloud/user_cloud_policy_manager_factory.cc b/chrome/browser/policy/cloud/user_cloud_policy_manager_factory.cc
index 3f43c4b..f1e5c35 100644
--- a/chrome/browser/policy/cloud/user_cloud_policy_manager_factory.cc
+++ b/chrome/browser/policy/cloud/user_cloud_policy_manager_factory.cc
@@ -160,7 +160,8 @@ UserCloudPolicyManagerFactory::CreateManagerForOriginalBrowserContext(
base::MessageLoopProxy::current(),
file_task_runner,
io_task_runner));
- manager->Init(SchemaRegistryServiceFactory::GetForContext(context));
+ manager->Init(
+ SchemaRegistryServiceFactory::GetForContext(context)->registry());
manager_wrappers_[context] = new ManagerWrapper(manager.get());
return manager.Pass();
}
diff --git a/chrome/browser/policy/profile_policy_connector_factory.cc b/chrome/browser/policy/profile_policy_connector_factory.cc
index 8089a3d..5f21949 100644
--- a/chrome/browser/policy/profile_policy_connector_factory.cc
+++ b/chrome/browser/policy/profile_policy_connector_factory.cc
@@ -91,7 +91,8 @@ ProfilePolicyConnectorFactory::CreateForProfileInternal(
CloudPolicyManager* user_cloud_policy_manager = NULL;
#if defined(ENABLE_CONFIGURATION_POLICY)
- schema_registry = SchemaRegistryServiceFactory::GetForContext(profile);
+ schema_registry =
+ SchemaRegistryServiceFactory::GetForContext(profile)->registry();
#if defined(OS_CHROMEOS)
chromeos::User* user = NULL;
diff --git a/chrome/browser/policy/schema_registry_service.cc b/chrome/browser/policy/schema_registry_service.cc
index b8124cd..9cf2b49 100644
--- a/chrome/browser/policy/schema_registry_service.cc
+++ b/chrome/browser/policy/schema_registry_service.cc
@@ -4,31 +4,26 @@
#include "chrome/browser/policy/schema_registry_service.h"
-#include "base/logging.h"
#include "components/policy/core/common/policy_namespace.h"
#include "components/policy/core/common/schema.h"
+#include "components/policy/core/common/schema_registry.h"
namespace policy {
SchemaRegistryService::SchemaRegistryService(
+ scoped_ptr<SchemaRegistry> registry,
const Schema& chrome_schema,
CombinedSchemaRegistry* global_registry)
- : global_registry_(global_registry) {
- if (chrome_schema.valid())
- RegisterComponent(PolicyNamespace(POLICY_DOMAIN_CHROME, ""), chrome_schema);
- SetReady(POLICY_DOMAIN_CHROME);
- if (global_registry_)
- global_registry->Track(this);
+ : registry_(registry.Pass()) {
+ if (chrome_schema.valid()) {
+ registry_->RegisterComponent(PolicyNamespace(POLICY_DOMAIN_CHROME, ""),
+ chrome_schema);
+ }
+ registry_->SetReady(POLICY_DOMAIN_CHROME);
+ if (global_registry)
+ global_registry->Track(registry_.get());
}
SchemaRegistryService::~SchemaRegistryService() {}
-void SchemaRegistryService::Shutdown() {
- if (global_registry_) {
- global_registry_->Untrack(this);
- global_registry_ = NULL;
- }
- DCHECK(!HasObservers());
-}
-
} // namespace policy
diff --git a/chrome/browser/policy/schema_registry_service.h b/chrome/browser/policy/schema_registry_service.h
index ecf97d7..24beefc 100644
--- a/chrome/browser/policy/schema_registry_service.h
+++ b/chrome/browser/policy/schema_registry_service.h
@@ -6,30 +6,30 @@
#define CHROME_BROWSER_POLICY_SCHEMA_REGISTRY_SERVICE_H_
#include "base/basictypes.h"
-#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
#include "components/keyed_service/core/keyed_service.h"
-#include "components/policy/core/common/schema_registry.h"
namespace policy {
+class CombinedSchemaRegistry;
class Schema;
+class SchemaRegistry;
-// A SchemaRegistry that is also a KeyedService, and is associated
-// with a Profile.
-class SchemaRegistryService : public SchemaRegistry, public KeyedService {
+// A KeyedService associated with a Profile that contains a SchemaRegistry.
+class SchemaRegistryService : public KeyedService {
public:
- // This SchemaRegistry will initially contain only the |chrome_schema|, if
+ // This |registry| will initially contain only the |chrome_schema|, if
// it's valid. The optional |global_registry| must outlive this, and will
- // track this registry.
- SchemaRegistryService(const Schema& chrome_schema,
+ // track |registry|.
+ SchemaRegistryService(scoped_ptr<SchemaRegistry> registry,
+ const Schema& chrome_schema,
CombinedSchemaRegistry* global_registry);
virtual ~SchemaRegistryService();
- // KeyedService:
- virtual void Shutdown() OVERRIDE;
+ SchemaRegistry* registry() const { return registry_.get(); }
private:
- CombinedSchemaRegistry* global_registry_;
+ scoped_ptr<SchemaRegistry> registry_;
DISALLOW_COPY_AND_ASSIGN(SchemaRegistryService);
};
diff --git a/chrome/browser/policy/schema_registry_service_factory.cc b/chrome/browser/policy/schema_registry_service_factory.cc
index 71758ff..eaa5268 100644
--- a/chrome/browser/policy/schema_registry_service_factory.cc
+++ b/chrome/browser/policy/schema_registry_service_factory.cc
@@ -60,10 +60,11 @@ SchemaRegistryServiceFactory::CreateForContextInternal(
CombinedSchemaRegistry* global_registry) {
DCHECK(!context->IsOffTheRecord());
DCHECK(registries_.find(context) == registries_.end());
- SchemaRegistryService* registry =
- new SchemaRegistryService(chrome_schema, global_registry);
- registries_[context] = registry;
- return make_scoped_ptr(registry);
+ scoped_ptr<SchemaRegistry> registry(new SchemaRegistry);
+ scoped_ptr<SchemaRegistryService> service(new SchemaRegistryService(
+ registry.Pass(), chrome_schema, global_registry));
+ registries_[context] = service.get();
+ return service.Pass();
}
void SchemaRegistryServiceFactory::BrowserContextShutdown(
diff --git a/chrome/browser/ui/webui/policy_ui.cc b/chrome/browser/ui/webui/policy_ui.cc
index 15c0b98..b1f3c39 100644
--- a/chrome/browser/ui/webui/policy_ui.cc
+++ b/chrome/browser/ui/webui/policy_ui.cc
@@ -613,7 +613,7 @@ void PolicyUIHandler::SendPolicyNames() const {
Profile* profile = Profile::FromWebUI(web_ui());
policy::SchemaRegistry* registry =
policy::SchemaRegistryServiceFactory::GetForContext(
- profile->GetOriginalProfile());
+ profile->GetOriginalProfile())->registry();
scoped_refptr<policy::SchemaMap> schema_map = registry->schema_map();
// Add Chrome policy names.
diff --git a/components/policy/core/common/schema_registry.cc b/components/policy/core/common/schema_registry.cc
index ff95579..f3cb0ed 100644
--- a/components/policy/core/common/schema_registry.cc
+++ b/components/policy/core/common/schema_registry.cc
@@ -10,6 +10,8 @@ namespace policy {
SchemaRegistry::Observer::~Observer() {}
+SchemaRegistry::InternalObserver::~InternalObserver() {}
+
SchemaRegistry::SchemaRegistry() : schema_map_(new SchemaMap) {
for (int i = 0; i < POLICY_DOMAIN_SIZE; ++i)
domains_ready_[i] = false;
@@ -18,7 +20,11 @@ SchemaRegistry::SchemaRegistry() : schema_map_(new SchemaMap) {
#endif
}
-SchemaRegistry::~SchemaRegistry() {}
+SchemaRegistry::~SchemaRegistry() {
+ FOR_EACH_OBSERVER(InternalObserver,
+ internal_observers_,
+ OnSchemaRegistryShuttingDown(this));
+}
void SchemaRegistry::RegisterComponent(const PolicyNamespace& ns,
const Schema& schema) {
@@ -77,15 +83,19 @@ void SchemaRegistry::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
+void SchemaRegistry::AddInternalObserver(InternalObserver* observer) {
+ internal_observers_.AddObserver(observer);
+}
+
+void SchemaRegistry::RemoveInternalObserver(InternalObserver* observer) {
+ internal_observers_.RemoveObserver(observer);
+}
+
void SchemaRegistry::Notify(bool has_new_schemas) {
FOR_EACH_OBSERVER(
Observer, observers_, OnSchemaRegistryUpdated(has_new_schemas));
}
-bool SchemaRegistry::HasObservers() const {
- return observers_.might_have_observers();
-}
-
CombinedSchemaRegistry::CombinedSchemaRegistry()
: own_schema_map_(new SchemaMap) {
// The combined registry is always ready, since it can always start tracking
@@ -100,22 +110,13 @@ CombinedSchemaRegistry::~CombinedSchemaRegistry() {}
void CombinedSchemaRegistry::Track(SchemaRegistry* registry) {
registries_.insert(registry);
registry->AddObserver(this);
+ registry->AddInternalObserver(this);
// Recombine the maps only if the |registry| has any components other than
// POLICY_DOMAIN_CHROME.
if (registry->schema_map()->HasComponents())
Combine(true);
}
-void CombinedSchemaRegistry::Untrack(SchemaRegistry* registry) {
- registry->RemoveObserver(this);
- if (registries_.erase(registry) != 0) {
- if (registry->schema_map()->HasComponents())
- Combine(false);
- } else {
- NOTREACHED();
- }
-}
-
void CombinedSchemaRegistry::RegisterComponents(
PolicyDomain domain,
const ComponentMap& components) {
@@ -146,6 +147,18 @@ void CombinedSchemaRegistry::OnSchemaRegistryReady() {
// Ignore.
}
+void CombinedSchemaRegistry::OnSchemaRegistryShuttingDown(
+ SchemaRegistry* registry) {
+ registry->RemoveObserver(this);
+ registry->RemoveInternalObserver(this);
+ if (registries_.erase(registry) != 0) {
+ if (registry->schema_map()->HasComponents())
+ Combine(false);
+ } else {
+ NOTREACHED();
+ }
+}
+
void CombinedSchemaRegistry::Combine(bool has_new_schemas) {
// If two registries publish a Schema for the same component then it's
// undefined which version gets in the combined registry.
@@ -175,4 +188,53 @@ void CombinedSchemaRegistry::Combine(bool has_new_schemas) {
Notify(has_new_schemas);
}
+ForwardingSchemaRegistry::ForwardingSchemaRegistry(SchemaRegistry* wrapped)
+ : wrapped_(wrapped) {
+ schema_map_ = wrapped_->schema_map();
+ wrapped_->AddObserver(this);
+ wrapped_->AddInternalObserver(this);
+ // This registry is always ready.
+ for (int i = 0; i < POLICY_DOMAIN_SIZE; ++i)
+ SetReady(static_cast<PolicyDomain>(i));
+}
+
+ForwardingSchemaRegistry::~ForwardingSchemaRegistry() {
+ if (wrapped_) {
+ wrapped_->RemoveObserver(this);
+ wrapped_->RemoveInternalObserver(this);
+ }
+}
+
+void ForwardingSchemaRegistry::RegisterComponents(
+ PolicyDomain domain,
+ const ComponentMap& components) {
+ if (wrapped_)
+ wrapped_->RegisterComponents(domain, components);
+ // Ignore otherwise.
+}
+
+void ForwardingSchemaRegistry::UnregisterComponent(const PolicyNamespace& ns) {
+ if (wrapped_)
+ wrapped_->UnregisterComponent(ns);
+ // Ignore otherwise.
+}
+
+void ForwardingSchemaRegistry::OnSchemaRegistryUpdated(bool has_new_schemas) {
+ schema_map_ = wrapped_->schema_map();
+ Notify(has_new_schemas);
+}
+
+void ForwardingSchemaRegistry::OnSchemaRegistryReady() {
+ // Ignore.
+}
+
+void ForwardingSchemaRegistry::OnSchemaRegistryShuttingDown(
+ SchemaRegistry* registry) {
+ DCHECK_EQ(wrapped_, registry);
+ wrapped_->RemoveObserver(this);
+ wrapped_->RemoveInternalObserver(this);
+ wrapped_ = NULL;
+ // Keep serving the same |schema_map_|.
+}
+
} // namespace policy
diff --git a/components/policy/core/common/schema_registry.h b/components/policy/core/common/schema_registry.h
index b9f7fa8..6df4db2 100644
--- a/components/policy/core/common/schema_registry.h
+++ b/components/policy/core/common/schema_registry.h
@@ -43,6 +43,16 @@ class POLICY_EXPORT SchemaRegistry : public base::NonThreadSafe {
virtual ~Observer();
};
+ // This observer is only meant to be used by subclasses.
+ class POLICY_EXPORT InternalObserver {
+ public:
+ // Invoked when |registry| is about to be destroyed.
+ virtual void OnSchemaRegistryShuttingDown(SchemaRegistry* registry) = 0;
+
+ protected:
+ virtual ~InternalObserver();
+ };
+
SchemaRegistry();
virtual ~SchemaRegistry();
@@ -69,7 +79,8 @@ class POLICY_EXPORT SchemaRegistry : public base::NonThreadSafe {
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
- bool HasObservers() const;
+ void AddInternalObserver(InternalObserver* observer);
+ void RemoveInternalObserver(InternalObserver* observer);
protected:
void Notify(bool has_new_schemas);
@@ -78,30 +89,35 @@ class POLICY_EXPORT SchemaRegistry : public base::NonThreadSafe {
private:
ObserverList<Observer, true> observers_;
+ ObserverList<InternalObserver, true> internal_observers_;
bool domains_ready_[POLICY_DOMAIN_SIZE];
DISALLOW_COPY_AND_ASSIGN(SchemaRegistry);
};
// A registry that combines the maps of other registries.
-class POLICY_EXPORT CombinedSchemaRegistry : public SchemaRegistry,
- public SchemaRegistry::Observer {
+class POLICY_EXPORT CombinedSchemaRegistry
+ : public SchemaRegistry,
+ public SchemaRegistry::Observer,
+ public SchemaRegistry::InternalObserver {
public:
CombinedSchemaRegistry();
virtual ~CombinedSchemaRegistry();
void Track(SchemaRegistry* registry);
- void Untrack(SchemaRegistry* registry);
+ // SchemaRegistry:
virtual void RegisterComponents(PolicyDomain domain,
const ComponentMap& components) OVERRIDE;
-
virtual void UnregisterComponent(const PolicyNamespace& ns) OVERRIDE;
+ // SchemaRegistry::Observer:
virtual void OnSchemaRegistryUpdated(bool has_new_schemas) OVERRIDE;
-
virtual void OnSchemaRegistryReady() OVERRIDE;
+ // SchemaRegistry::InternalObserver:
+ virtual void OnSchemaRegistryShuttingDown(SchemaRegistry* registry) OVERRIDE;
+
private:
void Combine(bool has_new_schemas);
@@ -111,6 +127,35 @@ class POLICY_EXPORT CombinedSchemaRegistry : public SchemaRegistry,
DISALLOW_COPY_AND_ASSIGN(CombinedSchemaRegistry);
};
+// A registry that wraps another schema registry.
+class POLICY_EXPORT ForwardingSchemaRegistry
+ : public SchemaRegistry,
+ public SchemaRegistry::Observer,
+ public SchemaRegistry::InternalObserver {
+ public:
+ // This registry will stop updating its SchemaMap when |wrapped| is
+ // destroyed.
+ explicit ForwardingSchemaRegistry(SchemaRegistry* wrapped);
+ virtual ~ForwardingSchemaRegistry();
+
+ // SchemaRegistry:
+ virtual void RegisterComponents(PolicyDomain domain,
+ const ComponentMap& components) OVERRIDE;
+ virtual void UnregisterComponent(const PolicyNamespace& ns) OVERRIDE;
+
+ // SchemaRegistry::Observer:
+ virtual void OnSchemaRegistryUpdated(bool has_new_schemas) OVERRIDE;
+ virtual void OnSchemaRegistryReady() OVERRIDE;
+
+ // SchemaRegistry::InternalObserver:
+ virtual void OnSchemaRegistryShuttingDown(SchemaRegistry* registry) OVERRIDE;
+
+ private:
+ SchemaRegistry* wrapped_;
+
+ DISALLOW_COPY_AND_ASSIGN(ForwardingSchemaRegistry);
+};
+
} // namespace policy
#endif // COMPONENTS_POLICY_CORE_COMMON_SCHEMA_REGISTRY_H_
diff --git a/components/policy/core/common/schema_registry_unittest.cc b/components/policy/core/common/schema_registry_unittest.cc
index 36749ea..b3d6dae 100644
--- a/components/policy/core/common/schema_registry_unittest.cc
+++ b/components/policy/core/common/schema_registry_unittest.cc
@@ -4,6 +4,7 @@
#include "components/policy/core/common/schema_registry.h"
+#include "base/memory/scoped_ptr.h"
#include "components/policy/core/common/policy_namespace.h"
#include "components/policy/core/common/schema.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -48,6 +49,14 @@ class MockSchemaRegistryObserver : public SchemaRegistry::Observer {
MOCK_METHOD0(OnSchemaRegistryReady, void());
};
+bool SchemaMapEquals(const scoped_refptr<SchemaMap>& schema_map1,
+ const scoped_refptr<SchemaMap>& schema_map2) {
+ PolicyNamespaceList added;
+ PolicyNamespaceList removed;
+ schema_map1->GetChanges(schema_map2, &removed, &added);
+ return added.empty() && removed.empty();
+}
+
} // namespace
TEST(SchemaRegistryTest, Notifications) {
@@ -57,9 +66,7 @@ TEST(SchemaRegistryTest, Notifications) {
MockSchemaRegistryObserver observer;
SchemaRegistry registry;
- EXPECT_FALSE(registry.HasObservers());
registry.AddObserver(&observer);
- EXPECT_TRUE(registry.HasObservers());
ASSERT_TRUE(registry.schema_map());
EXPECT_FALSE(registry.schema_map()->GetSchema(
@@ -98,7 +105,6 @@ TEST(SchemaRegistryTest, Notifications) {
Mock::VerifyAndClearExpectations(&observer);
registry.RemoveObserver(&observer);
- EXPECT_FALSE(registry.HasObservers());
}
TEST(SchemaRegistryTest, IsReady) {
@@ -134,25 +140,25 @@ TEST(SchemaRegistryTest, Combined) {
ASSERT_TRUE(schema.valid()) << error;
MockSchemaRegistryObserver observer;
- SchemaRegistry registry1;
- SchemaRegistry registry2;
+ scoped_ptr<SchemaRegistry> registry1(new SchemaRegistry);
+ scoped_ptr<SchemaRegistry> registry2(new SchemaRegistry);
CombinedSchemaRegistry combined;
combined.AddObserver(&observer);
EXPECT_CALL(observer, OnSchemaRegistryUpdated(_)).Times(0);
- registry1.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"),
- schema);
+ registry1->RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"),
+ schema);
Mock::VerifyAndClearExpectations(&observer);
// Starting to track a registry issues notifications when it comes with new
// schemas.
EXPECT_CALL(observer, OnSchemaRegistryUpdated(true));
- combined.Track(&registry1);
+ combined.Track(registry1.get());
Mock::VerifyAndClearExpectations(&observer);
// Adding a new empty registry does not trigger notifications.
EXPECT_CALL(observer, OnSchemaRegistryUpdated(_)).Times(0);
- combined.Track(&registry2);
+ combined.Track(registry2.get());
Mock::VerifyAndClearExpectations(&observer);
// Adding the same component to the combined registry itself triggers
@@ -164,15 +170,15 @@ TEST(SchemaRegistryTest, Combined) {
// Adding components to the sub-registries triggers notifications.
EXPECT_CALL(observer, OnSchemaRegistryUpdated(true));
- registry2.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def"),
- schema);
+ registry2->RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def"),
+ schema);
Mock::VerifyAndClearExpectations(&observer);
// If the same component is published in 2 sub-registries then the combined
// registry publishes one of them.
EXPECT_CALL(observer, OnSchemaRegistryUpdated(true));
- registry1.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def"),
- schema);
+ registry1->RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def"),
+ schema);
Mock::VerifyAndClearExpectations(&observer);
ASSERT_EQ(1u, combined.schema_map()->GetDomains().size());
@@ -188,7 +194,7 @@ TEST(SchemaRegistryTest, Combined) {
PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "xyz")));
EXPECT_CALL(observer, OnSchemaRegistryUpdated(false));
- registry1.UnregisterComponent(
+ registry1->UnregisterComponent(
PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"));
Mock::VerifyAndClearExpectations(&observer);
// Still registered at the combined registry.
@@ -204,7 +210,7 @@ TEST(SchemaRegistryTest, Combined) {
PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc")));
EXPECT_CALL(observer, OnSchemaRegistryUpdated(false));
- registry1.UnregisterComponent(
+ registry1->UnregisterComponent(
PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def"));
Mock::VerifyAndClearExpectations(&observer);
// Still registered at registry2.
@@ -212,7 +218,7 @@ TEST(SchemaRegistryTest, Combined) {
PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def")));
EXPECT_CALL(observer, OnSchemaRegistryUpdated(false));
- registry2.UnregisterComponent(
+ registry2->UnregisterComponent(
PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def"));
Mock::VerifyAndClearExpectations(&observer);
// Now it's gone.
@@ -220,23 +226,66 @@ TEST(SchemaRegistryTest, Combined) {
PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def")));
EXPECT_CALL(observer, OnSchemaRegistryUpdated(true)).Times(2);
- registry1.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_CHROME, ""),
- schema);
- registry2.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "hij"),
- schema);
+ registry1->RegisterComponent(PolicyNamespace(POLICY_DOMAIN_CHROME, ""),
+ schema);
+ registry2->RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "hij"),
+ schema);
Mock::VerifyAndClearExpectations(&observer);
// Untracking |registry1| doesn't trigger an update notification, because it
// doesn't contain any components.
EXPECT_CALL(observer, OnSchemaRegistryUpdated(_)).Times(0);
- combined.Untrack(&registry1);
+ registry1.reset();
Mock::VerifyAndClearExpectations(&observer);
EXPECT_CALL(observer, OnSchemaRegistryUpdated(false));
- combined.Untrack(&registry2);
+ registry2.reset();
Mock::VerifyAndClearExpectations(&observer);
combined.RemoveObserver(&observer);
}
+TEST(SchemaRegistryTest, ForwardingSchemaRegistry) {
+ scoped_ptr<SchemaRegistry> registry(new SchemaRegistry);
+ ForwardingSchemaRegistry forwarding(registry.get());
+ MockSchemaRegistryObserver observer;
+ forwarding.AddObserver(&observer);
+
+ EXPECT_FALSE(registry->IsReady());
+ // The ForwardingSchemaRegistry is always ready, even if the wrapped registry
+ // isn't.
+ EXPECT_TRUE(forwarding.IsReady());
+ // But they alreday have the same SchemaMap.
+ EXPECT_TRUE(SchemaMapEquals(registry->schema_map(), forwarding.schema_map()));
+
+ EXPECT_CALL(observer, OnSchemaRegistryUpdated(true));
+ registry->RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"),
+ Schema());
+ Mock::VerifyAndClearExpectations(&observer);
+ EXPECT_TRUE(SchemaMapEquals(registry->schema_map(), forwarding.schema_map()));
+
+ EXPECT_CALL(observer, OnSchemaRegistryUpdated(false));
+ registry->UnregisterComponent(
+ PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"));
+ Mock::VerifyAndClearExpectations(&observer);
+ EXPECT_TRUE(SchemaMapEquals(registry->schema_map(), forwarding.schema_map()));
+
+ // No notifications expected for this call.
+ EXPECT_FALSE(registry->IsReady());
+ registry->SetReady(POLICY_DOMAIN_CHROME);
+ registry->SetReady(POLICY_DOMAIN_EXTENSIONS);
+ EXPECT_TRUE(registry->IsReady());
+ EXPECT_TRUE(SchemaMapEquals(registry->schema_map(), forwarding.schema_map()));
+ Mock::VerifyAndClearExpectations(&observer);
+
+ // Keep the same SchemaMap when the original registry is gone.
+ // No notifications are expected in this case either.
+ scoped_refptr<SchemaMap> schema_map = registry->schema_map();
+ registry.reset();
+ EXPECT_TRUE(SchemaMapEquals(schema_map, forwarding.schema_map()));
+ Mock::VerifyAndClearExpectations(&observer);
+
+ forwarding.RemoveObserver(&observer);
+}
+
} // namespace policy