1 // Copyright 2012 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_BASE_NETWORK_CHANGE_NOTIFIER_APPLE_H_ 6 #define NET_BASE_NETWORK_CHANGE_NOTIFIER_APPLE_H_ 7 8 #include <SystemConfiguration/SystemConfiguration.h> 9 10 #include <memory> 11 #include <optional> 12 13 #include "base/apple/scoped_cftyperef.h" 14 #include "base/compiler_specific.h" 15 #include "base/functional/callback_forward.h" 16 #include "base/memory/raw_ptr.h" 17 #include "base/memory/scoped_refptr.h" 18 #include "base/synchronization/condition_variable.h" 19 #include "base/synchronization/lock.h" 20 #include "build/build_config.h" 21 #include "net/base/net_export.h" 22 #include "net/base/network_change_notifier.h" 23 #include "net/base/network_config_watcher_apple.h" 24 #include "net/base/network_interfaces.h" 25 #include "net/log/net_log_with_source.h" 26 27 namespace net { 28 29 class NET_EXPORT_PRIVATE NetworkChangeNotifierApple 30 : public NetworkChangeNotifier { 31 public: 32 NetworkChangeNotifierApple(); 33 NetworkChangeNotifierApple(const NetworkChangeNotifierApple&) = delete; 34 NetworkChangeNotifierApple& operator=(const NetworkChangeNotifierApple&) = delete; 35 ~NetworkChangeNotifierApple() override; 36 37 // NetworkChangeNotifier implementation: 38 ConnectionType GetCurrentConnectionType() const override; 39 40 // Forwarder just exists to keep the NetworkConfigWatcherApple API out of 41 // NetworkChangeNotifierApple's public API. 42 class Forwarder : public NetworkConfigWatcherApple::Delegate { 43 public: Forwarder(NetworkChangeNotifierApple * net_config_watcher)44 explicit Forwarder(NetworkChangeNotifierApple* net_config_watcher) 45 : net_config_watcher_(net_config_watcher) {} 46 Forwarder(const Forwarder&) = delete; 47 Forwarder& operator=(const Forwarder&) = delete; 48 49 // NetworkConfigWatcherApple::Delegate implementation: 50 void Init() override; 51 void StartReachabilityNotifications() override; 52 void SetDynamicStoreNotificationKeys( 53 base::apple::ScopedCFTypeRef<SCDynamicStoreRef> store) override; 54 void OnNetworkConfigChange(CFArrayRef changed_keys) override; 55 void CleanUpOnNotifierThread() override; 56 57 private: 58 const raw_ptr<NetworkChangeNotifierApple> net_config_watcher_; 59 }; 60 61 private: 62 friend class NetworkChangeNotifierAppleTest; 63 64 // Called on the main thread on startup, afterwards on the notifier thread. 65 static ConnectionType CalculateConnectionType(SCNetworkConnectionFlags flags); 66 67 // Methods directly called by the NetworkConfigWatcherApple::Delegate: 68 void StartReachabilityNotifications(); 69 void SetDynamicStoreNotificationKeys( 70 base::apple::ScopedCFTypeRef<SCDynamicStoreRef> store); 71 void OnNetworkConfigChange(CFArrayRef changed_keys); 72 void CleanUpOnNotifierThread(); 73 74 void SetInitialConnectionType(); 75 76 static void ReachabilityCallback(SCNetworkReachabilityRef target, 77 SCNetworkConnectionFlags flags, 78 void* notifier); 79 80 static NetworkChangeCalculatorParams NetworkChangeCalculatorParamsMac(); 81 82 #if BUILDFLAG(IS_MAC) 83 void SetCallbacksForTest( 84 base::OnceClosure initialized_callback, 85 base::RepeatingCallback<bool(NetworkInterfaceList*, int)> 86 get_network_list_callback, 87 base::RepeatingCallback<std::string(SCDynamicStoreRef)> 88 get_ipv4_primary_interface_name_callback, 89 base::RepeatingCallback<std::string(SCDynamicStoreRef)> 90 get_ipv6_primary_interface_name_callback); 91 #endif // BUILDFLAG(IS_MAC) 92 93 // These must be constructed before config_watcher_ to ensure 94 // the lock is in a valid state when Forwarder::Init is called. 95 ConnectionType connection_type_ = CONNECTION_UNKNOWN; 96 bool connection_type_initialized_ = false; 97 mutable base::Lock connection_type_lock_; 98 mutable base::ConditionVariable initial_connection_type_cv_; 99 base::apple::ScopedCFTypeRef<SCNetworkReachabilityRef> reachability_; 100 base::apple::ScopedCFTypeRef<CFRunLoopRef> run_loop_; 101 102 Forwarder forwarder_; 103 std::unique_ptr<NetworkConfigWatcherApple> config_watcher_; 104 105 #if BUILDFLAG(IS_MAC) 106 const bool reduce_ip_address_change_notification_; 107 base::apple::ScopedCFTypeRef<SCDynamicStoreRef> store_; 108 std::optional<NetworkInterfaceList> interfaces_for_network_change_check_; 109 std::string ipv4_primary_interface_name_; 110 std::string ipv6_primary_interface_name_; 111 112 base::OnceClosure initialized_callback_for_test_; 113 base::RepeatingCallback<bool(NetworkInterfaceList*, int)> 114 get_network_list_callback_; 115 base::RepeatingCallback<std::string(SCDynamicStoreRef)> 116 get_ipv4_primary_interface_name_callback_; 117 base::RepeatingCallback<std::string(SCDynamicStoreRef)> 118 get_ipv6_primary_interface_name_callback_; 119 #endif // BUILDFLAG(IS_MAC) 120 NetLogWithSource net_log_; 121 }; 122 123 } // namespace net 124 125 #endif // NET_BASE_NETWORK_CHANGE_NOTIFIER_APPLE_H_ 126