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 26 namespace net { 27 28 class NET_EXPORT_PRIVATE NetworkChangeNotifierApple 29 : public NetworkChangeNotifier { 30 public: 31 NetworkChangeNotifierApple(); 32 NetworkChangeNotifierApple(const NetworkChangeNotifierApple&) = delete; 33 NetworkChangeNotifierApple& operator=(const NetworkChangeNotifierApple&) = delete; 34 ~NetworkChangeNotifierApple() override; 35 36 // NetworkChangeNotifier implementation: 37 ConnectionType GetCurrentConnectionType() const override; 38 39 // Forwarder just exists to keep the NetworkConfigWatcherApple API out of 40 // NetworkChangeNotifierApple's public API. 41 class Forwarder : public NetworkConfigWatcherApple::Delegate { 42 public: Forwarder(NetworkChangeNotifierApple * net_config_watcher)43 explicit Forwarder(NetworkChangeNotifierApple* net_config_watcher) 44 : net_config_watcher_(net_config_watcher) {} 45 Forwarder(const Forwarder&) = delete; 46 Forwarder& operator=(const Forwarder&) = delete; 47 48 // NetworkConfigWatcherApple::Delegate implementation: 49 void Init() override; 50 void StartReachabilityNotifications() override; 51 void SetDynamicStoreNotificationKeys( 52 base::apple::ScopedCFTypeRef<SCDynamicStoreRef> store) override; 53 void OnNetworkConfigChange(CFArrayRef changed_keys) override; 54 void CleanUpOnNotifierThread() override; 55 56 private: 57 const raw_ptr<NetworkChangeNotifierApple> net_config_watcher_; 58 }; 59 60 private: 61 friend class NetworkChangeNotifierAppleTest; 62 63 // Called on the main thread on startup, afterwards on the notifier thread. 64 static ConnectionType CalculateConnectionType(SCNetworkConnectionFlags flags); 65 66 // Methods directly called by the NetworkConfigWatcherApple::Delegate: 67 void StartReachabilityNotifications(); 68 void SetDynamicStoreNotificationKeys( 69 base::apple::ScopedCFTypeRef<SCDynamicStoreRef> store); 70 void OnNetworkConfigChange(CFArrayRef changed_keys); 71 void CleanUpOnNotifierThread(); 72 73 void SetInitialConnectionType(); 74 75 static void ReachabilityCallback(SCNetworkReachabilityRef target, 76 SCNetworkConnectionFlags flags, 77 void* notifier); 78 79 static NetworkChangeCalculatorParams NetworkChangeCalculatorParamsMac(); 80 81 #if BUILDFLAG(IS_MAC) 82 void SetCallbacksForTest( 83 base::OnceClosure initialized_callback, 84 base::RepeatingCallback<bool(NetworkInterfaceList*, int)> 85 get_network_list_callback, 86 base::RepeatingCallback<std::string(SCDynamicStoreRef)> 87 get_ipv6_primary_interface_name_callback); 88 #endif // BUILDFLAG(IS_MAC) 89 90 // These must be constructed before config_watcher_ to ensure 91 // the lock is in a valid state when Forwarder::Init is called. 92 ConnectionType connection_type_ = CONNECTION_UNKNOWN; 93 bool connection_type_initialized_ = false; 94 mutable base::Lock connection_type_lock_; 95 mutable base::ConditionVariable initial_connection_type_cv_; 96 base::apple::ScopedCFTypeRef<SCNetworkReachabilityRef> reachability_; 97 base::apple::ScopedCFTypeRef<CFRunLoopRef> run_loop_; 98 99 Forwarder forwarder_; 100 std::unique_ptr<NetworkConfigWatcherApple> config_watcher_; 101 102 #if BUILDFLAG(IS_MAC) 103 const bool reduce_ip_address_change_notification_; 104 base::apple::ScopedCFTypeRef<SCDynamicStoreRef> store_; 105 std::optional<NetworkInterfaceList> interfaces_for_network_change_check_; 106 107 base::OnceClosure initialized_callback_for_test_; 108 base::RepeatingCallback<bool(NetworkInterfaceList*, int)> 109 get_network_list_callback_; 110 base::RepeatingCallback<std::string(SCDynamicStoreRef)> 111 get_ipv6_primary_interface_name_callback_; 112 #endif // BUILDFLAG(IS_MAC) 113 }; 114 115 } // namespace net 116 117 #endif // NET_BASE_NETWORK_CHANGE_NOTIFIER_APPLE_H_ 118