Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
d871521
flutter create -t plugin connectivity_web
ditman Feb 20, 2020
f1c9cec
Remove default example
ditman Feb 20, 2020
025ffc4
Docs
ditman Feb 20, 2020
be7cbbd
Script that auto-generates the Dart facade from TS.
ditman Feb 21, 2020
f2c80ce
Facade as it comes from the generator script (has bugs)
ditman Feb 21, 2020
6b20c50
Tweaks to the generated API
ditman Feb 21, 2020
3e20200
Initial web version of the plugin.
ditman Feb 21, 2020
14e5f9c
Modify core example to run on web.
ditman Feb 21, 2020
a4a2f62
Update facade with output from latest version of the script.
ditman Feb 21, 2020
3776379
Overridable script.
ditman Feb 21, 2020
35706db
Tests WIP
ditman Feb 24, 2020
25bdff9
Update facade generation script.
ditman Feb 24, 2020
1e05c00
Remove autogenerated file, and add gitignore.
ditman Feb 25, 2020
61edefc
Make the NetworkInformation object used by the plugin overridable (fo…
ditman Feb 25, 2020
6720cc9
Another go at e2e tests.
ditman Feb 25, 2020
c050e7c
Update instructions to run tests.
ditman Feb 25, 2020
a64d700
Fix analyzer
ditman Feb 25, 2020
44b64d8
Revert "Modify core example to run on web."
ditman Feb 25, 2020
5e94fcd
Fix publishable errors:
ditman Feb 25, 2020
2900d38
Fix dart:js -> package:js import.
ditman Feb 25, 2020
af042d0
Fix publishability of the package.
ditman Feb 25, 2020
a80c2a0
Call the named constructor from the default one properly.
ditman Feb 25, 2020
de4e9dc
Address PR feedback.
ditman Feb 26, 2020
442852f
Return `null` in unsupported browsers.
ditman Mar 4, 2020
bd56ea1
Preparing to publish from my flutter fork.
ditman Apr 9, 2020
fe645cd
Some more renaming
ditman Apr 9, 2020
4cc6238
Final renaming?
ditman Apr 9, 2020
38a8440
Add fallback on dart:html for other browsers.
ditman Apr 14, 2020
8c1d631
Update docs.
ditman Apr 14, 2020
74e8811
Update example app for web.
ditman Apr 14, 2020
ee846c3
Merge branch 'connectivity-web' into connectivity-for-web
ditman Jun 8, 2020
8bbf89c
[connectivity_for_web] Rename plugin after rebasing.
ditman Jun 8, 2020
ce3d486
Revert changes in connectivity example.
ditman Jun 8, 2020
0b3151e
Update README
ditman Jun 8, 2020
a9d5f32
Address PR comments.
ditman Jun 30, 2020
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
8 changes: 8 additions & 0 deletions packages/connectivity/connectivity_for_web/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.DS_Store
.dart_tool/

.packages
.pub/

build/
lib/generated_plugin_registrant.dart
10 changes: 10 additions & 0 deletions packages/connectivity/connectivity_for_web/.metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: 52ee8a6c6565cd421dfa32042941eb40691f4746
channel: master

project_type: plugin
11 changes: 11 additions & 0 deletions packages/connectivity/connectivity_for_web/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## 0.3.0

* Rename from "experimental_connectivity_web" to "connectivity_for_web", and move to flutter/plugins master.

## 0.2.0

* Add fallback on dart:html for browsers where NetworkInformationAPI is not supported.

## 0.1.0

* Initial release.
26 changes: 26 additions & 0 deletions packages/connectivity/connectivity_for_web/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Copyright 2016, the Flutter project authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 changes: 62 additions & 0 deletions packages/connectivity/connectivity_for_web/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# connectivity_for_web

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.

## Usage

### Import the package

This package is a non-endorsed implementation of `connectivity` for the web platform, so you need to modify your `pubspec.yaml` to use it:

```yaml
...
dependencies:
...
connectivity: ^0.4.9
connectivity_for_web: ^0.3.0
...
...
```

## Example

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).

## Limitations on the web platform

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:

