Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 388c66e

Browse files
authored
[connectivity_for_web] Introduce connectivity_for_web package. (#2820)
Move the package formerly known as `experimental_connectivity_web` to flutter/plugins master, as `connectivity_for_web`.
1 parent 88319a9 commit 388c66e

22 files changed

Lines changed: 805 additions & 0 deletions
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.DS_Store
2+
.dart_tool/
3+
4+
.packages
5+
.pub/
6+
7+
build/
8+
lib/generated_plugin_registrant.dart
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: 52ee8a6c6565cd421dfa32042941eb40691f4746
8+
channel: master
9+
10+
project_type: plugin
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
## 0.3.0
2+
3+
* Rename from "experimental_connectivity_web" to "connectivity_for_web", and move to flutter/plugins master.
4+
5+
## 0.2.0
6+
7+
* Add fallback on dart:html for browsers where NetworkInformationAPI is not supported.
8+
9+
## 0.1.0
10+
11+
* Initial release.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Copyright 2016, the Flutter project authors. All rights reserved.
2+
Redistribution and use in source and binary forms, with or without
3+
modification, are permitted provided that the following conditions are
4+
met:
5+
6+
* Redistributions of source code must retain the above copyright
7+
notice, this list of conditions and the following disclaimer.
8+
* Redistributions in binary form must reproduce the above
9+
copyright notice, this list of conditions and the following
10+
disclaimer in the documentation and/or other materials provided
11+
with the distribution.
12+
* Neither the name of Google Inc. nor the names of its
13+
contributors may be used to endorse or promote products derived
14+
from this software without specific prior written permission.
15+
16+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# connectivity_for_web
2+
3+
A web implementation of [connectivity](https://pub.dev/connectivity/connectivity). Currently this package uses an experimental API, with a fallback to dart:html, so not all features may be available to all browsers.
4+
5+
## Usage
6+
7+
### Import the package
8+
9+
This package is a non-endorsed implementation of `connectivity` for the web platform, so you need to modify your `pubspec.yaml` to use it:
10+
11+
```yaml
12+
...
13+
dependencies:
14+
...
15+
connectivity: ^0.4.9
16+
connectivity_for_web: ^0.3.0
17+
...
18+
...
19+
```
20+
21+
## Example
22+
23+
Find the example wiring in the [Google sign-in example application](https://github.com/ditman/plugins/blob/connectivity-web/packages/connectivity/connectivity/example/lib/main.dart).
24+
25+
## Limitations on the web platform
26+
27+
In order to retrieve information about the quality/speed of a browser's connection, the web implementation of the `connectivity` plugin uses the browser's [**NetworkInformation** Web API](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation), which as of this writing (June 2020) is still "experimental", and not available in all browsers:
28+
29+
![Data on support for the netinfo feature across the major browsers from caniuse.com](https://caniuse.bitsofco.de/image/netinfo.png)
30+
31+
On desktop browsers, this API only returns a very broad set of connectivity statuses (One of `'slow-2g', '2g', '3g', or '4g'`), and may *not* provide a Stream of changes. Firefox still hasn't enabled this feature by default.
32+
33+
**Fallback to `navigator.onLine`**
34+
35+
For those browsers where the NetworkInformation Web API is not available, the plugin falls back to the [**NavigatorOnLine** Web API](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine), which is more broadly supported:
36+
37+
![Data on support for the online-status feature across the major browsers from caniuse.com](https://caniuse.bitsofco.de/image/online-status.png)
38+
39+
40+
The NavigatorOnLine API is [provided by `dart:html`](https://api.dart.dev/stable/2.7.2/dart-html/Navigator/onLine.html), and only supports a boolean connectivity status (either online or offline), with no network speed information. In those cases the plugin will return either `wifi` (when the browser is online) or `none` (when it's not).
41+
42+
Other than the approximate "downlink" speed, where available, and due to security and privacy concerns, **no Web browser will provide** any specific information about the actual network your users' device is connected to, like **the SSID on a Wi-Fi, or the MAC address of their device.**
43+
44+
## Contributions and Testing
45+
46+
Tests are crucial to contributions to this package. All new contributions should be reasonably tested.
47+
48+
In order to run tests in this package, do:
49+
50+
```
51+
cd test
52+
flutter run -d chrome
53+
```
54+
55+
All contributions to this package are welcome. Read the [Contributing to Flutter Plugins](https://github.com/flutter/plugins/blob/master/CONTRIBUTING.md) guide to get started.
56+
57+
## Issues and feedback
58+
59+
Please file an [issue](https://github.com/ditman/plugins/issues/new)
60+
to send feedback or report a bug.
61+
62+
**Thank you!**
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#
2+
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
3+
# Run `pod lib lint connectivity_web.podspec' to validate before publishing.
4+
#
5+
Pod::Spec.new do |s|
6+
s.name = 'connectivity_for_web'
7+
s.version = '0.1.0'
8+
s.summary = 'No-op implementation of connectivity web plugin to avoid build issues on iOS'
9+
s.description = <<-DESC
10+
temp fake connectivity_web plugin
11+
DESC
12+
s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_for_web'
13+
s.license = { :file => '../LICENSE' }
14+
s.author = { 'Flutter Team' => '[email protected]' }
15+
s.source = { :path => '.' }
16+
s.source_files = 'Classes/**/*'
17+
s.dependency 'Flutter'
18+
s.platform = :ios, '8.0'
19+
20+
# Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported.
21+
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' }
22+
s.swift_version = '5.0'
23+
end
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import 'dart:async';
2+
3+
import 'package:connectivity_platform_interface/connectivity_platform_interface.dart';
4+
import 'package:flutter/services.dart';
5+
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
6+
7+
import 'src/network_information_api_connectivity_plugin.dart';
8+
import 'src/dart_html_connectivity_plugin.dart';
9+
10+
/// The web implementation of the ConnectivityPlatform of the Connectivity plugin.
11+
class ConnectivityPlugin extends ConnectivityPlatform {
12+
/// Factory method that initializes the connectivity plugin platform with an instance
13+
/// of the plugin for the web.
14+
static void registerWith(Registrar registrar) {
15+
if (NetworkInformationApiConnectivityPlugin.isSupported()) {
16+
ConnectivityPlatform.instance = NetworkInformationApiConnectivityPlugin();
17+
} else {
18+
ConnectivityPlatform.instance = DartHtmlConnectivityPlugin();
19+
}
20+
}
21+
22+
// The following are completely unsupported methods on the web platform.
23+
24+
// Creates an "unsupported_operation" PlatformException for a given `method` name.
25+
Object _unsupported(String method) {
26+
return PlatformException(
27+
code: 'UNSUPPORTED_OPERATION',
28+
message: '$method() is not supported on the web platform.',
29+
);
30+
}
31+
32+
/// Obtains the wifi name (SSID) of the connected network
33+
@override
34+
Future<String> getWifiName() {
35+
throw _unsupported('getWifiName');
36+
}
37+
38+
/// Obtains the wifi BSSID of the connected network.
39+
@override
40+
Future<String> getWifiBSSID() {
41+
throw _unsupported('getWifiBSSID');
42+
}
43+
44+
/// Obtains the IP address of the connected wifi network
45+
@override
46+
Future<String> getWifiIP() {
47+
throw _unsupported('getWifiIP');
48+
}
49+
50+
/// Request to authorize the location service (Only on iOS).
51+
@override
52+
Future<LocationAuthorizationStatus> requestLocationServiceAuthorization({
53+
bool requestAlwaysLocationUsage = false,
54+
}) {
55+
throw _unsupported('requestLocationServiceAuthorization');
56+
}
57+
58+
/// Get the current location service authorization (Only on iOS).
59+
@override
60+
Future<LocationAuthorizationStatus> getLocationServiceAuthorization() {
61+
throw _unsupported('getLocationServiceAuthorization');
62+
}
63+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import 'dart:async';
2+
import 'dart:html' as html show window;
3+
4+
import 'package:connectivity_platform_interface/connectivity_platform_interface.dart';
5+
import 'package:connectivity_for_web/connectivity_for_web.dart';
6+
7+
/// The web implementation of the ConnectivityPlatform of the Connectivity plugin.
8+
class DartHtmlConnectivityPlugin extends ConnectivityPlugin {
9+
/// Checks the connection status of the device.
10+
@override
11+
Future<ConnectivityResult> checkConnectivity() async {
12+
return html.window.navigator.onLine
13+
? ConnectivityResult.wifi
14+
: ConnectivityResult.none;
15+
}
16+
17+
StreamController<ConnectivityResult> _connectivityResult;
18+
19+
/// Returns a Stream of ConnectivityResults changes.
20+
@override
21+
Stream<ConnectivityResult> get onConnectivityChanged {
22+
if (_connectivityResult == null) {
23+
_connectivityResult = StreamController<ConnectivityResult>();
24+
// Fallback to dart:html window.onOnline / window.onOffline
25+
html.window.onOnline.listen((event) {
26+
_connectivityResult.add(ConnectivityResult.wifi);
27+
});
28+
html.window.onOffline.listen((event) {
29+
_connectivityResult.add(ConnectivityResult.none);
30+
});
31+
}
32+
return _connectivityResult.stream;
33+
}
34+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
@JS()
2+
library network_information_types;
3+
4+
import "package:js/js.dart";
5+
import "dart:html" show EventListener, EventTarget;
6+
7+
/// W3C Spec Draft http://wicg.github.io/netinfo/
8+
/// Edition: Draft Community Group Report 20 February 2019
9+
10+
/// http://wicg.github.io/netinfo/#navigatornetworkinformation-interface
11+
@anonymous
12+
@JS()
13+
abstract class Navigator implements NavigatorNetworkInformation {}
14+
15+
@anonymous
16+
@JS()
17+
abstract class WorkerNavigator implements NavigatorNetworkInformation {
18+
external factory WorkerNavigator({NetworkInformation connection});
19+
}
20+
21+
/// http://wicg.github.io/netinfo/#navigatornetworkinformation-interface
22+
@anonymous
23+
@JS()
24+
abstract class NavigatorNetworkInformation {
25+
external NetworkInformation get connection;
26+
external factory NavigatorNetworkInformation({NetworkInformation connection});
27+
}
28+
29+
/// http://wicg.github.io/netinfo/#connection-types
30+
/*type ConnectionType =
31+
| 'bluetooth'
32+
| 'cellular'
33+
| 'ethernet'
34+
| 'mixed'
35+
| 'none'
36+
| 'other'
37+
| 'unknown'
38+
| 'wifi'
39+
| 'wimax';
40+
*/
41+
42+
/// http://wicg.github.io/netinfo/#effectiveconnectiontype-enum
43+
/*type EffectiveConnectionType = '2g' | '3g' | '4g' | 'slow-2g';*/
44+
45+
/// http://wicg.github.io/netinfo/#dom-megabit
46+
/*type Megabit = number;*/
47+
/// http://wicg.github.io/netinfo/#dom-millisecond
48+
/*type Millisecond = number;*/
49+
50+
/// http://wicg.github.io/netinfo/#networkinformation-interface
51+
@anonymous
52+
@JS()
53+
abstract class NetworkInformation implements EventTarget {
54+
/// http://wicg.github.io/netinfo/#type-attribute
55+
external String /*'bluetooth'|'cellular'|'ethernet'|'mixed'|'none'|'other'|'unknown'|'wifi'|'wimax'*/ get type;
56+
57+
/// http://wicg.github.io/netinfo/#effectivetype-attribute
58+
external String /*'2g'|'3g'|'4g'|'slow-2g'*/ get effectiveType;
59+
60+
/// http://wicg.github.io/netinfo/#downlinkmax-attribute
61+
external num get downlinkMax;
62+
63+
/// http://wicg.github.io/netinfo/#downlink-attribute
64+
external num get downlink;
65+
66+
/// http://wicg.github.io/netinfo/#rtt-attribute
67+
external num get rtt;
68+
69+
/// http://wicg.github.io/netinfo/#savedata-attribute
70+
external bool get saveData;
71+
72+
/// http://wicg.github.io/netinfo/#handling-changes-to-the-underlying-connection
73+
external EventListener get onchange;
74+
external set onchange(EventListener v);
75+
}
76+
77+
@JS()
78+
external Navigator get navigator;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import 'dart:async';
2+
3+
import 'package:connectivity_platform_interface/connectivity_platform_interface.dart';
4+
import 'package:connectivity_for_web/connectivity_for_web.dart';
5+
import 'package:flutter/foundation.dart';
6+
import 'package:js/js.dart';
7+
8+
import 'generated/network_information_types.dart' as dom;
9+
import 'utils/connectivity_result.dart';
10+
11+
/// The web implementation of the ConnectivityPlatform of the Connectivity plugin.
12+
class NetworkInformationApiConnectivityPlugin extends ConnectivityPlugin {
13+
final dom.NetworkInformation _networkInformation;
14+
15+
/// A check to determine if this version of the plugin can be used.
16+
static bool isSupported() => dom.navigator?.connection != null;
17+
18+
/// The constructor of the plugin.
19+
NetworkInformationApiConnectivityPlugin()
20+
: this.withConnection(dom.navigator?.connection);
21+
22+
/// Creates the plugin, with an override of the NetworkInformation object.
23+
@visibleForTesting
24+
NetworkInformationApiConnectivityPlugin.withConnection(
25+
dom.NetworkInformation connection)
26+
: _networkInformation = connection;
27+
28+
/// Checks the connection status of the device.
29+
@override
30+
Future<ConnectivityResult> checkConnectivity() async {
31+
return networkInformationToConnectivityResult(_networkInformation);
32+
}
33+
34+
StreamController<ConnectivityResult> _connectivityResult;
35+
36+
/// Returns a Stream of ConnectivityResults changes.
37+
@override
38+
Stream<ConnectivityResult> get onConnectivityChanged {
39+
if (_connectivityResult == null) {
40+
_connectivityResult = StreamController<ConnectivityResult>();
41+
_networkInformation.onchange = allowInterop((_) {
42+
_connectivityResult
43+
.add(networkInformationToConnectivityResult(_networkInformation));
44+
});
45+
}
46+
return _connectivityResult.stream;
47+
}
48+
}

0 commit comments

Comments
 (0)