0

ash: Remove crosapi's NetworkSettingsService and related code

Remove NetworkSettingsService and related crosapi interfaces as well
as their implementations. They are no longer needed.

This includes deprecating the ash.lacros_proxy_controlling_extension
preference.

No change in behavior intended.

Bug: b:365741912
Change-Id: I2abd425d5e0c87f4ddcd97b1d068e420d47e4857
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6054898
Reviewed-by: Erik Chen <erikchen@chromium.org>
Reviewed-by: Andreea Costinas <acostinas@google.com>
Reviewed-by: Colin Blundell <blundell@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1390781}
This commit is contained in:
Georg Neis
2024-12-03 03:27:29 +00:00
committed by Chromium LUCI CQ
parent c67ddb2c19
commit 0d09fe492e
30 changed files with 9 additions and 1706 deletions

@ -1845,14 +1845,6 @@ inline constexpr char kNextImeShortcutReminderDismissed[] =
inline constexpr char kDeviceI18nShortcutsEnabled[] =
"ash.device_i18n_shortcuts_enabled";
// If a user installs an extension which controls the proxy settings in the
// primary profile of Chrome OS, this dictionary will contain information about
// the extension controlling the proxy (name, id and if it can be disabled by
// the user). Used to show the name and icon of the extension in the "Proxy"
// section of the OS Settings>Network dialog.
inline constexpr char kLacrosProxyControllingExtension[] =
"ash.lacros_proxy_controlling_extension";
// A boolean pref which is true if Fast Pair is enabled.
inline constexpr char kFastPairEnabled[] = "ash.fast_pair.enabled";

