#include "chrome/browser/policy/profile_policy_connector.h"
#include <memory>
#include <optional>
#include <utility>
#include "base/check.h"
#include "base/check_op.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/ranges/algorithm.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_switcher/browser_switcher_policy_migrator.h"
#include "chrome/browser/enterprise/util/affiliation.h"
#include "chrome/browser/infobars/simple_alert_infobar_creator.h"
#include "chrome/browser/policy/chrome_browser_policy_connector.h"
#include "components/infobars/content/content_infobar_manager.h"
#include "components/infobars/core/infobar.h"
#include "components/infobars/core/infobar_delegate.h"
#include "components/policy/core/browser/browser_policy_connector.h"
#include "components/policy/core/common/cloud/cloud_policy_core.h"
#include "components/policy/core/common/cloud/cloud_policy_manager.h"
#include "components/policy/core/common/cloud/cloud_policy_store.h"
#include "components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.h"
#include "components/policy/core/common/configuration_policy_provider.h"
#include "components/policy/core/common/local_test_policy_provider.h"
#include "components/policy/core/common/policy_bundle.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_namespace.h"
#include "components/policy/core/common/policy_service_impl.h"
#include "components/policy/core/common/policy_types.h"
#include "components/policy/core/common/proxy_policy_provider.h"
#include "components/policy/core/common/schema_registry_tracking_policy_provider.h"
#include "components/policy/policy_constants.h"
#include "components/strings/grit/components_strings.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/policy/restricted_mgs_policy_provider.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/ash/policy/core/browser_policy_connector_ash.h"
#include "chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.h"
#include "chrome/browser/ash/policy/core/device_local_account.h"
#include "chrome/browser/ash/policy/core/device_local_account_policy_provider.h"
#include "chrome/browser/ash/policy/login/login_profile_policy_provider.h"
#include "chrome/browser/browser_process_platform_part.h"
#include "components/user_manager/user.h"
#include "components/user_manager/user_manager.h"
#include "components/user_manager/user_type.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_LACROS)
#include "chrome/browser/profiles/profile_manager.h"
#include "components/user_manager/user_manager.h"
#endif
#if BUILDFLAG(IS_ANDROID)
#include "chrome/browser/android/tab_android.h"
#include "chrome/browser/ui/android/tab_model/tab_model.h"
#include "chrome/browser/ui/android/tab_model/tab_model_list.h"
#else
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
#endif
namespace policy {
namespace internal {
#if BUILDFLAG(IS_CHROMEOS_ASH)
class ProxiedPoliciesPropagatedWatcher : PolicyService::ProviderUpdateObserver {
public:
ProxiedPoliciesPropagatedWatcher(
PolicyService* device_wide_policy_service,
ProxyPolicyProvider* proxy_policy_provider,
ConfigurationPolicyProvider* source_policy_provider,
base::OnceClosure proxied_policies_propagated_callback)
: device_wide_policy_service_(device_wide_policy_service),
proxy_policy_provider_(proxy_policy_provider),
source_policy_provider_(source_policy_provider),
proxied_policies_propagated_callback_(
std::move(proxied_policies_propagated_callback)) {
device_wide_policy_service->AddProviderUpdateObserver(this);
timeout_timer_.Start(
FROM_HERE, base::Seconds(kProxiedPoliciesPropagationTimeoutInSeconds),
this,
&ProxiedPoliciesPropagatedWatcher::OnProviderUpdatePropagationTimedOut);
}
ProxiedPoliciesPropagatedWatcher(const ProxiedPoliciesPropagatedWatcher&) =
delete;
ProxiedPoliciesPropagatedWatcher& operator=(
const ProxiedPoliciesPropagatedWatcher&) = delete;
~ProxiedPoliciesPropagatedWatcher() override {
device_wide_policy_service_->RemoveProviderUpdateObserver(this);
}
void OnProviderUpdatePropagated(
ConfigurationPolicyProvider* provider) override {
if (!proxied_policies_propagated_callback_)
return;
if (provider != proxy_policy_provider_)
return;
if (!source_policy_provider_->IsInitializationComplete(
POLICY_DOMAIN_CHROME)) {
return;
}
ReportTimeUma();
std::move(proxied_policies_propagated_callback_).Run();
}
void OnProviderUpdatePropagationTimedOut() {
if (!proxied_policies_propagated_callback_)
return;
LOG(WARNING) << "Waiting for proxied policies to propagate timed out.";
ReportTimeUma();
std::move(proxied_policies_propagated_callback_).Run();
}
private:
static constexpr int kProxiedPoliciesPropagationTimeoutInSeconds = 5;
void ReportTimeUma() const {
UmaHistogramTimes("Enterprise.TimeToUnthrottlePolicyInit",
base::TimeTicks::Now() - construction_time_);
}
const raw_ptr<PolicyService> device_wide_policy_service_;
const raw_ptr<const ProxyPolicyProvider> proxy_policy_provider_;
const raw_ptr<const ConfigurationPolicyProvider> source_policy_provider_;
const base::TimeTicks construction_time_ = base::TimeTicks::Now();
base::OnceClosure proxied_policies_propagated_callback_;
base::OneShotTimer timeout_timer_;
};
#endif
class LocalTestInfoBarVisibilityManager :
#if BUILDFLAG(IS_ANDROID)
public TabModelObserver
#else
public BrowserListObserver,
public TabStripModelObserver
#endif
{ … };
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
namespace {
PolicyService* GetDeviceWidePolicyService() {
BrowserPolicyConnectorAsh* browser_policy_connector =
g_browser_process->platform_part()->browser_policy_connector_ash();
return browser_policy_connector->GetPolicyService();
}
ProxyPolicyProvider* GetProxyPolicyProvider() {
BrowserPolicyConnectorAsh* browser_policy_connector =
g_browser_process->platform_part()->browser_policy_connector_ash();
return browser_policy_connector->GetGlobalUserCloudPolicyProvider();
}
}
#endif
ProfilePolicyConnector::ProfilePolicyConnector() = default;
ProfilePolicyConnector::~ProfilePolicyConnector() { … }
void ProfilePolicyConnector::Init(
const user_manager::User* user,
SchemaRegistry* schema_registry,
ConfigurationPolicyProvider* configuration_policy_provider,
const CloudPolicyStore* policy_store,
policy::ChromeBrowserPolicyConnector* connector,
bool force_immediate_load) { … }
void ProfilePolicyConnector::InitForTesting(
std::unique_ptr<PolicyService> service) { … }
void ProfilePolicyConnector::OverrideIsManagedForTesting(bool is_managed) { … }
void ProfilePolicyConnector::Shutdown() { … }
bool ProfilePolicyConnector::IsManaged() const { … }
#if BUILDFLAG(IS_CHROMEOS_LACROS)
bool ProfilePolicyConnector::IsMainProfile() const {
ProfileManager* profile_manager = g_browser_process->profile_manager();
if (profile_manager->GetNumberOfProfiles() <= 1)
return true;
auto profiles = profile_manager->GetLoadedProfiles();
const auto main_it = base::ranges::find_if(profiles, &Profile::IsMainProfile);
if (main_it == profiles.end())
return false;
return (*main_it)->GetProfilePolicyConnector() == this;
}
#endif
bool ProfilePolicyConnector::IsProfilePolicy(const char* policy_key) const { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
void ProfilePolicyConnector::TriggerProxiedPoliciesWaitTimeoutForTesting() {
CHECK(proxied_policies_propagated_watcher_);
proxied_policies_propagated_watcher_->OnProviderUpdatePropagationTimedOut();
}
#endif
base::flat_set<std::string> ProfilePolicyConnector::user_affiliation_ids()
const { … }
void ProfilePolicyConnector::SetUserAffiliationIdsForTesting(
const base::flat_set<std::string>& user_affiliation_ids) { … }
void ProfilePolicyConnector::OnPolicyServiceInitialized(PolicyDomain domain) { … }
void ProfilePolicyConnector::DoPostInit() { … }
const CloudPolicyStore* ProfilePolicyConnector::GetActualPolicyStore() const { … }
const ConfigurationPolicyProvider*
ProfilePolicyConnector::DeterminePolicyProviderForPolicy(
const char* policy_key) const { … }
void ProfilePolicyConnector::AppendPolicyProviderWithSchemaTracking(
ConfigurationPolicyProvider* policy_provider,
SchemaRegistry* schema_registry) { … }
std::string ProfilePolicyConnector::GetTimeToFirstPolicyLoadMetricSuffix()
const { … }
void ProfilePolicyConnector::UseLocalTestPolicyProvider() { … }
void ProfilePolicyConnector::RevertUseLocalTestPolicyProvider() { … }
bool ProfilePolicyConnector::IsUsingLocalTestPolicyProvider() const { … }
void ProfilePolicyConnector::RecordAffiliationMetrics() { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
std::unique_ptr<PolicyService>
ProfilePolicyConnector::CreatePolicyServiceWithInitializationThrottled(
const std::vector<raw_ptr<ConfigurationPolicyProvider, VectorExperimental>>&
policy_providers,
std::vector<std::unique_ptr<PolicyMigrator>> migrators,
ConfigurationPolicyProvider* user_policy_delegate) {
DCHECK(user_policy_delegate);
auto policy_service = PolicyServiceImpl::CreateWithThrottledInitialization(
policy_providers, PolicyServiceImpl::ScopeForMetrics::kUser,
std::move(migrators));
proxied_policies_propagated_watcher_ =
std::make_unique<internal::ProxiedPoliciesPropagatedWatcher>(
GetDeviceWidePolicyService(), GetProxyPolicyProvider(),
user_policy_delegate,
base::BindOnce(&ProfilePolicyConnector::OnProxiedPoliciesPropagated,
base::Unretained(this),
base::Unretained(policy_service.get())));
return std::move(policy_service);
}
void ProfilePolicyConnector::OnProxiedPoliciesPropagated(
PolicyServiceImpl* policy_service) {
policy_service->UnthrottleInitialization();
base::SingleThreadTaskRunner::GetCurrentDefault()->DeleteSoon(
FROM_HERE, std::move(proxied_policies_propagated_watcher_));
}
#endif
}