-
Notifications
You must be signed in to change notification settings - Fork 2k
Update Android Connectivity implementation to use modern APIs #30348
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
e86a19c
6d1ecb4
a7ffb94
7ab4a35
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -151,13 +151,9 @@ public NetworkAccess NetworkAccess | |||||||
| var currentAccess = NetworkAccess.None; | ||||||||
| var manager = ConnectivityManager; | ||||||||
|
|
||||||||
| #pragma warning disable CS0618 // Type or member is obsolete | ||||||||
| #pragma warning disable CA1416 // Validate platform compatibility | ||||||||
| #pragma warning disable CA1422 // Validate platform compatibility | ||||||||
| var networks = manager.GetAllNetworks(); | ||||||||
| #pragma warning restore CA1422 // Validate platform compatibility | ||||||||
| #pragma warning restore CA1416 // Validate platform compatibility | ||||||||
| #pragma warning restore CS0618 // Type or member is obsolete | ||||||||
|
|
||||||||
| // some devices running 21 and 22 only use the older api. | ||||||||
| if (networks.Length == 0 && !OperatingSystem.IsAndroidVersionAtLeast(23)) | ||||||||
|
|
@@ -177,17 +173,6 @@ public NetworkAccess NetworkAccess | |||||||
| continue; | ||||||||
| } | ||||||||
|
|
||||||||
| #pragma warning disable CS0618 // Type or member is obsolete | ||||||||
| #pragma warning disable CA1416 // Validate platform compatibility | ||||||||
| #pragma warning disable CA1422 // Validate platform compatibility | ||||||||
| var info = manager.GetNetworkInfo(network); | ||||||||
|
|
||||||||
| if (info == null || !info.IsAvailable) | ||||||||
| { | ||||||||
| continue; | ||||||||
| } | ||||||||
| #pragma warning restore CS0618 // Type or member is obsolete | ||||||||
|
|
||||||||
| // Check to see if it has the internet capability | ||||||||
| if (!capabilities.HasCapability(NetCapability.Internet)) | ||||||||
| { | ||||||||
|
|
@@ -196,21 +181,36 @@ public NetworkAccess NetworkAccess | |||||||
| continue; | ||||||||
| } | ||||||||
|
|
||||||||
| ProcessNetworkInfo(info); | ||||||||
| // Use modern NetworkCapabilities instead of obsolete NetworkInfo | ||||||||
| ProcessNetworkCapabilities(capabilities); | ||||||||
| } | ||||||||
| catch | ||||||||
| catch (Exception ex) | ||||||||
| { | ||||||||
| // there is a possibility, but don't worry | ||||||||
| Debug.WriteLine("Failed to get network capabilities: {0}", ex); | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| void ProcessAllNetworkInfo() | ||||||||
| { | ||||||||
| // Fallback for API 21-22 devices where GetAllNetworks() returns empty. | ||||||||
| // NOTE: The original code used GetAllNetworkInfo() which enumerated all | ||||||||
| // network interfaces; ActiveNetworkInfo returns only the current default | ||||||||
| // network. On these older API levels multi-network support is limited, | ||||||||
| // so this is an acceptable trade-off. | ||||||||
| try | ||||||||
| { | ||||||||
| #pragma warning disable CS0618 // Type or member is obsolete | ||||||||
| foreach (var info in manager.GetAllNetworkInfo()) | ||||||||
| var activeInfo = manager.ActiveNetworkInfo; | ||||||||
| if (activeInfo != null) | ||||||||
| { | ||||||||
| ProcessNetworkInfo(activeInfo); | ||||||||
| } | ||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Behavioral change: The old code used On API 21–22 devices with multiple network connections, the old code would evaluate all of them via The comment acknowledges the trade-off, but consider noting explicitly that this is a behavioral change from the original implementation, not just a different API surface. |
||||||||
| #pragma warning restore CS0618 // Type or member is obsolete | ||||||||
| } | ||||||||
| catch (Exception ex) | ||||||||
| { | ||||||||
| ProcessNetworkInfo(info); | ||||||||
| Debug.WriteLine("Failed to query active network info: {0}", ex); | ||||||||
| currentAccess = NetworkAccess.None; | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
|
|
@@ -230,9 +230,35 @@ void ProcessNetworkInfo(NetworkInfo info) | |||||||
| { | ||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Stale pragma restores:
Suggested change
|
||||||||
| currentAccess = IsBetterAccess(currentAccess, NetworkAccess.ConstrainedInternet); | ||||||||
| } | ||||||||
| } | ||||||||
| #pragma warning restore CA1422 // Validate platform compatibility | ||||||||
| #pragma warning restore CA1416 // Validate platform compatibility | ||||||||
| #pragma warning restore CS0618 // Type or member is obsolete | ||||||||
|
|
||||||||
| // Caller guarantees capabilities is non-null and has NetCapability.Internet. | ||||||||
| void ProcessNetworkCapabilities(NetworkCapabilities capabilities) | ||||||||
| { | ||||||||
| // NetCapability.Validated (API 23+) means the system has verified the | ||||||||
| // network can actually reach the internet (passes Google's connectivity check). | ||||||||
| // Without it, the network may be behind a captive portal or otherwise unusable. | ||||||||
| if (OperatingSystem.IsAndroidVersionAtLeast(23)) | ||||||||
| { | ||||||||
| if (capabilities.HasCapability(NetCapability.Validated)) | ||||||||
| { | ||||||||
| currentAccess = IsBetterAccess(currentAccess, NetworkAccess.Internet); | ||||||||
| } | ||||||||
| else | ||||||||
| { | ||||||||
| // Has internet capability but not validated (e.g. captive portal) | ||||||||
| currentAccess = IsBetterAccess(currentAccess, NetworkAccess.ConstrainedInternet); | ||||||||
| } | ||||||||
| } | ||||||||
| else | ||||||||
| { | ||||||||
| // NetCapability.Validated is unavailable on API 21-22; | ||||||||
| // treat Internet capability alone as a connected state. | ||||||||
| currentAccess = IsBetterAccess(currentAccess, NetworkAccess.Internet); | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| return currentAccess; | ||||||||
|
|
@@ -253,50 +279,79 @@ public IEnumerable<ConnectionProfile> ConnectionProfiles | |||||||
| Permissions.EnsureDeclared<Permissions.NetworkState>(); | ||||||||
|
|
||||||||
| var manager = ConnectivityManager; | ||||||||
| #pragma warning disable CS0618 // Type or member is obsolete | ||||||||
| #pragma warning disable CA1416 // Validate platform compatibility | ||||||||
| #pragma warning disable CA1422 // Validate platform compatibility | ||||||||
| var networks = manager.GetAllNetworks(); | ||||||||
| #pragma warning restore CS0618 // Type or member is obsolete | ||||||||
| #pragma warning restore CA1422 // Validate platform compatibility | ||||||||
| foreach (var network in networks) | ||||||||
| { | ||||||||
| #pragma warning disable CS0618 // Type or member is obsolete | ||||||||
| NetworkInfo info = null; | ||||||||
| NetworkCapabilities capabilities = null; | ||||||||
| try | ||||||||
| { | ||||||||
| info = manager.GetNetworkInfo(network); | ||||||||
| capabilities = manager.GetNetworkCapabilities(network); | ||||||||
| } | ||||||||
| catch | ||||||||
| catch (Exception ex) | ||||||||
| { | ||||||||
| // there is a possibility, but don't worry about it | ||||||||
| Debug.WriteLine("Failed to get network capabilities for profile: {0}", ex); | ||||||||
| } | ||||||||
| #pragma warning restore CS0618 // Type or member is obsolete | ||||||||
|
|
||||||||
| var p = ProcessNetworkInfo(info); | ||||||||
| var p = ProcessNetworkCapabilities(capabilities); | ||||||||
| if (p.HasValue) | ||||||||
| { | ||||||||
| yield return p.Value; | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| #pragma warning disable CS0618 // Type or member is obsolete | ||||||||
| static ConnectionProfile? ProcessNetworkInfo(NetworkInfo info) | ||||||||
| static ConnectionProfile? ProcessNetworkCapabilities(NetworkCapabilities capabilities) | ||||||||
| { | ||||||||
|
|
||||||||
| if (info == null || !info.IsAvailable || !info.IsConnectedOrConnecting) | ||||||||
| if (capabilities == null) | ||||||||
| { | ||||||||
| return null; | ||||||||
| } | ||||||||
|
|
||||||||
| // Only include networks that declare internet capability | ||||||||
| if (!capabilities.HasCapability(NetCapability.Internet)) | ||||||||
| { | ||||||||
| return null; | ||||||||
| } | ||||||||
|
|
||||||||
| return GetConnectionType(info.Type, info.TypeName); | ||||||||
| return GetConnectionTypeFromCapabilities(capabilities); | ||||||||
| } | ||||||||
| #pragma warning restore CA1422 // Validate platform compatibility | ||||||||
| #pragma warning restore CA1416 // Validate platform compatibility | ||||||||
| #pragma warning restore CS0618 // Type or member is obsolete | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| internal static ConnectionProfile GetConnectionTypeFromCapabilities(NetworkCapabilities capabilities) | ||||||||
| { | ||||||||
| if (capabilities == null) | ||||||||
| { | ||||||||
| return ConnectionProfile.Unknown; | ||||||||
| } | ||||||||
|
|
||||||||
| // A network may advertise multiple transports (e.g. WiFi + VPN). | ||||||||
| // We return the first "underlying" transport match, prioritising the | ||||||||
| // physical link type over overlay transports like VPN. | ||||||||
| if (capabilities.HasTransport(TransportType.Wifi)) | ||||||||
| { | ||||||||
| return ConnectionProfile.WiFi; | ||||||||
| } | ||||||||
|
|
||||||||
| if (capabilities.HasTransport(TransportType.Cellular)) | ||||||||
| { | ||||||||
| return ConnectionProfile.Cellular; | ||||||||
| } | ||||||||
|
|
||||||||
| if (capabilities.HasTransport(TransportType.Ethernet)) | ||||||||
| { | ||||||||
| return ConnectionProfile.Ethernet; | ||||||||
| } | ||||||||
|
|
||||||||
| if (capabilities.HasTransport(TransportType.Bluetooth)) | ||||||||
| { | ||||||||
| return ConnectionProfile.Bluetooth; | ||||||||
| } | ||||||||
|
|
||||||||
| return ConnectionProfile.Unknown; | ||||||||
| } | ||||||||
|
|
||||||||
| internal static ConnectionProfile GetConnectionType(ConnectivityType connectivityType, string typeName) | ||||||||
| { | ||||||||
| switch (connectivityType) | ||||||||
|
|
||||||||
Uh oh!
There was an error while loading. Please reload this page.