1 // Copyright 2015 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 #include "components/policy/core/browser/browser_policy_connector_base.h"
6 
7 #include <stddef.h>
8 #include <utility>
9 #include <vector>
10 
11 #include "base/check.h"
12 #include "components/policy/core/common/chrome_schema.h"
13 #include "components/policy/core/common/configuration_policy_provider.h"
14 #include "components/policy/core/common/policy_namespace.h"
15 #include "components/policy/core/common/policy_service_impl.h"
16 #include "ui/base/resource/resource_bundle.h"
17 
18 namespace policy {
19 
20 namespace {
21 
22 // Used in BrowserPolicyConnectorBase::SetPolicyProviderForTesting.
23 bool g_created_policy_service = false;
24 ConfigurationPolicyProvider* g_testing_provider = nullptr;
25 
26 }  // namespace
27 
BrowserPolicyConnectorBase(const HandlerListFactory & handler_list_factory)28 BrowserPolicyConnectorBase::BrowserPolicyConnectorBase(
29     const HandlerListFactory& handler_list_factory) {
30   // GetPolicyService() must be ready after the constructor is done.
31   // The connector is created very early during startup, when the browser
32   // threads aren't running yet; initialize components that need local_state,
33   // the system request context or other threads (e.g. FILE) at
34   // SetPolicyProviders().
35 
36   // Initialize the SchemaRegistry with the Chrome schema before creating any
37   // of the policy providers in subclasses.
38   const Schema& chrome_schema = policy::GetChromeSchema();
39   handler_list_ = handler_list_factory.Run(chrome_schema);
40   schema_registry_.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_CHROME, ""),
41                                      chrome_schema);
42 }
43 
~BrowserPolicyConnectorBase()44 BrowserPolicyConnectorBase::~BrowserPolicyConnectorBase() {
45   if (is_initialized()) {
46     // Shutdown() wasn't invoked by our owner after having called
47     // SetPolicyProviders(). This usually means it's an early shutdown and
48     // BrowserProcessImpl::StartTearDown() wasn't invoked.
49     // Cleanup properly in those cases and avoid crashing the ToastCrasher test.
50     Shutdown();
51   }
52 }
53 
Shutdown()54 void BrowserPolicyConnectorBase::Shutdown() {
55   is_initialized_ = false;
56   if (g_testing_provider)
57     g_testing_provider->Shutdown();
58   for (const auto& provider : policy_providers_)
59     provider->Shutdown();
60   // Drop g_testing_provider so that tests executed with --single-process-tests
61   // can call SetPolicyProviderForTesting() again. It is still owned by the
62   // test.
63   g_testing_provider = nullptr;
64   g_created_policy_service = false;
65 }
66 
GetChromeSchema() const67 const Schema& BrowserPolicyConnectorBase::GetChromeSchema() const {
68   return policy::GetChromeSchema();
69 }
70 
GetSchemaRegistry()71 CombinedSchemaRegistry* BrowserPolicyConnectorBase::GetSchemaRegistry() {
72   return &schema_registry_;
73 }
74 
GetPolicyService()75 PolicyService* BrowserPolicyConnectorBase::GetPolicyService() {
76   if (policy_service_)
77     return policy_service_.get();
78 
79   DCHECK(!is_initialized_);
80   is_initialized_ = true;
81 
82   policy_providers_ = CreatePolicyProviders();
83 
84   if (g_testing_provider)
85     g_testing_provider->Init(GetSchemaRegistry());
86 
87   for (const auto& provider : policy_providers_)
88     provider->Init(GetSchemaRegistry());
89 
90   g_created_policy_service = true;
91   policy_service_ =
92       std::make_unique<PolicyServiceImpl>(GetProvidersForPolicyService());
93   return policy_service_.get();
94 }
95 
96 const ConfigurationPolicyHandlerList*
GetHandlerList() const97 BrowserPolicyConnectorBase::GetHandlerList() const {
98   return handler_list_.get();
99 }
100 
101 std::vector<ConfigurationPolicyProvider*>
GetPolicyProviders() const102 BrowserPolicyConnectorBase::GetPolicyProviders() const {
103   std::vector<ConfigurationPolicyProvider*> providers;
104   for (const auto& provider : policy_providers_)
105     providers.push_back(provider.get());
106 
107   return providers;
108 }
109 
110 // static
SetPolicyProviderForTesting(ConfigurationPolicyProvider * provider)111 void BrowserPolicyConnectorBase::SetPolicyProviderForTesting(
112     ConfigurationPolicyProvider* provider) {
113   // If this function is used by a test then it must be called before the
114   // browser is created, and GetPolicyService() gets called.
115   CHECK(!g_created_policy_service);
116   g_testing_provider = provider;
117 }
118 
NotifyWhenResourceBundleReady(base::OnceClosure closure)119 void BrowserPolicyConnectorBase::NotifyWhenResourceBundleReady(
120     base::OnceClosure closure) {
121   DCHECK(!ui::ResourceBundle::HasSharedInstance());
122   resource_bundle_callbacks_.push_back(std::move(closure));
123 }
124 
125 // static
126 ConfigurationPolicyProvider*
GetPolicyProviderForTesting()127 BrowserPolicyConnectorBase::GetPolicyProviderForTesting() {
128   return g_testing_provider;
129 }
130 
131 std::vector<ConfigurationPolicyProvider*>
GetProvidersForPolicyService()132 BrowserPolicyConnectorBase::GetProvidersForPolicyService() {
133   std::vector<ConfigurationPolicyProvider*> providers;
134   if (g_testing_provider) {
135     providers.push_back(g_testing_provider);
136     return providers;
137   }
138   providers.reserve(policy_providers_.size());
139   for (const auto& policy : policy_providers_)
140     providers.push_back(policy.get());
141   return providers;
142 }
143 
144 std::vector<std::unique_ptr<ConfigurationPolicyProvider>>
CreatePolicyProviders()145 BrowserPolicyConnectorBase::CreatePolicyProviders() {
146   return {};
147 }
148 
OnResourceBundleCreated()149 void BrowserPolicyConnectorBase::OnResourceBundleCreated() {
150   std::vector<base::OnceClosure> resource_bundle_callbacks;
151   std::swap(resource_bundle_callbacks, resource_bundle_callbacks_);
152   for (auto& closure : resource_bundle_callbacks)
153     std::move(closure).Run();
154 }
155 
156 }  // namespace policy
157