@ -164,9 +164,6 @@ static_library("crosapi") {
"multi_capture_service_ash.h",
"native_theme_service_ash.cc",
"native_theme_service_ash.h",
"network_settings_service_ash.cc",
"network_settings_service_ash.h",
"network_settings_translation.h",
"networking_attributes_ash.cc",
"networking_attributes_ash.h",
"networking_private_ash.cc",
@ -215,8 +212,6 @@ static_library("crosapi") {
"task_manager_ash.h",
"time_zone_service_ash.cc",
"time_zone_service_ash.h",
"translate_crosapi_to_proxy_config.cc",
"translate_proxy_config_to_crosapi.cc",
"virtual_keyboard_ash.cc",
"virtual_keyboard_ash.h",
"volume_manager_ash.cc",
@ -300,7 +295,6 @@ static_library("crosapi") {
"//chrome/browser/ash/magic_boost",
"//chrome/browser/ash/mahi",
"//chrome/browser/ash/mahi/media_app",
"//chrome/browser/ash/net",
"//chrome/browser/ash/notifications",
"//chrome/browser/ash/platform_keys",
"//chrome/browser/ash/platform_keys/key_permissions",
@ -526,7 +520,6 @@ static_library("crosapi") {
"//chrome/browser/ash/login/session",
"//chrome/browser/ash/mahi",
"//chrome/browser/ash/mahi/media_app",
"//chrome/browser/ash/net",
"//chrome/browser/ash/policy/core",
"//chrome/browser/ash/policy/dlp",
"//chrome/browser/ash/scalable_iph",
@ -647,7 +640,6 @@ source_set("unit_tests") {
"local_printer_ash_unittest.cc",
"login_screen_storage_ash_unittest.cc",
"login_state_ash_unittest.cc",
"network_settings_translation_unittest.cc",
"networking_attributes_ash_unittest.cc",
"one_drive_integration_service_ash_unittest.cc",
"parent_access_ash_unittest.cc",
@ -743,7 +735,6 @@ source_set("browser_tests") {
"file_change_service_bridge_ash_browsertest.cc",
"magic_boost_ash_browsertest.cc",
"media_ui_ash_browsertest.cc",
"network_settings_service_ash_browsertest.cc",
"power_ash_apitest.cc",
"print_preview_ash_browsertest.cc",
"screen_manager_ash_browsertest.cc",
@ -765,7 +756,6 @@ source_set("browser_tests") {
"//chrome/browser/ash/fileapi",
"//chrome/browser/ash/magic_boost",
"//chrome/browser/ash/mahi",
"//chrome/browser/ash/net",
"//chrome/browser/ash/printing/print_preview",
"//chrome/browser/ash/system_web_apps/test_support:test_support_ui",
"//chrome/browser/ash/video_conference",

@ -38,7 +38,6 @@ include_rules = [
"+chrome/browser/ash/login",
"+chrome/browser/ash/magic_boost",
"+chrome/browser/ash/mahi",
"+chrome/browser/ash/net",
"+chrome/browser/ash/network_change_manager",
"+chrome/browser/ash/notifications",
"+chrome/browser/ash/passkeys",

@ -70,7 +70,6 @@
#include "chrome/browser/ash/crosapi/metrics_ash.h"
#include "chrome/browser/ash/crosapi/multi_capture_service_ash.h"
#include "chrome/browser/ash/crosapi/native_theme_service_ash.h"
#include "chrome/browser/ash/crosapi/network_settings_service_ash.h"
#include "chrome/browser/ash/crosapi/networking_attributes_ash.h"
#include "chrome/browser/ash/crosapi/networking_private_ash.h"
#include "chrome/browser/ash/crosapi/nonclosable_app_toast_service_ash.h"
@ -252,8 +251,6 @@ CrosapiAsh::CrosapiAsh()
native_theme_service_ash_(std::make_unique<NativeThemeServiceAsh>()),
networking_attributes_ash_(std::make_unique<NetworkingAttributesAsh>()),
networking_private_ash_(std::make_unique<NetworkingPrivateAsh>()),
network_settings_service_ash_(std::make_unique<NetworkSettingsServiceAsh>(
g_browser_process->platform_part()->ash_proxy_monitor())),
one_drive_notification_service_ash_(
std::make_unique<OneDriveNotificationServiceAsh>()),
one_drive_integration_service_ash_(
@ -702,12 +699,6 @@ void CrosapiAsh::BindNetworkChange(
NOTREACHED();
}
void CrosapiAsh::BindNetworkSettingsService(
::mojo::PendingReceiver<::crosapi::mojom::NetworkSettingsService>
receiver) {
network_settings_service_ash_->BindReceiver(std::move(receiver));
}
void CrosapiAsh::BindNetworkingAttributes(
mojo::PendingReceiver<mojom::NetworkingAttributes> receiver) {
networking_attributes_ash_->BindReceiver(std::move(receiver));

@ -105,7 +105,6 @@ class MediaUIAsh;
class MetricsAsh;
class MultiCaptureServiceAsh;
class NativeThemeServiceAsh;
class NetworkSettingsServiceAsh;
class NetworkingAttributesAsh;
class NetworkingPrivateAsh;
class OneDriveNotificationServiceAsh;
@ -297,9 +296,6 @@ class CrosapiAsh : public mojom::Crosapi {
mojo::PendingReceiver<mojom::NativeThemeService> receiver) override;
void BindNetworkChange(
mojo::PendingReceiver<mojom::NetworkChange> receiver) override;
void BindNetworkSettingsService(
::mojo::PendingReceiver<::crosapi::mojom::NetworkSettingsService>
receiver) override;
void BindNetworkingAttributes(
mojo::PendingReceiver<mojom::NetworkingAttributes> receiver) override;
void BindNetworkingPrivate(
@ -588,10 +584,6 @@ class CrosapiAsh : public mojom::Crosapi {
VpnServiceAsh* vpn_service_ash() { return vpn_service_ash_.get(); }
NetworkSettingsServiceAsh* network_settings_service_ash() {
return network_settings_service_ash_.get();
}
private:
// Called when a connection is lost.
void OnDisconnected();
@ -656,7 +648,6 @@ class CrosapiAsh : public mojom::Crosapi {
std::unique_ptr<NativeThemeServiceAsh> native_theme_service_ash_;
std::unique_ptr<NetworkingAttributesAsh> networking_attributes_ash_;
std::unique_ptr<NetworkingPrivateAsh> networking_private_ash_;
std::unique_ptr<NetworkSettingsServiceAsh> network_settings_service_ash_;
std::unique_ptr<OneDriveNotificationServiceAsh>
one_drive_notification_service_ash_;
std::unique_ptr<OneDriveIntegrationServiceAsh>

@ -122,7 +122,6 @@
#include "chromeos/crosapi/mojom/metrics.mojom.h"
#include "chromeos/crosapi/mojom/multi_capture_service.mojom.h"
#include "chromeos/crosapi/mojom/network_change.mojom.h"
#include "chromeos/crosapi/mojom/network_settings_service.mojom.h"
#include "chromeos/crosapi/mojom/networking_attributes.mojom.h"
#include "chromeos/crosapi/mojom/networking_private.mojom.h"
#include "chromeos/crosapi/mojom/nonclosable_app_toast_service.mojom.h"
@ -374,7 +373,6 @@ constexpr InterfaceVersionEntry kInterfaceVersionEntries[] = {
MakeInterfaceVersionEntry<crosapi::mojom::NetworkChange>(),
MakeInterfaceVersionEntry<crosapi::mojom::NetworkingAttributes>(),
MakeInterfaceVersionEntry<crosapi::mojom::NetworkingPrivate>(),
MakeInterfaceVersionEntry<crosapi::mojom::NetworkSettingsService>(),
MakeInterfaceVersionEntry<crosapi::mojom::OneDriveIntegrationService>(),
MakeInterfaceVersionEntry<crosapi::mojom::OneDriveNotificationService>(),
MakeInterfaceVersionEntry<crosapi::mojom::PasskeyAuthenticator>(),

@ -1,136 +0,0 @@
// Copyright 2021 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/crosapi/network_settings_service_ash.h"
#include <stdint.h>
#include "ash/constants/ash_pref_names.h"
#include "base/check_is_test.h"
#include "base/logging.h"
#include "base/notreached.h"
#include "chrome/browser/ash/crosapi/browser_util.h"
#include "chrome/browser/ash/crosapi/network_settings_translation.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/proxy_config/proxy_config_pref_names.h"
#include "components/user_manager/user_manager.h"
namespace {
// Returns the extension metadata (as a crosapi object) for the extension which
// is controlling the proxy in the Lacros primary profile. If the proxy is not
// controlled by an extension, returns the null pointer.
crosapi::mojom::ExtensionControllingProxyPtr GetExtensionPtr(
const ash::AshProxyMonitor* ash_proxy_monitor) {
if (!ash_proxy_monitor ||
!ash_proxy_monitor->GetLacrosExtensionControllingTheProxy()) {
return nullptr;
}
std::optional<ash::AshProxyMonitor::ExtensionMetadata> extension_metadata =
ash_proxy_monitor->GetLacrosExtensionControllingTheProxy();
crosapi::mojom::ExtensionControllingProxyPtr extension =
crosapi::mojom::ExtensionControllingProxy::New();
extension->name = extension_metadata->name;
extension->id = extension_metadata->id;
extension->can_be_disabled = extension_metadata->can_be_disabled;
return extension;
}
} // namespace
namespace crosapi {
NetworkSettingsServiceAsh::NetworkSettingsServiceAsh(
ash::AshProxyMonitor* ash_proxy_monitor)
: ash_proxy_monitor_(ash_proxy_monitor) {
// Missing in unit tests.
if (ash_proxy_monitor_) {
ash_proxy_monitor_observation_.Observe(ash_proxy_monitor_);
} else {
CHECK_IS_TEST();
}
observers_.set_disconnect_handler(base::BindRepeating(
&NetworkSettingsServiceAsh::OnDisconnect, base::Unretained(this)));
}
NetworkSettingsServiceAsh::~NetworkSettingsServiceAsh() = default;
void NetworkSettingsServiceAsh::BindReceiver(
mojo::PendingReceiver<mojom::NetworkSettingsService> pending_receiver) {
receivers_.Add(this, std::move(pending_receiver));
}
void NetworkSettingsServiceAsh::SetExtensionProxy(
crosapi::mojom::ProxyConfigPtr proxy_config) {
NOTREACHED()
<< "This version of Ash receives the proxy pref from the Prefs mojo "
"service. Please use SetExtensionControllingProxyMetadata to set the "
"extension metadata.";
}
void NetworkSettingsServiceAsh::ClearExtensionProxy() {
NOTREACHED()
<< "This version of Ash clears the proxy pref from the Prefs mojo "
"service. Please use ClearExtensionControllingProxyMetadata to clear "
"the extension metadata.";
}
void NetworkSettingsServiceAsh::SetExtensionControllingProxyMetadata(
crosapi::mojom::ExtensionControllingProxyPtr extension) {
DCHECK(extension);
ash_proxy_monitor_->SetLacrosExtensionControllingProxyInfo(
extension->name, extension->id, extension->can_be_disabled);
}
void NetworkSettingsServiceAsh::ClearExtensionControllingProxyMetadata() {
ash_proxy_monitor_->ClearLacrosExtensionControllingProxyInfo();
}
void NetworkSettingsServiceAsh::AddNetworkSettingsObserver(
mojo::PendingRemote<mojom::NetworkSettingsObserver> observer) {
mojo::Remote<mojom::NetworkSettingsObserver> remote(std::move(observer));
if (cached_proxy_config_) {
remote->OnProxyChanged(cached_proxy_config_.Clone());
}
observers_.Add(std::move(remote));
}
void NetworkSettingsServiceAsh::IsAlwaysOnVpnPreConnectUrlAllowlistEnforced(
IsAlwaysOnVpnPreConnectUrlAllowlistEnforcedCallback callback) {
std::move(callback).Run(alwayson_vpn_pre_connect_url_allowlist_enforced_);
}
void NetworkSettingsServiceAsh::SetAlwaysOnVpnPreConnectUrlAllowlistEnforced(
bool enforced) {
alwayson_vpn_pre_connect_url_allowlist_enforced_ = enforced;
for (const auto& obs : observers_) {
obs->OnAlwaysOnVpnPreConnectUrlAllowlistEnforcedChanged(
alwayson_vpn_pre_connect_url_allowlist_enforced_);
}
}
void NetworkSettingsServiceAsh::OnProxyChanged() {
crosapi::mojom::ProxyConfigPtr new_proxy_config =
ProxyConfigToCrosapiProxy(ash_proxy_monitor_->GetLatestProxyConfig(),
ash_proxy_monitor_->GetLatestWpadUrl());
new_proxy_config->extension = GetExtensionPtr(ash_proxy_monitor_);
// Proxy config has not changed.
if (cached_proxy_config_ && new_proxy_config->Equals(*cached_proxy_config_)) {
return;
}
cached_proxy_config_ = std::move(new_proxy_config);
for (const auto& obs : observers_) {
obs->OnProxyChanged(cached_proxy_config_.Clone());
}
}
void NetworkSettingsServiceAsh::OnDisconnect(mojo::RemoteSetElementId mojo_id) {
observers_.Remove(mojo_id);
}
} // namespace crosapi

@ -1,81 +0,0 @@
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_CROSAPI_NETWORK_SETTINGS_SERVICE_ASH_H_
#define CHROME_BROWSER_ASH_CROSAPI_NETWORK_SETTINGS_SERVICE_ASH_H_
#include "base/scoped_observation.h"
#include "chrome/browser/ash/net/ash_proxy_monitor.h"
#include "chromeos/crosapi/mojom/network_settings_service.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/bindings/remote_set.h"
#include "url/gurl.h"
namespace crosapi {
// This class is the Ash-Chrome implementation of the NetworkSettingsService
// interface. This class must only be used from the main thread.
class NetworkSettingsServiceAsh : public crosapi::mojom::NetworkSettingsService,
public ash::AshProxyMonitor::Observer {
public:
explicit NetworkSettingsServiceAsh(ash::AshProxyMonitor* ash_proxy_monitor);
NetworkSettingsServiceAsh(const NetworkSettingsServiceAsh&) = delete;
NetworkSettingsServiceAsh& operator=(const NetworkSettingsServiceAsh&) =
delete;
~NetworkSettingsServiceAsh() override;
void BindReceiver(
mojo::PendingReceiver<crosapi::mojom::NetworkSettingsService>
pending_receiver);
// crosapi::mojom::NetworkSettingsServiceAsh:
void AddNetworkSettingsObserver(
mojo::PendingRemote<mojom::NetworkSettingsObserver> observer) override;
void IsAlwaysOnVpnPreConnectUrlAllowlistEnforced(
IsAlwaysOnVpnPreConnectUrlAllowlistEnforcedCallback callback) override;
// Deprecated. Please use `SetExtensionControllingProxyMetadata` and
// `ClearExtensionControllingProxyMetadata`.
void SetExtensionProxy(crosapi::mojom::ProxyConfigPtr proxy_config) override;
void ClearExtensionProxy() override;
// Stores metadata about the extension controlling the proxy in the primary
// profile. The actual proxy config is being set and cleared from the
// PrefService via the mojo::Prefs service.
// TODO(acostinas,b/268607394) Deprecate these methods when the mojo Prefs
// service implements sending the extension metadata along with the pref
// value.
void SetExtensionControllingProxyMetadata(
crosapi::mojom::ExtensionControllingProxyPtr extension) override;
void ClearExtensionControllingProxyMetadata() override;
// Sets a value which indicates if the AlwaysOnVpnPreConnectUrlAllowlist
// should be used to restrict user navigation.
void SetAlwaysOnVpnPreConnectUrlAllowlistEnforced(bool enforced);
private:
// ash::AshProxyMonitor::Observer:
void OnProxyChanged() override;
// Called when a mojo observer is disconnecting. If there's no observer for
// this service, the service will stop listening for pref changes.
void OnDisconnect(mojo::RemoteSetElementId mojo_id);
crosapi::mojom::ProxyConfigPtr cached_proxy_config_;
bool alwayson_vpn_pre_connect_url_allowlist_enforced_ = false;
base::ScopedObservation<ash::AshProxyMonitor, ash::AshProxyMonitor::Observer>
ash_proxy_monitor_observation_{this};
raw_ptr<ash::AshProxyMonitor> ash_proxy_monitor_;
// Support any number of connections.
mojo::ReceiverSet<mojom::NetworkSettingsService> receivers_;
// Support any number of observers.
mojo::RemoteSet<mojom::NetworkSettingsObserver> observers_;
};
} // namespace crosapi
#endif // CHROME_BROWSER_ASH_CROSAPI_NETWORK_SETTINGS_SERVICE_ASH_H_

@ -1,452 +0,0 @@
// Copyright 2021 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/crosapi/network_settings_service_ash.h"
#include "ash/constants/ash_pref_names.h"
#include "base/test/test_future.h"
#include "chrome/browser/ash/crosapi/network_settings_translation.h"
#include "chrome/browser/ash/crosapi/prefs_ash.h"
#include "chrome/browser/ash/net/ash_proxy_monitor.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chromeos/ash/components/dbus/shill/shill_profile_client.h"
#include "chromeos/ash/components/dbus/shill/shill_service_client.h"
#include "chromeos/ash/components/network/network_state_handler.h"
#include "chromeos/crosapi/mojom/network_settings_service.mojom.h"
#include "chromeos/crosapi/mojom/prefs.mojom.h"
#include "components/policy/core/browser/browser_policy_connector.h"
#include "components/policy/core/common/mock_configuration_policy_provider.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_types.h"
#include "components/policy/policy_constants.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/pref_test_utils.h"
#include "components/proxy_config/proxy_config_dictionary.h"
#include "components/proxy_config/proxy_config_pref_names.h"
#include "components/proxy_config/proxy_prefs.h"
#include "content/public/test/browser_test.h"
#include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
namespace {
constexpr char kPacUrl[] = "http://pac.pac/";
constexpr char kExtensionName[] = "Lacros Test Extension Name";
constexpr char kExtensionId[] = "Lacros Test Extension ID";
constexpr char kPrefExtensionNameKey[] = "extension_name_key";
constexpr char kPrefExtensionIdKey[] = "extension_id_key";
constexpr char kPrefExtensionCanDisabled[] = "can_be_disabled_key";
constexpr char kUserProfilePath[] = "user_profile";
constexpr char kWifiServicePath[] = "stub_wifi";
constexpr char kWifiSsid[] = "wifi0";
constexpr char kWifiGuid[] = "{wifi0_guid}";
constexpr char kONCPolicyWifi0Proxy[] =
R"({
"NetworkConfigurations": [ {
"GUID": "{wifi0_guid}",
"Name": "wifi0",
"ProxySettings": {
"Manual": {
"HTTPProxy": {
"Host": "proxyhost",
"Port": 3128
}
},
"Type": "Manual"
},
"Type": "WiFi",
"WiFi": {
"AutoConnect": true,
"HiddenSSID": false,
"SSID": "wifi0",
"Security": "None"
}
} ]
})";
// Observes network changes coming from the network settings service.
class NetworkSettingsObserver : public crosapi::mojom::NetworkSettingsObserver {
public:
NetworkSettingsObserver() = default;
NetworkSettingsObserver(const NetworkSettingsObserver&) = delete;
NetworkSettingsObserver& operator=(const NetworkSettingsObserver&) = delete;
~NetworkSettingsObserver() override = default;
// crosapi::mojom::NetworkSettingsObserver:
void OnProxyChanged(crosapi::mojom::ProxyConfigPtr proxy_config) override {
future_.SetValue(std::move(proxy_config));
}
void OnAlwaysOnVpnPreConnectUrlAllowlistEnforcedChanged(
bool enforced) override {
alwayson_vpn_pre_connect_url_allowlist_enforced_changed_future_.SetValue(
enforced);
}
crosapi::mojom::ProxyConfigPtr WaitForProxyConfig() { return future_.Take(); }
bool WaitForAlwaysOnVpnPreConnectUrlAllowlistEnforced() {
return alwayson_vpn_pre_connect_url_allowlist_enforced_changed_future_
.Take();
}
mojo::Receiver<crosapi::mojom::NetworkSettingsObserver> receiver_{this};
bool AreAllProxyUpdatesRead() { return !future_.IsReady(); }
private:
base::test::TestFuture<crosapi::mojom::ProxyConfigPtr> future_;
base::test::TestFuture<bool>
alwayson_vpn_pre_connect_url_allowlist_enforced_changed_future_;
};
} // namespace
namespace crosapi {
class NetworkSettingsServiceAshTest : public InProcessBrowserTest {
public:
NetworkSettingsServiceAshTest() = default;
NetworkSettingsServiceAshTest(const NetworkSettingsServiceAshTest&) = delete;
NetworkSettingsServiceAshTest& operator=(
const NetworkSettingsServiceAshTest&) = delete;
~NetworkSettingsServiceAshTest() override = default;
protected:
void SetUpInProcessBrowserTestFixture() override {
InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
ON_CALL(provider_, IsInitializationComplete(testing::_))
.WillByDefault(testing::Return(true));
ON_CALL(provider_, IsFirstPolicyLoadComplete(testing::_))
.WillByDefault(testing::Return(true));
policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_);
}
void SetUpOnMainThread() override {
InProcessBrowserTest::SetUpOnMainThread();
SetupNetworkEnvironment();
ash_proxy_monitor_ = std::make_unique<ash::AshProxyMonitor>(
g_browser_process->local_state(), g_browser_process->profile_manager());
network_service_ash_ =
std::make_unique<NetworkSettingsServiceAsh>(ash_proxy_monitor_.get());
mojo::Remote<mojom::NetworkSettingsService> network_service_ash_remote;
network_service_ash_->BindReceiver(
network_service_ash_remote.BindNewPipeAndPassReceiver());
observer_ = std::make_unique<NetworkSettingsObserver>();
network_service_ash_remote->AddNetworkSettingsObserver(
observer_->receiver_.BindNewPipeAndPassRemote());
ash_proxy_monitor_->SetProfileForTesting(browser()->profile());
network_service_ash_remote.FlushForTesting();
auto result = observer_->WaitForProxyConfig();
ASSERT_FALSE(result.is_null());
EXPECT_TRUE(result->proxy_settings->is_direct());
EXPECT_TRUE(result->extension.is_null());
}
void TearDownOnMainThread() override {
observer_.reset();
network_service_ash_.reset();
ash_proxy_monitor_.reset();
}
void SetupNetworkEnvironment() {
ash::ShillProfileClient::TestInterface* profile_test =
ash::ShillProfileClient::Get()->GetTestInterface();
ash::ShillServiceClient::TestInterface* service_test =
ash::ShillServiceClient::Get()->GetTestInterface();
profile_test->AddProfile(kUserProfilePath, "test-user");
service_test->ClearServices();
ConnectWifiNetworkService(kWifiServicePath, kWifiGuid, kWifiSsid);
}
void SetOncPolicy(const std::string& policy_json, policy::PolicyScope scope) {
policy::PolicyMap policy;
policy.Set(policy::key::kOpenNetworkConfiguration,
policy::POLICY_LEVEL_MANDATORY, scope,
policy::POLICY_SOURCE_CLOUD, base::Value(policy_json), nullptr);
provider_.UpdateChromePolicy(policy);
}
void ConnectWifiNetworkService(const std::string& service_path,
const std::string& guid,
const std::string& ssid) {
ash::ShillServiceClient::TestInterface* service_test =
ash::ShillServiceClient::Get()->GetTestInterface();
service_test->AddService(service_path, guid, ssid, shill::kTypeWifi,
shill::kStateOnline, true /* add_to_visible */);
service_test->SetServiceProperty(service_path, shill::kProfileProperty,
base::Value(kUserProfilePath));
}
policy::MockConfigurationPolicyProvider provider_;
std::unique_ptr<ash::AshProxyMonitor> ash_proxy_monitor_;
std::unique_ptr<NetworkSettingsServiceAsh> network_service_ash_;
std::unique_ptr<NetworkSettingsObserver> observer_;
};
// Verifies that the `NetworkSettingsServiceAsh` listens to default network
// changes and propagates the network configurations to observers via the mojo
// API.
IN_PROC_BROWSER_TEST_F(NetworkSettingsServiceAshTest, ProxyConfigUpdate) {
SetOncPolicy(kONCPolicyWifi0Proxy, policy::POLICY_SCOPE_USER);
auto result = observer_->WaitForProxyConfig();
crosapi::mojom::ProxySettingsManualPtr manual =
std::move(result->proxy_settings->get_manual());
ASSERT_EQ(manual->http_proxies.size(), 1u);
EXPECT_EQ(manual->http_proxies[0]->host, "proxyhost");
EXPECT_EQ(manual->http_proxies[0]->port, 3128);
EXPECT_TRUE(result->extension.is_null());
}
IN_PROC_BROWSER_TEST_F(NetworkSettingsServiceAshTest,
SetAlwaysOnVpnPreConnectUrlAllowlistEnforced) {
network_service_ash_->SetAlwaysOnVpnPreConnectUrlAllowlistEnforced(
/*enforced=*/true);
EXPECT_TRUE(observer_->WaitForAlwaysOnVpnPreConnectUrlAllowlistEnforced());
network_service_ash_->SetAlwaysOnVpnPreConnectUrlAllowlistEnforced(
/*enforced=*/false);
EXPECT_FALSE(observer_->WaitForAlwaysOnVpnPreConnectUrlAllowlistEnforced());
}
// Test suite for testing the AshNetworkSettingsService with proxies set via
// extensions in the Lacros primary profile.
class NetworkSettingsServiceAshExtensionTest
: public NetworkSettingsServiceAshTest {
public:
NetworkSettingsServiceAshExtensionTest() = default;
NetworkSettingsServiceAshExtensionTest(
const NetworkSettingsServiceAshExtensionTest&) = delete;
NetworkSettingsServiceAshExtensionTest& operator=(
const NetworkSettingsServiceAshExtensionTest&) = delete;
~NetworkSettingsServiceAshExtensionTest() override = default;
void SetUpOnMainThread() override {
NetworkSettingsServiceAshTest::SetUpOnMainThread();
prefs_ash_ = std::make_unique<PrefsAsh>(
g_browser_process->profile_manager(), g_browser_process->local_state());
prefs_ash_->OnProfileAdded(browser()->profile());
}
protected:
// This method simulates mojo call which happen when an extension sets the
// proxy in the Lacros primary profile.
void SetExtensionProxyInLacros(base::Value::Dict proxy_dict,
bool can_be_disabled) {
SetProxyMetadata(can_be_disabled);
SetProxyPref(std::move(proxy_dict));
}
void ClearExtensionProxyInLacros() {
base::test::TestFuture<void> future;
prefs_ash_->ClearExtensionControlledPref(mojom::PrefPath::kProxy,
future.GetCallback());
EXPECT_TRUE(future.Wait());
network_service_ash_->ClearExtensionControllingProxyMetadata();
}
void SetProxyPref(base::Value::Dict proxy_dict) {
base::test::TestFuture<void> future;
prefs_ash_->SetPref(mojom::PrefPath::kProxy,
base::Value(std::move(proxy_dict)),
future.GetCallback());
EXPECT_TRUE(future.Wait());
}
// Sends the proxy metadata through the mojo service NetworkSettingsService
// and waits for Ash to store the metadata in the profile prefs.
void SetProxyMetadata(bool can_be_disabled) {
auto extension = crosapi::mojom::ExtensionControllingProxy::New();
extension->name = kExtensionName;
extension->id = kExtensionId;
extension->can_be_disabled = can_be_disabled;
network_service_ash_->SetExtensionControllingProxyMetadata(
std::move(extension));
base::Value::Dict expected_pref =
base::Value::Dict()
.Set(kPrefExtensionNameKey, kExtensionName)
.Set(kPrefExtensionIdKey, kExtensionId)
.Set(kPrefExtensionCanDisabled, can_be_disabled);
WaitForPrefValue(browser()->profile()->GetPrefs(),
ash::prefs::kLacrosProxyControllingExtension,
base::Value(std::move(expected_pref)));
}
std::unique_ptr<PrefsAsh> prefs_ash_;
};
IN_PROC_BROWSER_TEST_F(NetworkSettingsServiceAshExtensionTest,
SetAndClearExtensionProxy) {
// Emulate receiving an initial proxy config from lacros-chrome.
base::Value::Dict proxy_config =
ProxyConfigDictionary::CreatePacScript(kPacUrl, /*pac_mandatory=*/true);
SetExtensionProxyInLacros(proxy_config.Clone(),
/*can_be_disabled=*/true);
auto result = observer_->WaitForProxyConfig();
ASSERT_FALSE(result.is_null());
EXPECT_TRUE(result->proxy_settings->is_pac());
EXPECT_EQ(result->proxy_settings->get_pac()->pac_url, kPacUrl);
ASSERT_FALSE(result->extension.is_null());
EXPECT_EQ(result->extension->name, kExtensionName);
EXPECT_EQ(result->extension->id, kExtensionId);
ClearExtensionProxyInLacros();
result = observer_->WaitForProxyConfig();
ASSERT_FALSE(result.is_null());
EXPECT_TRUE(result->proxy_settings->is_direct());
EXPECT_TRUE(result->extension.is_null());
}
// Verifies that proxies set via policy have precedence over proxies set via
// Lacros extensions. The test sets a PAC proxy via extension, a direct proxy
// via policy and then verifies that the direct proxy is applied.
IN_PROC_BROWSER_TEST_F(NetworkSettingsServiceAshExtensionTest,
UserPolicyHasPrecedence) {
base::Value::Dict pac_proxy =
ProxyConfigDictionary::CreatePacScript(kPacUrl,
/*pac_mandatory=*/true);
SetExtensionProxyInLacros(pac_proxy.Clone(),
/*can_be_disabled=*/true);
auto result = observer_->WaitForProxyConfig();
ASSERT_FALSE(result->extension.is_null());
EXPECT_EQ(result->extension->name, kExtensionName);
EXPECT_EQ(result->extension->id, kExtensionId);
// Set proxy by policy.
policy::PolicyMap policy;
policy.Set(policy::key::kProxyMode, policy::POLICY_LEVEL_MANDATORY,
policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
base::Value(ProxyPrefs::kAutoDetectProxyModeName), nullptr);
provider_.UpdateChromePolicy(policy);
const base::Value::Dict& proxy_pref =
browser()->profile()->GetPrefs()->GetDict(proxy_config::prefs::kProxy);
EXPECT_EQ(proxy_pref, ProxyConfigDictionary::CreateAutoDetect());
EXPECT_FALSE(ash_proxy_monitor_->IsLacrosExtensionControllingProxy());
result = observer_->WaitForProxyConfig();
EXPECT_TRUE(result->extension.is_null());
}
// Same as the `UserPolicyHasPrecedence` test, but with reverse order of proxies
// applied. This test ensures that priority order is assigned according to proxy
// source and not the latest applied config.
IN_PROC_BROWSER_TEST_F(NetworkSettingsServiceAshExtensionTest,
ExtensionHasLowerPrecedenceThanUserPolicy) {
// Set proxy by policy.
policy::PolicyMap policy;
policy.Set(policy::key::kProxyMode, policy::POLICY_LEVEL_MANDATORY,
policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
base::Value(ProxyPrefs::kDirectProxyModeName), nullptr);
provider_.UpdateChromePolicy(policy);
ProxyConfigDictionary proxy_config_dict(
ProxyConfigDictionary::CreatePacScript(kPacUrl,
/*pac_mandatory=*/true));
// Do not use `SetExtensionProxyInLacros` here because
// `SetExtensionProxyInLacros` will wait until the proxy is changed in Ash and
// an update is sent to a fake observer. Since this test verifies that the
// proxy set by extension has a lower priority, no update should be sent
// here (`SetExtensionProxyInLacros` would wait forever).
SetProxyPref(ProxyConfigDictionary::CreatePacScript(kPacUrl,
/*pac_mandatory=*/true));
const base::Value::Dict& proxy_pref =
browser()->profile()->GetPrefs()->GetDict(proxy_config::prefs::kProxy);
EXPECT_EQ(proxy_pref, ProxyConfigDictionary::CreateDirect());
}
// Proxies set by extensions in the primary profile should have priority in Ash
// over proxies set via ONC policy. This test sets a manual proxy via ONC and a
// PAC proxy via Lacros extension and then verifies that the Lacros proxy has
// priority. It also verifies that after clearing the proxy extension, the
// AshNetworkSettingsService uses the ONC proxy.
IN_PROC_BROWSER_TEST_F(NetworkSettingsServiceAshExtensionTest,
OncPolicyHasLowerPriority) {
SetOncPolicy(kONCPolicyWifi0Proxy, policy::POLICY_SCOPE_USER);
auto result = observer_->WaitForProxyConfig();
EXPECT_TRUE(result->proxy_settings->is_manual());
base::Value::Dict pac_proxy =
ProxyConfigDictionary::CreatePacScript(kPacUrl,
/*pac_mandatory=*/true);
SetExtensionProxyInLacros(pac_proxy.Clone(),
/*can_be_disabled=*/true);
result = observer_->WaitForProxyConfig();
// The first update may have been triggered by the pref change via the Prefs
// service. Wait for update which contains the extension metadata.
if (result->extension.is_null()) {
result = observer_->WaitForProxyConfig();
}
ASSERT_TRUE(result);
EXPECT_TRUE(result->proxy_settings->is_pac());
ASSERT_FALSE(result->extension.is_null());
EXPECT_EQ(result->extension->name, kExtensionName);
EXPECT_EQ(result->extension->id, kExtensionId);
ClearExtensionProxyInLacros();
// Wait for the update which clear the proxy extension metadata and sets the
// proxy value to manual, as specified by the ONC policy.
if (!result->proxy_settings->is_manual()) {
result = observer_->WaitForProxyConfig();
}
EXPECT_TRUE(result->extension.is_null());
}
// Same as the `OncPolicyHasLowerPriority` test, but with reverse order of
// proxies applied. This test ensures that priority order is assigned according
// to proxy source and not the latest applied config.
IN_PROC_BROWSER_TEST_F(NetworkSettingsServiceAshExtensionTest,
ExtensionHasHigherPriorityThanOncPolicy) {
base::Value::Dict pac_proxy =
ProxyConfigDictionary::CreatePacScript(kPacUrl,
/*pac_mandatory=*/true);
SetExtensionProxyInLacros(pac_proxy.Clone(),
/*can_be_disabled=*/true);
// Set a manual proxy.
SetOncPolicy(kONCPolicyWifi0Proxy, policy::POLICY_SCOPE_USER);
auto result = observer_->WaitForProxyConfig();
// The first update may have been triggered by the pref change via the Prefs
// service. Wait for update which sets the extension metadata.
if (result->extension.is_null()) {
result = observer_->WaitForProxyConfig();
}
EXPECT_TRUE(observer_->AreAllProxyUpdatesRead());
// Expect that the PAC proxy set by the extension is still active.
ASSERT_TRUE(result);
EXPECT_TRUE(result->proxy_settings->is_pac());
ASSERT_FALSE(result->extension.is_null());
EXPECT_EQ(result->extension->name, kExtensionName);
EXPECT_EQ(result->extension->id, kExtensionId);
}
} // namespace crosapi

@ -1,34 +0,0 @@
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_CROSAPI_NETWORK_SETTINGS_TRANSLATION_H_
#define CHROME_BROWSER_ASH_CROSAPI_NETWORK_SETTINGS_TRANSLATION_H_
#include "base/values.h"
#include "chromeos/crosapi/mojom/network_settings_service.mojom.h"
#include "url/gurl.h"
class ProxyConfigDictionary;
namespace crosapi {
// Translates the proxy from a ProxyConfigDictionary value to a crosapi mojo
// representation. If the `proxy_config` type is Web Proxy Auto-Detection
// (WPAD), `wpad_url` can specify a PAC URL (useful when the WPAD URL is
// configured via DHCP).
crosapi::mojom::ProxyConfigPtr ProxyConfigToCrosapiProxy(
ProxyConfigDictionary* proxy_dict,
GURL dhcp_wpad_url);
// Translates the proxy from a crosapi mojo representation to a
// ProxyConfigDictionary value. Used when the proxy is being set in the Lacros
// primary profile via an extension and then forwarded to Ash-Chrome via the
// mojo API.
ProxyConfigDictionary CrosapiProxyToProxyConfig(
crosapi::mojom::ProxyConfigPtr crosapi_proxy);
} // namespace crosapi
#endif // CHROME_BROWSER_ASH_CROSAPI_NETWORK_SETTINGS_TRANSLATION_H_

@ -1,208 +0,0 @@
// Copyright 2021 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/crosapi/network_settings_translation.h"
#include "chromeos/crosapi/mojom/network_settings_service.mojom.h"
#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
#include "components/proxy_config/proxy_config_dictionary.h"
#include "net/base/proxy_server.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
constexpr char kPacUrl[] = "http://pac.pac/";
base::Value::Dict GetPacProxyConfig(const std::string& pac_url,
bool pac_mandatory) {
return ProxyConfigDictionary::CreatePacScript(pac_url, pac_mandatory);
}
base::Value::Dict GetManualProxyConfig(const std::string& proxy_servers,
const std::string& bypass_list) {
return ProxyConfigDictionary::CreateFixedServers(proxy_servers, bypass_list);
}
} // namespace
namespace crosapi {
TEST(NetworkSettingsTranslationTest, ProxyConfigToCrosapiProxyDirect) {
ProxyConfigDictionary proxy_dict(ProxyConfigDictionary::CreateDirect());
crosapi::mojom::ProxyConfigPtr actual =
crosapi::ProxyConfigToCrosapiProxy(&proxy_dict,
/*wpad_url=*/GURL(""));
EXPECT_TRUE(actual->proxy_settings->is_direct());
}
TEST(NetworkSettingsTranslationTest, ProxyConfigToCrosapiProxyWpadNoUrl) {
ProxyConfigDictionary proxy_dict(ProxyConfigDictionary::CreateAutoDetect());
crosapi::mojom::ProxyConfigPtr actual =
crosapi::ProxyConfigToCrosapiProxy(&proxy_dict,
/*wpad_url=*/GURL(""));
GURL default_wpad_url("http://wpad/wpad.dat");
ASSERT_TRUE(actual->proxy_settings->is_wpad());
EXPECT_EQ(actual->proxy_settings->get_wpad()->pac_url, default_wpad_url);
}
TEST(NetworkSettingsTranslationTest, ProxyConfigToCrosapiProxyWpadUrl) {
GURL wpad_url(kPacUrl);
ProxyConfigDictionary proxy_dict(ProxyConfigDictionary::CreateAutoDetect());
crosapi::mojom::ProxyConfigPtr actual =
crosapi::ProxyConfigToCrosapiProxy(&proxy_dict, wpad_url);
ASSERT_TRUE(actual->proxy_settings->is_wpad());
EXPECT_EQ(actual->proxy_settings->get_wpad()->pac_url, wpad_url);
}
TEST(NetworkSettingsTranslationTest, ProxyConfigToCrosapiProxyPacMandatory) {
ProxyConfigDictionary proxy_dict(
GetPacProxyConfig(kPacUrl, /*pac_mandatory=*/true));
crosapi::mojom::ProxyConfigPtr actual =
crosapi::ProxyConfigToCrosapiProxy(&proxy_dict,
/*wpad_url=*/GURL(""));
ASSERT_TRUE(actual->proxy_settings->is_pac());
EXPECT_EQ(actual->proxy_settings->get_pac()->pac_url, GURL(kPacUrl));
EXPECT_EQ(actual->proxy_settings->get_pac()->pac_mandatory, true);
}
TEST(NetworkSettingsTranslationTest, ProxyConfigToCrosapiProxyPacNotMandatory) {
ProxyConfigDictionary proxy_dict(
GetPacProxyConfig(kPacUrl, /*pac_mandatory=*/false));
crosapi::mojom::ProxyConfigPtr actual =
crosapi::ProxyConfigToCrosapiProxy(&proxy_dict,
/*wpad_url=*/GURL(""));
ASSERT_TRUE(actual->proxy_settings->is_pac());
EXPECT_EQ(actual->proxy_settings->get_pac()->pac_url, GURL(kPacUrl));
EXPECT_EQ(actual->proxy_settings->get_pac()->pac_mandatory, false);
}
TEST(NetworkSettingsTranslationTest, ProxyConfigToCrosapiProxyManual) {
std::string proxy_servers =
"http=proxy:80;http=proxy2:80;https=secure_proxy:81;socks=socks_proxy:"
"82;";
std::string bypass_list = "localhost;google.com;";
ProxyConfigDictionary proxy_dict(
GetManualProxyConfig(proxy_servers, bypass_list));
crosapi::mojom::ProxyConfigPtr actual =
crosapi::ProxyConfigToCrosapiProxy(&proxy_dict,
/*wpad_url=*/GURL(""));
ASSERT_TRUE(actual->proxy_settings->is_manual());
std::vector<crosapi::mojom::ProxyLocationPtr> proxy_ptr =
std::move(actual->proxy_settings->get_manual()->http_proxies);
ASSERT_EQ(proxy_ptr.size(), 2u);
EXPECT_EQ(proxy_ptr[0]->host, "proxy");
EXPECT_EQ(proxy_ptr[0]->port, 80);
EXPECT_EQ(proxy_ptr[1]->host, "proxy2");
EXPECT_EQ(proxy_ptr[1]->port, 80);
proxy_ptr =
std::move(actual->proxy_settings->get_manual()->secure_http_proxies);
ASSERT_EQ(proxy_ptr.size(), 1u);
EXPECT_EQ(proxy_ptr[0]->host, "secure_proxy");
EXPECT_EQ(proxy_ptr[0]->port, 81);
proxy_ptr = std::move(actual->proxy_settings->get_manual()->socks_proxies);
ASSERT_EQ(proxy_ptr.size(), 1u);
EXPECT_EQ(proxy_ptr[0]->host, "socks_proxy");
EXPECT_EQ(proxy_ptr[0]->port, 82);
const std::vector<std::string> exclude_domains =
actual->proxy_settings->get_manual()->exclude_domains;
ASSERT_EQ(exclude_domains.size(), 2u);
EXPECT_EQ(exclude_domains[0], "localhost");
EXPECT_EQ(exclude_domains[1], "google.com");
}
TEST(NetworkSettingsTranslationTest, CrosapiProxyToProxyConfigDirect) {
crosapi::mojom::ProxyConfigPtr ptr = crosapi::mojom::ProxyConfig::New();
ptr->proxy_settings = crosapi::mojom::ProxySettings::NewDirect(
crosapi::mojom::ProxySettingsDirect::New());
EXPECT_EQ(CrosapiProxyToProxyConfig(std::move(ptr)).GetDictionary(),
ProxyConfigDictionary::CreateDirect());
}
TEST(NetworkSettingsTranslationTest, CrosapiProxyToProxyConfigWpad) {
crosapi::mojom::ProxyConfigPtr ptr = crosapi::mojom::ProxyConfig::New();
crosapi::mojom::ProxySettingsWpadPtr wpad =
crosapi::mojom::ProxySettingsWpad::New();
wpad->pac_url = GURL("pac.pac");
ptr->proxy_settings = crosapi::mojom::ProxySettings::NewWpad(std::move(wpad));
EXPECT_EQ(CrosapiProxyToProxyConfig(std::move(ptr)).GetDictionary(),
ProxyConfigDictionary::CreateAutoDetect());
}
TEST(NetworkSettingsTranslationTest, CrosapiProxyToProxyConfigPac) {
crosapi::mojom::ProxyConfigPtr ptr = crosapi::mojom::ProxyConfig::New();
crosapi::mojom::ProxySettingsPacPtr pac =
crosapi::mojom::ProxySettingsPac::New();
pac->pac_url = GURL(kPacUrl);
pac->pac_mandatory = true;
ptr->proxy_settings = crosapi::mojom::ProxySettings::NewPac(pac.Clone());
EXPECT_EQ(CrosapiProxyToProxyConfig(ptr.Clone()).GetDictionary(),
GetPacProxyConfig(kPacUrl, true));
pac->pac_mandatory = false;
ptr->proxy_settings = crosapi::mojom::ProxySettings::NewPac(pac.Clone());
EXPECT_EQ(CrosapiProxyToProxyConfig(std::move(ptr)).GetDictionary(),
GetPacProxyConfig(kPacUrl, false));
}
TEST(NetworkSettingsTranslationTest, CrosapiProxyToProxyConfigManual) {
crosapi::mojom::ProxyConfigPtr ptr = crosapi::mojom::ProxyConfig::New();
crosapi::mojom::ProxySettingsManualPtr manual =
crosapi::mojom::ProxySettingsManual::New();
crosapi::mojom::ProxyLocationPtr location =
crosapi::mojom::ProxyLocation::New();
location->host = "proxy1";
location->port = 80;
location->scheme = crosapi::mojom::ProxyLocation::Scheme::kHttp;
manual->http_proxies.push_back(location.Clone());
location->host = "proxy2";
location->port = 80;
location->scheme = crosapi::mojom::ProxyLocation::Scheme::kHttps;
manual->http_proxies.push_back(location.Clone());
location->host = "proxy3";
location->port = 83;
location->scheme = crosapi::mojom::ProxyLocation::Scheme::kUnknown;
manual->http_proxies.push_back(location.Clone());
location->host = "proxy4";
location->port = 84;
location->scheme = crosapi::mojom::ProxyLocation::Scheme::kInvalid;
manual->http_proxies.push_back(location.Clone());
location->host = "proxy5";
location->port = 85;
location->scheme = crosapi::mojom::ProxyLocation::Scheme::kDirect;
manual->http_proxies.push_back(location.Clone());
location->host = "proxy6";
location->port = 86;
location->scheme = crosapi::mojom::ProxyLocation::Scheme::kSocks5;
manual->http_proxies.push_back(location.Clone());
location->host = "secure_proxy";
location->port = 81;
location->scheme = crosapi::mojom::ProxyLocation::Scheme::kHttps;
manual->secure_http_proxies.push_back(location.Clone());
location->host = "socks_proxy";
location->port = 82;
location->scheme = crosapi::mojom::ProxyLocation::Scheme::kSocks4;
manual->socks_proxies.push_back(std::move(location));
manual->exclude_domains = {"localhost", "google.com"};
ptr->proxy_settings =
crosapi::mojom::ProxySettings::NewManual(std::move(manual));
EXPECT_EQ(
CrosapiProxyToProxyConfig(std::move(ptr)).GetDictionary(),
GetManualProxyConfig("http=http://proxy1:80;http=https://proxy2:80;"
"http=http://proxy3:83;http=invalid://proxy4:84;"
"http=direct://proxy5:85;http=socks5://proxy6:86;"
"https=https://secure_proxy:81;"
"socks=socks://socks_proxy:82",
/*bypass_list=*/"localhost;google.com"));
}
} // namespace crosapi

@ -211,19 +211,6 @@ void PrefsAsh::SetPref(mojom::PrefPath path,
std::move(callback).Run();
}
void PrefsAsh::ClearExtensionControlledPref(
mojom::PrefPath path,
ClearExtensionControlledPrefCallback callback) {
auto state = GetState(path);
if (state && state->pref_source == AshPrefSource::kExtensionControlled) {
state->pref_service->RemoveStandaloneBrowserPref(state->path);
} else {
// Only logging to be robust against version skew (lacros ahead of ash)
LOG(WARNING) << "Tried to clear a pref that is not extension controlled";
}
std::move(callback).Run();
}
void PrefsAsh::AddObserver(mojom::PrefPath path,
mojo::PendingRemote<mojom::PrefObserver> observer) {
auto state = GetState(path);

@ -56,9 +56,6 @@ class PrefsAsh : public mojom::Prefs,
void GetExtensionPrefWithControl(
mojom::PrefPath path,
GetExtensionPrefWithControlCallback callback) override;
void ClearExtensionControlledPref(
mojom::PrefPath path,
ClearExtensionControlledPrefCallback callback) override;
// ProfileManagerObserver:
void OnProfileAdded(Profile* profile) override;

@ -295,42 +295,6 @@ TEST_F(PrefsAshTest, ExtensionPrefsControllable) {
EXPECT_TRUE(get_value.GetBool());
}
TEST_F(PrefsAshTest, ExtensionPrefsGetSetClear) {
local_state()->registry()->RegisterBooleanPref(
ash::prefs::kDockedMagnifierEnabled, false);
Profile* const profile = CreateProfile();
PrefsAsh prefs_ash(profile_manager(), local_state());
prefs_ash.OnPrimaryProfileReadyForTesting(profile);
mojo::Remote<mojom::Prefs> prefs_remote;
prefs_ash.BindReceiver(prefs_remote.BindNewPipeAndPassReceiver());
mojom::PrefPath path = mojom::PrefPath::kDockedMagnifierEnabled;
prefs_remote->SetPref(path, base::Value(true), base::DoNothing());
prefs_remote.FlushForTesting();
base::Value get_value;
mojom::PrefControlState get_control;
GetExtensionPrefWithControl(prefs_remote, path, &get_value, &get_control);
// Controlled by lacros as it was set above.
EXPECT_EQ(get_control, mojom::PrefControlState::kLacrosExtensionControlled);
EXPECT_TRUE(get_value.GetBool());
// Clear Extension controlled pref.
prefs_remote->ClearExtensionControlledPref(path, base::DoNothing());
prefs_remote.FlushForTesting();
GetExtensionPrefWithControl(prefs_remote, path, &get_value, &get_control);
// Controllable by lacros, as it was unset above. No longer enabled as it
// was cleared.
EXPECT_EQ(get_control, mojom::PrefControlState::kLacrosExtensionControllable);
EXPECT_FALSE(get_value.GetBool());
}
TEST_F(PrefsAshTest, ExtensionPrefsClearNonExtensionPref) {
local_state()->registry()->RegisterBooleanPref(
ash::prefs::kAccessibilitySpokenFeedbackEnabled, false);
@ -348,10 +312,6 @@ TEST_F(PrefsAshTest, ExtensionPrefsClearNonExtensionPref) {
// Note this is the non-extension PrefPath.
mojom::PrefPath path = mojom::PrefPath::kAccessibilitySpokenFeedbackEnabled;
// Does nothing since this is not an extension controlled pref.
prefs_remote->ClearExtensionControlledPref(path, base::DoNothing());
prefs_remote.FlushForTesting();
// Get returns value.
base::Value get_value;
GetPref(prefs_remote, path, &get_value);

@ -1,139 +0,0 @@
// Copyright 2021 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/crosapi/network_settings_translation.h"
#include "base/notreached.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "components/proxy_config/proxy_config_dictionary.h"
#include "components/proxy_config/proxy_config_pref_names.h"
#include "components/proxy_config/proxy_prefs.h"
#include "url/url_constants.h"
namespace {
// Some strings are not URL schemes, but they are given in the same spot in
// the proxy server specifier strings. So we return other strings in that
// case.
constexpr char kInvalidScheme[] = "invalid";
constexpr char kDirectScheme[] = "direct";
constexpr char kSocksScheme[] = "socks";
constexpr char kSocks5Scheme[] = "socks5";
constexpr char kQuicScheme[] = "quic";
// Format the proxy url. The request scheme is the scheme the request to the
// actual web server is using. The proxy scheme is the scheme the proxy is using
// to receive requests. For example a proxy receiving its request through http
// can forward requests going to an https server.
std::string FormatProxyUri(const char* request_scheme,
const crosapi::mojom::ProxyLocationPtr& proxy) {
const char* proxy_scheme_string = url::kHttpScheme;
switch (proxy->scheme) {
// We map kUnknown to HTTP because this will make the proxy setting work for
// most deployments with older ASH browser versions which do not support
// sending the ProxyLocation::Scheme yet, as HTTP is the most commonly used
// scheme for communicating with a HTTP proxy server.
case crosapi::mojom::ProxyLocation::Scheme::kUnknown:
proxy_scheme_string = url::kHttpScheme;
break;
case crosapi::mojom::ProxyLocation::Scheme::kInvalid:
proxy_scheme_string = kInvalidScheme;
break;
case crosapi::mojom::ProxyLocation::Scheme::kDirect:
proxy_scheme_string = kDirectScheme;
break;
case crosapi::mojom::ProxyLocation::Scheme::kHttp:
proxy_scheme_string = url::kHttpScheme;
break;
case crosapi::mojom::ProxyLocation::Scheme::kSocks4:
proxy_scheme_string = kSocksScheme;
break;
case crosapi::mojom::ProxyLocation::Scheme::kSocks5:
proxy_scheme_string = kSocks5Scheme;
break;
case crosapi::mojom::ProxyLocation::Scheme::kHttps:
proxy_scheme_string = url::kHttpsScheme;
break;
case crosapi::mojom::ProxyLocation::Scheme::kQuic:
// Quic support on Chrome OS is experimental. Can be set by an extension
// in the primary profile.
proxy_scheme_string = kQuicScheme;
break;
}
return base::StringPrintf("%s=%s://%s:%d", request_scheme,
proxy_scheme_string, proxy->host.c_str(),
proxy->port);
}
// See //net/docs/proxy.md and net::ProxyConfig::ProxyRules::ParseFromString()
// for translation rules.
base::Value::Dict TranslateManualProxySettings(
crosapi::mojom::ProxySettingsManualPtr proxy_settings) {
std::vector<std::string> proxy_server_specs;
for (auto const& proxy : proxy_settings->http_proxies) {
proxy_server_specs.push_back(FormatProxyUri(url::kHttpScheme, proxy));
}
for (auto const& proxy : proxy_settings->secure_http_proxies) {
proxy_server_specs.push_back(FormatProxyUri(url::kHttpsScheme, proxy));
}
for (auto const& proxy : proxy_settings->socks_proxies) {
proxy_server_specs.push_back(FormatProxyUri(kSocksScheme, proxy));
}
if (proxy_server_specs.empty()) {
return ProxyConfigDictionary::CreateDirect();
}
return ProxyConfigDictionary::CreateFixedServers(
base::JoinString(proxy_server_specs, ";"),
base::JoinString(proxy_settings->exclude_domains, ";"));
}
base::Value::Dict TranslatePacProxySettings(
crosapi::mojom::ProxySettingsPacPtr proxy_settings) {
if (!proxy_settings->pac_url.is_valid())
return ProxyConfigDictionary::CreateDirect();
return ProxyConfigDictionary::CreatePacScript(proxy_settings->pac_url.spec(),
proxy_settings->pac_mandatory);
}
base::Value::Dict TranslateWpadProxySettings(
crosapi::mojom::ProxySettingsWpadPtr proxy_settings) {
return ProxyConfigDictionary::CreateAutoDetect();
}
ProxyConfigDictionary DirectProxyConfig() {
return ProxyConfigDictionary(ProxyConfigDictionary::CreateDirect());
}
} // namespace
namespace crosapi {
ProxyConfigDictionary CrosapiProxyToProxyConfig(
crosapi::mojom::ProxyConfigPtr crosapi_proxy) {
if (!crosapi_proxy)
return DirectProxyConfig();
if (crosapi_proxy->proxy_settings->is_direct())
return DirectProxyConfig();
if (crosapi_proxy->proxy_settings->is_pac())
return ProxyConfigDictionary(TranslatePacProxySettings(
std::move(crosapi_proxy->proxy_settings->get_pac())));
if (crosapi_proxy->proxy_settings->is_wpad())
return ProxyConfigDictionary(TranslateWpadProxySettings(
std::move(crosapi_proxy->proxy_settings->get_wpad())));
if (crosapi_proxy->proxy_settings->is_manual())
return ProxyConfigDictionary(TranslateManualProxySettings(
std::move(crosapi_proxy->proxy_settings->get_manual())));
NOTREACHED() << "Invalid crosapi proxy settings";
}
} // namespace crosapi

@ -1,190 +0,0 @@
// Copyright 2021 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/crosapi/network_settings_translation.h"
#include "base/strings/string_split.h"
#include "components/proxy_config/proxy_config_dictionary.h"
#include "components/proxy_config/proxy_config_pref_names.h"
#include "components/proxy_config/proxy_prefs.h"
#include "net/base/host_port_pair.h"
#include "net/base/proxy_server.h"
#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_list.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
namespace {
crosapi::mojom::ProxyLocation::Scheme NetSchemeToCrosapiScheme(
net::ProxyServer::Scheme in) {
switch (in) {
case net::ProxyServer::Scheme::SCHEME_INVALID:
return crosapi::mojom::ProxyLocation::Scheme::kInvalid;
case net::ProxyServer::Scheme::SCHEME_HTTP:
return crosapi::mojom::ProxyLocation::Scheme::kHttp;
case net::ProxyServer::Scheme::SCHEME_SOCKS4:
return crosapi::mojom::ProxyLocation::Scheme::kSocks4;
case net::ProxyServer::Scheme::SCHEME_SOCKS5:
return crosapi::mojom::ProxyLocation::Scheme::kSocks5;
case net::ProxyServer::Scheme::SCHEME_HTTPS:
return crosapi::mojom::ProxyLocation::Scheme::kHttps;
case net::ProxyServer::Scheme::SCHEME_QUIC:
return crosapi::mojom::ProxyLocation::Scheme::kQuic;
}
return crosapi::mojom::ProxyLocation::Scheme::kUnknown;
}
std::vector<crosapi::mojom::ProxyLocationPtr> TranslateProxyLocations(
const net::ProxyList& proxy_list) {
std::vector<crosapi::mojom::ProxyLocationPtr> proxy_ptr_list;
for (const auto& proxy_chain : proxy_list.AllChains()) {
// TODO(crbug.com/40284947): Remove single hop check when multi-hop proxy
// chains are supported.
CHECK(proxy_chain.is_single_proxy());
net::ProxyServer proxy = proxy_chain.First();
crosapi::mojom::ProxyLocationPtr proxy_ptr;
proxy_ptr = crosapi::mojom::ProxyLocation::New();
proxy_ptr->host = proxy.host_port_pair().host();
proxy_ptr->port = proxy.host_port_pair().port();
proxy_ptr->scheme = NetSchemeToCrosapiScheme(proxy.scheme());
proxy_ptr_list.push_back(std::move(proxy_ptr));
}
return proxy_ptr_list;
}
crosapi::mojom::ProxySettingsManualPtr TranslateManualProxySettings(
ProxyConfigDictionary* proxy_config) {
crosapi::mojom::ProxySettingsManualPtr manual_proxy =
crosapi::mojom::ProxySettingsManual::New();
ProxyPrefs::ProxyMode mode;
DCHECK(proxy_config->GetMode(&mode) &&
mode == ProxyPrefs::MODE_FIXED_SERVERS);
std::string proxy_servers;
if (!proxy_config->GetProxyServer(&proxy_servers)) {
LOG(ERROR) << "Missing manual proxy servers.";
return nullptr;
}
net::ProxyConfig::ProxyRules rules;
rules.ParseFromString(proxy_servers);
switch (rules.type) {
case net::ProxyConfig::ProxyRules::Type::EMPTY:
return nullptr;
case net::ProxyConfig::ProxyRules::Type::PROXY_LIST:
if (!rules.single_proxies.IsEmpty()) {
manual_proxy->http_proxies =
TranslateProxyLocations(rules.single_proxies);
manual_proxy->secure_http_proxies =
TranslateProxyLocations(rules.single_proxies);
manual_proxy->socks_proxies =
TranslateProxyLocations(rules.single_proxies);
}
break;
case net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME:
if (!rules.proxies_for_http.IsEmpty()) {
manual_proxy->http_proxies =
TranslateProxyLocations(rules.proxies_for_http);
}
if (!rules.proxies_for_https.IsEmpty()) {
manual_proxy->secure_http_proxies =
TranslateProxyLocations(rules.proxies_for_https);
}
if (!rules.fallback_proxies.IsEmpty()) {
manual_proxy->socks_proxies =
TranslateProxyLocations(rules.fallback_proxies);
}
break;
}
std::string bypass_list;
if (proxy_config->GetBypassList(&bypass_list) && !bypass_list.empty()) {
manual_proxy->exclude_domains = base::SplitString(
bypass_list, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
}
return manual_proxy;
}
} // namespace
namespace crosapi {
// static
crosapi::mojom::ProxyConfigPtr ProxyConfigToCrosapiProxy(
ProxyConfigDictionary* proxy_dict,
GURL dhcp_wpad_url) {
crosapi::mojom::ProxyConfigPtr proxy_config =
crosapi::mojom::ProxyConfig::New();
crosapi::mojom::ProxySettingsDirectPtr direct =
crosapi::mojom::ProxySettingsDirect::New();
ProxyPrefs::ProxyMode mode;
if (!proxy_dict || !proxy_dict->GetMode(&mode)) {
proxy_config->proxy_settings =
crosapi::mojom::ProxySettings::NewDirect(std::move(direct));
return proxy_config;
}
switch (mode) {
case ProxyPrefs::MODE_DIRECT:
proxy_config->proxy_settings =
crosapi::mojom::ProxySettings::NewDirect(std::move(direct));
break;
case ProxyPrefs::MODE_AUTO_DETECT: {
crosapi::mojom::ProxySettingsWpadPtr wpad =
crosapi::mojom::ProxySettingsWpad::New();
// WPAD with DHCP has a higher priority than DNS.
if (dhcp_wpad_url.is_valid()) {
wpad->pac_url = std::move(dhcp_wpad_url);
} else {
// Fallback to WPAD via DNS.
wpad->pac_url = GURL("http://wpad/wpad.dat");
}
proxy_config->proxy_settings =
crosapi::mojom::ProxySettings::NewWpad(std::move(wpad));
break;
}
case ProxyPrefs::MODE_PAC_SCRIPT: {
std::string pac_url;
if (!proxy_dict->GetPacUrl(&pac_url)) {
proxy_config->proxy_settings =
crosapi::mojom::ProxySettings::NewDirect(std::move(direct));
LOG(ERROR) << "No pac URL for pac_script proxy mode.";
break;
}
bool pac_mandatory = false;
proxy_dict->GetPacMandatory(&pac_mandatory);
crosapi::mojom::ProxySettingsPacPtr pac =
crosapi::mojom::ProxySettingsPac::New();
pac->pac_url = GURL(pac_url);
pac->pac_mandatory = pac_mandatory;
proxy_config->proxy_settings =
crosapi::mojom::ProxySettings::NewPac(std::move(pac));
break;
}
case ProxyPrefs::MODE_FIXED_SERVERS: {
crosapi::mojom::ProxySettingsManualPtr manual =
TranslateManualProxySettings(proxy_dict);
proxy_config->proxy_settings =
crosapi::mojom::ProxySettings::NewManual(std::move(manual));
break;
}
case ProxyPrefs::MODE_SYSTEM:
// This mode means Chrome is getting the settings from the operating
// system. On Chrome OS, ash-chrome is the source of truth for proxy
// settings so this mode is never used.
NOTREACHED() << "The system mode doesn't apply to Ash-Chrome";
default:
LOG(ERROR) << "Incorrect proxy mode.";
proxy_config->proxy_settings =
crosapi::mojom::ProxySettings::NewDirect(std::move(direct));
}
return proxy_config;
}
} // namespace crosapi

@ -192,7 +192,6 @@ source_set("browser_tests") {
"//base/test:test_support",
"//chrome/browser",
"//chrome/browser:browser_process",
"//chrome/browser/ash/crosapi",
"//chrome/browser/ash/login:test_support",
"//chrome/browser/ash/notifications",
"//chrome/browser/ash/policy/affiliation:test_support",
@ -207,7 +206,6 @@ source_set("browser_tests") {
"//chromeos/ash/components/dbus/system_proxy",
"//chromeos/ash/components/dbus/system_proxy:system_proxy_proto",
"//chromeos/ash/components/network",
"//chromeos/crosapi/mojom",
"//components/account_id",
"//components/device_event_log",
"//components/policy/core/browser",

@ -17,7 +17,6 @@ include_rules = [
# individually. Other dependencies within //chrome are listed on a per-
# directory basis. See //tools/chromeos/gen_deps.sh for details.
"+chrome/browser/ash/app_list/arc",
"+chrome/browser/ash/crosapi",
"+chrome/browser/ash/login",
"+chrome/browser/ash/notifications",
"+chrome/browser/ash/ownership",

@ -6,9 +6,6 @@
#include "ash/components/arc/arc_prefs.h"
#include "ash/components/arc/net/always_on_vpn_manager.h"
#include "chrome/browser/ash/crosapi/crosapi_ash.h"
#include "chrome/browser/ash/crosapi/crosapi_manager.h"
#include "chrome/browser/ash/crosapi/network_settings_service_ash.h"
#include "chrome/browser/ash/login/session/user_session_manager.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
@ -110,17 +107,6 @@ void AlwaysOnVpnPreConnectUrlAllowlistService::
PolicyBlocklistFactory::GetForBrowserContext(browser_context_.get());
service->SetAlwaysOnVpnPreConnectUrlAllowlistEnforced(
enforce_alwayson_pre_connect_url_allowlist_);
// Notify the Lacros browser instances (via the `NetworkSettingsService` mojo
// crosapi) that user traffic should be restricted to the URL filters
// configured in the AlwaysOnVpnPreConnectUrlAllowlist policy.
if (crosapi::CrosapiManager::IsInitialized()) {
crosapi::CrosapiManager::Get()
->crosapi_ash()
->network_settings_service_ash()
->SetAlwaysOnVpnPreConnectUrlAllowlistEnforced(
enforce_alwayson_pre_connect_url_allowlist_);
}
}
void AlwaysOnVpnPreConnectUrlAllowlistService::OnShuttingDown() {

@ -25,10 +25,6 @@
namespace {
const char kPrefExtensionNameKey[] = "extension_name_key";
const char kPrefExtensionIdKey[] = "extension_id_key";
const char kPrefExtensionCanDisabledKey[] = "can_be_disabled_key";
// TODO(acostinas,b/267158784) Remove this method after the new version of
// Lacros, which sets the proxy via the mojo Prefs service, is deployed to Ash
// (after minimum four releases to keep up with the version skew).
@ -85,12 +81,6 @@ void AshProxyMonitor::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
// static
void AshProxyMonitor::RegisterProfilePrefs(PrefRegistrySimple* registry) {
registry->RegisterDictionaryPref(
ash::prefs::kLacrosProxyControllingExtension);
}
void AshProxyMonitor::DefaultNetworkChanged(const ash::NetworkState* network) {
if (!network) {
cached_wpad_url_ = GURL();
@ -154,9 +144,8 @@ void AshProxyMonitor::OnProfileAdded(Profile* profile) {
CleanupPrefFromUserStore(primary_profile_);
profile_prefs_registrar_ = std::make_unique<PrefChangeRegistrar>();
profile_prefs_registrar_->Init(primary_profile_->GetPrefs());
// This can be triggered by user policy changes or extensions running in Ash
// or Lacros. The `wpad_url` can only be configured by DHCP and/or DNS
// discovery methods.
// This can be triggered by user policy changes or extensions. The `wpad_url`
// can only be configured by DHCP and/or DNS discovery methods.
profile_prefs_registrar_->Add(
proxy_config::prefs::kProxy,
base::BindRepeating(&AshProxyMonitor::OnProxyChanged,
@ -194,60 +183,4 @@ GURL AshProxyMonitor::GetLatestWpadUrl() const {
return cached_wpad_url_.value_or(GURL());
}
bool AshProxyMonitor::IsLacrosExtensionControllingProxy() const {
if (!primary_profile_) {
return false;
}
auto* pref =
primary_profile_->GetPrefs()->FindPreference(proxy_config::prefs::kProxy);
return pref && pref->IsStandaloneBrowserControlled();
}
void AshProxyMonitor::SetLacrosExtensionControllingProxyInfo(
const std::string& name,
const std::string& id,
bool can_be_disabled) {
DCHECK(primary_profile_) << "The primary profile is not initialized";
CleanupPrefFromUserStore(primary_profile_);
primary_profile_->GetPrefs()->SetDict(
ash::prefs::kLacrosProxyControllingExtension,
base::Value::Dict()
.Set(kPrefExtensionNameKey, name)
.Set(kPrefExtensionIdKey, id)
.Set(kPrefExtensionCanDisabledKey, can_be_disabled));
NotifyObservers();
}
void AshProxyMonitor::ClearLacrosExtensionControllingProxyInfo() {
DCHECK(primary_profile_) << "The primary profile is not initialized";
CleanupPrefFromUserStore(primary_profile_);
primary_profile_->GetPrefs()->ClearPref(
ash::prefs::kLacrosProxyControllingExtension);
NotifyObservers();
}
std::optional<AshProxyMonitor::ExtensionMetadata>
AshProxyMonitor::GetLacrosExtensionControllingTheProxy() const {
if (!IsLacrosExtensionControllingProxy()) {
return std::nullopt;
}
const base::Value::Dict& dictionary = primary_profile_->GetPrefs()->GetDict(
ash::prefs::kLacrosProxyControllingExtension);
const std::string* extension_name =
dictionary.FindString(kPrefExtensionNameKey);
if (!extension_name) {
// Ash received the proxy config from Lacros via the Prefs service but the
// metadata of the extension, which is sent from Lacros via the
// NetworkSettings service, is not yet received.
return std::nullopt;
}
const std::string* extension_id = dictionary.FindString(kPrefExtensionIdKey);
return ExtensionMetadata(
extension_name ? *extension_name : std::string(),
extension_id ? *extension_id : std::string(),
dictionary.FindBool(kPrefExtensionCanDisabledKey).value_or(false));
}
} // namespace ash

@ -19,7 +19,6 @@
class PrefService;
class PrefChangeRegistrar;
class PrefRegistrySimple;
class Profile;
class ProfileManager;
@ -50,8 +49,7 @@ class COMPONENT_EXPORT(CHROMEOS_NETWORK) AshProxyMonitor
class COMPONENT_EXPORT(CHROMEOS_NETWORK) Observer
: public base::CheckedObserver {
public:
// Called when the effective proxy config changes in Ash or when the
// metadata of the Lacros extension controlling the proxy changes.
// Called when the effective proxy config changes.
virtual void OnProxyChanged() = 0;
};
@ -65,25 +63,6 @@ class COMPONENT_EXPORT(CHROMEOS_NETWORK) AshProxyMonitor
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
static void RegisterProfilePrefs(PrefRegistrySimple* registry);
// Indicates if the proxy is controlled by an extension running in the primary
// profile in Lacros.
bool IsLacrosExtensionControllingProxy() const;
// Stores as a user preference the metadata about the extension which is
// controlling the pref in the Lacros primary profile. The metadata can be
// retrieved by calling `GetLacrosExtensionControllingTheProxy` method.
void SetLacrosExtensionControllingProxyInfo(const std::string& name,
const std::string& id,
bool can_be_disabled);
// If the `kProxy` pref is controlled by an extension running in the Lacros
// browser associated with the primary profile, these method returns metadata
// about the extension, otherwise it returns a null object.
std::optional<ExtensionMetadata> GetLacrosExtensionControllingTheProxy()
const;
void ClearLacrosExtensionControllingProxyInfo();
void SetProfileForTesting(Profile* profile);
ProxyConfigDictionary* GetLatestProxyConfig() const;

@ -9,7 +9,6 @@
#include "ash/constants/ash_pref_names.h"
#include "base/test/repeating_test_future.h"
#include "base/test/test_future.h"
#include "chrome/browser/ash/crosapi/prefs_ash.h"
#include "chrome/browser/ash/net/ash_proxy_monitor.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
@ -21,8 +20,6 @@
#include "chromeos/ash/components/dbus/shill/shill_profile_client.h"
#include "chromeos/ash/components/dbus/shill/shill_service_client.h"
#include "chromeos/ash/components/network/network_state_handler.h"
#include "chromeos/crosapi/mojom/network_settings_service.mojom.h"
#include "chromeos/crosapi/mojom/prefs.mojom.h"
#include "components/policy/core/browser/browser_policy_connector.h"
#include "components/policy/core/common/mock_configuration_policy_provider.h"
#include "components/policy/core/common/policy_map.h"
@ -40,12 +37,6 @@ namespace {
constexpr char kPacUrl[] = "http://pac.pac/";
constexpr char kExtensionName[] = "Lacros Test Extension Name";
constexpr char kExtensionId[] = "Lacros Test Extension ID";
constexpr char kPrefExtensionNameKey[] = "extension_name_key";
constexpr char kPrefExtensionIdKey[] = "extension_id_key";
constexpr char kPrefExtensionCanDisabledKey[] = "can_be_disabled_key";
constexpr char kDefaultServicePath[] = "default_wifi";
constexpr char kDefaultServiceSsid[] = "default_wifi_guid";
constexpr char kDefaultServiceGuid[] = "eth0";
@ -113,22 +104,6 @@ base::Value::Dict GetManualProxyConfig(const std::string& proxy_servers) {
proxy_servers, /*bypass_list=*/std::string());
}
class TestPrefObserver : public crosapi::mojom::PrefObserver {
public:
TestPrefObserver() = default;
TestPrefObserver(const TestPrefObserver&) = delete;
TestPrefObserver& operator=(const TestPrefObserver&) = delete;
~TestPrefObserver() override = default;
// crosapi::mojom::PrefObserver:
void OnPrefChanged(base::Value value) override {
future_.AddValue(std::move(value));
}
base::Value Wait() { return future_.Take(); }
base::test::RepeatingTestFuture<base::Value> future_;
mojo::Receiver<crosapi::mojom::PrefObserver> receiver_{this};
};
} // namespace
namespace ash {
@ -184,7 +159,6 @@ class AshProxyMonitorTest : public InProcessBrowserTest {
void SetUpOnMainThread() override {
InProcessBrowserTest::SetUpOnMainThread();
SetupFakePrefService();
SetupNetworkEnvironment();
ash_proxy_monitor_observer_ =
std::make_unique<TestAshProxyMonitorObserver>();
@ -195,7 +169,6 @@ class AshProxyMonitorTest : public InProcessBrowserTest {
void TearDownOnMainThread() override {
ash_proxy_monitor_observer_.reset();
prefs_observer_.reset();
}
void SetupNetworkEnvironment() {
@ -209,18 +182,6 @@ class AshProxyMonitorTest : public InProcessBrowserTest {
kDefaultServiceGuid);
}
void SetupFakePrefService() {
prefs_ash_ = std::make_unique<crosapi::PrefsAsh>(
g_browser_process->profile_manager(), g_browser_process->local_state());
mojo::Remote<crosapi::mojom::Prefs> prefs_ash_remote;
prefs_ash_->BindReceiver(prefs_ash_remote.BindNewPipeAndPassReceiver());
prefs_observer_ = std::make_unique<TestPrefObserver>();
prefs_ash_remote->AddObserver(
crosapi::mojom::PrefPath::kProxy,
prefs_observer_->receiver_.BindNewPipeAndPassRemote());
prefs_ash_->OnProfileAdded(browser()->profile());
}
void ConnectWifiNetworkService(const std::string& service_path,
const std::string& guid,
const std::string& ssid) {
@ -242,21 +203,6 @@ class AshProxyMonitorTest : public InProcessBrowserTest {
value);
}
void ClearProxyPrefFromLacrosExtension() {
base::test::TestFuture<void> future;
prefs_ash_->ClearExtensionControlledPref(crosapi::mojom::PrefPath::kProxy,
future.GetCallback());
EXPECT_TRUE(future.Wait());
}
void SetProxyPrefFromLacrosExtension(base::Value::Dict proxy_dict) {
base::test::TestFuture<void> future;
prefs_ash_->SetPref(crosapi::mojom::PrefPath::kProxy,
base::Value(std::move(proxy_dict)),
future.GetCallback());
EXPECT_TRUE(future.Wait());
}
void SetDhcpWpadUrl(const std::string& dhcp_url,
const std::string& service_path) {
auto wpad_config = base::Value::Dict().Set(
@ -271,8 +217,6 @@ class AshProxyMonitorTest : public InProcessBrowserTest {
service_test->SetServiceProperty(service_path, shill::kIPConfigProperty,
base::Value(kIPConfigPath));
}
std::unique_ptr<crosapi::PrefsAsh> prefs_ash_;
std::unique_ptr<TestPrefObserver> prefs_observer_;
policy::MockConfigurationPolicyProvider provider_;
std::unique_ptr<TestAshProxyMonitorObserver> ash_proxy_monitor_observer_;
@ -340,9 +284,6 @@ IN_PROC_BROWSER_TEST_F(AshProxyMonitorTest, ProxyPrefChanges) {
std::tuple<base::Value::Dict, GURL> result =
ash_proxy_monitor_observer_->WaitForUpdate();
EXPECT_EQ(std::get<0>(result), GetPacProxyConfig(kPacUrl));
EXPECT_FALSE(g_browser_process->platform_part()
->ash_proxy_monitor()
->IsLacrosExtensionControllingProxy());
// Clear the policy pref.
policy.Erase(policy::key::kProxyMode);
@ -386,39 +327,4 @@ IN_PROC_BROWSER_TEST_F(AshProxyMonitorTest, OrderOfPrecedence) {
EXPECT_TRUE(ash_proxy_monitor_observer_->AreAllProxyUpdatesRead());
}
IN_PROC_BROWSER_TEST_F(AshProxyMonitorTest, LacrosExtensionProxyPrefChanges) {
SetProxyPrefFromLacrosExtension(GetPacProxyConfig(kPacUrl));
std::tuple<base::Value::Dict, GURL> result =
ash_proxy_monitor_observer_->WaitForUpdate();
EXPECT_EQ(std::get<0>(result), GetPacProxyConfig(kPacUrl));
auto* ash_proxy_monitor =
g_browser_process->platform_part()->ash_proxy_monitor();
EXPECT_TRUE(ash_proxy_monitor->IsLacrosExtensionControllingProxy());
// Update the extension metadata.
ash_proxy_monitor->SetLacrosExtensionControllingProxyInfo(
kExtensionName, kExtensionId, false);
auto* pref_service = browser()->profile()->GetPrefs();
EXPECT_EQ(pref_service->GetDict(ash::prefs::kLacrosProxyControllingExtension),
base::Value::Dict()
.Set(kPrefExtensionNameKey, kExtensionName)
.Set(kPrefExtensionIdKey, kExtensionId)
.Set(kPrefExtensionCanDisabledKey, false));
auto extension = ash_proxy_monitor->GetLacrosExtensionControllingTheProxy();
EXPECT_EQ(extension->name, kExtensionName);
EXPECT_EQ(extension->id, kExtensionId);
EXPECT_EQ(extension->can_be_disabled, false);
ClearProxyPrefFromLacrosExtension();
ash_proxy_monitor->ClearLacrosExtensionControllingProxyInfo();
while (std::get<0>(result) != ProxyConfigDictionary::CreateDirect()) {
result = ash_proxy_monitor_observer_->WaitForUpdate();
}
EXPECT_FALSE(ash_proxy_monitor->GetLacrosExtensionControllingTheProxy());
}
} // namespace ash

@ -434,8 +434,6 @@ const PrefsUtil::TypedPrefMap& PrefsUtil::GetAllowlistedKeys() {
(*s_allowlist)[ash::prefs::kOrcaEnabled] = settings_api::PrefType::kBoolean;
(*s_allowlist)[ash::prefs::kEmojiSuggestionEnabled] =
settings_api::PrefType::kBoolean;
(*s_allowlist)[ash::prefs::kLacrosProxyControllingExtension] =
settings_api::PrefType::kDictionary;
(*s_allowlist)[::prefs::kLanguageInputMethodSpecificSettings] =
settings_api::PrefType::kDictionary;
(*s_allowlist)[ash::prefs::kLastUsedImeShortcutReminderDismissed] =

@ -1116,10 +1116,10 @@ constexpr char kNoteTakingAppsLockScreenToastShown[] =
constexpr char kRestoreLastLockScreenNote[] =
"settings.restore_last_lock_screen_note";
constexpr char kLockScreenDataPrefKey[] = "lockScreenDataItems";
// Deprecated 11/2024
inline constexpr char kSyncableVersionedWallpaperInfo[] =
"syncable_versioned_wallpaper_info";
constexpr char kLacrosProxyControllingExtension[] =
"ash.lacros_proxy_controlling_extension";
#endif
// Deprecated 11/2024
@ -1631,9 +1631,8 @@ void RegisterProfilePrefsForMigration(
base::Value::List());
registry->RegisterDictionaryPref(kNoteTakingAppsLockScreenToastShown);
registry->RegisterBooleanPref(kRestoreLastLockScreenNote, false);
// Deprecated 11/2024
registry->RegisterDictionaryPref(kSyncableVersionedWallpaperInfo);
registry->RegisterDictionaryPref(kLacrosProxyControllingExtension);
#endif
// Deprecated 11/2024
@ -2273,7 +2272,6 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry,
ash::ApkWebAppService::RegisterProfilePrefs(registry);
ash::app_time::AppActivityRegistry::RegisterProfilePrefs(registry);
ash::app_time::AppTimeController::RegisterProfilePrefs(registry);
ash::AshProxyMonitor::RegisterProfilePrefs(registry);
ash::assistant::prefs::RegisterProfilePrefs(registry);
ash::auth::AuthFactorConfig::RegisterPrefs(registry);
ash::bluetooth::DebugLogsManager::RegisterPrefs(registry);
@ -3007,9 +3005,8 @@ void MigrateObsoleteProfilePrefs(PrefService* profile_prefs,
profile_prefs->ClearPref(kNoteTakingAppsLockScreenAllowlist);
profile_prefs->ClearPref(kNoteTakingAppsLockScreenToastShown);
profile_prefs->ClearPref(kRestoreLastLockScreenNote);
// Deprecated 11/2024
profile_prefs->ClearPref(kSyncableVersionedWallpaperInfo);
profile_prefs->ClearPref(kLacrosProxyControllingExtension);
#endif
// Added 11/2024

@ -78,7 +78,6 @@ mojom("mojom") {
"multi_capture_service.mojom",
"native_theme.mojom",
"network_change.mojom",
"network_settings_service.mojom",
"networking_attributes.mojom",
"networking_private.mojom",
"nonclosable_app_toast_service.mojom",

@ -77,7 +77,6 @@ import "chromeos/crosapi/mojom/networking_private.mojom";
import "chromeos/crosapi/mojom/one_drive_notification_service.mojom";
import "chromeos/crosapi/mojom/one_drive_integration_service.mojom";
import "chromeos/crosapi/mojom/power.mojom";
import "chromeos/crosapi/mojom/network_settings_service.mojom";
import "chromeos/crosapi/mojom/parent_access.mojom";
import "chromeos/crosapi/mojom/passkeys.mojom";
import "chromeos/crosapi/mojom/prefs.mojom";
@ -425,12 +424,7 @@ interface Crosapi {
BindInSessionAuth@96(
pending_receiver<chromeos.auth.mojom.InSessionAuth> receiver);
// Binds the NetworkSettingsService interface for reading and observing
// network changes.
// Added in M93.
[MinVersion=41]
BindNetworkSettingsService@46(
pending_receiver<NetworkSettingsService> receiver);
// BindNetworkSettingsService@46 was removed.
// Binds the KerberosInBrowser interface for showing Kerberos UI.
// Added in M114.

@ -1,136 +0,0 @@
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module crosapi.mojom;
import "url/mojom/url.mojom";
struct ProxyLocation {
// Host (or IP address) to use for proxy.
string host;
int32 port;
[Extensible]
enum Scheme {
[Default] kUnknown,
kInvalid,
kDirect,
kHttp,
kSocks4,
kSocks5,
kHttps,
kQuic,
};
// Identifies the scheme which is used to connect to the proxy. This is
// independent of the type of the transmitted requests, e.g. it does not
// have to be kHttps for a proxy which handles https requests. That's why
// it has to be transmitted.
[MinVersion=1] Scheme scheme;
};
// Description of the extension in the primary profile which is controlling the
// OS proxy configuration. It is sent from Lacros' primary profile to Ash and
// from Ash to all profiles in Lacros, the PlayStore and Chrome OS system
// services.
// Note: In the Lacros primary profile, the extension set proxy has priority so
// proxy updates coming from the OS are ignored.
struct ExtensionControllingProxy {
string name;
string id;
[MinVersion=1] bool can_be_disabled;
};
struct ProxySettingsDirect {};
struct ProxySettingsManual {
array<ProxyLocation> http_proxies;
array<ProxyLocation> secure_http_proxies;
array<ProxyLocation> socks_proxies;
// Domains and hosts for which to exclude proxy settings.
array<string> exclude_domains;
};
struct ProxySettingsPac {
url.mojom.Url pac_url;
// If true, network traffic does not fall back to direct connections in
// case the PAC script is not available.
bool pac_mandatory;
};
struct ProxySettingsWpad {
url.mojom.Url pac_url;
};
union ProxySettings {
ProxySettingsDirect direct;
ProxySettingsManual manual;
ProxySettingsPac pac;
ProxySettingsWpad wpad;
};
// TODO(crbug.com/40284947): Add support for proxy chains.
struct ProxyConfig {
ProxySettings proxy_settings;
// Identifies the extension controlling the proxy.
ExtensionControllingProxy? extension;
};
// Implemented by Lacros-Chrome.
interface NetworkSettingsObserver {
// This methods is called when:
// - the observer is added to the `NetworkSettingsService`;
// - the proxy configuration in Ash is updated;
// - the WPAD URL on the default network is updated.
OnProxyChanged@0(ProxyConfig proxy_config);
// Enforcement of the `AlwaysOnVpnPreConnectUrlAllowlist` pref in the
// browser is determined by the network configuration and preference
// settings. This method is called when updates of the network and/or
// prefs settings change whether the `AlwaysOnVpnPreConnectUrlAllowlist`
// pref should be applied or not.
[MinVersion=1]
OnAlwaysOnVpnPreConnectUrlAllowlistEnforcedChanged@1(bool enfoced);
};
// Implemented by Ash-Chrome.
[Uuid="e8916037-b993-454a-96ef-20f269cace54"]
interface NetworkSettingsService {
// Adds an Ash network settings service observer.
// If a proxy is configured in Ash, the observer will be notified of the
// current proxy configuration as part of this call.
AddNetworkSettingsObserver@0(
pending_remote<NetworkSettingsObserver> observer);
// DEPRECATED. The proxy pref set by a Lacros extension is synced via the
// Prefs mojo service. Please use `SetExtensionControllingProxyMetadata` to
// set the extension metadata.
// Used by the Lacros browser to forward proxy configurations set via
// extensions in the primary profile to Ash. `proxy_config` must specify the
// extension setting the proxy.
[MinVersion=1]
SetExtensionProxy@1(ProxyConfig proxy_config);
// DEPRECATED. The proxy pref set by a Lacros extension is cleared via the
// Prefs mojo service. Please use `ClearExtensionControllingProxyMetadata`
// to clear the extension metadata.
// Used by the Lacros browser to clear proxy configurations set via
// extensions in the primary profile to Ash.
[MinVersion=1]
ClearExtensionProxy@2();
// Used by the Lacros browser to forward metadata about the extension which
// is controlling the proxy settings in the Lacros primary profile.
// TODO(b/268607394): When the Prefs mojo service carries source metadata
// along with the pref value, deprecate this method and rely on the Prefs
// mojo service for this information.
[MinVersion=2]
SetExtensionControllingProxyMetadata@3(ExtensionControllingProxy extension);
// Used by the Lacros browser to clear metadata about the extension which
// used to control the proxy settings in the Lacros primary profile.
[MinVersion=2]
ClearExtensionControllingProxyMetadata@4();
// Returns a boolean which indicates if user traffic should be restricted to
// URL filters configured via the `AlwaysOnVpnPreConnectUrlAllowlist` pref.
[MinVersion=3]
IsAlwaysOnVpnPreConnectUrlAllowlistEnforced@5() => (bool enabled);
};

@ -200,10 +200,7 @@ interface Prefs {
// registered.
SetPref@1(PrefPath path, mojo_base.mojom.Value value) => ();
// Clears the value of the specified ash pref set by lacros.
// The pref must be extension-controlled.
[MinVersion=2]
ClearExtensionControlledPref@4(PrefPath path) => ();
// ClearExtensionControlledPref@4 was removed.
// Adds an observer for ash pref. The observer is fired immediately with the
// current value. Multiple observers may be registered for any given pref.

@ -713,16 +713,6 @@ void PrefService::SetStandaloneBrowserPref(std::string_view path,
path, value.Clone(), WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
}
void PrefService::RemoveStandaloneBrowserPref(std::string_view path) {
if (!standalone_browser_pref_store_) {
LOG(WARNING) << "Failure to remove value of " << path
<< " in standalone browser store";
return;
}
standalone_browser_pref_store_->RemoveValue(
path, WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
}
void PrefService::RemoveAllStandaloneBrowserPrefs() {
if (!standalone_browser_pref_store_) {
LOG(WARNING) << "standalone_browser_pref_store_ is null";

@ -413,8 +413,6 @@ class COMPONENTS_PREFS_EXPORT PrefService {
// Write extension-controlled prefs from Lacros in ash.
void SetStandaloneBrowserPref(std::string_view path,
const base::Value& value);
// Clear extension-controlled prefs from Lacros in ash.
void RemoveStandaloneBrowserPref(std::string_view path);
// Clear all prefs in standalone_browser_pref_store_. Use it when rolling back
// to Ash (i.e. disabling Lacros).