Skip to content

Commit 44c54b7

Browse files
committed
Add Linux support to Connectivity Plus
1 parent e5ba18d commit 44c54b7

13 files changed

Lines changed: 451 additions & 1 deletion

packages/connectivity_plus/lib/connectivity_plus.dart

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@
33
// found in the LICENSE file.
44

55
import 'dart:async';
6+
import 'dart:io' show Platform;
67

78
import 'package:flutter/services.dart';
9+
import 'package:flutter/foundation.dart' show kIsWeb;
810
import 'package:connectivity_plus_platform_interface/connectivity_plus_platform_interface.dart';
11+
import 'package:connectivity_plus_platform_interface/src/method_channel_connectivity.dart';
12+
import 'package:connectivity_plus_linux/connectivity_plus_linux.dart';
913

1014
// Export enums from the platform_interface so plugin users can use them directly.
1115
export 'package:connectivity_plus_platform_interface/connectivity_plus_platform_interface.dart'
@@ -30,7 +34,25 @@ class Connectivity {
3034

3135
static Connectivity _singleton;
3236

33-
static ConnectivityPlatform get _platform => ConnectivityPlatform.instance;
37+
static bool _manualDartRegistrationNeeded = true;
38+
39+
// This is to manually endorse Dart implementations until automatic
40+
// registration of Dart plugins is implemented. For details see
41+
// https://github.com/flutter/flutter/issues/52267.
42+
static ConnectivityPlatform get _platform {
43+
if (_manualDartRegistrationNeeded) {
44+
// Only do the initial registration if it hasn't already been overridden
45+
// with a non-default instance.
46+
if (!kIsWeb &&
47+
ConnectivityPlatform.instance is MethodChannelConnectivity) {
48+
if (Platform.isLinux) {
49+
ConnectivityPlatform.instance = ConnectivityLinux();
50+
}
51+
}
52+
_manualDartRegistrationNeeded = false;
53+
}
54+
return ConnectivityPlatform.instance;
55+
}
3456

3557
/// Fires whenever the connectivity state changes.
3658
Stream<ConnectivityResult> get onConnectivityChanged {

packages/connectivity_plus/pubspec.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ flutter:
1111
pluginClass: ConnectivityPlugin
1212
ios:
1313
pluginClass: FLTConnectivityPlugin
14+
linux:
15+
default_package: connectivity_plus_linux
1416
macos:
1517
default_package: connectivity_plus_macos
1618
web:
@@ -21,6 +23,7 @@ dependencies:
2123
sdk: flutter
2224
meta: ^1.0.5
2325
connectivity_plus_platform_interface: ^0.2.0
26+
connectivity_plus_linux: ^0.1.0
2427
connectivity_plus_macos: ^0.2.0
2528
connectivity_plus_web: ^0.4.0
2629

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
.DS_Store
2+
.atom/
3+
.idea/
4+
.vscode/
5+
6+
.packages
7+
.pub/
8+
.dart_tool/
9+
pubspec.lock
10+
flutter_export_environment.sh
11+
12+
examples/all_plugins/pubspec.yaml
13+
14+
Podfile
15+
Podfile.lock
16+
Pods/
17+
.symlinks/
18+
**/Flutter/App.framework/
19+
**/Flutter/ephemeral/
20+
**/Flutter/Flutter.framework/
21+
**/Flutter/Generated.xcconfig
22+
**/Flutter/flutter_assets/
23+
24+
ServiceDefinitions.json
25+
xcuserdata/
26+
**/DerivedData/
27+
28+
local.properties
29+
keystore.properties
30+
.gradle/
31+
gradlew
32+
gradlew.bat
33+
gradle-wrapper.jar
34+
.flutter-plugins-dependencies
35+
*.iml
36+
37+
generated_plugin_registrant.dart
38+
GeneratedPluginRegistrant.h
39+
GeneratedPluginRegistrant.m
40+
GeneratedPluginRegistrant.java
41+
GeneratedPluginRegistrant.swift
42+
build/
43+
.flutter-plugins
44+
45+
.project
46+
.classpath
47+
.settings
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# This file tracks properties of this Flutter project.
2+
# Used by Flutter tool to assess capabilities and perform upgrades etc.
3+
#
4+
# This file should be version controlled and should not be manually edited.
5+
6+
version:
7+
revision: 34541c30735bc1086335e13d69a7e0acdc0538c5
8+
channel: master
9+
10+
project_type: package
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## 0.1.0
2+
3+
* Initial release for Linux.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2020 The Chromium Authors. All rights reserved.
2+
//
3+
// Redistribution and use in source and binary forms, with or without
4+
// modification, are permitted provided that the following conditions are
5+
// met:
6+
//
7+
// * Redistributions of source code must retain the above copyright
8+
// notice, this list of conditions and the following disclaimer.
9+
// * Redistributions in binary form must reproduce the above
10+
// copyright notice, this list of conditions and the following disclaimer
11+
// in the documentation and/or other materials provided with the
12+
// distribution.
13+
// * Neither the name of Google Inc. nor the names of its
14+
// contributors may be used to endorse or promote products derived from
15+
// this software without specific prior written permission.
16+
//
17+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Connectivity Plus Linux
2+
3+
[![Flutter Community: connectivity_plus_linux](https://fluttercommunity.dev/_github/header/connectivity_plus_linux)](https://github.com/fluttercommunity/community)
4+
5+
[![pub package](https://img.shields.io/pub/v/connectivity_plus_linux.svg)](https://pub.dev/packages/connectivity_plus_linux)
6+
7+
The Linux implementation of [`connectivity_plus`](https://pub.dev/packages/connectivity_plus).
8+
9+
## Usage
10+
11+
This package is already included as part of the `connectivity_plus` package dependency, and will
12+
be included when using `connectivity_plus` as normal.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include: package:pedantic/analysis_options.1.9.0.yaml
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/// The Linux implementation of `connectivity_plus`.
2+
library connectivity_plus_linux;
3+
4+
export 'src/connectivity.dart';
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import 'dart:async';
2+
3+
import 'package:connectivity_plus_platform_interface/connectivity_plus_platform_interface.dart';
4+
import 'package:meta/meta.dart';
5+
6+
import 'network_manager.dart';
7+
8+
typedef _DeviceGetter = Future<String> Function(NMDevice device);
9+
typedef _ConnectionGetter = Future<String> Function(NMConnection connection);
10+
11+
@visibleForTesting
12+
typedef NetworkManagerFactory = NetworkManager Function();
13+
14+
/// The Linux implementation of ConnectivityPlatform.
15+
class ConnectivityLinux extends ConnectivityPlatform {
16+
/// Checks the connection status of the device.
17+
@override
18+
Future<ConnectivityResult> checkConnectivity() {
19+
return _getConnectivity(_ref()).whenComplete(_deref);
20+
}
21+
22+
/// Obtains the wifi name (SSID) of the connected network
23+
@override
24+
Future<String> getWifiName() {
25+
return _getConnectionValue((connection) => connection.getId());
26+
}
27+
28+
/// Obtains the IP address of the connected wifi network
29+
@override
30+
Future<String> getWifiIP() {
31+
return _getDeviceValue((device) => device.getIp4());
32+
}
33+
34+
/// Obtains the wifi BSSID of the connected network.
35+
@override
36+
Future<String> getWifiBSSID() {
37+
return _getDeviceValue((device) {
38+
return device
39+
.asWirelessDevice()
40+
.then((wireless) => wireless?.getHwAddress());
41+
});
42+
}
43+
44+
Future<String> _getDeviceValue(_DeviceGetter getter) {
45+
return _getConnectionValue((connection) {
46+
return connection.createDevice().then((device) {
47+
return device != null ? getter(device) : null;
48+
});
49+
});
50+
}
51+
52+
Future<String> _getConnectionValue(_ConnectionGetter getter) {
53+
return _ref().createConnection().then((connection) {
54+
return connection != null ? getter(connection) : null;
55+
}).whenComplete(_deref);
56+
}
57+
58+
int _refCount = 0;
59+
NetworkManager _manager;
60+
StreamController<ConnectivityResult> _controller;
61+
62+
/// Returns a Stream of ConnectivityResults changes.
63+
@override
64+
Stream<ConnectivityResult> get onConnectivityChanged {
65+
_controller ??= StreamController<ConnectivityResult>.broadcast(
66+
onListen: _startListenConnectivity,
67+
onCancel: _deref,
68+
);
69+
return _controller.stream;
70+
}
71+
72+
Future<ConnectivityResult> _getConnectivity(NetworkManager manager) {
73+
return manager.getType().then((value) => value.toConnectivityResult());
74+
}
75+
76+
void _startListenConnectivity() {
77+
final manager = _ref();
78+
manager.getType().then((type) => _addConnectivity(type));
79+
manager.subscribeTypeChanged().listen((type) {
80+
_addConnectivity(type);
81+
});
82+
}
83+
84+
void _addConnectivity(String type) {
85+
_controller.add(type.toConnectivityResult());
86+
}
87+
88+
NetworkManager _ref() {
89+
_manager ??= createManager();
90+
++_refCount;
91+
return _manager;
92+
}
93+
94+
void _deref() {
95+
// schedules an asynchronous disposal when the last reference is removed
96+
if (--_refCount == 0) {
97+
scheduleMicrotask(() {
98+
if (_refCount == 0) {
99+
_manager.dispose();
100+
_manager = null;
101+
}
102+
});
103+
}
104+
}
105+
106+
@visibleForTesting
107+
NetworkManagerFactory createManager = () => NetworkManager.system();
108+
}
109+
110+
extension _NMConnectivityType on String {
111+
ConnectivityResult toConnectivityResult() {
112+
if (isEmpty) {
113+
return ConnectivityResult.none;
114+
}
115+
if (contains('wireless')) {
116+
return ConnectivityResult.wifi;
117+
}
118+
// ### TODO: ethernet
119+
//if (contains('ethernet')) {
120+
// return ConnectivityResult.ethernet;
121+
//}
122+
// gsm, cdma, bluetooth, ...
123+
return ConnectivityResult.mobile;
124+
}
125+
}

0 commit comments

Comments
 (0)