Skip to content
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 93 additions & 38 deletions src/Essentials/src/Connectivity/Connectivity.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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))
{
Expand All @@ -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);
}
Comment thread
kubaflo marked this conversation as resolved.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Behavioral change: The old code used GetAllNetworkInfo() which returned info for every network interface. ActiveNetworkInfo only returns the currently active/default network.

On API 21–22 devices with multiple network connections, the old code would evaluate all of them via IsBetterAccess and report the highest NetworkAccess level. The new code only evaluates the active one, which could report a lower access level if a secondary network had better connectivity.

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;
}
}

Expand All @@ -230,9 +230,35 @@ void ProcessNetworkInfo(NetworkInfo info)
{

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale pragma restores: CA1422 and CA1416 are restored here but were never #pragma warning disable'd in this scope. These are leftovers from the old code's nesting structure. Only CS0618 needs to be restored here.

Suggested change
{
}
#pragma warning restore CS0618 // Type or member is obsolete

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;
Expand All @@ -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)
Expand Down
Loading