detectNetwork #670
|
@ -1 +1 @@
|
|||
2023-05-09-13-30-v0.0.3-24-g5b2f3cf
|
||||
2023-05-09-13-30-v0.0.3-24-g5b2f3cf
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#Mon Jun 20 10:33:21 PDT 2022
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
# third party plugin connectivity_plus should match, so when updating, also update
|
||||
# lib/third_party/connectivity_plus/connectivity_plus/android/gradle/wrapper/gradle-wrapper.properties
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
|
@ -139,6 +139,416 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.''');
|
||||
|
||||
yield LicenseEntryWithLineBreaks(["connectivity_plus", "connectivity_plus_platform_interface"], '''
|
||||
Copyright 2017 The Chromium 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.''');
|
||||
|
||||
yield LicenseEntryWithLineBreaks(["connectivity_plus"], '''
|
||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
||||
*
|
||||
* This file is part of Purple i2pd project and licensed under BSD3
|
||||
*
|
||||
* See full license text in LICENSE file at top of project tree''');
|
||||
|
||||
yield LicenseEntryWithLineBreaks(["nm"], '''Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
purposes of this definition, "control" means (a) the power, direct
|
||||
or indirect, to cause the direction or management of such entity,
|
||||
whether by contract or otherwise, or (b) ownership of more than
|
||||
fifty percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 6. Disclaimer of Warranty *
|
||||
* ------------------------- *
|
||||
* *
|
||||
* Covered Software is provided under this License on an "as is" *
|
||||
* basis, without warranty of any kind, either expressed, implied, or *
|
||||
* statutory, including, without limitation, warranties that the *
|
||||
* Covered Software is free of defects, merchantable, fit for a *
|
||||
* particular purpose or non-infringing. The entire risk as to the *
|
||||
* quality and performance of the Covered Software is with You. *
|
||||
* Should any Covered Software prove defective in any respect, You *
|
||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
||||
* essential part of this License. No use of any Covered Software is *
|
||||
* authorized under this License except under this disclaimer. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 7. Limitation of Liability *
|
||||
* -------------------------- *
|
||||
* *
|
||||
* Under no circumstances and under no legal theory, whether tort *
|
||||
* (including negligence), contract, or otherwise, shall any *
|
||||
* Contributor, or anyone who distributes Covered Software as *
|
||||
* permitted above, be liable to You for any direct, indirect, *
|
||||
* special, incidental, or consequential damages of any character *
|
||||
* including, without limitation, damages for lost profits, loss of *
|
||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
||||
* and all other commercial damages or losses, even if such party *
|
||||
* shall have been informed of the possibility of such damages. This *
|
||||
* limitation of liability shall not apply to liability for death or *
|
||||
* personal injury resulting from such party's negligence to the *
|
||||
* extent applicable law prohibits such limitation. Some *
|
||||
* jurisdictions do not allow the exclusion or limitation of *
|
||||
* incidental or consequential damages, so this exclusion and *
|
||||
* limitation may not apply to You. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
8. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.''');
|
||||
|
||||
yield LicenseEntryWithLineBreaks(["Roboto fonts"], '''
|
||||
|
||||
Apache License
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'package:cwtch/config.dart';
|
||||
import 'package:cwtch/notification_manager.dart';
|
||||
|
@ -29,6 +30,8 @@ import 'views/splashView.dart';
|
|||
import 'dart:io' show Platform, exit;
|
||||
import 'themes/opaque.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
|
||||
|
||||
import 'package:intl/intl.dart' as intl;
|
||||
|
||||
|
@ -53,6 +56,8 @@ class Flwtch extends StatefulWidget {
|
|||
FlwtchState createState() => FlwtchState();
|
||||
}
|
||||
|
||||
enum ConnectivityState { assumed_online, confirmed_offline, confirmed_online }
|
||||
|
||||
class FlwtchState extends State<Flwtch> with WindowListener {
|
||||
final TextStyle biggerFont = const TextStyle(fontSize: 18);
|
||||
late Cwtch cwtch;
|
||||
|
@ -60,6 +65,8 @@ class FlwtchState extends State<Flwtch> with WindowListener {
|
|||
final MethodChannel notificationClickChannel = MethodChannel('im.cwtch.flwtch/notificationClickHandler');
|
||||
final MethodChannel shutdownMethodChannel = MethodChannel('im.cwtch.flwtch/shutdownClickHandler');
|
||||
final MethodChannel shutdownLinuxMethodChannel = MethodChannel('im.cwtch.linux.shutdown');
|
||||
late StreamSubscription? connectivityStream;
|
||||
ConnectivityState connectivityState = ConnectivityState.assumed_online;
|
||||
|
||||
final GlobalKey<NavigatorState> navKey = GlobalKey<NavigatorState>();
|
||||
|
||||
|
@ -88,22 +95,74 @@ class FlwtchState extends State<Flwtch> with WindowListener {
|
|||
shutdownLinuxMethodChannel.setMethodCallHandler(shutdownDirect);
|
||||
print("initState: creating cwtchnotifier, ffi");
|
||||
if (Platform.isAndroid) {
|
||||
var cwtchNotifier = new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, NullNotificationsManager(), globalAppState, globalServersList, this);
|
||||
var cwtchNotifier = new CwtchNotifier(
|
||||
profs,
|
||||
globalSettings,
|
||||
globalErrorHandler,
|
||||
globalTorStatus,
|
||||
NullNotificationsManager(),
|
||||
globalAppState,
|
||||
globalServersList,
|
||||
this);
|
||||
cwtch = CwtchGomobile(cwtchNotifier);
|
||||
} else if (Platform.isLinux) {
|
||||
var cwtchNotifier =
|
||||
new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, newDesktopNotificationsManager(_notificationSelectConvo), globalAppState, globalServersList, this);
|
||||
new CwtchNotifier(
|
||||
profs,
|
||||
globalSettings,
|
||||
globalErrorHandler,
|
||||
globalTorStatus,
|
||||
newDesktopNotificationsManager(_notificationSelectConvo),
|
||||
globalAppState,
|
||||
globalServersList,
|
||||
this);
|
||||
cwtch = CwtchFfi(cwtchNotifier);
|
||||
} else {
|
||||
var cwtchNotifier =
|
||||
new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, newDesktopNotificationsManager(_notificationSelectConvo), globalAppState, globalServersList, this);
|
||||
new CwtchNotifier(
|
||||
profs,
|
||||
globalSettings,
|
||||
globalErrorHandler,
|
||||
globalTorStatus,
|
||||
newDesktopNotificationsManager(_notificationSelectConvo),
|
||||
globalAppState,
|
||||
globalServersList,
|
||||
this);
|
||||
cwtch = CwtchFfi(cwtchNotifier);
|
||||
}
|
||||
startConnectivityListener();
|
||||
print("initState: invoking cwtch.Start()");
|
||||
cwtch.Start();
|
||||
print("initState: done!");
|
||||
}
|
||||
|
||||
// connectivity listening is an optional enhancement feature that tries to listen for OS events about the network
|
||||
// and if it detects coming back online, restarts the ACN/tor
|
||||
// gracefully fails and NOPs, as it's not a required functionality
|
||||
startConnectivityListener() async {
|
||||
try {
|
||||
connectivityStream = await Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
|
||||
// Got a new connectivity status!
|
||||
if (result == ConnectivityResult.none) {
|
||||
connectivityState = ConnectivityState.confirmed_offline;
|
||||
} else {
|
||||
// were we offline?
|
||||
if (connectivityState == ConnectivityState.confirmed_offline) {
|
||||
EnvironmentConfig.debugLog("Network appears to have come back online, restarting Tor");
|
||||
cwtch.ResetTor();
|
||||
}
|
||||
connectivityState = ConnectivityState.confirmed_online;
|
||||
}
|
||||
}, onError: (Object error) {
|
||||
print("Error listening to connectivity for network state: {$error}");
|
||||
return null;
|
||||
}, cancelOnError: true);
|
||||
} catch (e) {
|
||||
print("Warning: Unable to open connectivity for listening to network state: {$e}");
|
||||
connectivityStream = null;
|
||||
}
|
||||
}
|
||||
|
||||
ChangeNotifierProvider<TorStatus> getTorStatusProvider() => ChangeNotifierProvider.value(value: globalTorStatus);
|
||||
ChangeNotifierProvider<ErrorHandler> getErrorHandlerProvider() => ChangeNotifierProvider.value(value: globalErrorHandler);
|
||||
ChangeNotifierProvider<Settings> getSettingsProvider() => ChangeNotifierProvider.value(value: globalSettings);
|
||||
|
@ -275,6 +334,7 @@ class FlwtchState extends State<Flwtch> with WindowListener {
|
|||
cwtch.Shutdown();
|
||||
windowManager.removeListener(this);
|
||||
cwtch.dispose();
|
||||
connectivityStream?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
Copyright 2017 The Chromium Authors. All rights reserved.
|
||||
dan marked this conversation as resolved
Outdated
|
||||
|
||||
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.
|
|
@ -0,0 +1,27 @@
|
|||
Copyright 2017 The Chromium Authors. All rights reserved.
|
||||
dan marked this conversation as resolved
Outdated
sarah
commented
Licenses needs to be added to licenses.dart Licenses needs to be added to licenses.dart
|
||||
|
||||
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.
|
|
@ -0,0 +1,108 @@
|
|||
# connectivity_plus
|
||||
dan marked this conversation as resolved
Outdated
sarah
commented
document changes document changes
|
||||
|
||||
- Open Privacy has updated this package to use local and stripped down version of `nm` package
|
||||
|
||||
[![Flutter Community: connectivity_plus](https://fluttercommunity.dev/_github/header/connectivity_plus)](https://github.com/fluttercommunity/community)
|
||||
|
||||
[![pub package](https://img.shields.io/pub/v/connectivity_plus.svg)](https://pub.dev/packages/connectivity_plus)
|
||||
[![pub points](https://img.shields.io/pub/points/connectivity_plus?color=2E8B57&label=pub%20points)](https://pub.dev/packages/connectivity_plus/score)
|
||||
[![connectivity_plus](https://github.com/fluttercommunity/plus_plugins/actions/workflows/connectivity_plus.yaml/badge.svg)](https://github.com/fluttercommunity/plus_plugins/actions/workflows/connectivity_plus.yaml)
|
||||
|
||||
<p class="center">
|
||||
<center><a href="https://flutter.dev/docs/development/packages-and-plugins/favorites" target="_blank" rel="noreferrer noopener"><img src="../../../website/static/img/flutter-favorite-badge.png" width="100" alt="build"></a></center>
|
||||
</p>
|
||||
|
||||
This plugin allows Flutter apps to discover network connectivity and configure
|
||||
themselves accordingly. It can distinguish between cellular vs WiFi connection.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> On Android, this does not guarantee connection to Internet. For instance, the app might have wifi access but it might be a VPN or a hotel WiFi > with no access.
|
||||
|
||||
## Platform Support
|
||||
|
||||
| Android | iOS | MacOS | Web | Linux | Windows |
|
||||
| :-----: | :-: | :---: | :-: | :---: | :-----: |
|
||||
| ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
|
||||
|
||||
## Usage
|
||||
|
||||
Sample usage to check current status:
|
||||
|
||||
```dart
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
|
||||
final connectivityResult = await (Connectivity().checkConnectivity());
|
||||
if (connectivityResult == ConnectivityResult.mobile) {
|
||||
// I am connected to a mobile network.
|
||||
} else if (connectivityResult == ConnectivityResult.wifi) {
|
||||
// I am connected to a wifi network.
|
||||
} else if (connectivityResult == ConnectivityResult.ethernet) {
|
||||
// I am connected to a ethernet network.
|
||||
} else if (connectivityResult == ConnectivityResult.vpn) {
|
||||
// I am connected to a vpn network.
|
||||
// Note for iOS and macOS:
|
||||
// There is no separate network interface type for [vpn].
|
||||
// It returns [other] on any device (also simulator)
|
||||
} else if (connectivityResult == ConnectivityResult.bluetooth) {
|
||||
// I am connected to a bluetooth.
|
||||
} else if (connectivityResult == ConnectivityResult.other) {
|
||||
// I am connected to a network which is not in the above mentioned networks.
|
||||
} else if (connectivityResult == ConnectivityResult.none) {
|
||||
// I am not connected to any network.
|
||||
}
|
||||
```
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> You should not be using the current network status for deciding whether you can reliably make a network connection. Always guard your app code against timeouts and errors that might come from the network layer.
|
||||
|
||||
You can also listen for network state changes by subscribing to the stream
|
||||
exposed by connectivity plugin:
|
||||
|
||||
```dart
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
|
||||
@override
|
||||
initState() {
|
||||
super.initState();
|
||||
|
||||
subscription = Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
|
||||
// Got a new connectivity status!
|
||||
});
|
||||
}
|
||||
|
||||
// Be sure to cancel subscription after you are done
|
||||
@override
|
||||
dispose() {
|
||||
subscription.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
```
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> Connectivity changes are no longer communicated to Android apps in the background starting with Android O (8.0). _You should always check for connectivity status when your app is resumed._ The broadcast is only useful when your application is in the foreground.
|
||||
|
||||
## 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.**
|
||||
|
||||
## Learn more
|
||||
|
||||
- [API Documentation](https://pub.dev/documentation/connectivity_plus/latest/connectivity_plus/connectivity_plus-library.html)
|
||||
- [Plugin documentation website](https://plus.fluttercommunity.dev/docs/connectivity_plus/overview)
|
|
@ -0,0 +1,47 @@
|
|||
group 'io.flutter.plugins.connectivity'
|
||||
version '1.0-SNAPSHOT'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
|
||||
android {
|
||||
compileSdkVersion 31
|
||||
|
||||
// as third_party include, don't need seperate namespace
|
||||
//namespace 'dev.fluttercommunity.plus.connectivity'
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 31
|
||||
//testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
lintOptions {
|
||||
disable 'InvalidPackage'
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
}
|
1
lib/third_party/connectivity_plus/connectivity_plus/android/gradle.properties
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
org.gradle.jvmargs=-Xmx1536M
|
|
@ -0,0 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
|
||||
dan marked this conversation as resolved
Outdated
sarah
commented
align gradle versions android/gradle/wrapper/gradle-wrapper.properties currently depends on align gradle versions android/gradle/wrapper/gradle-wrapper.properties currently depends on `gradle-6.5-bin.zip`
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
|
@ -0,0 +1 @@
|
|||
rootProject.name = 'connectivity'
|
4
lib/third_party/connectivity_plus/connectivity_plus/android/src/main/AndroidManifest.xml
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="dev.fluttercommunity.plus.connectivity">
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
</manifest>
|
|
@ -0,0 +1,62 @@
|
|||
// Copyright 2019 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package dev.fluttercommunity.plus.connectivity;
|
||||
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.os.Build;
|
||||
|
||||
/** Reports connectivity related information such as connectivity type and wifi information. */
|
||||
public class Connectivity {
|
||||
static final String CONNECTIVITY_NONE = "none";
|
||||
static final String CONNECTIVITY_MOBILE = "mobile";
|
||||
private final ConnectivityManager connectivityManager;
|
||||
|
||||
public Connectivity(ConnectivityManager connectivityManager) {
|
||||
dan marked this conversation as resolved
Outdated
sarah
commented
remove remove
|
||||
this.connectivityManager = connectivityManager;
|
||||
}
|
||||
|
||||
String getNetworkType() {
|
||||
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
Network network = connectivityManager.getActiveNetwork();
|
||||
NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
|
||||
if (capabilities == null) {
|
||||
return CONNECTIVITY_NONE;
|
||||
}
|
||||
// Cwtch UI only needs to know if online or offline, not type
|
||||
return CONNECTIVITY_MOBILE;
|
||||
}
|
||||
|
||||
return getNetworkTypeLegacy();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private String getNetworkTypeLegacy() {
|
||||
// handle type for Android versions less than Android 6
|
||||
android.net.NetworkInfo info = connectivityManager.getActiveNetworkInfo();
|
||||
if (info == null || !info.isConnected()) {
|
||||
return CONNECTIVITY_NONE;
|
||||
}
|
||||
int type = info.getType();
|
||||
switch (type) {
|
||||
case ConnectivityManager.TYPE_BLUETOOTH:
|
||||
case ConnectivityManager.TYPE_ETHERNET:
|
||||
dan marked this conversation as resolved
Outdated
sarah
commented
remove remove
|
||||
case ConnectivityManager.TYPE_WIFI:
|
||||
case ConnectivityManager.TYPE_WIMAX:
|
||||
case ConnectivityManager.TYPE_VPN:
|
||||
case ConnectivityManager.TYPE_MOBILE:
|
||||
case ConnectivityManager.TYPE_MOBILE_DUN:
|
||||
case ConnectivityManager.TYPE_MOBILE_HIPRI:
|
||||
return CONNECTIVITY_MOBILE;
|
||||
default:
|
||||
return CONNECTIVITY_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
public ConnectivityManager getConnectivityManager() {
|
||||
return connectivityManager;
|
||||
}
|
||||
}
|
||||
dan marked this conversation as resolved
Outdated
sarah
commented
remove remove
|
|
@ -0,0 +1,94 @@
|
|||
// Copyright 2019 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package dev.fluttercommunity.plus.connectivity;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.Network;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import io.flutter.plugin.common.EventChannel;
|
||||
|
||||
/**
|
||||
* The ConnectivityBroadcastReceiver receives the connectivity updates and send them to the UIThread
|
||||
* through an {@link EventChannel.EventSink}
|
||||
*
|
||||
* <p>Use {@link
|
||||
* io.flutter.plugin.common.EventChannel#setStreamHandler(io.flutter.plugin.common.EventChannel.StreamHandler)}
|
||||
* to set up the receiver.
|
||||
*/
|
||||
public class ConnectivityBroadcastReceiver extends BroadcastReceiver
|
||||
implements EventChannel.StreamHandler {
|
||||
private final Context context;
|
||||
private final Connectivity connectivity;
|
||||
private EventChannel.EventSink events;
|
||||
private final Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
private ConnectivityManager.NetworkCallback networkCallback;
|
||||
public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
|
||||
|
||||
public ConnectivityBroadcastReceiver(Context context, Connectivity connectivity) {
|
||||
this.context = context;
|
||||
this.connectivity = connectivity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListen(Object arguments, EventChannel.EventSink events) {
|
||||
this.events = events;
|
||||
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
networkCallback =
|
||||
new ConnectivityManager.NetworkCallback() {
|
||||
@Override
|
||||
public void onAvailable(Network network) {
|
||||
sendEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLost(Network network) {
|
||||
sendEvent(Connectivity.CONNECTIVITY_NONE);
|
||||
}
|
||||
};
|
||||
connectivity.getConnectivityManager().registerDefaultNetworkCallback(networkCallback);
|
||||
} else {
|
||||
context.registerReceiver(this, new IntentFilter(CONNECTIVITY_ACTION));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel(Object arguments) {
|
||||
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
if (networkCallback != null) {
|
||||
connectivity.getConnectivityManager().unregisterNetworkCallback(networkCallback);
|
||||
networkCallback = null;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
context.unregisterReceiver(this);
|
||||
} catch (Exception e) {
|
||||
//listen never called, ignore the error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (events != null) {
|
||||
events.success(connectivity.getNetworkType());
|
||||
}
|
||||
}
|
||||
|
||||
private void sendEvent() {
|
||||
Runnable runnable = () -> events.success(connectivity.getNetworkType());
|
||||
mainHandler.post(runnable);
|
||||
}
|
||||
|
||||
private void sendEvent(final String networkType) {
|
||||
Runnable runnable = () -> events.success(networkType);
|
||||
mainHandler.post(runnable);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright 2019 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package dev.fluttercommunity.plus.connectivity;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
/**
|
||||
* The handler receives {@link MethodCall}s from the UIThread, gets the related information from
|
||||
* a @{@link Connectivity}, and then send the result back to the UIThread through the {@link
|
||||
* MethodChannel.Result}.
|
||||
*/
|
||||
class ConnectivityMethodChannelHandler implements MethodChannel.MethodCallHandler {
|
||||
|
||||
private final Connectivity connectivity;
|
||||
|
||||
/**
|
||||
* Construct the ConnectivityMethodChannelHandler with a {@code connectivity}. The {@code
|
||||
* connectivity} must not be null.
|
||||
*/
|
||||
ConnectivityMethodChannelHandler(Connectivity connectivity) {
|
||||
assert (connectivity != null);
|
||||
this.connectivity = connectivity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMethodCall(MethodCall call, @NonNull MethodChannel.Result result) {
|
||||
if ("check".equals(call.method)) {
|
||||
result.success(connectivity.getNetworkType());
|
||||
} else {
|
||||
result.notImplemented();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright 2017 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package dev.fluttercommunity.plus.connectivity;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import androidx.annotation.NonNull;
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin;
|
||||
import io.flutter.plugin.common.BinaryMessenger;
|
||||
import io.flutter.plugin.common.EventChannel;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
/** ConnectivityPlugin */
|
||||
public class ConnectivityPlugin implements FlutterPlugin {
|
||||
|
||||
private MethodChannel methodChannel;
|
||||
private EventChannel eventChannel;
|
||||
private ConnectivityBroadcastReceiver receiver;
|
||||
|
||||
@Override
|
||||
public void onAttachedToEngine(FlutterPluginBinding binding) {
|
||||
setupChannels(binding.getBinaryMessenger(), binding.getApplicationContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
|
||||
teardownChannels();
|
||||
}
|
||||
|
||||
private void setupChannels(BinaryMessenger messenger, Context context) {
|
||||
methodChannel = new MethodChannel(messenger, "dev.fluttercommunity.plus/connectivity");
|
||||
eventChannel = new EventChannel(messenger, "dev.fluttercommunity.plus/connectivity_status");
|
||||
ConnectivityManager connectivityManager =
|
||||
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
|
||||
Connectivity connectivity = new Connectivity(connectivityManager);
|
||||
|
||||
ConnectivityMethodChannelHandler methodChannelHandler =
|
||||
new ConnectivityMethodChannelHandler(connectivity);
|
||||
receiver = new ConnectivityBroadcastReceiver(context, connectivity);
|
||||
|
||||
methodChannel.setMethodCallHandler(methodChannelHandler);
|
||||
eventChannel.setStreamHandler(receiver);
|
||||
}
|
||||
|
||||
private void teardownChannels() {
|
||||
methodChannel.setMethodCallHandler(null);
|
||||
eventChannel.setStreamHandler(null);
|
||||
receiver.onCancel(null);
|
||||
methodChannel = null;
|
||||
eventChannel = null;
|
||||
receiver = null;
|
||||
}
|
||||
}
|
4
lib/third_party/connectivity_plus/connectivity_plus/ios/Classes/ConnectivityPlusPlugin.h
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
#import <Flutter/Flutter.h>
|
||||
|
||||
@interface ConnectivityPlusPlugin : NSObject <FlutterPlugin>
|
||||
@end
|
15
lib/third_party/connectivity_plus/connectivity_plus/ios/Classes/ConnectivityPlusPlugin.m
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
#import "ConnectivityPlusPlugin.h"
|
||||
#if __has_include(<connectivity_plus/connectivity_plus-Swift.h>)
|
||||
#import <connectivity_plus/connectivity_plus-Swift.h>
|
||||
#else
|
||||
// Support project import fallback if the generated compatibility header
|
||||
// is not copied when this plugin is created as a library.
|
||||
// https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816
|
||||
#import "connectivity_plus-Swift.h"
|
||||
#endif
|
||||
|
||||
@implementation ConnectivityPlusPlugin
|
||||
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
|
||||
[SwiftConnectivityPlusPlugin registerWithRegistrar:registrar];
|
||||
}
|
||||
@end
|
21
lib/third_party/connectivity_plus/connectivity_plus/ios/Classes/ConnectivityProvider.swift
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
import Foundation
|
||||
|
||||
public enum ConnectivityType {
|
||||
case none
|
||||
case wiredEthernet
|
||||
case wifi
|
||||
case cellular
|
||||
case other
|
||||
}
|
||||
|
||||
public protocol ConnectivityProvider: NSObjectProtocol {
|
||||
typealias ConnectivityUpdateHandler = (ConnectivityType) -> Void
|
||||
|
||||
var currentConnectivityType: ConnectivityType { get }
|
||||
|
||||
var connectivityUpdateHandler: ConnectivityUpdateHandler? { get set }
|
||||
|
||||
func start()
|
||||
|
||||
func stop()
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
import Foundation
|
||||
import Network
|
||||
|
||||
@available(iOS 12, *)
|
||||
public class PathMonitorConnectivityProvider: NSObject, ConnectivityProvider {
|
||||
|
||||
private let queue = DispatchQueue.global(qos: .background)
|
||||
|
||||
private var _pathMonitor: NWPathMonitor?
|
||||
|
||||
public var currentConnectivityType: ConnectivityType {
|
||||
let path = ensurePathMonitor().currentPath
|
||||
// .satisfied means that the network is available
|
||||
if path.status == .satisfied {
|
||||
if path.usesInterfaceType(.wifi) {
|
||||
return .wifi
|
||||
} else if path.usesInterfaceType(.cellular) {
|
||||
return .cellular
|
||||
} else if path.usesInterfaceType(.wiredEthernet) {
|
||||
// .wiredEthernet is available in simulator
|
||||
// but for consistency it is probably correct to report .wifi
|
||||
return .wifi
|
||||
} else if path.usesInterfaceType(.other) {
|
||||
return .other
|
||||
}
|
||||
}
|
||||
return .none
|
||||
}
|
||||
|
||||
public var connectivityUpdateHandler: ConnectivityUpdateHandler?
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
_ = ensurePathMonitor()
|
||||
}
|
||||
|
||||
public func start() {
|
||||
_ = ensurePathMonitor()
|
||||
}
|
||||
|
||||
public func stop() {
|
||||
_pathMonitor?.cancel()
|
||||
_pathMonitor = nil
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
private func ensurePathMonitor() -> NWPathMonitor {
|
||||
if (_pathMonitor == nil) {
|
||||
let pathMonitor = NWPathMonitor()
|
||||
pathMonitor.start(queue: queue)
|
||||
pathMonitor.pathUpdateHandler = pathUpdateHandler
|
||||
_pathMonitor = pathMonitor
|
||||
}
|
||||
return _pathMonitor!
|
||||
}
|
||||
|
||||
private func pathUpdateHandler(path: NWPath) {
|
||||
connectivityUpdateHandler?(currentConnectivityType)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
import Foundation
|
||||
import Reachability
|
||||
|
||||
public class ReachabilityConnectivityProvider: NSObject, ConnectivityProvider {
|
||||
private var _reachability: Reachability?
|
||||
|
||||
public var currentConnectivityType: ConnectivityType {
|
||||
let reachability = ensureReachability()
|
||||
switch reachability.connection {
|
||||
case .wifi:
|
||||
return .wifi
|
||||
case .cellular:
|
||||
return .cellular
|
||||
default:
|
||||
return .none
|
||||
}
|
||||
}
|
||||
|
||||
public var connectivityUpdateHandler: ConnectivityUpdateHandler?
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
_ = ensureReachability()
|
||||
}
|
||||
|
||||
public func start() {
|
||||
let reachability = ensureReachability()
|
||||
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(reachabilityChanged),
|
||||
name: .reachabilityChanged,
|
||||
object: reachability)
|
||||
|
||||
try? reachability.startNotifier()
|
||||
}
|
||||
|
||||
public func stop() {
|
||||
NotificationCenter.default.removeObserver(
|
||||
self,
|
||||
name: .reachabilityChanged,
|
||||
object: _reachability)
|
||||
|
||||
_reachability?.stopNotifier()
|
||||
_reachability = nil
|
||||
}
|
||||
|
||||
private func ensureReachability() -> Reachability {
|
||||
if (_reachability == nil) {
|
||||
let reachability = try? Reachability()
|
||||
_reachability = reachability
|
||||
}
|
||||
return _reachability!
|
||||
}
|
||||
|
||||
@objc private func reachabilityChanged(notification: NSNotification) {
|
||||
connectivityUpdateHandler?(currentConnectivityType)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
// Copyright 2019 The Chromium Authors. All rights reserved.
|
||||
// Use of this source is governed by a BSD-style license that can
|
||||
// be found in the LICENSE file.
|
||||
|
||||
import Flutter
|
||||
|
||||
public class SwiftConnectivityPlusPlugin: NSObject, FlutterPlugin, FlutterStreamHandler {
|
||||
private let connectivityProvider: ConnectivityProvider
|
||||
private var eventSink: FlutterEventSink?
|
||||
|
||||
init(connectivityProvider: ConnectivityProvider) {
|
||||
self.connectivityProvider = connectivityProvider
|
||||
super.init()
|
||||
self.connectivityProvider.connectivityUpdateHandler = connectivityUpdateHandler
|
||||
}
|
||||
|
||||
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||
let channel = FlutterMethodChannel(
|
||||
name: "dev.fluttercommunity.plus/connectivity",
|
||||
binaryMessenger: registrar.messenger())
|
||||
|
||||
let streamChannel = FlutterEventChannel(
|
||||
name: "dev.fluttercommunity.plus/connectivity_status",
|
||||
binaryMessenger: registrar.messenger())
|
||||
|
||||
let connectivityProvider: ConnectivityProvider
|
||||
if #available(iOS 12, *) {
|
||||
connectivityProvider = PathMonitorConnectivityProvider()
|
||||
} else {
|
||||
connectivityProvider = ReachabilityConnectivityProvider()
|
||||
}
|
||||
|
||||
let instance = SwiftConnectivityPlusPlugin(connectivityProvider: connectivityProvider)
|
||||
streamChannel.setStreamHandler(instance)
|
||||
|
||||
registrar.addMethodCallDelegate(instance, channel: channel)
|
||||
}
|
||||
|
||||
public func detachFromEngine(for registrar: FlutterPluginRegistrar) {
|
||||
eventSink = nil
|
||||
connectivityProvider.stop()
|
||||
}
|
||||
|
||||
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||
switch call.method {
|
||||
case "check":
|
||||
result(statusFrom(connectivityType: connectivityProvider.currentConnectivityType))
|
||||
default:
|
||||
result(FlutterMethodNotImplemented)
|
||||
}
|
||||
}
|
||||
|
||||
private func statusFrom(connectivityType: ConnectivityType) -> String {
|
||||
switch connectivityType {
|
||||
case .wifi:
|
||||
return "wifi"
|
||||
case .cellular:
|
||||
return "mobile"
|
||||
case .wiredEthernet:
|
||||
return "ethernet"
|
||||
case .other:
|
||||
return "other"
|
||||
case .none:
|
||||
return "none"
|
||||
}
|
||||
}
|
||||
|
||||
public func onListen(
|
||||
withArguments _: Any?,
|
||||
eventSink events: @escaping FlutterEventSink
|
||||
) -> FlutterError? {
|
||||
eventSink = events
|
||||
connectivityProvider.start()
|
||||
connectivityUpdateHandler(connectivityType: connectivityProvider.currentConnectivityType)
|
||||
return nil
|
||||
}
|
||||
|
||||
private func connectivityUpdateHandler(connectivityType: ConnectivityType) {
|
||||
DispatchQueue.main.async {
|
||||
self.eventSink?(self.statusFrom(connectivityType: connectivityType))
|
||||
}
|
||||
}
|
||||
|
||||
public func onCancel(withArguments _: Any?) -> FlutterError? {
|
||||
connectivityProvider.stop()
|
||||
eventSink = nil
|
||||
return nil
|
||||
}
|
||||
}
|
24
lib/third_party/connectivity_plus/connectivity_plus/ios/connectivity_plus.podspec
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
#
|
||||
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
|
||||
#
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'connectivity_plus'
|
||||
s.version = '0.0.1'
|
||||
s.summary = 'Flutter Connectivity'
|
||||
s.description = <<-DESC
|
||||
This plugin allows Flutter apps to discover network connectivity and configure themselves accordingly.
|
||||
Downloaded by pub (not CocoaPods).
|
||||
DESC
|
||||
s.homepage = 'https://plus.fluttercommunity.dev/'
|
||||
s.license = { :type => 'BSD', :file => '../LICENSE' }
|
||||
s.author = { 'Flutter Community Team' => 'authors@fluttercommunity.dev' }
|
||||
s.source = { :http => 'https://github.com/fluttercommunity/plus_plugins' }
|
||||
s.documentation_url = 'https://pub.dev/packages/connectivity_plus'
|
||||
s.source_files = 'Classes/**/*'
|
||||
s.public_header_files = 'Classes/**/*.h'
|
||||
s.dependency 'Flutter'
|
||||
s.dependency 'ReachabilitySwift'
|
||||
s.platform = :ios, '9.0'
|
||||
s.swift_version = '5.0'
|
||||
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' }
|
||||
end
|
54
lib/third_party/connectivity_plus/connectivity_plus/lib/connectivity_plus.dart
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
// Copyright 2017 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:connectivity_plus_platform_interface/connectivity_plus_platform_interface.dart';
|
||||
|
||||
// Export enums from the platform_interface so plugin users can use them directly.
|
||||
export 'package:connectivity_plus_platform_interface/connectivity_plus_platform_interface.dart'
|
||||
show ConnectivityResult;
|
||||
|
||||
export 'src/connectivity_plus_linux.dart';
|
||||
|
||||
dan marked this conversation as resolved
Outdated
sarah
commented
delete this. delete this.
|
||||
/// Discover network connectivity configurations: Distinguish between WI-FI and cellular, check WI-FI status and more.
|
||||
class Connectivity {
|
||||
/// Constructs a singleton instance of [Connectivity].
|
||||
///
|
||||
/// [Connectivity] is designed to work as a singleton.
|
||||
// When a second instance is created, the first instance will not be able to listen to the
|
||||
// EventChannel because it is overridden. Forcing the class to be a singleton class can prevent
|
||||
// misuse of creating a second instance from a programmer.
|
||||
factory Connectivity() {
|
||||
_singleton ??= Connectivity._();
|
||||
return _singleton!;
|
||||
}
|
||||
|
||||
Connectivity._();
|
||||
|
||||
static Connectivity? _singleton;
|
||||
|
||||
static ConnectivityPlatform get _platform {
|
||||
return ConnectivityPlatform.instance;
|
||||
}
|
||||
|
||||
/// Fires whenever the connectivity state changes.
|
||||
///
|
||||
/// On iOS, the connectivity status might not update when WiFi
|
||||
/// status changes, this is a known issue that only affects simulators.
|
||||
/// For details see https://github.com/fluttercommunity/plus_plugins/issues/479.
|
||||
Stream<ConnectivityResult> get onConnectivityChanged {
|
||||
return _platform.onConnectivityChanged;
|
||||
}
|
||||
|
||||
/// Checks the connection status of the device.
|
||||
///
|
||||
/// Do not use the result of this function to decide whether you can reliably
|
||||
/// make a network request. It only gives you the radio status.
|
||||
///
|
||||
/// Instead listen for connectivity changes via [onConnectivityChanged] stream.
|
||||
Future<ConnectivityResult> checkConnectivity() {
|
||||
return _platform.checkConnectivity();
|
||||
}
|
||||
}
|
74
lib/third_party/connectivity_plus/connectivity_plus/lib/src/connectivity_plus_linux.dart
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:connectivity_plus_platform_interface/connectivity_plus_platform_interface.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:cwtch/third_party/nm/nm.dart';
|
||||
|
||||
// Used internally
|
||||
// ignore_for_file: public_member_api_docs
|
||||
|
||||
@visibleForTesting
|
||||
typedef NetworkManagerClientFactory = NetworkManagerClient Function();
|
||||
|
||||
/// The Linux implementation of ConnectivityPlatform.
|
||||
class ConnectivityPlusLinuxPlugin extends ConnectivityPlatform {
|
||||
/// Register this dart class as the platform implementation for linux
|
||||
static void registerWith() {
|
||||
ConnectivityPlatform.instance = ConnectivityPlusLinuxPlugin();
|
||||
}
|
||||
|
||||
/// Checks the connection status of the device.
|
||||
@override
|
||||
Future<ConnectivityResult> checkConnectivity() async {
|
||||
final client = createClient();
|
||||
await client.connect();
|
||||
final connectivity = _getConnectivity(client);
|
||||
await client.close();
|
||||
return connectivity;
|
||||
}
|
||||
|
||||
NetworkManagerClient? _client;
|
||||
StreamController<ConnectivityResult>? _controller;
|
||||
|
||||
/// Returns a Stream of ConnectivityResults changes.
|
||||
@override
|
||||
Stream<ConnectivityResult> get onConnectivityChanged {
|
||||
_controller ??= StreamController<ConnectivityResult>.broadcast(
|
||||
onListen: _startListenConnectivity,
|
||||
onCancel: _stopListenConnectivity,
|
||||
);
|
||||
return _controller!.stream;
|
||||
}
|
||||
|
||||
ConnectivityResult _getConnectivity(NetworkManagerClient client) {
|
||||
if (client.connectivity != NetworkManagerConnectivityState.full) {
|
||||
return ConnectivityResult.none;
|
||||
}
|
||||
// Open privacy update: we only need online/offline, so deleting type specificity
|
||||
return ConnectivityResult.mobile;
|
||||
}
|
||||
|
||||
Future<void> _startListenConnectivity() async {
|
||||
_client ??= createClient();
|
||||
await _client!.connect();
|
||||
_addConnectivity(_client!);
|
||||
_client!.propertiesChanged.listen((properties) {
|
||||
if (properties.contains('Connectivity')) {
|
||||
_addConnectivity(_client!);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _addConnectivity(NetworkManagerClient client) {
|
||||
_controller!.add(_getConnectivity(client));
|
||||
}
|
||||
|
||||
Future<void> _stopListenConnectivity() async {
|
||||
await _client?.close();
|
||||
_client = null;
|
||||
}
|
||||
|
||||
@visibleForTesting
|
||||
// ignore: prefer_function_declarations_over_variables
|
||||
NetworkManagerClientFactory createClient = () => NetworkManagerClient();
|
||||
}
|
90
lib/third_party/connectivity_plus/connectivity_plus/macos/Classes/ConnectivityPlugin.swift
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
// Copyright 2019 The Chromium Authors. All rights reserved.
|
||||
// Use of this source is governed by a BSD-style license that can
|
||||
// be found in the LICENSE file.
|
||||
|
||||
import Cocoa
|
||||
import FlutterMacOS
|
||||
|
||||
public class ConnectivityPlugin: NSObject, FlutterPlugin, FlutterStreamHandler {
|
||||
private let connectivityProvider: ConnectivityProvider
|
||||
private var eventSink: FlutterEventSink?
|
||||
|
||||
init(connectivityProvider: ConnectivityProvider) {
|
||||
self.connectivityProvider = connectivityProvider
|
||||
super.init()
|
||||
self.connectivityProvider.connectivityUpdateHandler = connectivityUpdateHandler
|
||||
}
|
||||
|
||||
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||
let channel = FlutterMethodChannel(
|
||||
name: "dev.fluttercommunity.plus/connectivity",
|
||||
binaryMessenger: registrar.messenger)
|
||||
|
||||
let streamChannel = FlutterEventChannel(
|
||||
name: "dev.fluttercommunity.plus/connectivity_status",
|
||||
binaryMessenger: registrar.messenger)
|
||||
|
||||
let connectivityProvider: ConnectivityProvider
|
||||
if #available(macOS 10.14, *) {
|
||||
connectivityProvider = PathMonitorConnectivityProvider()
|
||||
} else {
|
||||
connectivityProvider = ReachabilityConnectivityProvider()
|
||||
}
|
||||
|
||||
let instance = ConnectivityPlugin(connectivityProvider: connectivityProvider)
|
||||
streamChannel.setStreamHandler(instance)
|
||||
|
||||
registrar.addMethodCallDelegate(instance, channel: channel)
|
||||
}
|
||||
|
||||
public func detachFromEngine(for registrar: FlutterPluginRegistrar) {
|
||||
eventSink = nil
|
||||
connectivityProvider.stop()
|
||||
}
|
||||
|
||||
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||
switch call.method {
|
||||
case "check":
|
||||
result(statusFrom(connectivityType: connectivityProvider.currentConnectivityType))
|
||||
default:
|
||||
result(FlutterMethodNotImplemented)
|
||||
}
|
||||
}
|
||||
|
||||
private func statusFrom(connectivityType: ConnectivityType) -> String {
|
||||
switch connectivityType {
|
||||
case .wifi:
|
||||
return "wifi"
|
||||
case .cellular:
|
||||
return "mobile"
|
||||
case .wiredEthernet:
|
||||
return "ethernet"
|
||||
case .other:
|
||||
return "other"
|
||||
case .none:
|
||||
return "none"
|
||||
}
|
||||
}
|
||||
|
||||
public func onListen(
|
||||
withArguments _: Any?,
|
||||
eventSink events: @escaping FlutterEventSink
|
||||
) -> FlutterError? {
|
||||
eventSink = events
|
||||
connectivityProvider.start()
|
||||
connectivityUpdateHandler(connectivityType: connectivityProvider.currentConnectivityType)
|
||||
return nil
|
||||
}
|
||||
|
||||
private func connectivityUpdateHandler(connectivityType: ConnectivityType) {
|
||||
DispatchQueue.main.async {
|
||||
self.eventSink?(self.statusFrom(connectivityType: connectivityType))
|
||||
}
|
||||
}
|
||||
|
||||
public func onCancel(withArguments _: Any?) -> FlutterError? {
|
||||
connectivityProvider.stop()
|
||||
eventSink = nil
|
||||
return nil
|
||||
}
|
||||
}
|
21
lib/third_party/connectivity_plus/connectivity_plus/macos/Classes/ConnectivityProvider.swift
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
import Foundation
|
||||
|
||||
public enum ConnectivityType {
|
||||
case none
|
||||
case wiredEthernet
|
||||
case wifi
|
||||
case cellular
|
||||
case other
|
||||
}
|
||||
|
||||
public protocol ConnectivityProvider: NSObjectProtocol {
|
||||
typealias ConnectivityUpdateHandler = (ConnectivityType) -> Void
|
||||
|
||||
var currentConnectivityType: ConnectivityType { get }
|
||||
|
||||
var connectivityUpdateHandler: ConnectivityUpdateHandler? { get set }
|
||||
|
||||
func start()
|
||||
|
||||
func stop()
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
import Foundation
|
||||
import Network
|
||||
|
||||
@available(macOS 10.14, *)
|
||||
public class PathMonitorConnectivityProvider: NSObject, ConnectivityProvider {
|
||||
|
||||
private let queue = DispatchQueue.global(qos: .background)
|
||||
|
||||
private var _pathMonitor: NWPathMonitor?
|
||||
|
||||
public var currentConnectivityType: ConnectivityType {
|
||||
let path = ensurePathMonitor().currentPath
|
||||
// .satisfied means that the network is available
|
||||
if path.status == .satisfied {
|
||||
if path.usesInterfaceType(.wifi) {
|
||||
return .wifi
|
||||
} else if path.usesInterfaceType(.cellular) {
|
||||
return .cellular
|
||||
} else if path.usesInterfaceType(.wiredEthernet) {
|
||||
return .wiredEthernet
|
||||
} else if path.usesInterfaceType(.other) {
|
||||
return .other
|
||||
}
|
||||
}
|
||||
return .none
|
||||
}
|
||||
|
||||
public var connectivityUpdateHandler: ConnectivityUpdateHandler?
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
_ = ensurePathMonitor()
|
||||
}
|
||||
|
||||
public func start() {
|
||||
_ = ensurePathMonitor()
|
||||
}
|
||||
|
||||
public func stop() {
|
||||
_pathMonitor?.cancel()
|
||||
_pathMonitor = nil
|
||||
}
|
||||
|
||||
private func ensurePathMonitor() -> NWPathMonitor {
|
||||
if (_pathMonitor == nil) {
|
||||
let pathMonitor = NWPathMonitor()
|
||||
pathMonitor.start(queue: queue)
|
||||
pathMonitor.pathUpdateHandler = pathUpdateHandler
|
||||
_pathMonitor = pathMonitor
|
||||
}
|
||||
return _pathMonitor!
|
||||
}
|
||||
|
||||
private func pathUpdateHandler(path: NWPath) {
|
||||
connectivityUpdateHandler?(currentConnectivityType)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
import Foundation
|
||||
import Reachability
|
||||
|
||||
public class ReachabilityConnectivityProvider: NSObject, ConnectivityProvider {
|
||||
private var _reachability: Reachability?
|
||||
|
||||
public var currentConnectivityType: ConnectivityType {
|
||||
let reachability = ensureReachability()
|
||||
switch reachability.connection {
|
||||
case .wifi:
|
||||
return .wifi
|
||||
case .cellular:
|
||||
return .cellular
|
||||
default:
|
||||
return .none
|
||||
}
|
||||
}
|
||||
|
||||
public var connectivityUpdateHandler: ConnectivityUpdateHandler?
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
_ = ensureReachability()
|
||||
}
|
||||
|
||||
public func start() {
|
||||
let reachability = ensureReachability()
|
||||
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(reachabilityChanged),
|
||||
name: .reachabilityChanged,
|
||||
object: reachability)
|
||||
|
||||
try? reachability.startNotifier()
|
||||
}
|
||||
|
||||
public func stop() {
|
||||
NotificationCenter.default.removeObserver(
|
||||
self,
|
||||
name: .reachabilityChanged,
|
||||
object: _reachability)
|
||||
|
||||
_reachability?.stopNotifier()
|
||||
_reachability = nil
|
||||
}
|
||||
|
||||
private func ensureReachability() -> Reachability {
|
||||
if (_reachability == nil) {
|
||||
let reachability = try? Reachability()
|
||||
_reachability = reachability
|
||||
}
|
||||
return _reachability!
|
||||
}
|
||||
|
||||
@objc private func reachabilityChanged(notification: NSNotification) {
|
||||
connectivityUpdateHandler?(currentConnectivityType)
|
||||
}
|
||||
}
|
22
lib/third_party/connectivity_plus/connectivity_plus/macos/connectivity_plus.podspec
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
#
|
||||
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
|
||||
#
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'connectivity_plus'
|
||||
s.version = '0.0.1'
|
||||
s.summary = 'Flutter plugin for checking connectivity'
|
||||
s.description = <<-DESC
|
||||
Desktop implementation of the connectivity plugin
|
||||
DESC
|
||||
s.homepage = 'https://plus.fluttercommunity.dev/'
|
||||
s.license = { :type => 'BSD', :file => '../LICENSE' }
|
||||
s.author = { 'Flutter Community Team' => 'authors@fluttercommunity.dev' }
|
||||
s.source = { :http => 'https://github.com/fluttercommunity/plus_plugins' }
|
||||
s.documentation_url = 'https://pub.dev/packages/connectivity_plus'
|
||||
s.source_files = 'Classes/**/*'
|
||||
s.dependency 'FlutterMacOS'
|
||||
s.dependency 'ReachabilitySwift'
|
||||
|
||||
s.platform = :osx
|
||||
s.osx.deployment_target = '10.11'
|
||||
end
|
|
@ -0,0 +1,45 @@
|
|||
name: connectivity_plus
|
||||
description: Flutter plugin for discovering the state of the network (WiFi & mobile/cellular) connectivity on Android and iOS.
|
||||
version: 3.0.6
|
||||
homepage: https://plus.fluttercommunity.dev/
|
||||
repository: https://github.com/fluttercommunity/plus_plugins/tree/main/packages/
|
||||
issue_tracker: https://github.com/fluttercommunity/plus_plugins/labels/connectivity_plus
|
||||
|
||||
environment:
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=2.11.0"
|
||||
|
||||
flutter:
|
||||
plugin:
|
||||
platforms:
|
||||
android:
|
||||
package: dev.fluttercommunity.plus.connectivity
|
||||
pluginClass: ConnectivityPlugin
|
||||
ios:
|
||||
pluginClass: ConnectivityPlusPlugin
|
||||
linux:
|
||||
dartPluginClass: ConnectivityPlusLinuxPlugin
|
||||
macos:
|
||||
pluginClass: ConnectivityPlugin
|
||||
windows:
|
||||
pluginClass: ConnectivityPlusWindowsPlugin
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
flutter_web_plugins:
|
||||
sdk: flutter
|
||||
connectivity_plus_platform_interface:
|
||||
path: ./../connectivity_plus_platform_interface
|
||||
js: ^0.6.3
|
||||
meta: ^1.8.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
build_runner: ^2.1.11
|
||||
dbus: ^0.7.5
|
||||
flutter_lints: ^2.0.1
|
||||
mockito: ^5.2.0
|
||||
plugin_platform_interface: ^2.1.2
|
||||
test: ^1.21.1
|
|
@ -0,0 +1,17 @@
|
|||
flutter/
|
||||
|
||||
# Visual Studio user-specific files.
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# Visual Studio build-related files.
|
||||
x64/
|
||||
x86/
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
|
@ -0,0 +1,29 @@
|
|||
cmake_minimum_required(VERSION 3.15)
|
||||
set(PROJECT_NAME "connectivity_plus")
|
||||
project(${PROJECT_NAME} LANGUAGES CXX)
|
||||
|
||||
# This value is used when generating builds using this plugin, so it must
|
||||
# not be changed
|
||||
set(PLUGIN_NAME "connectivity_plus_plugin")
|
||||
|
||||
add_library(${PLUGIN_NAME} SHARED
|
||||
"connectivity_plus_plugin.cpp"
|
||||
"network_manager.cpp"
|
||||
)
|
||||
apply_standard_settings(${PLUGIN_NAME})
|
||||
set_target_properties(${PLUGIN_NAME} PROPERTIES
|
||||
CXX_VISIBILITY_PRESET hidden)
|
||||
target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL)
|
||||
target_include_directories(${PLUGIN_NAME} INTERFACE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
target_link_libraries(${PLUGIN_NAME} PRIVATE
|
||||
flutter
|
||||
flutter_wrapper_plugin
|
||||
iphlpapi
|
||||
)
|
||||
|
||||
# List of absolute paths to libraries that should be bundled with the plugin
|
||||
set(connectivity_plus_bundled_libraries
|
||||
""
|
||||
PARENT_SCOPE
|
||||
)
|
171
lib/third_party/connectivity_plus/connectivity_plus/windows/connectivity_plus_plugin.cpp
vendored
Normal file
|
@ -0,0 +1,171 @@
|
|||
// clang-format off
|
||||
#include "include/connectivity_plus/network_manager.h"
|
||||
// clang-format on
|
||||
#include "include/connectivity_plus/connectivity_plus_windows_plugin.h"
|
||||
|
||||
#include <flutter/event_channel.h>
|
||||
#include <flutter/event_sink.h>
|
||||
#include <flutter/event_stream_handler.h>
|
||||
#include <flutter/method_channel.h>
|
||||
#include <flutter/plugin_registrar_windows.h>
|
||||
#include <flutter/standard_method_codec.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace {
|
||||
|
||||
typedef flutter::EventChannel<flutter::EncodableValue> FlEventChannel;
|
||||
typedef flutter::EventSink<flutter::EncodableValue> FlEventSink;
|
||||
typedef flutter::MethodCall<flutter::EncodableValue> FlMethodCall;
|
||||
typedef flutter::MethodResult<flutter::EncodableValue> FlMethodResult;
|
||||
typedef flutter::MethodChannel<flutter::EncodableValue> FlMethodChannel;
|
||||
typedef flutter::StreamHandler<flutter::EncodableValue> FlStreamHandler;
|
||||
typedef flutter::StreamHandlerError<flutter::EncodableValue>
|
||||
FlStreamHandlerError;
|
||||
|
||||
class ConnectivityPlusWindowsPlugin : public flutter::Plugin {
|
||||
public:
|
||||
ConnectivityPlusWindowsPlugin();
|
||||
virtual ~ConnectivityPlusWindowsPlugin();
|
||||
|
||||
std::shared_ptr<NetworkManager> GetManager() const;
|
||||
|
||||
static void RegisterWithRegistrar(flutter::PluginRegistrarWindows *registrar);
|
||||
|
||||
private:
|
||||
void HandleMethodCall(const FlMethodCall &method_call,
|
||||
std::unique_ptr<FlMethodResult> result);
|
||||
|
||||
std::shared_ptr<NetworkManager> manager;
|
||||
};
|
||||
|
||||
class ConnectivityStreamHandler : public FlStreamHandler {
|
||||
public:
|
||||
ConnectivityStreamHandler(std::shared_ptr<NetworkManager> manager);
|
||||
virtual ~ConnectivityStreamHandler();
|
||||
|
||||
protected:
|
||||
void AddConnectivityEvent();
|
||||
|
||||
std::unique_ptr<FlStreamHandlerError>
|
||||
OnListenInternal(const flutter::EncodableValue *arguments,
|
||||
std::unique_ptr<FlEventSink> &&sink) override;
|
||||
|
||||
std::unique_ptr<FlStreamHandlerError>
|
||||
OnCancelInternal(const flutter::EncodableValue *arguments) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<NetworkManager> manager;
|
||||
std::unique_ptr<FlEventSink> sink;
|
||||
};
|
||||
|
||||
ConnectivityPlusWindowsPlugin::ConnectivityPlusWindowsPlugin() {
|
||||
manager = std::make_shared<NetworkManager>();
|
||||
manager->Init();
|
||||
}
|
||||
|
||||
ConnectivityPlusWindowsPlugin::~ConnectivityPlusWindowsPlugin() {
|
||||
manager->Cleanup();
|
||||
}
|
||||
|
||||
std::shared_ptr<NetworkManager>
|
||||
ConnectivityPlusWindowsPlugin::GetManager() const {
|
||||
return manager;
|
||||
}
|
||||
|
||||
void ConnectivityPlusWindowsPlugin::RegisterWithRegistrar(
|
||||
flutter::PluginRegistrarWindows *registrar) {
|
||||
auto plugin = std::make_unique<ConnectivityPlusWindowsPlugin>();
|
||||
|
||||
auto methodChannel =
|
||||
std::make_unique<flutter::MethodChannel<flutter::EncodableValue>>(
|
||||
registrar->messenger(), "dev.fluttercommunity.plus/connectivity",
|
||||
&flutter::StandardMethodCodec::GetInstance());
|
||||
|
||||
methodChannel->SetMethodCallHandler(
|
||||
[plugin_pointer = plugin.get()](const auto &call, auto result) {
|
||||
plugin_pointer->HandleMethodCall(call, std::move(result));
|
||||
});
|
||||
|
||||
auto eventChannel = std::make_unique<FlEventChannel>(
|
||||
registrar->messenger(), "dev.fluttercommunity.plus/connectivity_status",
|
||||
&flutter::StandardMethodCodec::GetInstance());
|
||||
|
||||
eventChannel->SetStreamHandler(
|
||||
std::make_unique<ConnectivityStreamHandler>(plugin->GetManager()));
|
||||
|
||||
registrar->AddPlugin(std::move(plugin));
|
||||
}
|
||||
|
||||
static std::string ConnectivityToString(ConnectivityType connectivityType) {
|
||||
switch (connectivityType) {
|
||||
case ConnectivityType::WiFi:
|
||||
return "wifi";
|
||||
case ConnectivityType::Ethernet:
|
||||
return "ethernet";
|
||||
case ConnectivityType::None:
|
||||
default:
|
||||
return "none";
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectivityPlusWindowsPlugin::HandleMethodCall(
|
||||
const flutter::MethodCall<flutter::EncodableValue> &method_call,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
if (method_call.method_name().compare("check") == 0) {
|
||||
std::string connectivity =
|
||||
ConnectivityToString(manager->GetConnectivityType());
|
||||
result->Success(flutter::EncodableValue(connectivity));
|
||||
} else {
|
||||
result->NotImplemented();
|
||||
}
|
||||
}
|
||||
|
||||
ConnectivityStreamHandler::ConnectivityStreamHandler(
|
||||
std::shared_ptr<NetworkManager> manager)
|
||||
: manager(manager) {}
|
||||
|
||||
ConnectivityStreamHandler::~ConnectivityStreamHandler() {}
|
||||
|
||||
void ConnectivityStreamHandler::AddConnectivityEvent() {
|
||||
std::string connectivity =
|
||||
ConnectivityToString(manager->GetConnectivityType());
|
||||
sink->Success(flutter::EncodableValue(connectivity));
|
||||
}
|
||||
|
||||
std::unique_ptr<FlStreamHandlerError>
|
||||
ConnectivityStreamHandler::OnListenInternal(
|
||||
const flutter::EncodableValue *arguments,
|
||||
std::unique_ptr<FlEventSink> &&events) {
|
||||
sink = std::move(events);
|
||||
|
||||
auto callback =
|
||||
std::bind(&ConnectivityStreamHandler::AddConnectivityEvent, this);
|
||||
|
||||
if (!manager->StartListen(callback)) {
|
||||
return std::make_unique<FlStreamHandlerError>(
|
||||
std::to_string(manager->GetError()), "NetworkManager::StartListen",
|
||||
nullptr);
|
||||
}
|
||||
|
||||
AddConnectivityEvent();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<FlStreamHandlerError>
|
||||
ConnectivityStreamHandler::OnCancelInternal(
|
||||
const flutter::EncodableValue *arguments) {
|
||||
manager->StopListen();
|
||||
sink.reset();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void ConnectivityPlusWindowsPluginRegisterWithRegistrar(
|
||||
FlutterDesktopPluginRegistrarRef registrar) {
|
||||
ConnectivityPlusWindowsPlugin::RegisterWithRegistrar(
|
||||
flutter::PluginRegistrarManager::GetInstance()
|
||||
->GetRegistrar<flutter::PluginRegistrarWindows>(registrar));
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef FLUTTER_PLUGIN_CONNECTIVITY_WINDOWS_PLUS_PLUGIN_H_
|
||||
#define FLUTTER_PLUGIN_CONNECTIVITY_WINDOWS_PLUS_PLUGIN_H_
|
||||
|
||||
#include <flutter_plugin_registrar.h>
|
||||
|
||||
#ifdef FLUTTER_PLUGIN_IMPL
|
||||
#define FLUTTER_PLUGIN_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define FLUTTER_PLUGIN_EXPORT __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
FLUTTER_PLUGIN_EXPORT void ConnectivityPlusWindowsPluginRegisterWithRegistrar(
|
||||
FlutterDesktopPluginRegistrarRef registrar);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // FLUTTER_PLUGIN_CONNECTIVITY_PLUS_WINDOWS_PLUGIN_H_
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef NETWORK_MANAGER_H
|
||||
#define NETWORK_MANAGER_H
|
||||
|
||||
// clang-format off
|
||||
#include <winsock2.h>
|
||||
// clang-format on
|
||||
#include <windows.h>
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
enum class ConnectivityType { None, Ethernet, WiFi };
|
||||
|
||||
class NetworkListener;
|
||||
struct IConnectionPoint;
|
||||
struct IConnectionPointContainer;
|
||||
struct INetworkListManager;
|
||||
struct IUnknown;
|
||||
|
||||
typedef std::function<void()> NetworkCallback;
|
||||
|
||||
class NetworkManager {
|
||||
public:
|
||||
NetworkManager();
|
||||
~NetworkManager();
|
||||
|
||||
bool Init();
|
||||
void Cleanup();
|
||||
|
||||
ConnectivityType GetConnectivityType() const;
|
||||
|
||||
bool StartListen(NetworkCallback pCallback);
|
||||
void StopListen();
|
||||
|
||||
bool HasError() const;
|
||||
int GetError() const;
|
||||
|
||||
private:
|
||||
std::vector<GUID> GetConnectedAdapterIds() const;
|
||||
|
||||
DWORD dwCookie = 0;
|
||||
IUnknown *pUnknown = NULL;
|
||||
INetworkListManager *pNetworkListManager = NULL;
|
||||
IConnectionPointContainer *pCPContainer = NULL;
|
||||
IConnectionPoint *pConnectPoint = NULL;
|
||||
NetworkListener *pListener = NULL;
|
||||
};
|
||||
|
||||
#endif // NETWORK_MANAGER_H
|
243
lib/third_party/connectivity_plus/connectivity_plus/windows/network_manager.cpp
vendored
Normal file
|
@ -0,0 +1,243 @@
|
|||
// based on
|
||||
// https://github.com/PurpleI2P/i2pd/blob/master/Win32/Win32NetState.cpp
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
||||
dan marked this conversation as resolved
Outdated
sarah
commented
another license that needs to be in licenses.dart. Also appears that the original code is violating this license by distributing a separate license that doesn't contain this copyright information... another license that needs to be in licenses.dart.
Also appears that the original code is violating this license by distributing a separate license that doesn't contain this copyright information...
|
||||
*
|
||||
* This file is part of Purple i2pd project and licensed under BSD3
|
||||
*
|
||||
* See full license text in LICENSE file at top of project tree
|
||||
*/
|
||||
|
||||
#include "include/connectivity_plus/network_manager.h"
|
||||
|
||||
#include <iphlpapi.h>
|
||||
#include <netlistmgr.h>
|
||||
#include <ocidl.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <set>
|
||||
|
||||
class NetworkListener final : public INetworkEvents {
|
||||
public:
|
||||
NetworkListener(NetworkCallback pCb) : pCallback(pCb) {}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) {
|
||||
AddRef();
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
if (IsEqualIID(riid, IID_IUnknown)) {
|
||||
*ppvObject = (IUnknown *)this;
|
||||
} else if (IsEqualIID(riid, IID_INetworkEvents)) {
|
||||
*ppvObject = (INetworkEvents *)this;
|
||||
} else {
|
||||
hr = E_NOINTERFACE;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef() { return InterlockedIncrement(&lRef); }
|
||||
|
||||
ULONG STDMETHODCALLTYPE Release() {
|
||||
LONG lAddend = InterlockedDecrement(&lRef);
|
||||
if (lRef == 0) {
|
||||
delete this;
|
||||
}
|
||||
return lAddend;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE NetworkAdded(GUID networkId) { return S_OK; }
|
||||
|
||||
HRESULT STDMETHODCALLTYPE
|
||||
NetworkConnectivityChanged(GUID networkId, NLM_CONNECTIVITY newConnectivity) {
|
||||
Callback();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE NetworkDeleted(GUID networkId) { return S_OK; }
|
||||
|
||||
HRESULT STDMETHODCALLTYPE
|
||||
NetworkPropertyChanged(GUID networkId, NLM_NETWORK_PROPERTY_CHANGE flags) {
|
||||
if (flags & NLM_NETWORK_PROPERTY_CHANGE_CONNECTION) {
|
||||
Callback();
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void Callback() {
|
||||
assert(pCallback);
|
||||
pCallback();
|
||||
}
|
||||
|
||||
private:
|
||||
volatile LONG lRef = 1;
|
||||
NetworkCallback pCallback = nullptr;
|
||||
};
|
||||
|
||||
NetworkManager::NetworkManager() {}
|
||||
|
||||
NetworkManager::~NetworkManager() {
|
||||
StopListen();
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
bool NetworkManager::Init() {
|
||||
CoInitialize(NULL);
|
||||
|
||||
HRESULT hr = CoCreateInstance(CLSID_NetworkListManager, NULL, CLSCTX_ALL,
|
||||
IID_IUnknown, (void **)&pUnknown);
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = pUnknown->QueryInterface(IID_INetworkListManager,
|
||||
(void **)&pNetworkListManager);
|
||||
}
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
void NetworkManager::Cleanup() {
|
||||
if (pNetworkListManager) {
|
||||
pNetworkListManager->Release();
|
||||
pNetworkListManager = NULL;
|
||||
}
|
||||
|
||||
if (pUnknown) {
|
||||
pUnknown->Release();
|
||||
pUnknown = NULL;
|
||||
}
|
||||
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
std::vector<GUID> NetworkManager::GetConnectedAdapterIds() const {
|
||||
std::vector<GUID> adapterIds;
|
||||
|
||||
IEnumNetworkConnections *connections = NULL;
|
||||
HRESULT hr = pNetworkListManager->GetNetworkConnections(&connections);
|
||||
if (hr == S_OK) {
|
||||
while (true) {
|
||||
INetworkConnection *connection = NULL;
|
||||
hr = connections->Next(1, &connection, NULL);
|
||||
if (hr != S_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
VARIANT_BOOL isConnected = VARIANT_FALSE;
|
||||
hr = connection->get_IsConnectedToInternet(&isConnected);
|
||||
if (hr == S_OK && isConnected == VARIANT_TRUE) {
|
||||
GUID guid;
|
||||
hr = connection->GetAdapterId(&guid);
|
||||
if (hr == S_OK) {
|
||||
adapterIds.push_back(std::move(guid));
|
||||
}
|
||||
}
|
||||
connection->Release();
|
||||
}
|
||||
connections->Release();
|
||||
}
|
||||
|
||||
return adapterIds;
|
||||
}
|
||||
|
||||
ConnectivityType NetworkManager::GetConnectivityType() const {
|
||||
ULONG bufferSize = 15 * 1024;
|
||||
ULONG flags = GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST |
|
||||
GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER |
|
||||
GAA_FLAG_SKIP_FRIENDLY_NAME;
|
||||
std::vector<unsigned char> buffer(bufferSize);
|
||||
PIP_ADAPTER_ADDRESSES addresses =
|
||||
reinterpret_cast<PIP_ADAPTER_ADDRESSES>(&buffer.front());
|
||||
DWORD rc = GetAdaptersAddresses(AF_UNSPEC, flags, 0, addresses, &bufferSize);
|
||||
if (rc == ERROR_BUFFER_OVERFLOW) {
|
||||
buffer.resize(bufferSize);
|
||||
addresses = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(&buffer.front());
|
||||
rc = GetAdaptersAddresses(AF_UNSPEC, flags, 0, addresses, &bufferSize);
|
||||
}
|
||||
|
||||
if (rc != NO_ERROR) {
|
||||
return ConnectivityType::None;
|
||||
}
|
||||
|
||||
std::vector<GUID> adapterIds = GetConnectedAdapterIds();
|
||||
if (adapterIds.empty()) {
|
||||
return ConnectivityType::None;
|
||||
}
|
||||
|
||||
std::set<ConnectivityType> connectivities;
|
||||
for (; addresses != NULL; addresses = addresses->Next) {
|
||||
NET_LUID luid;
|
||||
rc = ConvertInterfaceIndexToLuid(addresses->IfIndex, &luid);
|
||||
if (rc != NO_ERROR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GUID guid;
|
||||
rc = ConvertInterfaceLuidToGuid(&luid, &guid);
|
||||
if (rc != NO_ERROR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (std::find(adapterIds.begin(), adapterIds.end(), guid) !=
|
||||
adapterIds.end()) {
|
||||
switch (addresses->IfType) {
|
||||
case IF_TYPE_ETHERNET_CSMACD:
|
||||
connectivities.insert(ConnectivityType::Ethernet);
|
||||
break;
|
||||
default:
|
||||
connectivities.insert(ConnectivityType::WiFi);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (connectivities.find(ConnectivityType::WiFi) != connectivities.end()) {
|
||||
return ConnectivityType::WiFi;
|
||||
}
|
||||
|
||||
if (connectivities.find(ConnectivityType::Ethernet) != connectivities.end()) {
|
||||
return ConnectivityType::Ethernet;
|
||||
}
|
||||
|
||||
return ConnectivityType::None;
|
||||
}
|
||||
|
||||
bool NetworkManager::StartListen(NetworkCallback pCallback) {
|
||||
if (!pCallback || pListener) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT hr = pNetworkListManager->QueryInterface(
|
||||
IID_IConnectionPointContainer, (void **)&pCPContainer);
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = pCPContainer->FindConnectionPoint(IID_INetworkEvents, &pConnectPoint);
|
||||
if (SUCCEEDED(hr)) {
|
||||
pListener = new NetworkListener(pCallback);
|
||||
hr = pConnectPoint->Advise((IUnknown *)pListener, &dwCookie);
|
||||
if (SUCCEEDED(hr)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void NetworkManager::StopListen() {
|
||||
if (pConnectPoint) {
|
||||
pConnectPoint->Unadvise(dwCookie);
|
||||
pConnectPoint->Release();
|
||||
pConnectPoint = NULL;
|
||||
dwCookie = 0;
|
||||
}
|
||||
|
||||
if (pCPContainer) {
|
||||
pCPContainer->Release();
|
||||
pCPContainer = NULL;
|
||||
}
|
||||
|
||||
if (pListener) {
|
||||
pListener->Release();
|
||||
pListener = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool NetworkManager::HasError() const { return GetLastError() != 0; }
|
||||
|
||||
int NetworkManager::GetError() const { return GetLastError(); }
|
25
lib/third_party/connectivity_plus/connectivity_plus_platform_interface/.gitattributes
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Always perform LF normalization on these files
|
||||
*.dart text
|
||||
*.gradle text
|
||||
*.html text
|
||||
*.java text
|
||||
*.json text
|
||||
*.md text
|
||||
*.py text
|
||||
*.sh text
|
||||
*.txt text
|
||||
*.xml text
|
||||
*.yaml text
|
||||
|
||||
# Make sure that these Windows files always have CRLF line endings in checkout
|
||||
*.bat text eol=crlf
|
||||
*.ps1 text eol=crlf
|
||||
|
||||
# Never perform LF normalization on these files
|
||||
*.ico binary
|
||||
*.jar binary
|
||||
*.png binary
|
||||
*.zip binary
|
46
lib/third_party/connectivity_plus/connectivity_plus_platform_interface/.gitignore
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
.DS_Store
|
||||
.atom/
|
||||
.idea/
|
||||
.vscode/
|
||||
|
||||
.packages
|
||||
.pub/
|
||||
.dart_tool/
|
||||
pubspec.lock
|
||||
flutter_export_environment.sh
|
||||
|
||||
examples/all_plugins/pubspec.yaml
|
||||
|
||||
Podfile
|
||||
Podfile.lock
|
||||
Pods/
|
||||
.symlinks/
|
||||
**/Flutter/App.framework/
|
||||
**/Flutter/ephemeral/
|
||||
**/Flutter/Flutter.framework/
|
||||
**/Flutter/Generated.xcconfig
|
||||
**/Flutter/flutter_assets/
|
||||
|
||||
ServiceDefinitions.json
|
||||
xcuserdata/
|
||||
**/DerivedData/
|
||||
|
||||
local.properties
|
||||
keystore.properties
|
||||
.gradle/
|
||||
gradlew
|
||||
gradlew.bat
|
||||
gradle-wrapper.jar
|
||||
.flutter-plugins-dependencies
|
||||
*.iml
|
||||
|
||||
GeneratedPluginRegistrant.h
|
||||
GeneratedPluginRegistrant.m
|
||||
GeneratedPluginRegistrant.java
|
||||
GeneratedPluginRegistrant.swift
|
||||
build/
|
||||
.flutter-plugins
|
||||
|
||||
.project
|
||||
.classpath
|
||||
.settings
|
27
lib/third_party/connectivity_plus/connectivity_plus_platform_interface/LICENSE
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
Copyright 2020 The Chromium Authors. All rights reserved.
|
||||
dan marked this conversation as resolved
Outdated
sarah
commented
license needs to also be in license.dart license needs to also be in license.dart
|
||||
|
||||
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.
|
12
lib/third_party/connectivity_plus/connectivity_plus_platform_interface/README.md
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
# Connectivity Plus Platform Interface
|
||||
|
||||
[![Flutter Community: connectivity_plus_platform_interface](https://fluttercommunity.dev/_github/header/connectivity_plus_platform_interface)](https://github.com/fluttercommunity/community)
|
||||
|
||||
[![pub package](https://img.shields.io/pub/v/connectivity_plus_platform_interface.svg)](https://pub.dev/packages/connectivity_plus_platform_interface)
|
||||
|
||||
A common platform interface for [`connectivity_plus`](https://pub.dev/packages/connectivity_plus).
|
||||
|
||||
## Usage
|
||||
|
||||
This package is already included as part of the `connectivity_plus` package dependency, and will
|
||||
be included when using `connectivity_plus` as normal.
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright 2020 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
||||
|
||||
import 'method_channel_connectivity.dart';
|
||||
import 'src/enums.dart';
|
||||
|
||||
export 'src/enums.dart';
|
||||
|
||||
/// The interface that implementations of connectivity must implement.
|
||||
///
|
||||
/// Platform implementations should extend this class rather than implement it as `Connectivity`
|
||||
/// does not consider newly added methods to be breaking changes. Extending this class
|
||||
/// (using `extends`) ensures that the subclass will get the default implementation, while
|
||||
/// platform implementations that `implements` this interface will be broken by newly added
|
||||
/// [ConnectivityPlatform] methods.
|
||||
abstract class ConnectivityPlatform extends PlatformInterface {
|
||||
/// Constructs a ConnectivityPlatform.
|
||||
ConnectivityPlatform() : super(token: _token);
|
||||
|
||||
static final Object _token = Object();
|
||||
|
||||
static ConnectivityPlatform _instance = MethodChannelConnectivity();
|
||||
|
||||
/// The default instance of [ConnectivityPlatform] to use.
|
||||
///
|
||||
/// Defaults to [MethodChannelConnectivity].
|
||||
static ConnectivityPlatform get instance => _instance;
|
||||
|
||||
/// Platform-specific plugins should set this with their own platform-specific
|
||||
/// class that extends [ConnectivityPlatform] when they register themselves.
|
||||
static set instance(ConnectivityPlatform instance) {
|
||||
PlatformInterface.verifyToken(instance, _token);
|
||||
_instance = instance;
|
||||
}
|
||||
|
||||
/// Checks the connection status of the device.
|
||||
Future<ConnectivityResult> checkConnectivity() {
|
||||
throw UnimplementedError('checkConnectivity() has not been implemented.');
|
||||
}
|
||||
|
||||
/// Returns a Stream of ConnectivityResults changes.
|
||||
Stream<ConnectivityResult> get onConnectivityChanged {
|
||||
throw UnimplementedError(
|
||||
'get onConnectivityChanged has not been implemented.');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright 2020 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:connectivity_plus_platform_interface/connectivity_plus_platform_interface.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import 'src/utils.dart';
|
||||
|
||||
/// An implementation of [ConnectivityPlatform] that uses method channels.
|
||||
class MethodChannelConnectivity extends ConnectivityPlatform {
|
||||
/// The method channel used to interact with the native platform.
|
||||
@visibleForTesting
|
||||
MethodChannel methodChannel =
|
||||
const MethodChannel('dev.fluttercommunity.plus/connectivity');
|
||||
|
||||
/// The event channel used to receive ConnectivityResult changes from the native platform.
|
||||
@visibleForTesting
|
||||
EventChannel eventChannel =
|
||||
const EventChannel('dev.fluttercommunity.plus/connectivity_status');
|
||||
|
||||
Stream<ConnectivityResult>? _onConnectivityChanged;
|
||||
|
||||
/// Fires whenever the connectivity state changes.
|
||||
@override
|
||||
Stream<ConnectivityResult> get onConnectivityChanged {
|
||||
_onConnectivityChanged ??= eventChannel
|
||||
.receiveBroadcastStream()
|
||||
.map((dynamic result) => result.toString())
|
||||
.map(parseConnectivityResult);
|
||||
return _onConnectivityChanged!;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ConnectivityResult> checkConnectivity() {
|
||||
return methodChannel
|
||||
.invokeMethod<String>('check')
|
||||
.then((value) => parseConnectivityResult(value ?? ''));
|
||||
}
|
||||
}
|
18
lib/third_party/connectivity_plus/connectivity_plus_platform_interface/lib/src/enums.dart
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
/// Connection status check result.
|
||||
enum ConnectivityResult {
|
||||
|
||||
/// WiFi: Device connected via Wi-Fi
|
||||
dan marked this conversation as resolved
Outdated
sarah
commented
remove remove
|
||||
wifi,
|
||||
|
||||
/// Ethernet: Device connected to ethernet network
|
||||
ethernet,
|
||||
|
||||
/// Mobile: Device connected to cellular network
|
||||
mobile,
|
||||
|
||||
/// None: Device not connected to any network
|
||||
none,
|
||||
|
||||
/// Other: Device is connected to an unknown network
|
||||
other
|
||||
}
|
17
lib/third_party/connectivity_plus/connectivity_plus_platform_interface/lib/src/utils.dart
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
import 'package:connectivity_plus_platform_interface/connectivity_plus_platform_interface.dart';
|
||||
|
||||
/// Convert a String to a ConnectivityResult value.
|
||||
ConnectivityResult parseConnectivityResult(String state) {
|
||||
switch (state) {
|
||||
case 'bluetooth':
|
||||
case 'wifi':
|
||||
dan marked this conversation as resolved
Outdated
sarah
commented
remove remove
|
||||
case 'ethernet':
|
||||
case 'mobile':
|
||||
case 'vpn':
|
||||
case 'other':
|
||||
return ConnectivityResult.mobile;
|
||||
case 'none':
|
||||
default:
|
||||
return ConnectivityResult.none;
|
||||
dan marked this conversation as resolved
Outdated
sarah
commented
tor over vpn is a terrible idea...we should probably by-default restrict this. tor over vpn is a terrible idea...we should probably by-default restrict this.
dan
commented
all we're doing is detecting if the network is up or not to reboot the ACN, i'm not sure what the logic for this would even look like, an excemption in main.lib listener to jsut not resetTor if the type is vpn? but since we dont want this system to know to much we're deleting knowledge of this specificity (like bluetooth) so that doesn't work anyways all we're doing is detecting if the network is up or not to reboot the ACN, i'm not sure what the logic for this would even look like, an excemption in main.lib listener to jsut not resetTor if the type is vpn? but since we dont want this system to know to much we're deleting knowledge of this specificity (like bluetooth) so that doesn't work anyways
|
||||
}
|
||||
}
|
||||
dan marked this conversation as resolved
Outdated
sarah
commented
remove remove
|
20
lib/third_party/connectivity_plus/connectivity_plus_platform_interface/pubspec.yaml
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
name: connectivity_plus_platform_interface
|
||||
description: A common platform interface for the connectivity_plus plugin.
|
||||
version: 1.2.4
|
||||
homepage: https://plus.fluttercommunity.dev/
|
||||
repository: https://github.com/fluttercommunity/plus_plugins/tree/main/packages/
|
||||
|
||||
environment:
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=2.11.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
meta: ^1.7.0
|
||||
plugin_platform_interface: ^2.1.2
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
flutter_lints: ^2.0.1
|
|
@ -0,0 +1,373 @@
|
|||
Mozilla Public License Version 2.0
|
||||
dan marked this conversation as resolved
Outdated
sarah
commented
Another...License.... Another...License....
|
||||
==================================
|
||||
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
purposes of this definition, "control" means (a) the power, direct
|
||||
or indirect, to cause the direction or management of such entity,
|
||||
whether by contract or otherwise, or (b) ownership of more than
|
||||
fifty percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 6. Disclaimer of Warranty *
|
||||
* ------------------------- *
|
||||
* *
|
||||
* Covered Software is provided under this License on an "as is" *
|
||||
* basis, without warranty of any kind, either expressed, implied, or *
|
||||
* statutory, including, without limitation, warranties that the *
|
||||
* Covered Software is free of defects, merchantable, fit for a *
|
||||
* particular purpose or non-infringing. The entire risk as to the *
|
||||
* quality and performance of the Covered Software is with You. *
|
||||
* Should any Covered Software prove defective in any respect, You *
|
||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
||||
* essential part of this License. No use of any Covered Software is *
|
||||
* authorized under this License except under this disclaimer. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 7. Limitation of Liability *
|
||||
* -------------------------- *
|
||||
* *
|
||||
* Under no circumstances and under no legal theory, whether tort *
|
||||
* (including negligence), contract, or otherwise, shall any *
|
||||
* Contributor, or anyone who distributes Covered Software as *
|
||||
* permitted above, be liable to You for any direct, indirect, *
|
||||
* special, incidental, or consequential damages of any character *
|
||||
* including, without limitation, damages for lost profits, loss of *
|
||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
||||
* and all other commercial damages or losses, even if such party *
|
||||
* shall have been informed of the possibility of such damages. This *
|
||||
* limitation of liability shall not apply to liability for death or *
|
||||
* personal injury resulting from such party's negligence to the *
|
||||
* extent applicable law prohibits such limitation. Some *
|
||||
* jurisdictions do not allow the exclusion or limitation of *
|
||||
* incidental or consequential damages, so this exclusion and *
|
||||
* limitation may not apply to You. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
8. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.
|
|
@ -0,0 +1 @@
|
|||
export 'src/network_manager_client.dart';
|
|
@ -0,0 +1,415 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dbus/dbus.dart';
|
||||
|
||||
/// D-Bus interface names
|
||||
const _managerInterfaceName = 'org.freedesktop.NetworkManager';
|
||||
|
||||
/// Overall networking states.
|
||||
enum NetworkManagerState {
|
||||
unknown,
|
||||
asleep,
|
||||
disconnected,
|
||||
disconnecting,
|
||||
connecting,
|
||||
connectedLocal,
|
||||
connectedSite,
|
||||
connectedGlobal,
|
||||
}
|
||||
|
||||
NetworkManagerState _decodeState(int value) {
|
||||
switch (value) {
|
||||
case 10:
|
||||
return NetworkManagerState.asleep;
|
||||
case 20:
|
||||
return NetworkManagerState.disconnected;
|
||||
case 30:
|
||||
return NetworkManagerState.disconnecting;
|
||||
case 40:
|
||||
return NetworkManagerState.connecting;
|
||||
case 50:
|
||||
return NetworkManagerState.connectedLocal;
|
||||
case 60:
|
||||
return NetworkManagerState.connectedSite;
|
||||
case 70:
|
||||
return NetworkManagerState.connectedGlobal;
|
||||
default:
|
||||
return NetworkManagerState.unknown;
|
||||
}
|
||||
}
|
||||
|
||||
/// Internet connectivity states.
|
||||
enum NetworkManagerConnectivityState { unknown, none, portal, limited, full }
|
||||
|
||||
NetworkManagerConnectivityState _decodeConnectivityState(int value) {
|
||||
switch (value) {
|
||||
case 1:
|
||||
return NetworkManagerConnectivityState.none;
|
||||
case 2:
|
||||
return NetworkManagerConnectivityState.portal;
|
||||
case 3:
|
||||
return NetworkManagerConnectivityState.limited;
|
||||
case 4:
|
||||
return NetworkManagerConnectivityState.full;
|
||||
default:
|
||||
return NetworkManagerConnectivityState.unknown;
|
||||
}
|
||||
}
|
||||
|
||||
class _NetworkManagerInterface {
|
||||
final Map<String, DBusValue> properties;
|
||||
final propertiesChangedStreamController =
|
||||
StreamController<List<String>>.broadcast();
|
||||
|
||||
/// Stream of property names as their values change.
|
||||
Stream<List<String>> get propertiesChanged =>
|
||||
propertiesChangedStreamController.stream;
|
||||
|
||||
_NetworkManagerInterface(this.properties);
|
||||
|
||||
void updateProperties(Map<String, DBusValue> changedProperties) {
|
||||
properties.addAll(changedProperties);
|
||||
propertiesChangedStreamController.add(changedProperties.keys.toList());
|
||||
}
|
||||
}
|
||||
|
||||
class _NetworkManagerObject extends DBusRemoteObject {
|
||||
final interfaces = <String, _NetworkManagerInterface>{};
|
||||
|
||||
void updateInterfaces(
|
||||
Map<String, Map<String, DBusValue>> interfacesAndProperties) {
|
||||
interfacesAndProperties.forEach((interfaceName, properties) {
|
||||
interfaces[interfaceName] = _NetworkManagerInterface(properties);
|
||||
});
|
||||
}
|
||||
|
||||
/// Returns true if removing [interfaceNames] would remove all interfaces on this object.
|
||||
bool wouldRemoveAllInterfaces(List<String> interfaceNames) {
|
||||
for (var interface in interfaces.keys) {
|
||||
if (!interfaceNames.contains(interface)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void removeInterfaces(List<String> interfaceNames) {
|
||||
for (var interfaceName in interfaceNames) {
|
||||
interfaces.remove(interfaceName);
|
||||
}
|
||||
}
|
||||
|
||||
void updateProperties(
|
||||
String interfaceName, Map<String, DBusValue> changedProperties) {
|
||||
var interface = interfaces[interfaceName];
|
||||
if (interface != null) {
|
||||
interface.updateProperties(changedProperties);
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets a cached property.
|
||||
DBusValue? getCachedProperty(String interfaceName, String name) {
|
||||
var interface = interfaces[interfaceName];
|
||||
if (interface == null) {
|
||||
return null;
|
||||
}
|
||||
return interface.properties[name];
|
||||
}
|
||||
|
||||
/// Gets a cached boolean property, or returns null if not present or not the correct type.
|
||||
bool? getBooleanProperty(String interface, String name) {
|
||||
var value = getCachedProperty(interface, name);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value.signature != DBusSignature('b')) {
|
||||
return null;
|
||||
}
|
||||
return (value as DBusBoolean).value;
|
||||
}
|
||||
|
||||
/// Gets a cached unsigned 8 bit integer property, or returns null if not present or not the correct type.
|
||||
int? getByteProperty(String interface, String name) {
|
||||
var value = getCachedProperty(interface, name);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value.signature != DBusSignature('y')) {
|
||||
return null;
|
||||
}
|
||||
return (value as DBusByte).value;
|
||||
}
|
||||
|
||||
/// Gets a cached signed 32 bit integer property, or returns null if not present or not the correct type.
|
||||
int? getInt32Property(String interface, String name) {
|
||||
var value = getCachedProperty(interface, name);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value.signature != DBusSignature('i')) {
|
||||
return null;
|
||||
}
|
||||
return (value as DBusInt32).value;
|
||||
}
|
||||
|
||||
/// Gets a cached unsigned 32 bit integer property, or returns null if not present or not the correct type.
|
||||
int? getUint32Property(String interface, String name) {
|
||||
var value = getCachedProperty(interface, name);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value.signature != DBusSignature('u')) {
|
||||
return null;
|
||||
}
|
||||
return (value as DBusUint32).value;
|
||||
}
|
||||
|
||||
/// Gets a cached signed 64 bit integer property, or returns null if not present or not the correct type.
|
||||
int? getInt64Property(String interface, String name) {
|
||||
var value = getCachedProperty(interface, name);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value.signature != DBusSignature('x')) {
|
||||
return null;
|
||||
}
|
||||
return (value as DBusInt64).value;
|
||||
}
|
||||
|
||||
/// Gets a cached unsigned 64 bit integer property, or returns null if not present or not the correct type.
|
||||
int? getUint64Property(String interface, String name) {
|
||||
var value = getCachedProperty(interface, name);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value.signature != DBusSignature('t')) {
|
||||
return null;
|
||||
}
|
||||
return (value as DBusUint64).value;
|
||||
}
|
||||
|
||||
/// Gets a cached string property, or returns null if not present or not the correct type.
|
||||
String? getStringProperty(String interface, String name) {
|
||||
var value = getCachedProperty(interface, name);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value.signature != DBusSignature('s')) {
|
||||
return null;
|
||||
}
|
||||
return (value as DBusString).value;
|
||||
}
|
||||
|
||||
/// Gets a cached string array property, or returns null if not present or not the correct type.
|
||||
List<String>? getStringArrayProperty(String interface, String name) {
|
||||
var value = getCachedProperty(interface, name);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value.signature != DBusSignature('as')) {
|
||||
return null;
|
||||
}
|
||||
return (value as DBusArray)
|
||||
.children
|
||||
.map((e) => (e as DBusString).value)
|
||||
.toList();
|
||||
}
|
||||
|
||||
/// Gets a cached object path property, or returns null if not present or not the correct type.
|
||||
DBusObjectPath? getObjectPathProperty(String interface, String name) {
|
||||
var value = getCachedProperty(interface, name);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value.signature != DBusSignature('o')) {
|
||||
return null;
|
||||
}
|
||||
return (value as DBusObjectPath);
|
||||
}
|
||||
|
||||
/// Gets a cached object path array property, or returns null if not present or not the correct type.
|
||||
List<DBusObjectPath>? getObjectPathArrayProperty(
|
||||
String interface, String name) {
|
||||
var value = getCachedProperty(interface, name);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value.signature != DBusSignature('ao')) {
|
||||
return null;
|
||||
}
|
||||
return (value as DBusArray)
|
||||
.children
|
||||
.map((e) => (e as DBusObjectPath))
|
||||
.toList();
|
||||
}
|
||||
|
||||
/// Gets a cached list of data property, or returns null if not present or not the correct type.
|
||||
List<Map<String, dynamic>>? getDataListProperty(
|
||||
String interface, String name) {
|
||||
var value = getCachedProperty(interface, name);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value.signature != DBusSignature('aa{sv}')) {
|
||||
return null;
|
||||
}
|
||||
Map<String, dynamic> convertData(DBusValue value) {
|
||||
return (value as DBusDict).children.map((key, value) => MapEntry(
|
||||
(key as DBusString).value,
|
||||
(value as DBusVariant).value.toNative(),
|
||||
));
|
||||
}
|
||||
|
||||
return (value as DBusArray)
|
||||
.children
|
||||
.map((value) => convertData(value))
|
||||
.toList();
|
||||
}
|
||||
|
||||
_NetworkManagerObject(DBusClient client, DBusObjectPath path,
|
||||
Map<String, Map<String, DBusValue>> interfacesAndProperties)
|
||||
: super(client, name: 'org.freedesktop.NetworkManager', path: path) {
|
||||
updateInterfaces(interfacesAndProperties);
|
||||
}
|
||||
}
|
||||
|
||||
/// A client that connects to NetworkManager.
|
||||
class NetworkManagerClient {
|
||||
|
||||
/// The bus this client is connected to.
|
||||
final DBusClient _bus;
|
||||
final bool _closeBus;
|
||||
|
||||
/// The root D-Bus NetworkManager object at path '/org/freedesktop'.
|
||||
late final DBusRemoteObjectManager _root;
|
||||
|
||||
// Objects exported on the bus.
|
||||
final _objects = <DBusObjectPath, _NetworkManagerObject>{};
|
||||
|
||||
// Subscription to object manager signals.
|
||||
StreamSubscription? _objectManagerSubscription;
|
||||
|
||||
/// Creates a new NetworkManager client connected to the system D-Bus.
|
||||
NetworkManagerClient({DBusClient? bus})
|
||||
: _bus = bus ?? DBusClient.system(),
|
||||
_closeBus = bus == null {
|
||||
_root = DBusRemoteObjectManager(
|
||||
_bus,
|
||||
name: 'org.freedesktop.NetworkManager',
|
||||
path: DBusObjectPath('/org/freedesktop'),
|
||||
);
|
||||
}
|
||||
|
||||
/// Stream of property names as their values change.
|
||||
Stream<List<String>> get propertiesChanged =>
|
||||
_manager?.interfaces[_managerInterfaceName]
|
||||
?.propertiesChangedStreamController.stream ??
|
||||
Stream<List<String>>.empty();
|
||||
|
||||
/// Connects to the NetworkManager D-Bus objects.
|
||||
/// Must be called before accessing methods and properties.
|
||||
Future<void> connect() async {
|
||||
// Already connected
|
||||
if (_objectManagerSubscription != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Big old grody Hack
|
||||
// DBus/nm doesnt seem to offer a way to deter ine if dbus is available on system
|
||||
// worse the first connections get triggered in dbus_client onListen an isn't a catahable exception so crashes the app
|
||||
// this is a hacky way to force an exception on thread if dbus isn't available and bail with out crashing
|
||||
try {
|
||||
await _root.client.getNameOwner(_root.name);
|
||||
} on SocketException catch (e) {
|
||||
print("nm dbus connect/emit test threw exception, dbus likely unavailable on system, aborting connect: $e");
|
||||
return;
|
||||
}
|
||||
|
||||
// Subscribe to changes
|
||||
_objectManagerSubscription = _root.signals.listen((signal) {
|
||||
if (signal is DBusObjectManagerInterfacesAddedSignal) {
|
||||
var object = _objects[signal.changedPath];
|
||||
if (object != null) {
|
||||
object.updateInterfaces(signal.interfacesAndProperties);
|
||||
} else {
|
||||
object = _NetworkManagerObject(
|
||||
_bus, signal.changedPath, signal.interfacesAndProperties);
|
||||
_objects[signal.changedPath] = object;
|
||||
}
|
||||
} else if (signal is DBusObjectManagerInterfacesRemovedSignal) {
|
||||
var object = _objects[signal.changedPath];
|
||||
if (object != null) {
|
||||
// If all the interface are removed, then this object has been removed.
|
||||
// Keep the previous values around for the client to use.
|
||||
if (object.wouldRemoveAllInterfaces(signal.interfaces)) {
|
||||
_objects.remove(signal.changedPath);
|
||||
} else {
|
||||
object.removeInterfaces(signal.interfaces);
|
||||
}
|
||||
}
|
||||
} else if (signal is DBusPropertiesChangedSignal) {
|
||||
var object = _objects[signal.path];
|
||||
if (object != null) {
|
||||
object.updateProperties(
|
||||
signal.propertiesInterface, signal.changedProperties);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Find all the objects exported.
|
||||
var objects = await _root.getManagedObjects();
|
||||
objects.forEach((objectPath, interfacesAndProperties) {
|
||||
_objects[objectPath] =
|
||||
_NetworkManagerObject(_bus, objectPath, interfacesAndProperties);
|
||||
});
|
||||
}
|
||||
|
||||
/// The type of connection being used to access the network.
|
||||
String get primaryConnectionType {
|
||||
return _manager?.getStringProperty(
|
||||
_managerInterfaceName,
|
||||
'PrimaryConnectionType',
|
||||
) ??
|
||||
'';
|
||||
}
|
||||
|
||||
/// True is NetworkManager is still starting up.
|
||||
bool get startup {
|
||||
return _manager?.getBooleanProperty(_managerInterfaceName, 'Startup') ??
|
||||
false;
|
||||
}
|
||||
|
||||
/// The version of NetworkManager running.
|
||||
String get version {
|
||||
return _manager?.getStringProperty(_managerInterfaceName, 'Version') ?? '';
|
||||
}
|
||||
|
||||
/// The result of the last connectivity check.
|
||||
NetworkManagerConnectivityState get connectivity {
|
||||
var value =
|
||||
_manager?.getUint32Property(_managerInterfaceName, 'Connectivity') ?? 0;
|
||||
return _decodeConnectivityState(value);
|
||||
}
|
||||
|
||||
/// The overall networking state.
|
||||
NetworkManagerState get state {
|
||||
var value =
|
||||
_manager?.getUint32Property(_managerInterfaceName, 'State') ?? 0;
|
||||
return _decodeState(value);
|
||||
}
|
||||
|
||||
_NetworkManagerObject? get _manager =>
|
||||
_objects[DBusObjectPath('/org/freedesktop/NetworkManager')];
|
||||
|
||||
/// Terminates all active connections. If a client remains unclosed, the Dart process may not terminate.
|
||||
Future<void> close() async {
|
||||
if (_objectManagerSubscription != null) {
|
||||
await _objectManagerSubscription!.cancel();
|
||||
_objectManagerSubscription = null;
|
||||
}
|
||||
if (_closeBus) {
|
||||
await _bus.close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import connectivity_plus
|
||||
import flutter_local_notifications
|
||||
import package_info_plus_macos
|
||||
import path_provider_foundation
|
||||
|
@ -13,6 +14,7 @@ import url_launcher_macos
|
|||
import window_manager
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
|
||||
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
|
||||
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
|
|
24
pubspec.lock
|
@ -85,10 +85,10 @@ packages:
|
|||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_runner
|
||||
sha256: b0a8a7b8a76c493e85f1b84bffa0588859a06197863dba8c9036b15581fd9727
|
||||
sha256: "56942f8114731d1e79942cd981cfef29501937ff1bccf4dbdce0273f31f13640"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.3"
|
||||
version: "2.2.0"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -161,6 +161,20 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.17.0"
|
||||
connectivity_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "lib/third_party/connectivity_plus/connectivity_plus"
|
||||
relative: true
|
||||
source: path
|
||||
version: "3.0.6"
|
||||
connectivity_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
path: "lib/third_party/connectivity_plus/connectivity_plus_platform_interface"
|
||||
relative: true
|
||||
source: path
|
||||
version: "1.2.4"
|
||||
console:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -202,7 +216,7 @@ packages:
|
|||
source: hosted
|
||||
version: "2.2.4"
|
||||
dbus:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: dbus
|
||||
sha256: "253bfaa3d340778d8bc755e89c3af38e85ef95e65fd5d5670aa3167f8d4f6577"
|
||||
|
@ -335,10 +349,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: frontend_server_client
|
||||
sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612"
|
||||
sha256: "4f4a162323c86ffc1245765cfe138872b8f069deb42f7dbb36115fa27f31469b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.0"
|
||||
version: "2.1.3"
|
||||
fuchsia_remote_debug_protocol:
|
||||
dan marked this conversation as resolved
Outdated
sarah
commented
massive downgrade? massive downgrade?
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
|
|
|
@ -32,6 +32,7 @@ dependencies:
|
|||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
cupertino_icons: ^1.0.0
|
||||
# Todo: upgrade to 2.x, allow other package upgrades (dbus)
|
||||
ffi: ^1.2.1
|
||||
path_provider: ^2.0.0
|
||||
crypto: ^3.0.2
|
||||
|
@ -46,6 +47,12 @@ dependencies:
|
|||
win_toast: ^0.0.2
|
||||
flutter_local_notifications: ^9.6.1
|
||||
desktop_notifications: ^0.6.3
|
||||
# network management plugins
|
||||
dan marked this conversation as resolved
Outdated
sarah
commented
specify a concrete version. specify a concrete version.
|
||||
# dbus >=0.7.5 depends on ffi ^2.0.0 and cwtch depends on ffi ^1.2.1, dbus >=0.7.5 is forbidden.
|
||||
dbus: 0.7.4
|
||||
connectivity_plus:
|
||||
path: lib/third_party/connectivity_plus/connectivity_plus
|
||||
# misc plugins
|
||||
qr_flutter: ^4.0.0
|
||||
|
||||
dev_dependencies:
|
||||
|
|
|
@ -6,12 +6,15 @@
|
|||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <connectivity_plus/connectivity_plus_windows_plugin.h>
|
||||
#include <screen_retriever/screen_retriever_plugin.h>
|
||||
#include <url_launcher_windows/url_launcher_windows.h>
|
||||
#include <win_toast/win_toast_plugin.h>
|
||||
#include <window_manager/window_manager_plugin.h>
|
||||
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
ConnectivityPlusWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
|
||||
ScreenRetrieverPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("ScreenRetrieverPlugin"));
|
||||
UrlLauncherWindowsRegisterWithRegistrar(
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
connectivity_plus
|
||||
screen_retriever
|
||||
url_launcher_windows
|
||||
win_toast
|
||||
|
|
Licenses needs to be added to licenses.dart