// Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "content/browser/network_service_client.h" #include <utility> #include "base/bind.h" #include "base/feature_list.h" #include "base/task/post_task.h" #include "base/threading/sequence_bound.h" #include "base/unguessable_token.h" #include "content/browser/browsing_data/clear_site_data_handler.h" #include "content/browser/renderer_host/frame_tree_node.h" #include "content/browser/ssl/ssl_manager.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/browser/webrtc/webrtc_connections_observer.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/global_request_id.h" #include "content/public/browser/network_service_instance.h" #include "content/public/common/content_client.h" #include "content/public/common/content_features.h" #include "content/public/common/network_service_util.h" #include "services/network/public/cpp/network_switches.h" #include "services/network/public/mojom/network_context.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/mojom/web_feature/web_feature.mojom.h" #if defined(OS_ANDROID) #include "base/android/content_uri_utils.h" #endif #if defined(OS_MAC) #include "base/task/current_thread.h" #endif namespace content { NetworkServiceClient::NetworkServiceClient() #if defined(OS_ANDROID) : app_status_listener_(base::android::ApplicationStatusListener::New( base::BindRepeating(&NetworkServiceClient::OnApplicationStateChange, base::Unretained(this)))) #endif { #if defined(OS_MAC) if (base::CurrentUIThread::IsSet()) // Not set in some unit tests. net::CertDatabase::GetInstance()->StartListeningForKeychainEvents(); #endif if (IsOutOfProcessNetworkService()) { net::CertDatabase::GetInstance()->AddObserver(this); memory_pressure_listener_ = std::make_unique<base::MemoryPressureListener>( FROM_HERE, base::BindRepeating(&NetworkServiceClient::OnMemoryPressure, base::Unretained(this))); #if defined(OS_ANDROID) DCHECK(!net::NetworkChangeNotifier::CreateIfNeeded()); GetNetworkService()->GetNetworkChangeManager( network_change_manager_.BindNewPipeAndPassReceiver()); net::NetworkChangeNotifier::AddConnectionTypeObserver(this); net::NetworkChangeNotifier::AddMaxBandwidthObserver(this); net::NetworkChangeNotifier::AddIPAddressObserver(this); net::NetworkChangeNotifier::AddDNSObserver(this); #endif } webrtc_connections_observer_ = std::make_unique<content::WebRtcConnectionsObserver>(base::BindRepeating( &NetworkServiceClient::OnPeerToPeerConnectionsCountChange, base::Unretained(this))); } NetworkServiceClient::~NetworkServiceClient() { if (IsOutOfProcessNetworkService()) { net::CertDatabase::GetInstance()->RemoveObserver(this); #if defined(OS_ANDROID) net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); net::NetworkChangeNotifier::RemoveMaxBandwidthObserver(this); net::NetworkChangeNotifier::RemoveIPAddressObserver(this); net::NetworkChangeNotifier::RemoveDNSObserver(this); #endif } } void NetworkServiceClient::OnCertDBChanged() { GetNetworkService()->OnCertDBChanged(); } void NetworkServiceClient::OnMemoryPressure( base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) { GetNetworkService()->OnMemoryPressure(memory_pressure_level); } void NetworkServiceClient::OnPeerToPeerConnectionsCountChange(uint32_t count) { GetNetworkService()->OnPeerToPeerConnectionsCountChange(count); } #if defined(OS_ANDROID) void NetworkServiceClient::OnApplicationStateChange( base::android::ApplicationState state) { GetNetworkService()->OnApplicationStateChange(state); } void NetworkServiceClient::OnConnectionTypeChanged( net::NetworkChangeNotifier::ConnectionType type) { network_change_manager_->OnNetworkChanged( false /* dns_changed */, false /* ip_address_changed */, true /* connection_type_changed */, network::mojom::ConnectionType(type), false /* connection_subtype_changed */, network::mojom::ConnectionSubtype( net::NetworkChangeNotifier::GetConnectionSubtype())); } void NetworkServiceClient::OnMaxBandwidthChanged( double max_bandwidth_mbps, net::NetworkChangeNotifier::ConnectionType type) { // The connection subtype change will trigger a max bandwidth change in the // network service notifier. network_change_manager_->OnNetworkChanged( false /* dns_changed */, false /* ip_address_changed */, false /* connection_type_changed */, network::mojom::ConnectionType(type), true /* connection_subtype_changed */, network::mojom::ConnectionSubtype( net::NetworkChangeNotifier::GetConnectionSubtype())); } void NetworkServiceClient::OnIPAddressChanged() { network_change_manager_->OnNetworkChanged( false /* dns_changed */, true /* ip_address_changed */, false /* connection_type_changed */, network::mojom::ConnectionType( net::NetworkChangeNotifier::GetConnectionType()), false /* connection_subtype_changed */, network::mojom::ConnectionSubtype( net::NetworkChangeNotifier::GetConnectionSubtype())); } void NetworkServiceClient::OnDNSChanged() { network_change_manager_->OnNetworkChanged( true /* dns_changed */, false /* ip_address_changed */, false /* connection_type_changed */, network::mojom::ConnectionType( net::NetworkChangeNotifier::GetConnectionType()), false /* connection_subtype_changed */, network::mojom::ConnectionSubtype( net::NetworkChangeNotifier::GetConnectionSubtype())); } #endif mojo::PendingRemote<network::mojom::URLLoaderNetworkServiceObserver> NetworkServiceClient::BindURLLoaderNetworkServiceObserver() { mojo::PendingRemote<network::mojom::URLLoaderNetworkServiceObserver> remote; url_loader_network_service_observers_.Add( this, remote.InitWithNewPipeAndPassReceiver()); return remote; } void NetworkServiceClient::OnSSLCertificateError( const GURL& url, int net_error, const net::SSLInfo& ssl_info, bool fatal, OnSSLCertificateErrorCallback response) { std::move(response).Run(net::ERR_INSECURE_RESPONSE); } void NetworkServiceClient::OnCertificateRequested( const absl::optional<base::UnguessableToken>& window_id, const scoped_refptr<net::SSLCertRequestInfo>& cert_info, mojo::PendingRemote<network::mojom::ClientCertificateResponder> cert_responder_remote) { mojo::Remote<network::mojom::ClientCertificateResponder> cert_responder( std::move(cert_responder_remote)); if (base::CommandLine::ForCurrentProcess()->HasSwitch( network::switches::kIgnoreUrlFetcherCertRequests)) { cert_responder->ContinueWithoutCertificate(); return; } cert_responder->CancelRequest(); } void NetworkServiceClient::OnAuthRequired( const absl::optional<base::UnguessableToken>& window_id, uint32_t request_id, const GURL& url, bool first_auth_attempt, const net::AuthChallengeInfo& auth_info, const scoped_refptr<net::HttpResponseHeaders>& head_headers, mojo::PendingRemote<network::mojom::AuthChallengeResponder> auth_challenge_responder) { mojo::Remote<network::mojom::AuthChallengeResponder> auth_challenge_responder_remote(std::move(auth_challenge_responder)); auth_challenge_responder_remote->OnAuthCredentials(absl::nullopt); } void NetworkServiceClient::OnClearSiteData(const GURL& url, const std::string& header_value, int load_flags, OnClearSiteDataCallback callback) { std::move(callback).Run(); } void NetworkServiceClient::OnLoadingStateUpdate( network::mojom::LoadInfoPtr info, OnLoadingStateUpdateCallback callback) { std::move(callback).Run(); } void NetworkServiceClient::OnDataUseUpdate( int32_t network_traffic_annotation_id_hash, int64_t recv_bytes, int64_t sent_bytes) { GetContentClient()->browser()->OnNetworkServiceDataUseUpdate( network::mojom::kBrowserProcessId, MSG_ROUTING_NONE, network_traffic_annotation_id_hash, recv_bytes, sent_bytes); } void NetworkServiceClient::Clone( mojo::PendingReceiver<network::mojom::URLLoaderNetworkServiceObserver> observer) { url_loader_network_service_observers_.Add(this, std::move(observer)); } } // namespace content