diff options
author | joaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-20 17:14:15 +0000 |
---|---|---|
committer | joaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-20 17:14:15 +0000 |
commit | 80bfae1142d44fa37e51d9bec0610c3010796642 (patch) | |
tree | 2e7c1e6dfc789051c996fd9e2f3a879ac1d47452 | |
parent | 68a31b1b3ed40a9146d45cd0e262a0d939275c48 (diff) | |
download | chromium_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
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(®istry1); + combined.Track(registry1.get()); Mock::VerifyAndClearExpectations(&observer); // Adding a new empty registry does not trigger notifications. EXPECT_CALL(observer, OnSchemaRegistryUpdated(_)).Times(0); - combined.Track(®istry2); + 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(®istry1); + registry1.reset(); Mock::VerifyAndClearExpectations(&observer); EXPECT_CALL(observer, OnSchemaRegistryUpdated(false)); - combined.Untrack(®istry2); + 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 |