![Data on support for the netinfo feature across the major browsers from caniuse.com](https://caniuse.bitsofco.de/image/netinfo.png)

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.

**Fallback to `navigator.onLine`**

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:

![Data on support for the online-status feature across the major browsers from caniuse.com](https://caniuse.bitsofco.de/image/online-status.png)


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).

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.**

## Contributions and Testing

Tests are crucial to contributions to this package. All new contributions should be reasonably tested.

In order to run tests in this package, do:

```
cd test
flutter run -d chrome
Copy link
Contributor

Choose a reason for hiding this comment

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

flutter test?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not yet. This requires the browser, so it's an unfinished e2e/driver test.

```

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.

## Issues and feedback

Please file an [issue](https://github.com/ditman/plugins/issues/new)
to send feedback or report a bug.

**Thank you!**
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint connectivity_web.podspec' to validate before publishing.
#
Pod::Spec.new do |s|
s.name = 'connectivity_for_web'
s.version = '0.1.0'
s.summary = 'No-op implementation of connectivity web plugin to avoid build issues on iOS'
s.description = <<-DESC
temp fake connectivity_web plugin
DESC
s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_for_web'
s.license = { :file => '../LICENSE' }
s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' }
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.dependency 'Flutter'
s.platform = :ios, '8.0'

# Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' }
s.swift_version = '5.0'
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import 'dart:async';

import 'package:connectivity_platform_interface/connectivity_platform_interface.dart';
import 'package:flutter/services.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';

import 'src/network_information_api_connectivity_plugin.dart';
import 'src/dart_html_connectivity_plugin.dart';

/// The web implementation of the ConnectivityPlatform of the Connectivity plugin.
class ConnectivityPlugin extends ConnectivityPlatform {
/// Factory method that initializes the connectivity plugin platform with an instance
/// of the plugin for the web.
static void registerWith(Registrar registrar) {
if (NetworkInformationApiConnectivityPlugin.isSupported()) {
ConnectivityPlatform.instance = NetworkInformationApiConnectivityPlugin();
} else {
ConnectivityPlatform.instance = DartHtmlConnectivityPlugin();
}
}

// The following are completely unsupported methods on the web platform.

// Creates an "unsupported_operation" PlatformException for a given `method` name.
Object _unsupported(String method) {
return PlatformException(
code: 'UNSUPPORTED_OPERATION',
message: '$method() is not supported on the web platform.',
);
}

/// Obtains the wifi name (SSID) of the connected network
@override
Future<String> getWifiName() {
throw _unsupported('getWifiName');
}

/// Obtains the wifi BSSID of the connected network.
@override
Future<String> getWifiBSSID() {
throw _unsupported('getWifiBSSID');
}

/// Obtains the IP address of the connected wifi network
@override
Future<String> getWifiIP() {
throw _unsupported('getWifiIP');
}

/// Request to authorize the location service (Only on iOS).
@override
Future<LocationAuthorizationStatus> requestLocationServiceAuthorization({
bool requestAlwaysLocationUsage = false,
}) {
throw _unsupported('requestLocationServiceAuthorization');
}

/// Get the current location service authorization (Only on iOS).
@override
Future<LocationAuthorizationStatus> getLocationServiceAuthorization() {
throw _unsupported('getLocationServiceAuthorization');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import 'dart:async';
import 'dart:html' as html show window;

import 'package:connectivity_platform_interface/connectivity_platform_interface.dart';
import 'package:connectivity_for_web/connectivity_for_web.dart';

/// The web implementation of the ConnectivityPlatform of the Connectivity plugin.
class DartHtmlConnectivityPlugin extends ConnectivityPlugin {
/// Checks the connection status of the device.
@override
Future<ConnectivityResult> checkConnectivity() async {
return html.window.navigator.onLine
Copy link
Contributor

Choose a reason for hiding this comment

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

Heads up: these things will become non-null soon. Consider performing null checks using JS-interop, or this hack:

bool _unsafeIsNull(dynamic object) => object == null;

(I'm not sure if this hack will work for long though; dart2js can inline it and decide to elide the null check)

Copy link
Member Author

Choose a reason for hiding this comment

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

Hm onLine is a boolean; I hope the whole chain is not-null and defaults to "false" when null safety comes!

? ConnectivityResult.wifi
: ConnectivityResult.none;
}

StreamController<ConnectivityResult> _connectivityResult;

/// Returns a Stream of ConnectivityResults changes.
@override
Stream<ConnectivityResult> get onConnectivityChanged {
if (_connectivityResult == null) {
_connectivityResult = StreamController<ConnectivityResult>();
// Fallback to dart:html window.onOnline / window.onOffline
html.window.onOnline.listen((event) {
_connectivityResult.add(ConnectivityResult.wifi);
});
html.window.onOffline.listen((event) {
_connectivityResult.add(ConnectivityResult.none);
});
}
return _connectivityResult.stream;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
@JS()
library network_information_types;

import "package:js/js.dart";
import "dart:html" show EventListener, EventTarget;

/// W3C Spec Draft http://wicg.github.io/netinfo/
/// Edition: Draft Community Group Report 20 February 2019

/// http://wicg.github.io/netinfo/#navigatornetworkinformation-interface
@anonymous
@JS()
abstract class Navigator implements NavigatorNetworkInformation {}

@anonymous
@JS()
abstract class WorkerNavigator implements NavigatorNetworkInformation {
external factory WorkerNavigator({NetworkInformation connection});
}

/// http://wicg.github.io/netinfo/#navigatornetworkinformation-interface
@anonymous
@JS()
abstract class NavigatorNetworkInformation {
external NetworkInformation get connection;
external factory NavigatorNetworkInformation({NetworkInformation connection});
}

/// http://wicg.github.io/netinfo/#connection-types
/*type ConnectionType =
| 'bluetooth'
| 'cellular'
| 'ethernet'
| 'mixed'
| 'none'
| 'other'
| 'unknown'
| 'wifi'
| 'wimax';
*/

/// http://wicg.github.io/netinfo/#effectiveconnectiontype-enum
/*type EffectiveConnectionType = '2g' | '3g' | '4g' | 'slow-2g';*/

/// http://wicg.github.io/netinfo/#dom-megabit
/*type Megabit = number;*/
/// http://wicg.github.io/netinfo/#dom-millisecond
/*type Millisecond = number;*/

/// http://wicg.github.io/netinfo/#networkinformation-interface
@anonymous
@JS()
abstract class NetworkInformation implements EventTarget {
/// http://wicg.github.io/netinfo/#type-attribute
external String /*'bluetooth'|'cellular'|'ethernet'|'mixed'|'none'|'other'|'unknown'|'wifi'|'wimax'*/ get type;

/// http://wicg.github.io/netinfo/#effectivetype-attribute
external String /*'2g'|'3g'|'4g'|'slow-2g'*/ get effectiveType;

/// http://wicg.github.io/netinfo/#downlinkmax-attribute
external num get downlinkMax;

/// http://wicg.github.io/netinfo/#downlink-attribute
external num get downlink;

/// http://wicg.github.io/netinfo/#rtt-attribute
external num get rtt;

/// http://wicg.github.io/netinfo/#savedata-attribute
external bool get saveData;

/// http://wicg.github.io/netinfo/#handling-changes-to-the-underlying-connection
external EventListener get onchange;
external set onchange(EventListener v);
}

@JS()
external Navigator get navigator;
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import 'dart:async';

import 'package:connectivity_platform_interface/connectivity_platform_interface.dart';
import 'package:connectivity_for_web/connectivity_for_web.dart';
import 'package:flutter/foundation.dart';
import 'package:js/js.dart';

import 'generated/network_information_types.dart' as dom;
import 'utils/connectivity_result.dart';

/// The web implementation of the ConnectivityPlatform of the Connectivity plugin.
class NetworkInformationApiConnectivityPlugin extends ConnectivityPlugin {
final dom.NetworkInformation _networkInformation;

/// A check to determine if this version of the plugin can be used.
static bool isSupported() => dom.navigator?.connection != null;

/// The constructor of the plugin.
NetworkInformationApiConnectivityPlugin()
: this.withConnection(dom.navigator?.connection);

/// Creates the plugin, with an override of the NetworkInformation object.
@visibleForTesting
NetworkInformationApiConnectivityPlugin.withConnection(
dom.NetworkInformation connection)
: _networkInformation = connection;

/// Checks the connection status of the device.
@override
Future<ConnectivityResult> checkConnectivity() async {
return networkInformationToConnectivityResult(_networkInformation);
}

StreamController<ConnectivityResult> _connectivityResult;

/// Returns a Stream of ConnectivityResults changes.
@override
Stream<ConnectivityResult> get onConnectivityChanged {
if (_connectivityResult == null) {
_connectivityResult = StreamController<ConnectivityResult>();
_networkInformation.onchange = allowInterop((_) {
_connectivityResult
.add(networkInformationToConnectivityResult(_networkInformation));
});
}
return _connectivityResult.stream;
}
}
Loading