blob: 810f40830b89c6277a3a75ba59aa1b8d09abf0d4 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/proxy_resolution/proxy_config_service.h"
#include <memory>
#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "build/build_config.h"
#include "net/proxy_resolution/proxy_config_with_annotation.h"
#if BUILDFLAG(IS_WIN)
#include "net/proxy_resolution/win/proxy_config_service_win.h"
#elif BUILDFLAG(IS_IOS)
#include "net/proxy_resolution/proxy_config_service_ios.h"
#elif BUILDFLAG(IS_MAC)
#include "net/proxy_resolution/proxy_config_service_mac.h"
#elif BUILDFLAG(IS_LINUX)
#include "net/proxy_resolution/proxy_config_service_linux.h"
#elif BUILDFLAG(IS_ANDROID)
#include "net/proxy_resolution/proxy_config_service_android.h"
#endif
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX)
#include "net/traffic_annotation/network_traffic_annotation.h"
#endif
namespace net {
namespace {
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX)
constexpr net::NetworkTrafficAnnotationTag kSystemProxyConfigTrafficAnnotation =
net::DefineNetworkTrafficAnnotation("proxy_config_system", R"(
semantics {
sender: "Proxy Config"
description:
"Establishing a connection through a proxy server using system proxy "
"settings."
trigger:
"Whenever a network request is made when the system proxy settings "
"are used, and they indicate to use a proxy server."
data:
"Proxy configuration."
destination: OTHER
destination_other:
"The proxy server specified in the configuration."
}
policy {
cookies_allowed: NO
setting:
"User cannot override system proxy settings, but can change them "
"through 'Advanced/System/Open proxy settings'."
policy_exception_justification:
"Using 'ProxySettings' policy can set Chrome to use specific "
"proxy settings and avoid system proxy."
})");
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
class UnsetProxyConfigService : public ProxyConfigService {
public:
UnsetProxyConfigService() = default;
~UnsetProxyConfigService() override = default;
void AddObserver(Observer* observer) override {}
void RemoveObserver(Observer* observer) override {}
ConfigAvailability GetLatestProxyConfig(
ProxyConfigWithAnnotation* config) override {
return CONFIG_UNSET;
}
};
#endif
// Config getter that always returns direct settings.
class ProxyConfigServiceDirect : public ProxyConfigService {
public:
// ProxyConfigService implementation:
void AddObserver(Observer* observer) override {}
void RemoveObserver(Observer* observer) override {}
ConfigAvailability GetLatestProxyConfig(
ProxyConfigWithAnnotation* config) override {
*config = ProxyConfigWithAnnotation::CreateDirect();
return CONFIG_VALID;
}
};
} // namespace
// static
std::unique_ptr<ProxyConfigService>
ProxyConfigService::CreateSystemProxyConfigService(
scoped_refptr<base::SequencedTaskRunner> main_task_runner) {
#if BUILDFLAG(IS_WIN)
return std::make_unique<ProxyConfigServiceWin>(
kSystemProxyConfigTrafficAnnotation);
#elif BUILDFLAG(IS_IOS)
return std::make_unique<ProxyConfigServiceIOS>(
kSystemProxyConfigTrafficAnnotation);
#elif BUILDFLAG(IS_MAC)
return std::make_unique<ProxyConfigServiceMac>(
std::move(main_task_runner), kSystemProxyConfigTrafficAnnotation);
#elif BUILDFLAG(IS_CHROMEOS_ASH)
LOG(ERROR) << "ProxyConfigService for ChromeOS should be created in "
<< "profile_io_data.cc::CreateProxyConfigService and this should "
<< "be used only for examples.";
return std::make_unique<UnsetProxyConfigService>();
#elif BUILDFLAG(IS_LINUX)
std::unique_ptr<ProxyConfigServiceLinux> linux_config_service(
std::make_unique<ProxyConfigServiceLinux>());
// Assume we got called on the thread that runs the default glib
// main loop, so the current thread is where we should be running
// gsettings calls from.
scoped_refptr<base::SingleThreadTaskRunner> glib_thread_task_runner =
base::SingleThreadTaskRunner::GetCurrentDefault();
// Synchronously fetch the current proxy config (since we are running on
// glib_default_loop). Additionally register for notifications (delivered in
// either |glib_default_loop| or an internal sequenced task runner) to
// keep us updated when the proxy config changes.
linux_config_service->SetupAndFetchInitialConfig(
glib_thread_task_runner, std::move(main_task_runner),
kSystemProxyConfigTrafficAnnotation);
return std::move(linux_config_service);
#elif BUILDFLAG(IS_ANDROID)
return std::make_unique<ProxyConfigServiceAndroid>(
std::move(main_task_runner),
base::SingleThreadTaskRunner::GetCurrentDefault());
#elif BUILDFLAG(IS_FUCHSIA)
// TODO(crbug.com/889195): Implement a system proxy service for Fuchsia.
return std::make_unique<ProxyConfigServiceDirect>();
#else
LOG(WARNING) << "Failed to choose a system proxy settings fetcher "
"for this platform.";
return std::make_unique<ProxyConfigServiceDirect>();
#endif
}
bool ProxyConfigService::UsesPolling() {
return false;
}
} // namespace net