Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class Connectivity {
static final String CONNECTIVITY_ETHERNET = "ethernet";
static final String CONNECTIVITY_BLUETOOTH = "bluetooth";
static final String CONNECTIVITY_VPN = "vpn";
static final String CONNECTIVITY_SATELLITE = "satellite";
static final String CONNECTIVITY_OTHER = "other";
private final ConnectivityManager connectivityManager;

Expand Down Expand Up @@ -70,6 +71,10 @@ List<String> getCapabilitiesList(NetworkCapabilities capabilities) {
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH)) {
types.add(CONNECTIVITY_BLUETOOTH);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
&& capabilities.hasTransport(NetworkCapabilities.TRANSPORT_SATELLITE)) {
types.add(CONNECTIVITY_SATELLITE);
}
if (types.isEmpty()
&& capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
types.add(CONNECTIVITY_OTHER);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ public class ConnectivityPlusPlugin: NSObject, FlutterPlugin, FlutterStreamHandl
return "mobile"
case .wiredEthernet:
return "ethernet"
case .constrained:
return "satellite"
case .other:
return "other"
case .none:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public enum ConnectivityType {
case wiredEthernet
case wifi
case cellular
case constrained
case other
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ public class PathMonitorConnectivityProvider: NSObject, ConnectivityProvider {
if path.usesInterfaceType(.other) {
types.append(.other)
}
if path.isConstrained {
types.append(.constrained)
}
}

return types.isEmpty ? [.none] : types
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public class ConnectivityPlusPlugin: NSObject, FlutterPlugin, FlutterStreamHandl
return "mobile"
case .wiredEthernet:
return "ethernet"
case .constrained:
return "satellite"
case .other:
return "other"
case .none:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public enum ConnectivityType {
case wiredEthernet
case wifi
case cellular
case constrained
case other
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ public class PathMonitorConnectivityProvider: NSObject, ConnectivityProvider {
if path.usesInterfaceType(.other) {
types.append(.other)
}
if path.isConstrained {
types.append(.constrained)
}
}

return types.isEmpty ? [.none] : types
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ const List<ConnectivityResult> kCheckConnectivityResult = [
ConnectivityResult.wifi
];

const List<ConnectivityResult> kCheckConnectivitySatelliteResult = [
ConnectivityResult.mobile,
ConnectivityResult.satellite,
];

void main() {
group('Connectivity', () {
late Connectivity connectivity;
Expand All @@ -26,6 +31,17 @@ void main() {
final result = await connectivity.checkConnectivity();
expect(result, kCheckConnectivityResult);
});

test('checkConnectivity passes through satellite', () async {
final satellitePlatform = MockSatelliteConnectivityPlatform();
ConnectivityPlatform.instance = satellitePlatform;
connectivity = Connectivity();
final result = await connectivity.checkConnectivity();
expect(
result,
containsAll(kCheckConnectivitySatelliteResult),
);
});
});
}

Expand All @@ -37,3 +53,12 @@ class MockConnectivityPlatform extends Mock
return kCheckConnectivityResult;
}
}

class MockSatelliteConnectivityPlatform extends Mock
with MockPlatformInterfaceMixin
implements ConnectivityPlatform {
@override
Future<List<ConnectivityResult>> checkConnectivity() async {
return kCheckConnectivitySatelliteResult;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ enum ConnectivityResult {
/// It returns [other] on any device (also simulator).
vpn,

/// Satellite: Device is connected via a highly constrained satellite link.
///
/// On iOS and macOS, reported when [NWPath.isConstrained] is true. This
/// covers both satellite connections and Low Data Mode enabled by the user.
/// Appears alongside [mobile] (e.g. `[mobile, satellite]`).
///
/// On Android 14+ (API 34), reported when [TRANSPORT_SATELLITE] capability
/// is present. Appears as a standalone result.
///
/// Not reported on other platforms.
satellite,

/// Other: Device is connected to an unknown network
other
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ List<ConnectivityResult> parseConnectivityResults(List<String> states) {
return ConnectivityResult.mobile;
case 'vpn':
return ConnectivityResult.vpn;
case 'satellite':
return ConnectivityResult.satellite;
case 'other':
return ConnectivityResult.other;
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,26 @@ void main() {
);
});

test('checkConnectivity with satellite', () async {
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(
methodChannelConnectivity.methodChannel,
(MethodCall methodCall) async {
switch (methodCall.method) {
case 'check':
return ['mobile', 'satellite'];
default:
return null;
}
},
);
final result = await methodChannelConnectivity.checkConnectivity();
expect(
result,
containsAll([ConnectivityResult.mobile, ConnectivityResult.satellite]),
);
});

// Test adjusted to handle multiple connectivity types
test('onConnectivityChanged', () async {
final result =
Expand Down
Loading