| // Copyright 2014 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ash/policy/enrollment/device_cloud_policy_initializer.h" |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "base/functional/bind.h" |
| #include "base/logging.h" |
| #include "chrome/browser/ash/policy/core/device_cloud_policy_client_factory_ash.h" |
| #include "chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.h" |
| #include "chrome/browser/ash/policy/core/device_cloud_policy_store_ash.h" |
| #include "chrome/browser/ash/policy/enrollment/auto_enrollment_type_checker.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/net/system_network_context_manager.h" |
| #include "chrome/common/chrome_content_client.h" |
| #include "chromeos/ash/components/cryptohome/cryptohome_parameters.h" |
| #include "chromeos/ash/components/install_attributes/install_attributes.h" |
| #include "chromeos/ash/components/system/statistics_provider.h" |
| #include "components/policy/core/common/cloud/cloud_policy_client.h" |
| #include "components/policy/core/common/cloud/cloud_policy_core.h" |
| #include "components/policy/core/common/cloud/device_management_service.h" |
| |
| namespace policy { |
| |
| DeviceCloudPolicyInitializer::DeviceCloudPolicyInitializer( |
| DeviceManagementService* enterprise_service, |
| ash::InstallAttributes* install_attributes, |
| ServerBackedStateKeysBroker* state_keys_broker, |
| DeviceCloudPolicyStoreAsh* policy_store, |
| DeviceCloudPolicyManagerAsh* policy_manager, |
| ash::system::StatisticsProvider* statistics_provider) |
| : enterprise_service_(enterprise_service), |
| install_attributes_(install_attributes), |
| state_keys_broker_(state_keys_broker), |
| policy_store_(policy_store), |
| policy_manager_(policy_manager), |
| statistics_provider_(statistics_provider) {} |
| |
| void DeviceCloudPolicyInitializer::SetSystemURLLoaderFactoryForTesting( |
| scoped_refptr<network::SharedURLLoaderFactory> system_url_loader_factory) { |
| system_url_loader_factory_for_testing_ = system_url_loader_factory; |
| } |
| |
| DeviceCloudPolicyInitializer::~DeviceCloudPolicyInitializer() { |
| DCHECK(!is_initialized_); |
| } |
| |
| void DeviceCloudPolicyInitializer::Init() { |
| DCHECK(!is_initialized_); |
| |
| is_initialized_ = true; |
| |
| policy_store_->AddObserver(this); |
| policy_manager_observer_.Observe(policy_manager_.get()); |
| |
| // If state keys are supported but not available, we need to obtain them |
| // before proceeding. |
| // Background: `DeviceCloudPolicyManagerAsh::StartConnection` expects state |
| // keys to be present if they are supported). |
| if (AutoEnrollmentTypeChecker::AreFREStateKeysSupported() && |
| !state_keys_broker_->available()) { |
| state_keys_update_subscription_ = |
| state_keys_broker_->RegisterUpdateCallback(base::BindRepeating( |
| &DeviceCloudPolicyInitializer::TryToStartConnection, |
| base::Unretained(this))); |
| return; |
| } |
| |
| TryToStartConnection(); |
| } |
| |
| void DeviceCloudPolicyInitializer::Shutdown() { |
| DCHECK(is_initialized_); |
| |
| policy_store_->RemoveObserver(this); |
| state_keys_update_subscription_ = {}; |
| policy_manager_observer_.Reset(); |
| is_initialized_ = false; |
| } |
| |
| void DeviceCloudPolicyInitializer::OnStoreLoaded(CloudPolicyStore* store) { |
| TryToStartConnection(); |
| } |
| |
| void DeviceCloudPolicyInitializer::OnStoreError(CloudPolicyStore* store) { |
| // Do nothing. |
| } |
| |
| void DeviceCloudPolicyInitializer::OnDeviceCloudPolicyManagerConnected() { |
| // Do nothing. |
| } |
| void DeviceCloudPolicyInitializer::OnDeviceCloudPolicyManagerGotRegistry() { |
| // `policy_manager_->HasSchemaRegistry()` is one of requirements for |
| // StartConnection. Make another attempt when `policy_manager_` gets its |
| // registry. |
| policy_manager_observer_.Reset(); |
| TryToStartConnection(); |
| } |
| |
| std::unique_ptr<CloudPolicyClient> DeviceCloudPolicyInitializer::CreateClient( |
| DeviceManagementService* device_management_service) { |
| // DeviceDMToken callback is empty here because for device policies this |
| // DMToken is already provided in the policy fetch requests. |
| return CreateDeviceCloudPolicyClientAsh( |
| statistics_provider_, device_management_service, |
| system_url_loader_factory_for_testing_ |
| ? system_url_loader_factory_for_testing_ |
| : g_browser_process->shared_url_loader_factory(), |
| CloudPolicyClient::DeviceDMTokenCallback()); |
| } |
| |
| void DeviceCloudPolicyInitializer::TryToStartConnection() { |
| if (!policy_store_->is_initialized() || !policy_store_->has_policy()) { |
| return; |
| } |
| |
| if (!policy_manager_store_ready_notified_) { |
| policy_manager_store_ready_notified_ = true; |
| policy_manager_->OnPolicyStoreReady(install_attributes_); |
| } |
| |
| if (!policy_manager_->HasSchemaRegistry()) { |
| // crbug.com/1295871: `policy_manager_` might not have schema registry on |
| // start connection attempt. This may happen on chrome restart when |
| // `chrome::kInitialProfile` is created after login profile: policy will be |
| // loaded but `BuildSchemaRegistryServiceForProfile` will not be called for |
| // non-initial / non-sign-in profile. |
| return; |
| } |
| |
| if (state_keys_broker_->available() || |
| !AutoEnrollmentTypeChecker::AreFREStateKeysSupported()) { |
| StartConnection(CreateClient(enterprise_service_)); |
| } |
| } |
| |
| void DeviceCloudPolicyInitializer::StartConnection( |
| std::unique_ptr<CloudPolicyClient> client) { |
| // This initializer will be deleted once `policy_manager_` is connected. |
| // Stop observing the manager as there's nothing interesting it can say |
| // anymore. |
| policy_manager_observer_.Reset(); |
| |
| if (!policy_manager_->IsConnected()) { |
| policy_manager_->StartConnection(std::move(client), install_attributes_); |
| } |
| } |
| |
| } // namespace policy |