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.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
- 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
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
|
||||
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
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) {
|
||||
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:
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -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
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
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
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
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
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';
|
||||
|
||||
/// 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
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
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
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
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
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
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
|
||||
*
|
||||
* 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
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
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
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.
|
||||
|
||||
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
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
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
|
||||
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
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':
|
||||
case 'ethernet':
|
||||
case 'mobile':
|
||||
case 'vpn':
|
||||
case 'other':
|
||||
return ConnectivityResult.mobile;
|
||||
case 'none':
|
||||
default:
|
||||
return ConnectivityResult.none;
|
||||
}
|
||||
}
|
20
lib/third_party/connectivity_plus/connectivity_plus_platform_interface/pubspec.yaml
vendored
Normal file
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
|
||||
==================================
|
||||
|
||||
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
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:
|
||||
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
|
||||
# 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
|
||||
|
|
Loading…
Reference in New Issue