diff --git a/packages/network_info_plus/.gitattributes b/packages/network_info_plus/.gitattributes new file mode 100644 index 0000000000..31fda4bf1c --- /dev/null +++ b/packages/network_info_plus/.gitattributes @@ -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 diff --git a/packages/network_info_plus/.gitignore b/packages/network_info_plus/.gitignore new file mode 100644 index 0000000000..88ce490e47 --- /dev/null +++ b/packages/network_info_plus/.gitignore @@ -0,0 +1,47 @@ +.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 + +generated_plugin_registrant.dart +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m +GeneratedPluginRegistrant.java +GeneratedPluginRegistrant.swift +build/ +.flutter-plugins + +.project +.classpath +.settings diff --git a/packages/network_info_plus/CHANGELOG.md b/packages/network_info_plus/CHANGELOG.md new file mode 100644 index 0000000000..090fc36598 --- /dev/null +++ b/packages/network_info_plus/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.1.0 + +- Initial release diff --git a/packages/network_info_plus/LICENSE b/packages/network_info_plus/LICENSE new file mode 100644 index 0000000000..c89293372c --- /dev/null +++ b/packages/network_info_plus/LICENSE @@ -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. diff --git a/packages/network_info_plus/README.md b/packages/network_info_plus/README.md new file mode 100644 index 0000000000..a2ca841fc7 --- /dev/null +++ b/packages/network_info_plus/README.md @@ -0,0 +1,61 @@ +# network_info_plus + +[![Flutter Community: network_info_plus](https://fluttercommunity.dev/_github/header/network_info_plus)](https://github.com/fluttercommunity/community) + +[![pub package](https://img.shields.io/pub/v/network_info_plus.svg)](https://pub.dev/packages/network_info_plus) + +This plugin allows Flutter apps to discover network info and configure +themselves accordingly. + +## Usage + +You can get wi-fi related information using: + +```dart +import 'package:network_info_plus/network_info_plus.dart'; + +var wifiBSSID = await (NetworkInfo().getWifiBSSID()); +var wifiIP = await (NetworkInfo().getWifiIP());network +var wifiName = await (NetworkInfo().getWifiName());wifi network +``` + +### iOS 12 + +To use `.getWifiBSSID()` and `.getWifiName()` on iOS >= 12, the `Access WiFi information capability` in XCode must be enabled. Otherwise, both methods will return null. + +### iOS 13 + +The methods `.getWifiBSSID()` and `.getWifiName()` utilize the [`CNCopyCurrentNetworkInfo`](https://developer.apple.com/documentation/systemconfiguration/1614126-cncopycurrentnetworkinfo) function on iOS. + +As of iOS 13, Apple announced that these APIs will no longer return valid information. +An app linked against iOS 12 or earlier receives pseudo-values such as: + + * SSID: "Wi-Fi" or "WLAN" ("WLAN" will be returned for the China SKU). + + * BSSID: "00:00:00:00:00:00" + +An app linked against iOS 13 or later receives `null`. + +The `CNCopyCurrentNetworkInfo` will work for Apps that: + + * The app uses Core Location, and has the user’s authorization to use location information. + + * The app uses the NEHotspotConfiguration API to configure the current Wi-Fi network. + + * The app has active VPN configurations installed. + +If your app falls into the last two categories, it will work as it is. If your app doesn't fall into the last two categories, +and you still need to access the wifi information, you should request user's authorization to use location information. + +There is a helper method provided in this plugin to request the location authorization: `requestLocationServiceAuthorization`. +To request location authorization, make sure to add the following keys to your _Info.plist_ file, located in `/ios/Runner/Info.plist`: + +* `NSLocationAlwaysAndWhenInUseUsageDescription` - describe why the app needs access to the user’s location information all the time (foreground and background). This is called _Privacy - Location Always and When In Use Usage Description_ in the visual editor. +* `NSLocationWhenInUseUsageDescription` - describe why the app needs access to the user’s location information when the app is running in the foreground. This is called _Privacy - Location When In Use Usage Description_ in the visual editor. + +## Getting Started + +For help getting started with Flutter, view our online +[documentation](https://flutter.dev/). + +For help on editing plugin code, view the [documentation](https://flutter.dev/platform-plugins/#edit-code). diff --git a/packages/network_info_plus/android/build.gradle b/packages/network_info_plus/android/build.gradle new file mode 100644 index 0000000000..d6e4638304 --- /dev/null +++ b/packages/network_info_plus/android/build.gradle @@ -0,0 +1,34 @@ +group 'dev.fluttercommunity.plus.network_info' +version '1.0-SNAPSHOT' + +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.3.0' + } +} + +rootProject.allprojects { + repositories { + google() + jcenter() + } +} + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 28 + + defaultConfig { + minSdkVersion 16 + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + lintOptions { + disable 'InvalidPackage' + } +} diff --git a/packages/network_info_plus/android/gradle.properties b/packages/network_info_plus/android/gradle.properties new file mode 100644 index 0000000000..8bd86f6805 --- /dev/null +++ b/packages/network_info_plus/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/packages/network_info_plus/android/settings.gradle b/packages/network_info_plus/android/settings.gradle new file mode 100644 index 0000000000..aa218d55a1 --- /dev/null +++ b/packages/network_info_plus/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'network_info' diff --git a/packages/network_info_plus/android/src/main/AndroidManifest.xml b/packages/network_info_plus/android/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..dd7b047f5f --- /dev/null +++ b/packages/network_info_plus/android/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ + + + + diff --git a/packages/network_info_plus/android/src/main/java/dev/fluttercommunity/plus/network_info/NetworkInfo.java b/packages/network_info_plus/android/src/main/java/dev/fluttercommunity/plus/network_info/NetworkInfo.java new file mode 100644 index 0000000000..cb03a0769f --- /dev/null +++ b/packages/network_info_plus/android/src/main/java/dev/fluttercommunity/plus/network_info/NetworkInfo.java @@ -0,0 +1,55 @@ +// 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.network_info; + +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; + +/** Reports network info such as wifi name and address. */ +class NetworkInfo { + private WifiManager wifiManager; + + NetworkInfo(WifiManager wifiManager) { + this.wifiManager = wifiManager; + } + + String getWifiName() { + WifiInfo wifiInfo = getWifiInfo(); + String ssid = null; + if (wifiInfo != null) ssid = wifiInfo.getSSID(); + if (ssid != null) ssid = ssid.replaceAll("\"", ""); // Android returns "SSID" + return ssid; + } + + String getWifiBSSID() { + WifiInfo wifiInfo = getWifiInfo(); + String bssid = null; + if (wifiInfo != null) { + bssid = wifiInfo.getBSSID(); + } + return bssid; + } + + String getWifiIPAddress() { + WifiInfo wifiInfo = null; + if (wifiManager != null) wifiInfo = wifiManager.getConnectionInfo(); + + String ip = null; + int i_ip = 0; + if (wifiInfo != null) i_ip = wifiInfo.getIpAddress(); + + if (i_ip != 0) + ip = + String.format( + "%d.%d.%d.%d", + (i_ip & 0xff), (i_ip >> 8 & 0xff), (i_ip >> 16 & 0xff), (i_ip >> 24 & 0xff)); + + return ip; + } + + private WifiInfo getWifiInfo() { + return wifiManager == null ? null : wifiManager.getConnectionInfo(); + } +} diff --git a/packages/network_info_plus/android/src/main/java/dev/fluttercommunity/plus/network_info/NetworkInfoMethodChannelHandler.java b/packages/network_info_plus/android/src/main/java/dev/fluttercommunity/plus/network_info/NetworkInfoMethodChannelHandler.java new file mode 100644 index 0000000000..a5df91d14f --- /dev/null +++ b/packages/network_info_plus/android/src/main/java/dev/fluttercommunity/plus/network_info/NetworkInfoMethodChannelHandler.java @@ -0,0 +1,45 @@ +// 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.network_info; + +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 NetworkInfo}, and then send the result back to the UIThread through the {@link + * MethodChannel.Result}. + */ +class NetworkInfoMethodChannelHandler implements MethodChannel.MethodCallHandler { + + private NetworkInfo networkInfo; + + /** + * Construct the NetworkInfoMethodChannelHandler with a {@code networkInfo}. The {@code + * networkInfo} must not be null. + */ + NetworkInfoMethodChannelHandler(NetworkInfo networkInfo) { + assert (networkInfo != null); + this.networkInfo = networkInfo; + } + + @Override + public void onMethodCall(MethodCall call, MethodChannel.Result result) { + switch (call.method) { + case "wifiName": + result.success(networkInfo.getWifiName()); + break; + case "wifiBSSID": + result.success(networkInfo.getWifiBSSID()); + break; + case "wifiIPAddress": + result.success(networkInfo.getWifiIPAddress()); + break; + default: + result.notImplemented(); + break; + } + } +} diff --git a/packages/network_info_plus/android/src/main/java/dev/fluttercommunity/plus/network_info/NetworkInfoPlusPlugin.java b/packages/network_info_plus/android/src/main/java/dev/fluttercommunity/plus/network_info/NetworkInfoPlusPlugin.java new file mode 100644 index 0000000000..8ccd16022a --- /dev/null +++ b/packages/network_info_plus/android/src/main/java/dev/fluttercommunity/plus/network_info/NetworkInfoPlusPlugin.java @@ -0,0 +1,52 @@ +// 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.network_info; + +import android.content.Context; +import android.net.wifi.WifiManager; +import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.plugin.common.BinaryMessenger; +import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugin.common.PluginRegistry.Registrar; + +/** NetworkInfoPlusPlugin */ +public class NetworkInfoPlusPlugin implements FlutterPlugin { + + private MethodChannel methodChannel; + + /** Plugin registration. */ + public static void registerWith(Registrar registrar) { + + NetworkInfoPlusPlugin plugin = new NetworkInfoPlusPlugin(); + plugin.setupChannels(registrar.messenger(), registrar.context()); + } + + @Override + public void onAttachedToEngine(FlutterPluginBinding binding) { + setupChannels(binding.getBinaryMessenger(), binding.getApplicationContext()); + } + + @Override + public void onDetachedFromEngine(FlutterPluginBinding binding) { + teardownChannels(); + } + + private void setupChannels(BinaryMessenger messenger, Context context) { + methodChannel = new MethodChannel(messenger, "dev.fluttercommunity.plus/network_info"); + WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + + NetworkInfo networkInfo = new NetworkInfo(wifiManager); + + NetworkInfoMethodChannelHandler methodChannelHandler = + new NetworkInfoMethodChannelHandler(networkInfo); + + methodChannel.setMethodCallHandler(methodChannelHandler); + } + + private void teardownChannels() { + methodChannel.setMethodCallHandler(null); + methodChannel = null; + } +} diff --git a/packages/network_info_plus/example/.gitignore b/packages/network_info_plus/example/.gitignore new file mode 100644 index 0000000000..0fa6b675c0 --- /dev/null +++ b/packages/network_info_plus/example/.gitignore @@ -0,0 +1,46 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/packages/network_info_plus/example/android/app/build.gradle b/packages/network_info_plus/example/android/app/build.gradle new file mode 100644 index 0000000000..99786cdb6c --- /dev/null +++ b/packages/network_info_plus/example/android/app/build.gradle @@ -0,0 +1,58 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + applicationId "dev.fluttercommunity.plus.network_info_plus_example" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test:runner:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' +} diff --git a/packages/network_info_plus/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/network_info_plus/example/android/app/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..9a4163a4f5 --- /dev/null +++ b/packages/network_info_plus/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/packages/network_info_plus/example/android/app/src/main/AndroidManifest.xml b/packages/network_info_plus/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..9e8e49ef8e --- /dev/null +++ b/packages/network_info_plus/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + diff --git a/packages/network_info_plus/example/android/app/src/main/java/dev/fluttercommunity/plus/network_info_plus_example/EmbeddingV1Activity.java b/packages/network_info_plus/example/android/app/src/main/java/dev/fluttercommunity/plus/network_info_plus_example/EmbeddingV1Activity.java new file mode 100644 index 0000000000..3656874ed8 --- /dev/null +++ b/packages/network_info_plus/example/android/app/src/main/java/dev/fluttercommunity/plus/network_info_plus_example/EmbeddingV1Activity.java @@ -0,0 +1,18 @@ +// 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.network_info_plus_example; + +import android.os.Bundle; +import dev.fluttercommunity.plus.network_info.NetworkInfoPlusPlugin; +import io.flutter.app.FlutterActivity; + +public class EmbeddingV1Activity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + NetworkInfoPlusPlugin.registerWith( + registrarFor("dev.fluttercommunity.plus.network_info.NetworkPlusPlugin")); + } +} diff --git a/packages/network_info_plus/example/android/app/src/main/java/dev/fluttercommunity/plus/network_info_plus_example/EmbeddingV1ActivityTest.java b/packages/network_info_plus/example/android/app/src/main/java/dev/fluttercommunity/plus/network_info_plus_example/EmbeddingV1ActivityTest.java new file mode 100644 index 0000000000..e17382feaa --- /dev/null +++ b/packages/network_info_plus/example/android/app/src/main/java/dev/fluttercommunity/plus/network_info_plus_example/EmbeddingV1ActivityTest.java @@ -0,0 +1,17 @@ +// 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.network_info_plus_example; + +import androidx.test.rule.ActivityTestRule; +import dev.flutter.plugins.integration_test.FlutterTestRunner; +import org.junit.Rule; +import org.junit.runner.RunWith; + +@RunWith(FlutterTestRunner.class) +public class EmbeddingV1ActivityTest { + @Rule + public ActivityTestRule rule = + new ActivityTestRule<>(EmbeddingV1Activity.class); +} diff --git a/packages/network_info_plus/example/android/app/src/main/java/dev/fluttercommunity/plus/network_info_plus_example/FlutterActivityTest.java b/packages/network_info_plus/example/android/app/src/main/java/dev/fluttercommunity/plus/network_info_plus_example/FlutterActivityTest.java new file mode 100644 index 0000000000..251b10e998 --- /dev/null +++ b/packages/network_info_plus/example/android/app/src/main/java/dev/fluttercommunity/plus/network_info_plus_example/FlutterActivityTest.java @@ -0,0 +1,17 @@ +// 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.network_info_plus_example; + +import androidx.test.rule.ActivityTestRule; +import dev.flutter.plugins.integration_test.FlutterTestRunner; +import io.flutter.embedding.android.FlutterActivity; +import org.junit.Rule; +import org.junit.runner.RunWith; + +@RunWith(FlutterTestRunner.class) +public class FlutterActivityTest { + @Rule + public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); +} diff --git a/packages/network_info_plus/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/packages/network_info_plus/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000..db77bb4b7b Binary files /dev/null and b/packages/network_info_plus/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/packages/network_info_plus/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/packages/network_info_plus/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000..17987b79bb Binary files /dev/null and b/packages/network_info_plus/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/packages/network_info_plus/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/packages/network_info_plus/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000..09d4391482 Binary files /dev/null and b/packages/network_info_plus/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/packages/network_info_plus/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/packages/network_info_plus/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000..d5f1c8d34e Binary files /dev/null and b/packages/network_info_plus/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/packages/network_info_plus/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/packages/network_info_plus/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000..4d6372eebd Binary files /dev/null and b/packages/network_info_plus/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/packages/network_info_plus/example/android/build.gradle b/packages/network_info_plus/example/android/build.gradle new file mode 100644 index 0000000000..541636cc49 --- /dev/null +++ b/packages/network_info_plus/example/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.3.0' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/packages/network_info_plus/example/android/gradle.properties b/packages/network_info_plus/example/android/gradle.properties new file mode 100644 index 0000000000..a6738207fd --- /dev/null +++ b/packages/network_info_plus/example/android/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true +android.enableR8=true diff --git a/packages/network_info_plus/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/network_info_plus/example/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..019065d1d6 --- /dev/null +++ b/packages/network_info_plus/example/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/packages/network_info_plus/example/android/settings.gradle b/packages/network_info_plus/example/android/settings.gradle new file mode 100644 index 0000000000..a159ea7cb9 --- /dev/null +++ b/packages/network_info_plus/example/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withInputStream { stream -> plugins.load(stream) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/packages/network_info_plus/example/ios/Flutter/AppFrameworkInfo.plist b/packages/network_info_plus/example/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000000..6c2de8086b --- /dev/null +++ b/packages/network_info_plus/example/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + UIRequiredDeviceCapabilities + + arm64 + + MinimumOSVersion + 8.0 + + diff --git a/packages/network_info_plus/example/ios/Flutter/Debug.xcconfig b/packages/network_info_plus/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000000..e8efba1146 --- /dev/null +++ b/packages/network_info_plus/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/packages/network_info_plus/example/ios/Flutter/Flutter.podspec b/packages/network_info_plus/example/ios/Flutter/Flutter.podspec new file mode 100644 index 0000000000..2c4421cfe5 --- /dev/null +++ b/packages/network_info_plus/example/ios/Flutter/Flutter.podspec @@ -0,0 +1,18 @@ +# +# NOTE: This podspec is NOT to be published. It is only used as a local source! +# This is a generated file; do not edit or check into version control. +# + +Pod::Spec.new do |s| + s.name = 'Flutter' + s.version = '1.0.0' + s.summary = 'High-performance, high-fidelity mobile apps.' + s.homepage = 'https://flutter.io' + s.license = { :type => 'MIT' } + s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } + s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s } + s.ios.deployment_target = '8.0' + # Framework linking is handled by Flutter tooling, not CocoaPods. + # Add a placeholder to satisfy `s.dependency 'Flutter'` plugin podspecs. + s.vendored_frameworks = 'path/to/nothing' +end diff --git a/packages/network_info_plus/example/ios/Flutter/Release.xcconfig b/packages/network_info_plus/example/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000000..399e9340e6 --- /dev/null +++ b/packages/network_info_plus/example/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/packages/network_info_plus/example/ios/Runner.xcodeproj/project.pbxproj b/packages/network_info_plus/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..818569bdf5 --- /dev/null +++ b/packages/network_info_plus/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,460 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + EB0BA966000B5C35B13186D7 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C80D49AFD183103034E444C2 /* libPods-Runner.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3173C764DD180BE02EB51E47 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 69D903F0A9A7C636EE803AF8 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + C80D49AFD183103034E444C2 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EB0BA966000B5C35B13186D7 /* libPods-Runner.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 89F516DEFCBF79E39D2885C2 /* Frameworks */ = { + isa = PBXGroup; + children = ( + C80D49AFD183103034E444C2 /* libPods-Runner.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + 8ECC1C323F60D5498EEC2315 /* Pods */ = { + isa = PBXGroup; + children = ( + 69D903F0A9A7C636EE803AF8 /* Pods-Runner.debug.xcconfig */, + 3173C764DD180BE02EB51E47 /* Pods-Runner.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 8ECC1C323F60D5498EEC2315 /* Pods */, + 89F516DEFCBF79E39D2885C2 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 3BAF367E8BACBC7576CEE653 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 3BAF367E8BACBC7576CEE653 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = dev.fluttercommunity.plus.networkInfoExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = dev.fluttercommunity.plus.networkInfoExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/packages/network_info_plus/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/network_info_plus/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..1d526a16ed --- /dev/null +++ b/packages/network_info_plus/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/packages/network_info_plus/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/network_info_plus/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000000..3bb3697ef4 --- /dev/null +++ b/packages/network_info_plus/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/network_info_plus/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/network_info_plus/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..21a3cc14c7 --- /dev/null +++ b/packages/network_info_plus/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/packages/network_info_plus/example/ios/Runner/AppDelegate.h b/packages/network_info_plus/example/ios/Runner/AppDelegate.h new file mode 100644 index 0000000000..d9e18e990f --- /dev/null +++ b/packages/network_info_plus/example/ios/Runner/AppDelegate.h @@ -0,0 +1,10 @@ +// 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 +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/packages/network_info_plus/example/ios/Runner/AppDelegate.m b/packages/network_info_plus/example/ios/Runner/AppDelegate.m new file mode 100644 index 0000000000..f086757071 --- /dev/null +++ b/packages/network_info_plus/example/ios/Runner/AppDelegate.m @@ -0,0 +1,17 @@ +// 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. + +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..d22f10b2ab --- /dev/null +++ b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,116 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000000..28c6bf0301 Binary files /dev/null and b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000000..2ccbfd967d Binary files /dev/null and b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000000..f091b6b0bc Binary files /dev/null and b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000000..4cde12118d Binary files /dev/null and b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000000..d0ef06e7ed Binary files /dev/null and b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000000..dcdc2306c2 Binary files /dev/null and b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000000..2ccbfd967d Binary files /dev/null and b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000000..c8f9ed8f5c Binary files /dev/null and b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000000..a6d6b8609d Binary files /dev/null and b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000..a6d6b8609d Binary files /dev/null and b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000..75b2d164a5 Binary files /dev/null and b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000000..c4df70d39d Binary files /dev/null and b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000000..6a84f41e14 Binary files /dev/null and b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000000..d0e1f58536 Binary files /dev/null and b/packages/network_info_plus/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/packages/network_info_plus/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/network_info_plus/example/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000000..ebf48f6039 --- /dev/null +++ b/packages/network_info_plus/example/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/network_info_plus/example/ios/Runner/Base.lproj/Main.storyboard b/packages/network_info_plus/example/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000000..f3c28516fb --- /dev/null +++ b/packages/network_info_plus/example/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/network_info_plus/example/ios/Runner/Info.plist b/packages/network_info_plus/example/ios/Runner/Info.plist new file mode 100644 index 0000000000..153602ea04 --- /dev/null +++ b/packages/network_info_plus/example/ios/Runner/Info.plist @@ -0,0 +1,53 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + network_info_plus_example + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + NSLocationAlwaysAndWhenInUseUsageDescription + This app requires accessing your location information all the time to get wi-fi information. + NSLocationWhenInUseUsageDescription + This app requires accessing your location information when the app is in foreground to get wi-fi information. + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + arm64 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/packages/network_info_plus/example/ios/Runner/Runner.entitlements b/packages/network_info_plus/example/ios/Runner/Runner.entitlements new file mode 100644 index 0000000000..ba21fbdaf2 --- /dev/null +++ b/packages/network_info_plus/example/ios/Runner/Runner.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.developer.networking.wifi-info + + + diff --git a/packages/network_info_plus/example/ios/Runner/main.m b/packages/network_info_plus/example/ios/Runner/main.m new file mode 100644 index 0000000000..bec320c0be --- /dev/null +++ b/packages/network_info_plus/example/ios/Runner/main.m @@ -0,0 +1,13 @@ +// 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 +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/packages/network_info_plus/example/lib/main.dart b/packages/network_info_plus/example/lib/main.dart new file mode 100644 index 0000000000..9b02a1f918 --- /dev/null +++ b/packages/network_info_plus/example/lib/main.dart @@ -0,0 +1,127 @@ +// 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. + +// ignore_for_file: public_member_api_docs + +import 'dart:async'; +import 'dart:io'; + +import 'package:network_info_plus/network_info_plus.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +// Sets a platform override for desktop to avoid exceptions. See +// https://flutter.dev/desktop#target-platform-override for more info. +void _enablePlatformOverrideForDesktop() { + if (!kIsWeb && (Platform.isWindows || Platform.isLinux)) { + debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia; + } +} + +void main() { + _enablePlatformOverrideForDesktop(); + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: MyHomePage(title: 'Flutter Demo Home Page'), + ); + } +} + +class MyHomePage extends StatefulWidget { + MyHomePage({Key key, this.title}) : super(key: key); + + final String title; + + @override + _MyHomePageState createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + String _connectionStatus = 'Unknown'; + final NetworkInfo _networkInfo = NetworkInfo(); + + @override + void initState() { + super.initState(); + _initNetworkInfo(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('NetworkInfo example app'), + ), + body: Center(child: Text('Connection Status: $_connectionStatus')), + ); + } + + Future _initNetworkInfo() async { + String wifiName, wifiBSSID, wifiIP; + + try { + if (!kIsWeb && Platform.isIOS) { + var status = await _networkInfo.getLocationServiceAuthorization(); + if (status == LocationAuthorizationStatus.notDetermined) { + status = await _networkInfo.requestLocationServiceAuthorization(); + } + if (status == LocationAuthorizationStatus.authorizedAlways || + status == LocationAuthorizationStatus.authorizedWhenInUse) { + wifiName = await _networkInfo.getWifiName(); + } else { + wifiName = await _networkInfo.getWifiName(); + } + } else { + wifiName = await _networkInfo.getWifiName(); + } + } on PlatformException catch (e) { + print(e.toString()); + wifiName = 'Failed to get Wifi Name'; + } + + try { + if (!kIsWeb && Platform.isIOS) { + var status = await _networkInfo.getLocationServiceAuthorization(); + if (status == LocationAuthorizationStatus.notDetermined) { + status = await _networkInfo.requestLocationServiceAuthorization(); + } + if (status == LocationAuthorizationStatus.authorizedAlways || + status == LocationAuthorizationStatus.authorizedWhenInUse) { + wifiBSSID = await _networkInfo.getWifiBSSID(); + } else { + wifiBSSID = await _networkInfo.getWifiBSSID(); + } + } else { + wifiBSSID = await _networkInfo.getWifiBSSID(); + } + } on PlatformException catch (e) { + print(e.toString()); + wifiBSSID = 'Failed to get Wifi BSSID'; + } + + try { + wifiIP = await _networkInfo.getWifiIP(); + } on PlatformException catch (e) { + print(e.toString()); + wifiIP = 'Failed to get Wifi IP'; + } + + setState(() { + _connectionStatus = 'Wifi Name: $wifiName\n' + 'Wifi BSSID: $wifiBSSID\n' + 'Wifi IP: $wifiIP\n'; + }); + } +} diff --git a/packages/network_info_plus/example/linux/.gitignore b/packages/network_info_plus/example/linux/.gitignore new file mode 100644 index 0000000000..d3896c9844 --- /dev/null +++ b/packages/network_info_plus/example/linux/.gitignore @@ -0,0 +1 @@ +flutter/ephemeral diff --git a/packages/network_info_plus/example/linux/CMakeLists.txt b/packages/network_info_plus/example/linux/CMakeLists.txt new file mode 100644 index 0000000000..279007eb35 --- /dev/null +++ b/packages/network_info_plus/example/linux/CMakeLists.txt @@ -0,0 +1,106 @@ +cmake_minimum_required(VERSION 3.10) +project(runner LANGUAGES CXX) + +set(BINARY_NAME "example") +set(APPLICATION_ID "io.flutter.plugins.example") + +cmake_policy(SET CMP0063 NEW) + +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Configure build options. +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") +endif() + +# Compilation settings that should be applied to most targets. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_14) + target_compile_options(${TARGET} PRIVATE -Wall -Werror) + target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") + target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") +endfunction() + +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") + +# Flutter library and tool build rules. +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) + +add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") + +# Application build +add_executable(${BINARY_NAME} + "main.cc" + "my_application.cc" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" +) +apply_standard_settings(${BINARY_NAME}) +target_link_libraries(${BINARY_NAME} PRIVATE flutter) +target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) +add_dependencies(${BINARY_NAME} flutter_assemble) +# Only the install-generated bundle's copy of the executable will launch +# correctly, since the resources must in the right relative locations. To avoid +# people trying to run the unbundled copy, put it in a subdirectory instead of +# the default top-level location. +set_target_properties(${BINARY_NAME} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" +) + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# By default, "installing" just makes a relocatable bundle in the build +# directory. +set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +# Start with a clean build bundle directory every time. +install(CODE " + file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") + " COMPONENT Runtime) + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") + install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() diff --git a/packages/network_info_plus/example/linux/flutter/CMakeLists.txt b/packages/network_info_plus/example/linux/flutter/CMakeLists.txt new file mode 100644 index 0000000000..4f48a7ced5 --- /dev/null +++ b/packages/network_info_plus/example/linux/flutter/CMakeLists.txt @@ -0,0 +1,88 @@ +cmake_minimum_required(VERSION 3.10) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. + +# Serves the same purpose as list(TRANSFORM ... PREPEND ...), +# which isn't available in 3.10. +function(list_prepend LIST_NAME PREFIX) + set(NEW_LIST "") + foreach(element ${${LIST_NAME}}) + list(APPEND NEW_LIST "${PREFIX}${element}") + endforeach(element) + set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) +endfunction() + +# === Flutter Library === +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) +pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) +pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) +pkg_check_modules(BLKID REQUIRED IMPORTED_TARGET blkid) + +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "fl_basic_message_channel.h" + "fl_binary_codec.h" + "fl_binary_messenger.h" + "fl_dart_project.h" + "fl_engine.h" + "fl_json_message_codec.h" + "fl_json_method_codec.h" + "fl_message_codec.h" + "fl_method_call.h" + "fl_method_channel.h" + "fl_method_codec.h" + "fl_method_response.h" + "fl_plugin_registrar.h" + "fl_plugin_registry.h" + "fl_standard_message_codec.h" + "fl_standard_method_codec.h" + "fl_string_codec.h" + "fl_value.h" + "fl_view.h" + "flutter_linux.h" +) +list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") +target_link_libraries(flutter INTERFACE + PkgConfig::GTK + PkgConfig::GLIB + PkgConfig::GIO + PkgConfig::BLKID +) +add_dependencies(flutter flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CMAKE_CURRENT_BINARY_DIR}/_phony_ + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" + linux-x64 ${CMAKE_BUILD_TYPE} +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} +) diff --git a/packages/network_info_plus/example/linux/flutter/generated_plugin_registrant.cc b/packages/network_info_plus/example/linux/flutter/generated_plugin_registrant.cc new file mode 100644 index 0000000000..890de29bba --- /dev/null +++ b/packages/network_info_plus/example/linux/flutter/generated_plugin_registrant.cc @@ -0,0 +1,7 @@ +// +// Generated file. Do not edit. +// + +#include "generated_plugin_registrant.h" + +void fl_register_plugins(FlPluginRegistry* registry) {} diff --git a/packages/network_info_plus/example/linux/flutter/generated_plugin_registrant.h b/packages/network_info_plus/example/linux/flutter/generated_plugin_registrant.h new file mode 100644 index 0000000000..9bf7478940 --- /dev/null +++ b/packages/network_info_plus/example/linux/flutter/generated_plugin_registrant.h @@ -0,0 +1,13 @@ +// +// Generated file. Do not edit. +// + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void fl_register_plugins(FlPluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/packages/network_info_plus/example/linux/flutter/generated_plugins.cmake b/packages/network_info_plus/example/linux/flutter/generated_plugins.cmake new file mode 100644 index 0000000000..51436ae8c9 --- /dev/null +++ b/packages/network_info_plus/example/linux/flutter/generated_plugins.cmake @@ -0,0 +1,15 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) diff --git a/packages/network_info_plus/example/linux/main.cc b/packages/network_info_plus/example/linux/main.cc new file mode 100644 index 0000000000..10835acb58 --- /dev/null +++ b/packages/network_info_plus/example/linux/main.cc @@ -0,0 +1,11 @@ +#include "my_application.h" + +int main(int argc, char** argv) { + // Only X11 is currently supported. + // Wayland support is being developed: + // https://github.com/flutter/flutter/issues/57932. + gdk_set_allowed_backends("x11"); + + g_autoptr(MyApplication) app = my_application_new(); + return g_application_run(G_APPLICATION(app), argc, argv); +} diff --git a/packages/network_info_plus/example/linux/my_application.cc b/packages/network_info_plus/example/linux/my_application.cc new file mode 100644 index 0000000000..67ed0b9025 --- /dev/null +++ b/packages/network_info_plus/example/linux/my_application.cc @@ -0,0 +1,45 @@ +#include "my_application.h" + +#include + +#include "flutter/generated_plugin_registrant.h" + +struct _MyApplication { + GtkApplication parent_instance; +}; + +G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) + +// Implements GApplication::activate. +static void my_application_activate(GApplication* application) { + GtkWindow* window = + GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); + GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); + gtk_widget_show(GTK_WIDGET(header_bar)); + gtk_header_bar_set_title(header_bar, "example"); + gtk_header_bar_set_show_close_button(header_bar, TRUE); + gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); + gtk_window_set_default_size(window, 1280, 720); + gtk_widget_show(GTK_WIDGET(window)); + + g_autoptr(FlDartProject) project = fl_dart_project_new(); + + FlView* view = fl_view_new(project); + gtk_widget_show(GTK_WIDGET(view)); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); + + fl_register_plugins(FL_PLUGIN_REGISTRY(view)); + + gtk_widget_grab_focus(GTK_WIDGET(view)); +} + +static void my_application_class_init(MyApplicationClass* klass) { + G_APPLICATION_CLASS(klass)->activate = my_application_activate; +} + +static void my_application_init(MyApplication* self) {} + +MyApplication* my_application_new() { + return MY_APPLICATION(g_object_new( + my_application_get_type(), "application-id", APPLICATION_ID, nullptr)); +} diff --git a/packages/network_info_plus/example/linux/my_application.h b/packages/network_info_plus/example/linux/my_application.h new file mode 100644 index 0000000000..72271d5e41 --- /dev/null +++ b/packages/network_info_plus/example/linux/my_application.h @@ -0,0 +1,18 @@ +#ifndef FLUTTER_MY_APPLICATION_H_ +#define FLUTTER_MY_APPLICATION_H_ + +#include + +G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, + GtkApplication) + +/** + * my_application_new: + * + * Creates a new Flutter-based application. + * + * Returns: a new #MyApplication. + */ +MyApplication* my_application_new(); + +#endif // FLUTTER_MY_APPLICATION_H_ diff --git a/packages/network_info_plus/example/macos/Flutter/Flutter-Debug.xcconfig b/packages/network_info_plus/example/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 0000000000..785633d3a8 --- /dev/null +++ b/packages/network_info_plus/example/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/network_info_plus/example/macos/Flutter/Flutter-Release.xcconfig b/packages/network_info_plus/example/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 0000000000..5fba960c3a --- /dev/null +++ b/packages/network_info_plus/example/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/network_info_plus/example/macos/Runner.xcodeproj/project.pbxproj b/packages/network_info_plus/example/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..e5933e98cf --- /dev/null +++ b/packages/network_info_plus/example/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,644 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + EA473EC5F2038B17A2FE4D78 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 748ADDF1719804343BB18004 /* Pods_Runner.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* connectivity_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = connectivity_example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 748ADDF1719804343BB18004 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 80418F0A2F74D683C63A4D0A /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + AA19B00394637215A825CF5E /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + E960ED3977AF6DF197F74FFA /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EA473EC5F2038B17A2FE4D78 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + D42EAEE5849744148CC78D83 /* Pods */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* connectivity_example.app */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + D42EAEE5849744148CC78D83 /* Pods */ = { + isa = PBXGroup; + children = ( + 80418F0A2F74D683C63A4D0A /* Pods-Runner.debug.xcconfig */, + E960ED3977AF6DF197F74FFA /* Pods-Runner.release.xcconfig */, + AA19B00394637215A825CF5E /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 748ADDF1719804343BB18004 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + B24477CAB9D5BDFC8F3553DA /* [CP] Check Pods Manifest.lock */, + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + 84A8D21305B2F01D093A8F9C /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* connectivity_example.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = "Google LLC"; + TargetAttributes = { + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh\ntouch Flutter/ephemeral/tripwire\n"; + }; + 84A8D21305B2F01D093A8F9C /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + B24477CAB9D5BDFC8F3553DA /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter/ephemeral", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter/ephemeral", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter/ephemeral", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/packages/network_info_plus/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/network_info_plus/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000000..2a7d3e7f34 --- /dev/null +++ b/packages/network_info_plus/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/network_info_plus/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/packages/network_info_plus/example/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..21a3cc14c7 --- /dev/null +++ b/packages/network_info_plus/example/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/packages/network_info_plus/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/network_info_plus/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000..18d981003d --- /dev/null +++ b/packages/network_info_plus/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/network_info_plus/example/macos/Runner/AppDelegate.swift b/packages/network_info_plus/example/macos/Runner/AppDelegate.swift new file mode 100644 index 0000000000..d53ef64377 --- /dev/null +++ b/packages/network_info_plus/example/macos/Runner/AppDelegate.swift @@ -0,0 +1,9 @@ +import Cocoa +import FlutterMacOS + +@NSApplicationMain +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } +} diff --git a/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..a2ec33f19f --- /dev/null +++ b/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 0000000000..3c4935a7ca Binary files /dev/null and b/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 0000000000..ed4cc16421 Binary files /dev/null and b/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 0000000000..483be61389 Binary files /dev/null and b/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 0000000000..bcbf36df2f Binary files /dev/null and b/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png new file mode 100644 index 0000000000..9c0a652864 Binary files /dev/null and b/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 0000000000..e71a726136 Binary files /dev/null and b/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 0000000000..8a31fe2dd3 Binary files /dev/null and b/packages/network_info_plus/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/packages/network_info_plus/example/macos/Runner/Base.lproj/MainMenu.xib b/packages/network_info_plus/example/macos/Runner/Base.lproj/MainMenu.xib new file mode 100644 index 0000000000..537341abf9 --- /dev/null +++ b/packages/network_info_plus/example/macos/Runner/Base.lproj/MainMenu.xib @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/network_info_plus/example/macos/Runner/Configs/AppInfo.xcconfig b/packages/network_info_plus/example/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 0000000000..a951488145 --- /dev/null +++ b/packages/network_info_plus/example/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = connectivity_example + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.connectivityExample + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2019 io.flutter.plugins. All rights reserved. diff --git a/packages/network_info_plus/example/macos/Runner/Configs/Debug.xcconfig b/packages/network_info_plus/example/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 0000000000..36b0fd9464 --- /dev/null +++ b/packages/network_info_plus/example/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/packages/network_info_plus/example/macos/Runner/Configs/Release.xcconfig b/packages/network_info_plus/example/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 0000000000..dff4f49561 --- /dev/null +++ b/packages/network_info_plus/example/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/packages/network_info_plus/example/macos/Runner/Configs/Warnings.xcconfig b/packages/network_info_plus/example/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 0000000000..42bcbf4780 --- /dev/null +++ b/packages/network_info_plus/example/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/packages/network_info_plus/example/macos/Runner/DebugProfile.entitlements b/packages/network_info_plus/example/macos/Runner/DebugProfile.entitlements new file mode 100644 index 0000000000..dddb8a30c8 --- /dev/null +++ b/packages/network_info_plus/example/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + + diff --git a/packages/network_info_plus/example/macos/Runner/Info.plist b/packages/network_info_plus/example/macos/Runner/Info.plist new file mode 100644 index 0000000000..4789daa6a4 --- /dev/null +++ b/packages/network_info_plus/example/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/packages/network_info_plus/example/macos/Runner/MainFlutterWindow.swift b/packages/network_info_plus/example/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 0000000000..2722837ec9 --- /dev/null +++ b/packages/network_info_plus/example/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,15 @@ +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController.init() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/packages/network_info_plus/example/macos/Runner/Release.entitlements b/packages/network_info_plus/example/macos/Runner/Release.entitlements new file mode 100644 index 0000000000..852fa1a472 --- /dev/null +++ b/packages/network_info_plus/example/macos/Runner/Release.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/packages/network_info_plus/example/pubspec.yaml b/packages/network_info_plus/example/pubspec.yaml new file mode 100644 index 0000000000..6fb521646a --- /dev/null +++ b/packages/network_info_plus/example/pubspec.yaml @@ -0,0 +1,21 @@ +name: network_info_plus_example +description: Demonstrates how to use the network_info_plus plugin. + +environment: + sdk: ">=2.7.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + network_info_plus: + path: ../ + +dev_dependencies: + flutter_driver: + sdk: flutter + test: any + integration_test: ^0.9.1 + pedantic: ^1.9.2 + +flutter: + uses-material-design: true diff --git a/packages/network_info_plus/example/test_driver/network_info_plus_e2e.dart b/packages/network_info_plus/example/test_driver/network_info_plus_e2e.dart new file mode 100644 index 0000000000..1d930cfc99 --- /dev/null +++ b/packages/network_info_plus/example/test_driver/network_info_plus_e2e.dart @@ -0,0 +1,27 @@ +// 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. + +import 'dart:io'; +import 'package:integration_test/integration_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:network_info_plus/network_info_plus.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + group('NetworkInfo test driver', () { + NetworkInfo _networkInfo; + + setUpAll(() async { + _networkInfo = NetworkInfo(); + }); + + testWidgets('test location methods, iOS only', (WidgetTester tester) async { + if (Platform.isIOS) { + expect((await _networkInfo.getLocationServiceAuthorization()), + LocationAuthorizationStatus.notDetermined); + } + }); + }); +} diff --git a/packages/network_info_plus/example/test_driver/network_info_plus_e2e_test.dart b/packages/network_info_plus/example/test_driver/network_info_plus_e2e_test.dart new file mode 100644 index 0000000000..44c08f5784 --- /dev/null +++ b/packages/network_info_plus/example/test_driver/network_info_plus_e2e_test.dart @@ -0,0 +1,16 @@ +// 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. + +import 'dart:convert'; +import 'dart:io'; +import 'package:flutter_driver/flutter_driver.dart'; + +Future main() async { + final driver = await FlutterDriver.connect(); + final data = + await driver.requestData(null, timeout: const Duration(minutes: 1)); + await driver.close(); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); +} diff --git a/packages/network_info_plus/ios/Assets/.gitkeep b/packages/network_info_plus/ios/Assets/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/network_info_plus/ios/Classes/FLTNetworkInfoLocationPlusHandler.h b/packages/network_info_plus/ios/Classes/FLTNetworkInfoLocationPlusHandler.h new file mode 100644 index 0000000000..516a9bab85 --- /dev/null +++ b/packages/network_info_plus/ios/Classes/FLTNetworkInfoLocationPlusHandler.h @@ -0,0 +1,23 @@ +// 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. +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@class FLTNetworkInfoLocationPlusDelegate; + +typedef void (^FLTNetworkInfoLocationPlusCompletion)(CLAuthorizationStatus); + +@interface FLTNetworkInfoLocationPlusHandler : NSObject + ++ (CLAuthorizationStatus)locationAuthorizationStatus; + +- (void)requestLocationAuthorization:(BOOL)always + completion: + (_Nonnull FLTNetworkInfoLocationPlusCompletion)completionHnadler; + +@end + +NS_ASSUME_NONNULL_END diff --git a/packages/network_info_plus/ios/Classes/FLTNetworkInfoLocationPlusHandler.m b/packages/network_info_plus/ios/Classes/FLTNetworkInfoLocationPlusHandler.m new file mode 100644 index 0000000000..6fca387640 --- /dev/null +++ b/packages/network_info_plus/ios/Classes/FLTNetworkInfoLocationPlusHandler.m @@ -0,0 +1,58 @@ +// 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. + +#import "FLTNetworkInfoLocationPlusHandler.h" + +@interface FLTNetworkInfoLocationPlusHandler () + +@property(copy, nonatomic) FLTNetworkInfoLocationPlusCompletion completion; +@property(strong, nonatomic) CLLocationManager *locationManager; + +@end + +@implementation FLTNetworkInfoLocationPlusHandler + ++ (CLAuthorizationStatus)locationAuthorizationStatus { + return CLLocationManager.authorizationStatus; +} + +- (void)requestLocationAuthorization:(BOOL)always + completion:(FLTNetworkInfoLocationPlusCompletion)completionHandler { + CLAuthorizationStatus status = CLLocationManager.authorizationStatus; + if (status != kCLAuthorizationStatusAuthorizedWhenInUse && always) { + completionHandler(kCLAuthorizationStatusDenied); + return; + } else if (status != kCLAuthorizationStatusNotDetermined) { + completionHandler(status); + return; + } + + if (self.completion) { + // If a request is still in process, immediately return. + completionHandler(kCLAuthorizationStatusNotDetermined); + return; + } + + self.completion = completionHandler; + self.locationManager = [CLLocationManager new]; + self.locationManager.delegate = self; + if (always) { + [self.locationManager requestAlwaysAuthorization]; + } else { + [self.locationManager requestWhenInUseAuthorization]; + } +} + +- (void)locationManager:(CLLocationManager *)manager + didChangeAuthorizationStatus:(CLAuthorizationStatus)status { + if (status == kCLAuthorizationStatusNotDetermined) { + return; + } + if (self.completion) { + self.completion(status); + self.completion = nil; + } +} + +@end diff --git a/packages/network_info_plus/ios/Classes/FLTNetworkInfoPlusPlugin.h b/packages/network_info_plus/ios/Classes/FLTNetworkInfoPlusPlugin.h new file mode 100644 index 0000000000..31fedebb99 --- /dev/null +++ b/packages/network_info_plus/ios/Classes/FLTNetworkInfoPlusPlugin.h @@ -0,0 +1,8 @@ +// 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 + +@interface FLTNetworkInfoPlusPlugin : NSObject +@end diff --git a/packages/network_info_plus/ios/Classes/FLTNetworkInfoPlusPlugin.m b/packages/network_info_plus/ios/Classes/FLTNetworkInfoPlusPlugin.m new file mode 100644 index 0000000000..0dda81ba74 --- /dev/null +++ b/packages/network_info_plus/ios/Classes/FLTNetworkInfoPlusPlugin.m @@ -0,0 +1,139 @@ +// 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 "FLTNetworkInfoPlusPlugin.h" + +#import +#import "FLTNetworkInfoLocationPlusHandler.h" +#import "SystemConfiguration/CaptiveNetwork.h" + +#include + +#include + +@interface FLTNetworkInfoPlusPlugin () + +@property(strong, nonatomic) FLTNetworkInfoLocationPlusHandler* locationHandler; + +@end + +@implementation FLTNetworkInfoPlusPlugin { +} + ++ (void)registerWithRegistrar:(NSObject*)registrar { + FLTNetworkInfoPlusPlugin* instance = [[FLTNetworkInfoPlusPlugin alloc] init]; + + FlutterMethodChannel* channel = + [FlutterMethodChannel methodChannelWithName:@"dev.fluttercommunity.plus/network_info" + binaryMessenger:[registrar messenger]]; + [registrar addMethodCallDelegate:instance channel:channel]; +} + +- (NSString*)findNetworkInfo:(NSString*)key { + NSString* info = nil; + NSArray* interfaceNames = (__bridge_transfer id)CNCopySupportedInterfaces(); + for (NSString* interfaceName in interfaceNames) { + NSDictionary* networkInfo = + (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)interfaceName); + if (networkInfo[key]) { + info = networkInfo[key]; + } + } + return info; +} + +- (NSString*)getWifiName { + return [self findNetworkInfo:@"SSID"]; +} + +- (NSString*)getBSSID { + return [self findNetworkInfo:@"BSSID"]; +} + +- (NSString*)getWifiIP { + NSString* address = @"error"; + struct ifaddrs* interfaces = NULL; + struct ifaddrs* temp_addr = NULL; + int success = 0; + + // retrieve the current interfaces - returns 0 on success + success = getifaddrs(&interfaces); + if (success == 0) { + // Loop through linked list of interfaces + temp_addr = interfaces; + while (temp_addr != NULL) { + if (temp_addr->ifa_addr->sa_family == AF_INET) { + // Check if interface is en0 which is the wifi connection on the iPhone + if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) { + // Get NSString from C String + address = [NSString + stringWithUTF8String:inet_ntoa(((struct sockaddr_in*)temp_addr->ifa_addr)->sin_addr)]; + } + } + + temp_addr = temp_addr->ifa_next; + } + } + + // Free memory + freeifaddrs(interfaces); + + return address; +} + +- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { + if ([call.method isEqualToString:@"wifiName"]) { + result([self getWifiName]); + } else if ([call.method isEqualToString:@"wifiBSSID"]) { + result([self getBSSID]); + } else if ([call.method isEqualToString:@"wifiIPAddress"]) { + result([self getWifiIP]); + } else if ([call.method isEqualToString:@"getLocationServiceAuthorization"]) { + result([self convertCLAuthorizationStatusToString:[FLTNetworkInfoLocationPlusHandler + locationAuthorizationStatus]]); + } else if ([call.method isEqualToString:@"requestLocationServiceAuthorization"]) { + NSArray* arguments = call.arguments; + BOOL always = [arguments.firstObject boolValue]; + __weak typeof(self) weakSelf = self; + [self.locationHandler + requestLocationAuthorization:always + completion:^(CLAuthorizationStatus status) { + result([weakSelf convertCLAuthorizationStatusToString:status]); + }]; + } else { + result(FlutterMethodNotImplemented); + } +} + +- (NSString*)convertCLAuthorizationStatusToString:(CLAuthorizationStatus)status { + switch (status) { + case kCLAuthorizationStatusNotDetermined: { + return @"notDetermined"; + } + case kCLAuthorizationStatusRestricted: { + return @"restricted"; + } + case kCLAuthorizationStatusDenied: { + return @"denied"; + } + case kCLAuthorizationStatusAuthorizedAlways: { + return @"authorizedAlways"; + } + case kCLAuthorizationStatusAuthorizedWhenInUse: { + return @"authorizedWhenInUse"; + } + default: { + return @"unknown"; + } + } +} + +- (FLTNetworkInfoLocationPlusHandler*)locationHandler { + if (!_locationHandler) { + _locationHandler = [FLTNetworkInfoLocationPlusHandler new]; + } + return _locationHandler; +} + +@end diff --git a/packages/network_info_plus/ios/network_info_plus.podspec b/packages/network_info_plus/ios/network_info_plus.podspec new file mode 100644 index 0000000000..7b5e2cac77 --- /dev/null +++ b/packages/network_info_plus/ios/network_info_plus.podspec @@ -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 = 'network_info_plus' + s.version = '0.0.1' + s.summary = 'Flutter Network Info' + s.description = <<-DESC +This plugin allows Flutter apps to discover network info and configure themselves accordingly. +Downloaded by pub (not CocoaPods). + DESC + s.homepage = 'https://github.com/fluttercommunity/plus_plugins' + s.license = { :type => 'BSD', :file => '../LICENSE' } + s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } + s.source = { :http => 'https://github.com/fluttercommunity/plus_plugins/tree/main/packages/network_info_plus' } + s.documentation_url = 'https://pub.dev/packages/network_info_plus' + s.source_files = 'Classes/**/*' + s.public_header_files = 'Classes/**/*.h' + s.dependency 'Flutter' + s.platform = :ios, '8.0' + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } +end diff --git a/packages/network_info_plus/lib/network_info_plus.dart b/packages/network_info_plus/lib/network_info_plus.dart new file mode 100644 index 0000000000..00695cedba --- /dev/null +++ b/packages/network_info_plus/lib/network_info_plus.dart @@ -0,0 +1,174 @@ +// 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 'dart:io' show Platform; + +import 'package:flutter/services.dart'; +import 'package:flutter/foundation.dart' show kIsWeb; +import 'package:network_info_plus_platform_interface/network_info_plus_platform_interface.dart'; +import 'package:network_info_plus_platform_interface/src/method_channel_network_info.dart'; +import 'package:network_info_plus_linux/network_info_plus_linux.dart'; + +// Export enums from the platform_interface so plugin users can use them directly. +export 'package:network_info_plus_platform_interface/network_info_plus_platform_interface.dart' + show LocationAuthorizationStatus; + +/// Discover network info: check WI-FI details and more. +class NetworkInfo { + /// Constructs a singleton instance of [NetworkInfo]. + /// + /// [NetworkInfo] 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 NetworkInfo() { + _singleton ??= NetworkInfo._(); + return _singleton; + } + + NetworkInfo._(); + + static NetworkInfo _singleton; + + static bool _manualDartRegistrationNeeded = true; + + // This is to manually endorse Dart implementations until automatic + // registration of Dart plugins is implemented. For details see + // https://github.com/flutter/flutter/issues/52267. + static NetworkInfoPlatform get _platform { + if (_manualDartRegistrationNeeded) { + // Only do the initial registration if it hasn't already been overridden + // with a non-default instance. + if (!kIsWeb && NetworkInfoPlatform.instance is MethodChannelNetworkInfo) { + if (Platform.isLinux) { + NetworkInfoPlatform.instance = NetworkInfoLinux(); + } + } + _manualDartRegistrationNeeded = false; + } + return NetworkInfoPlatform.instance; + } + + /// Obtains the wifi name (SSID) of the connected network + /// + /// Please note that it DOESN'T WORK on emulators (returns null). + /// + /// From android 8.0 onwards the GPS must be ON (high accuracy) + /// in order to be able to obtain the SSID. + Future getWifiName() { + return _platform.getWifiName(); + } + + /// Obtains the wifi BSSID of the connected network. + /// + /// Please note that it DOESN'T WORK on emulators (returns null). + /// + /// From Android 8.0 onwards the GPS must be ON (high accuracy) + /// in order to be able to obtain the BSSID. + Future getWifiBSSID() { + return _platform.getWifiBSSID(); + } + + /// Obtains the IP address of the connected wifi network + Future getWifiIP() { + return _platform.getWifiIP(); + } + + /// Request to authorize the location service (Only on iOS). + /// + /// This method will throw a [PlatformException] on Android. + /// + /// Returns a [LocationAuthorizationStatus] after user authorized or denied the location on this request. + /// + /// If the location information needs to be accessible all the time, set `requestAlwaysLocationUsage` to true. If user has + /// already granted a [LocationAuthorizationStatus.authorizedWhenInUse] prior to requesting an "always" access, it will return [LocationAuthorizationStatus.denied]. + /// + /// If the location service authorization is not determined prior to making this call, a platform standard UI of requesting a location service will pop up. + /// This UI will only show once unless the user re-install the app to their phone which resets the location service authorization to not determined. + /// + /// This method is a helper to get the location authorization that is necessary for certain functionality of this plugin. + /// It can be replaced with other permission handling code/plugin if preferred. + /// To request location authorization, make sure to add the following keys to your _Info.plist_ file, located in `/ios/Runner/Info.plist`: + /// * `NSLocationAlwaysAndWhenInUseUsageDescription` - describe why the app needs access to the user’s location information + /// all the time (foreground and background). This is called _Privacy - Location Always and When In Use Usage Description_ in the visual editor. + /// * `NSLocationWhenInUseUsageDescription` - describe why the app needs access to the user’s location information when the app is + /// running in the foreground. This is called _Privacy - Location When In Use Usage Description_ in the visual editor. + /// + /// Starting from iOS 13, `getWifiBSSID` and `getWifiIP` will only work properly if: + /// + /// * The app uses Core Location, and has the user’s authorization to use location information. + /// * The app uses the NEHotspotConfiguration API to configure the current Wi-Fi network. + /// * The app has active VPN configurations installed. + /// + /// If the app falls into the first category, call this method before calling `getWifiBSSID` or `getWifiIP`. + /// For example, + /// ```dart + /// if (Platform.isIOS) { + /// LocationAuthorizationStatus status = await _networkInfo.getLocationServiceAuthorization(); + /// if (status == LocationAuthorizationStatus.notDetermined) { + /// status = await _networkInfo.requestLocationServiceAuthorization(); + /// } + /// if (status == LocationAuthorizationStatus.authorizedAlways || status == LocationAuthorizationStatus.authorizedWhenInUse) { + /// wifiBSSID = await _networkInfo.getWifiName(); + /// } else { + /// print('location service is not authorized, the data might not be correct'); + /// wifiBSSID = await _networkInfo.getWifiName(); + /// } + /// } else { + /// wifiBSSID = await _networkInfo.getWifiName(); + /// } + /// ``` + /// + /// Ideally, a location service authorization should only be requested if the current authorization status is not determined. + /// + /// See also [getLocationServiceAuthorization] to obtain current location service status. + Future requestLocationServiceAuthorization({ + bool requestAlwaysLocationUsage = false, + }) { + return _platform.requestLocationServiceAuthorization( + requestAlwaysLocationUsage: requestAlwaysLocationUsage, + ); + } + + /// Get the current location service authorization (Only on iOS). + /// + /// This method will throw a [PlatformException] on Android. + /// + /// Returns a [LocationAuthorizationStatus]. + /// If the returned value is [LocationAuthorizationStatus.notDetermined], a subsequent [requestLocationServiceAuthorization] call + /// can request the authorization. + /// If the returned value is not [LocationAuthorizationStatus.notDetermined], a subsequent [requestLocationServiceAuthorization] + /// will not initiate another request. It will instead return the "determined" status. + /// + /// This method is a helper to get the location authorization that is necessary for certain functionality of this plugin. + /// It can be replaced with other permission handling code/plugin if preferred. + /// + /// Starting from iOS 13, `getWifiBSSID` and `getWifiIP` will only work properly if: + /// + /// * The app uses Core Location, and has the user’s authorization to use location information. + /// * The app uses the NEHotspotConfiguration API to configure the current Wi-Fi network. + /// * The app has active VPN configurations installed. + /// + /// If the app falls into the first category, call this method before calling `getWifiBSSID` or `getWifiIP`. + /// For example, + /// ```dart + /// if (Platform.isIOS) { + /// LocationAuthorizationStatus status = await _networkInfo.getLocationServiceAuthorization(); + /// if (status == LocationAuthorizationStatus.authorizedAlways || status == LocationAuthorizationStatus.authorizedWhenInUse) { + /// wifiBSSID = await _networkInfo.getWifiName(); + /// } else { + /// print('location service is not authorized, the data might not be correct'); + /// wifiBSSID = await _networkInfo.getWifiName(); + /// } + /// } else { + /// wifiBSSID = await _networkInfo.getWifiName(); + /// } + /// ``` + /// + /// See also [requestLocationServiceAuthorization] for requesting a location service authorization. + Future getLocationServiceAuthorization() { + return _platform.getLocationServiceAuthorization(); + } +} diff --git a/packages/network_info_plus/macos/network_info_plus.podspec b/packages/network_info_plus/macos/network_info_plus.podspec new file mode 100644 index 0000000000..8371009463 --- /dev/null +++ b/packages/network_info_plus/macos/network_info_plus.podspec @@ -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 = 'network_info_plus' + s.version = '0.0.1' + s.summary = 'No-op implementation of the macos network_info_plus to avoid build issues on macos' + s.description = <<-DESC + No-op implementation of the network_info_plus plugin to avoid build issues on macos. + https://github.com/flutter/flutter/issues/46618 + DESC + s.homepage = 'https://github.com/fluttercommunity/plus_plugins' + s.license = { :file => '../LICENSE' } + s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.public_header_files = 'Classes/**/*.h' + + s.platform = :osx + s.osx.deployment_target = '10.11' +end + diff --git a/packages/network_info_plus/pubspec.yaml b/packages/network_info_plus/pubspec.yaml new file mode 100644 index 0000000000..e507c45427 --- /dev/null +++ b/packages/network_info_plus/pubspec.yaml @@ -0,0 +1,41 @@ +name: network_info_plus +description: Flutter plugin for discovering network info. +version: 0.1.0 +homepage: https://plus.fluttercommunity.dev/ +repository: https://github.com/fluttercommunity/plus_plugins/tree/main/packages/ + +flutter: + plugin: + platforms: + android: + package: dev.fluttercommunity.plus.network_info + pluginClass: NetworkInfoPlusPlugin + ios: + pluginClass: FLTNetworkInfoPlusPlugin + linux: + default_package: network_info_plus_linux + macos: + default_package: network_info_plus_macos + +dependencies: + flutter: + sdk: flutter + meta: ^1.0.5 + network_info_plus_platform_interface: ^0.1.0 + network_info_plus_linux: ^0.1.0 + network_info_plus_macos: ^0.1.0 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_driver: + sdk: flutter + test: any + integration_test: ^0.9.1 + mockito: ^4.1.1 + plugin_platform_interface: ^1.0.0 + pedantic: ^1.9.2 + +environment: + sdk: ">=2.1.0 <3.0.0" + flutter: ">=1.12.13+hotfix.5 <2.0.0" diff --git a/packages/network_info_plus/test/network_info_test.dart b/packages/network_info_plus/test/network_info_test.dart new file mode 100644 index 0000000000..4570c3169a --- /dev/null +++ b/packages/network_info_plus/test/network_info_test.dart @@ -0,0 +1,85 @@ +// 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 'package:network_info_plus/network_info_plus.dart'; +import 'package:network_info_plus_platform_interface/network_info_plus_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import 'package:mockito/mockito.dart'; + +const String kWifiNameResult = '1337wifi'; +const String kWifiBSSIDResult = 'c0:ff:33:c0:d3:55'; +const String kWifiIpAddressResult = '127.0.0.1'; +const LocationAuthorizationStatus kRequestLocationResult = + LocationAuthorizationStatus.authorizedAlways; +const LocationAuthorizationStatus kGetLocationResult = + LocationAuthorizationStatus.authorizedAlways; + +void main() { + group('NetworkInfo', () { + NetworkInfo networkInfo; + MockNetworkInfoPlatform fakePlatform; + setUp(() async { + fakePlatform = MockNetworkInfoPlatform(); + NetworkInfoPlatform.instance = fakePlatform; + networkInfo = NetworkInfo(); + }); + + test('getWifiName', () async { + final result = await networkInfo.getWifiName(); + expect(result, kWifiNameResult); + }); + + test('getWifiBSSID', () async { + final result = await networkInfo.getWifiBSSID(); + expect(result, kWifiBSSIDResult); + }); + + test('getWifiIP', () async { + final result = await networkInfo.getWifiIP(); + expect(result, kWifiIpAddressResult); + }); + + test('requestLocationServiceAuthorization', () async { + final result = await networkInfo.requestLocationServiceAuthorization(); + expect(result, kRequestLocationResult); + }); + + test('getLocationServiceAuthorization', () async { + final result = await networkInfo.getLocationServiceAuthorization(); + expect(result, kRequestLocationResult); + }); + }); +} + +class MockNetworkInfoPlatform extends Mock + with MockPlatformInterfaceMixin + implements NetworkInfoPlatform { + @override + Future getWifiName() async { + return kWifiNameResult; + } + + @override + Future getWifiBSSID() async { + return kWifiBSSIDResult; + } + + @override + Future getWifiIP() async { + return kWifiIpAddressResult; + } + + @override + Future requestLocationServiceAuthorization({ + bool requestAlwaysLocationUsage = false, + }) async { + return kRequestLocationResult; + } + + @override + Future getLocationServiceAuthorization() async { + return kGetLocationResult; + } +} diff --git a/packages/network_info_plus_linux/.gitignore b/packages/network_info_plus_linux/.gitignore new file mode 100644 index 0000000000..88ce490e47 --- /dev/null +++ b/packages/network_info_plus_linux/.gitignore @@ -0,0 +1,47 @@ +.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 + +generated_plugin_registrant.dart +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m +GeneratedPluginRegistrant.java +GeneratedPluginRegistrant.swift +build/ +.flutter-plugins + +.project +.classpath +.settings diff --git a/packages/network_info_plus_linux/.metadata b/packages/network_info_plus_linux/.metadata new file mode 100644 index 0000000000..6b9d686e29 --- /dev/null +++ b/packages/network_info_plus_linux/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 34541c30735bc1086335e13d69a7e0acdc0538c5 + channel: master + +project_type: package diff --git a/packages/network_info_plus_linux/CHANGELOG.md b/packages/network_info_plus_linux/CHANGELOG.md new file mode 100644 index 0000000000..f7950bb58c --- /dev/null +++ b/packages/network_info_plus_linux/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.1.0 + +* Initial release for Linux. diff --git a/packages/network_info_plus_linux/LICENSE b/packages/network_info_plus_linux/LICENSE new file mode 100644 index 0000000000..0c91662b3f --- /dev/null +++ b/packages/network_info_plus_linux/LICENSE @@ -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. diff --git a/packages/network_info_plus_linux/README.md b/packages/network_info_plus_linux/README.md new file mode 100644 index 0000000000..2ae3411189 --- /dev/null +++ b/packages/network_info_plus_linux/README.md @@ -0,0 +1,12 @@ +# Network Info Plus Linux + +[![Flutter Community: network_info_plus_linux](https://fluttercommunity.dev/_github/header/network_info_plus_linux)](https://github.com/fluttercommunity/community) + +[![pub package](https://img.shields.io/pub/v/network_info_plus_linux.svg)](https://pub.dev/packages/network_info_plus_linux) + +The Linux implementation of [`network_info_plus`](https://pub.dev/packages/network_info_plus). + +## Usage + +This package is already included as part of the `network_info_plus` package dependency, and will +be included when using `network_info_plus` as normal. diff --git a/packages/network_info_plus_linux/lib/network_info_plus_linux.dart b/packages/network_info_plus_linux/lib/network_info_plus_linux.dart new file mode 100644 index 0000000000..d3eb2252e9 --- /dev/null +++ b/packages/network_info_plus_linux/lib/network_info_plus_linux.dart @@ -0,0 +1,8 @@ +/// The Linux implementation of `network_info_plus`. +library network_info_plus_linux; + +// network_info_plus_linux depends on dbus which uses FFI internally; export +// a stub for platforms that don't support FFI (e.g., web) to avoid having +// transitive dependencies break web compilation. +export 'src/network_info_stub.dart' + if (dart.library.ffi) 'src/network_info_real.dart'; diff --git a/packages/network_info_plus_linux/lib/src/network_info_real.dart b/packages/network_info_plus_linux/lib/src/network_info_real.dart new file mode 100644 index 0000000000..e50b59990f --- /dev/null +++ b/packages/network_info_plus_linux/lib/src/network_info_real.dart @@ -0,0 +1,78 @@ +import 'dart:async'; + +import 'package:network_info_plus_platform_interface/network_info_plus_platform_interface.dart'; +import 'package:meta/meta.dart'; + +import 'network_manager.dart'; + +// Used internally +// ignore_for_file: public_member_api_docs + +typedef _DeviceGetter = Future Function(NMDevice device); +typedef _ConnectionGetter = Future Function(NMConnection connection); + +@visibleForTesting +typedef NetworkManagerFactory = NetworkManager Function(); + +/// The Linux implementation of NetworkInfoPlatform. +class NetworkInfoLinux extends NetworkInfoPlatform { + /// Obtains the wifi name (SSID) of the connected network + @override + Future getWifiName() { + return _getConnectionValue((connection) => connection.getId()); + } + + /// Obtains the IP address of the connected wifi network + @override + Future getWifiIP() { + return _getDeviceValue((device) => device.getIp4()); + } + + /// Obtains the wifi BSSID of the connected network. + @override + Future getWifiBSSID() { + return _getDeviceValue((device) { + return device + .asWirelessDevice() + .then((wireless) => wireless?.getHwAddress()); + }); + } + + Future _getDeviceValue(_DeviceGetter getter) { + return _getConnectionValue((connection) { + return connection.createDevice().then((device) { + return device != null ? getter(device) : null; + }); + }); + } + + Future _getConnectionValue(_ConnectionGetter getter) { + return _ref().createConnection().then((connection) { + return connection != null ? getter(connection) : null; + }).whenComplete(_deref); + } + + int _refCount = 0; + NetworkManager _manager; + + NetworkManager _ref() { + _manager ??= createManager(); + ++_refCount; + return _manager; + } + + void _deref() { + // schedules an asynchronous disposal when the last reference is removed + if (--_refCount == 0) { + scheduleMicrotask(() { + if (_refCount == 0) { + _manager.dispose(); + _manager = null; + } + }); + } + } + + @visibleForTesting + NetworkManagerFactory createManager = () => NetworkManager.system(); +} diff --git a/packages/network_info_plus_linux/lib/src/network_info_stub.dart b/packages/network_info_plus_linux/lib/src/network_info_stub.dart new file mode 100644 index 0000000000..33a1420d5e --- /dev/null +++ b/packages/network_info_plus_linux/lib/src/network_info_stub.dart @@ -0,0 +1,16 @@ +import 'package:network_info_plus_platform_interface/network_info_plus_platform_interface.dart'; + +/// A stub implementation to satisfy compilation of multi-platform packages that +/// depend on network_info_plus_linux. This should never actually be created. +/// +/// Notably, because network_info_plus needs to manually register +/// network_info_plus_linux, anything with a transitive dependency on +/// network_info_plus will also depend on network_info_plus_linux, not just at +/// the pubspec level but the code level. +class NetworkInfoLinux extends NetworkInfoPlatform { + /// Errors on attempted instantiation of the stub. It exists only to satisfy + /// compile-time dependencies, and should never actually be created. + NetworkInfoLinux() { + assert(false); + } +} diff --git a/packages/network_info_plus_linux/lib/src/network_manager.dart b/packages/network_info_plus_linux/lib/src/network_manager.dart new file mode 100644 index 0000000000..38601baee4 --- /dev/null +++ b/packages/network_info_plus_linux/lib/src/network_manager.dart @@ -0,0 +1,123 @@ +import 'dart:async'; + +import 'package:dbus/dbus.dart'; + +// Used internally +// ignore_for_file: public_member_api_docs + +const _kNetworkManager = 'org.freedesktop.NetworkManager'; +const _kActiveConnection = _kNetworkManager + '.Connection.Active'; +const _kDevice = _kNetworkManager + '.Device'; +const _kWireless = _kDevice + '.Wireless'; + +const _kPath = '/org/freedesktop/NetworkManager'; +const _kType = 'PrimaryConnectionType'; + +class NetworkManager extends DBusRemoteObject { + NetworkManager(DBusClient client) + : super(client, _kNetworkManager, DBusObjectPath(_kPath)); + + factory NetworkManager.system() => NetworkManager(DBusClient.system()); + void dispose() => client?.close(); + + Future getPath() => _getString('PrimaryConnection', fallback: '/'); + Future getType() => _getString(_kType); + + Future _getString(String path, {String fallback = ''}) { + return getProperty(_kNetworkManager, path) + .then((value) => (value as DBusString).value) + .catchError((error) => print(error)) + .then((value) => value ?? fallback); + } + + Stream subscribeTypeChanged() { + return subscribePropertiesChanged() + .where((event) => event.changedProperties.containsKey(_kType)) + .map((event) => (event.changedProperties[_kType] as DBusString).value); + } + + Future createConnection() { + return getPath().then((path) => NMConnection.fromPath(client, path)); + } +} + +class NMConnection extends DBusRemoteObject { + NMConnection(DBusClient client, {DBusObjectPath path}) + : super(client, _kNetworkManager, path); + + factory NMConnection.fromPath(DBusClient client, String path) { + if (path == '/') return null; + return NMConnection(client, path: DBusObjectPath(path)); + } + + Future getId() { + return getProperty(_kActiveConnection, 'Id') + .then((value) => (value as DBusString).value) + .catchError((error) => print(error)) + .then((value) => value ?? ''); + } + + Future> getDevices() { + return getProperty(_kActiveConnection, 'Devices') + .then((value) => (value as DBusArray) + .children + .map((child) => (child as DBusObjectPath).value) + .toList()) + .catchError((error) => print(error)) + .then((value) => value ?? []); + } + + Future createDevice() { + return getDevices().then((devices) { + if (devices.isEmpty) return null; + return NMDevice.fromPath(client, devices.first); + }); + } +} + +enum NMDeviceType { unknown, ethernet, wifi } + +extension NMDeviceInt on int { + int byteAt(int i) => (this >> (i * 8)) & 0xff; + String toIp4() => '${byteAt(0)}.${byteAt(1)}.${byteAt(2)}.${byteAt(3)}'; + NMDeviceType toType() => NMDeviceType.values[this]; +} + +class NMDevice extends DBusRemoteObject { + NMDevice(DBusClient client, {DBusObjectPath path}) + : super(client, _kNetworkManager, path); + + factory NMDevice.fromPath(DBusClient client, String path) { + return NMDevice(client, path: DBusObjectPath(path)); + } + + Future getIp4() { + return getProperty(_kDevice, 'Ip4Address') + .then((value) => (value as DBusUint32).value.toIp4()) + .catchError((error) => print(error)); + } + + Future getType() { + return getProperty(_kDevice, 'DeviceType') + .then((value) => (value as DBusUint32).value.toType()) + .catchError((error) => print(error)); + } + + Future asWirelessDevice() { + return getType().then((type) { + if (type != NMDeviceType.wifi) return null; + return NMWirelessDevice(client, path: path); + }); + } +} + +class NMWirelessDevice extends DBusRemoteObject { + NMWirelessDevice(DBusClient client, {DBusObjectPath path}) + : super(client, _kNetworkManager, path); + + Future getHwAddress() { + return getProperty(_kWireless, 'HwAddress') + .then((value) => (value as DBusString).value) + .catchError((error) => print(error)); + } +} diff --git a/packages/network_info_plus_linux/pubspec.yaml b/packages/network_info_plus_linux/pubspec.yaml new file mode 100644 index 0000000000..8e53cd0920 --- /dev/null +++ b/packages/network_info_plus_linux/pubspec.yaml @@ -0,0 +1,29 @@ +name: network_info_plus_linux +description: Linux implementation of the network_info_plus plugin +homepage: https://plus.fluttercommunity.dev/ +repository: https://github.com/fluttercommunity/plus_plugins/tree/main/packages/ +version: 0.1.0 + +environment: + sdk: ">=2.7.0 <3.0.0" + flutter: ">=1.20.0" + +dependencies: + flutter: + sdk: flutter + network_info_plus_platform_interface: ^0.1.0 + dbus: ^0.1.0 + meta: ^1.2.3 + +dev_dependencies: + flutter_test: + sdk: flutter + mockito: ^4.1.2 + pedantic: ^1.9.2 + +flutter: + plugin: + platforms: + linux: + dartPluginClass: NetworkInfoLinux + pluginClass: none diff --git a/packages/network_info_plus_macos/.gitattributes b/packages/network_info_plus_macos/.gitattributes new file mode 100644 index 0000000000..31fda4bf1c --- /dev/null +++ b/packages/network_info_plus_macos/.gitattributes @@ -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 diff --git a/packages/network_info_plus_macos/.gitignore b/packages/network_info_plus_macos/.gitignore new file mode 100644 index 0000000000..88ce490e47 --- /dev/null +++ b/packages/network_info_plus_macos/.gitignore @@ -0,0 +1,47 @@ +.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 + +generated_plugin_registrant.dart +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m +GeneratedPluginRegistrant.java +GeneratedPluginRegistrant.swift +build/ +.flutter-plugins + +.project +.classpath +.settings diff --git a/packages/network_info_plus_macos/CHANGELOG.md b/packages/network_info_plus_macos/CHANGELOG.md new file mode 100644 index 0000000000..951a5a3f13 --- /dev/null +++ b/packages/network_info_plus_macos/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.1.0 + +- Initial release. diff --git a/packages/network_info_plus_macos/LICENSE b/packages/network_info_plus_macos/LICENSE new file mode 100644 index 0000000000..0c382ce171 --- /dev/null +++ b/packages/network_info_plus_macos/LICENSE @@ -0,0 +1,27 @@ +// Copyright 2019 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. diff --git a/packages/network_info_plus_macos/README.md b/packages/network_info_plus_macos/README.md new file mode 100644 index 0000000000..1030ea5c19 --- /dev/null +++ b/packages/network_info_plus_macos/README.md @@ -0,0 +1,12 @@ +# Network Info Plus macOS + +[![Flutter Community: network_info_plus_macos](https://fluttercommunity.dev/_github/header/network_info_plus_macos)](https://github.com/fluttercommunity/community) + +[![pub package](https://img.shields.io/pub/v/network_info_plus_macos.svg)](https://pub.dev/packages/network_info_plus_macos) + +The macOS implementation of [`network_info_plus`](https://pub.dev/packages/network_info_plus). + +## Usage + +This package is already included as part of the `network_info_plus` package dependency, and will +be included when using `network_info_plus` as normal. diff --git a/packages/network_info_plus_macos/lib/network_info_plus_macos.dart b/packages/network_info_plus_macos/lib/network_info_plus_macos.dart new file mode 100644 index 0000000000..ba7fc71daa --- /dev/null +++ b/packages/network_info_plus_macos/lib/network_info_plus_macos.dart @@ -0,0 +1,3 @@ +// Analyze will fail if there is no main.dart file. This file should +// be removed once an example app has been added to network_info_plus_macos. +// https://github.com/flutter/flutter/issues/51007 diff --git a/packages/network_info_plus_macos/macos/Classes/IPHelper.h b/packages/network_info_plus_macos/macos/Classes/IPHelper.h new file mode 100644 index 0000000000..5fef2b9721 --- /dev/null +++ b/packages/network_info_plus_macos/macos/Classes/IPHelper.h @@ -0,0 +1,51 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import + +#import "SystemConfiguration/CaptiveNetwork.h" + +#include +#include + +NSString* getWifiIP() { + NSString* address = @"error"; + struct ifaddrs* interfaces = NULL; + struct ifaddrs* temp_addr = NULL; + int success = 0; + + // Retrieve the current interfaces - returns 0 on success. + success = getifaddrs(&interfaces); + if (success == 0) { + // Loop through linked list of interfaces. + temp_addr = interfaces; + while (temp_addr != NULL) { + if (temp_addr->ifa_addr->sa_family == AF_INET) { + // Check if interface is en0 which is the wifi connection on the iPhone. + if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) { + // Get NSString from C String + address = [NSString + stringWithUTF8String:inet_ntoa(((struct sockaddr_in*)temp_addr->ifa_addr)->sin_addr)]; + } + } + + temp_addr = temp_addr->ifa_next; + } + } + + // Free memory + freeifaddrs(interfaces); + + return address; +} diff --git a/packages/network_info_plus_macos/macos/Classes/NetworkInfoPlusPlugin.swift b/packages/network_info_plus_macos/macos/Classes/NetworkInfoPlusPlugin.swift new file mode 100644 index 0000000000..45226789c2 --- /dev/null +++ b/packages/network_info_plus_macos/macos/Classes/NetworkInfoPlusPlugin.swift @@ -0,0 +1,48 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Cocoa +import CoreWLAN +import FlutterMacOS +import SystemConfiguration.CaptiveNetwork + +public class NetworkInfoPlusPlugin: NSObject, FlutterPlugin { + var cwinterface: CWInterface? + + public override init() { + cwinterface = CWWiFiClient.shared().interface() + } + + public static func register(with registrar: FlutterPluginRegistrar) { + let channel = FlutterMethodChannel( + name: "dev.fluttercommunity.plus/network_info", + binaryMessenger: registrar.messenger) + + let instance = NetworkInfoPlusPlugin() + registrar.addMethodCallDelegate(instance, channel: channel) + } + + public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + switch call.method { + case "wifiName": + result(cwinterface?.ssid()) + case "wifiBSSID": + result(cwinterface?.bssid()) + case "wifiIPAddress": + result(getWifiIP()) + default: + result(FlutterMethodNotImplemented) + } + } +} diff --git a/packages/network_info_plus_macos/macos/network_info_plus_macos.podspec b/packages/network_info_plus_macos/macos/network_info_plus_macos.podspec new file mode 100644 index 0000000000..15e50ed312 --- /dev/null +++ b/packages/network_info_plus_macos/macos/network_info_plus_macos.podspec @@ -0,0 +1,21 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# +Pod::Spec.new do |s| + s.name = 'network_info_plus_macos' + s.version = '0.0.1' + s.summary = 'Flutter plugin for checking network info' + s.description = <<-DESC + Desktop implementation of the network info plugin + DESC + s.homepage = 'https://github.com/fluttercommunity/plus_plugins' + s.license = { :type => 'BSD', :file => '../LICENSE' } + s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } + s.source = { :http => 'https://github.com/fluttercommunity/plus_plugins/tree/main/packages/network_info_plus_macos' } + s.source_files = 'Classes/**/*' + s.dependency 'FlutterMacOS' + s.dependency 'Reachability' + + s.platform = :osx + s.osx.deployment_target = '10.11' +end \ No newline at end of file diff --git a/packages/network_info_plus_macos/pubspec.yaml b/packages/network_info_plus_macos/pubspec.yaml new file mode 100644 index 0000000000..6569d847c5 --- /dev/null +++ b/packages/network_info_plus_macos/pubspec.yaml @@ -0,0 +1,20 @@ +name: network_info_plus_macos +description: macOS implementation of the network_info_plus plugin. +version: 0.1.0 +homepage: https://plus.fluttercommunity.dev/ +repository: https://github.com/fluttercommunity/plus_plugins/tree/main/packages/ + +flutter: + plugin: + platforms: + macos: + pluginClass: NetworkInfoPlusPlugin + +environment: + sdk: ">=2.1.0 <3.0.0" + flutter: '>=1.20.0' + +dependencies: + network_info_plus_platform_interface: ^0.1.0 + flutter: + sdk: flutter diff --git a/packages/network_info_plus_platform_interface/.gitattributes b/packages/network_info_plus_platform_interface/.gitattributes new file mode 100644 index 0000000000..31fda4bf1c --- /dev/null +++ b/packages/network_info_plus_platform_interface/.gitattributes @@ -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 diff --git a/packages/network_info_plus_platform_interface/.gitignore b/packages/network_info_plus_platform_interface/.gitignore new file mode 100644 index 0000000000..bfb8a70b52 --- /dev/null +++ b/packages/network_info_plus_platform_interface/.gitignore @@ -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 diff --git a/packages/network_info_plus_platform_interface/CHANGELOG.md b/packages/network_info_plus_platform_interface/CHANGELOG.md new file mode 100644 index 0000000000..951a5a3f13 --- /dev/null +++ b/packages/network_info_plus_platform_interface/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.1.0 + +- Initial release. diff --git a/packages/network_info_plus_platform_interface/LICENSE b/packages/network_info_plus_platform_interface/LICENSE new file mode 100644 index 0000000000..0c91662b3f --- /dev/null +++ b/packages/network_info_plus_platform_interface/LICENSE @@ -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. diff --git a/packages/network_info_plus_platform_interface/README.md b/packages/network_info_plus_platform_interface/README.md new file mode 100644 index 0000000000..686a1d09a7 --- /dev/null +++ b/packages/network_info_plus_platform_interface/README.md @@ -0,0 +1,12 @@ +# Network Info Plus Platform Interface + +[![Flutter Community: network_info_plus_platform_interface](https://fluttercommunity.dev/_github/header/network_info_plus_platform_interface)](https://github.com/fluttercommunity/community) + +[![pub package](https://img.shields.io/pub/v/network_info_plus_platform_interface.svg)](https://pub.dev/packages/network_info_plus_platform_interface) + +A common platform interface for [`network_info_plus`](https://pub.dev/packages/network_info_plus). + +## Usage + +This package is already included as part of the `network_info_plus` package dependency, and will +be included when using `network_info_plus` as normal. diff --git a/packages/network_info_plus_platform_interface/lib/network_info_plus_platform_interface.dart b/packages/network_info_plus_platform_interface/lib/network_info_plus_platform_interface.dart new file mode 100644 index 0000000000..2553bf06ae --- /dev/null +++ b/packages/network_info_plus_platform_interface/lib/network_info_plus_platform_interface.dart @@ -0,0 +1,68 @@ +// 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 'src/enums.dart'; +import 'src/method_channel_network_info.dart'; + +export 'src/enums.dart'; + +/// The interface that implementations of network_info must implement. +/// +/// Platform implementations should extend this class rather than implement it as `NetworkInfo` +/// 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 +/// [NetworkInfoPlatform] methods. +abstract class NetworkInfoPlatform extends PlatformInterface { + /// Constructs a NetworkInfoPlatform. + NetworkInfoPlatform() : super(token: _token); + + static final Object _token = Object(); + + static NetworkInfoPlatform _instance = MethodChannelNetworkInfo(); + + /// The default instance of [NetworkInfoPlatform] to use. + /// + /// Defaults to [MethodChannelNetworkInfo]. + static NetworkInfoPlatform get instance => _instance; + + /// Platform-specific plugins should set this with their own platform-specific + /// class that extends [NetworkInfoPlatform] when they register themselves. + static set instance(NetworkInfoPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + _instance = instance; + } + + /// Obtains the wifi name (SSID) of the connected network + Future getWifiName() { + throw UnimplementedError('getWifiName() has not been implemented.'); + } + + /// Obtains the wifi BSSID of the connected network. + Future getWifiBSSID() { + throw UnimplementedError('getWifiBSSID() has not been implemented.'); + } + + /// Obtains the IP address of the connected wifi network + Future getWifiIP() { + throw UnimplementedError('getWifiIP() has not been implemented.'); + } + + /// Request to authorize the location service (Only on iOS). + Future requestLocationServiceAuthorization( + {bool requestAlwaysLocationUsage = false}) { + throw UnimplementedError( + 'requestLocationServiceAuthorization() has not been implemented.'); + } + + /// Get the current location service authorization (Only on iOS). + Future getLocationServiceAuthorization() { + throw UnimplementedError( + 'getLocationServiceAuthorization() has not been implemented.'); + } +} diff --git a/packages/network_info_plus_platform_interface/lib/src/enums.dart b/packages/network_info_plus_platform_interface/lib/src/enums.dart new file mode 100644 index 0000000000..8cd7abaf25 --- /dev/null +++ b/packages/network_info_plus_platform_interface/lib/src/enums.dart @@ -0,0 +1,20 @@ +/// The status of the location service authorization. +enum LocationAuthorizationStatus { + /// The authorization of the location service is not determined. + notDetermined, + + /// This app is not authorized to use location. + restricted, + + /// User explicitly denied the location service. + denied, + + /// User authorized the app to access the location at any time. + authorizedAlways, + + /// User authorized the app to access the location when the app is visible to them. + authorizedWhenInUse, + + /// Status unknown. + unknown +} diff --git a/packages/network_info_plus_platform_interface/lib/src/method_channel_network_info.dart b/packages/network_info_plus_platform_interface/lib/src/method_channel_network_info.dart new file mode 100644 index 0000000000..a001ec3a16 --- /dev/null +++ b/packages/network_info_plus_platform_interface/lib/src/method_channel_network_info.dart @@ -0,0 +1,57 @@ +// 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:network_info_plus_platform_interface/network_info_plus_platform_interface.dart'; +import 'package:flutter/services.dart'; +import 'package:meta/meta.dart'; + +import 'utils.dart'; + +/// An implementation of [NetworkInfoPlatform] that uses method channels. +class MethodChannelNetworkInfo extends NetworkInfoPlatform { + /// The method channel used to interact with the native platform. + @visibleForTesting + MethodChannel methodChannel = + MethodChannel('dev.fluttercommunity.plus/network_info'); + + @override + Future getWifiName() async { + var wifiName = await methodChannel.invokeMethod('wifiName'); + // as Android might return , uniforming result + // our iOS implementation will return null + if (wifiName == '') { + wifiName = null; + } + return wifiName; + } + + @override + Future getWifiBSSID() { + return methodChannel.invokeMethod('wifiBSSID'); + } + + @override + Future getWifiIP() { + return methodChannel.invokeMethod('wifiIPAddress'); + } + + @override + Future requestLocationServiceAuthorization({ + bool requestAlwaysLocationUsage = false, + }) { + return methodChannel.invokeMethod( + 'requestLocationServiceAuthorization', [ + requestAlwaysLocationUsage + ]).then(parseLocationAuthorizationStatus); + } + + @override + Future getLocationServiceAuthorization() { + return methodChannel + .invokeMethod('getLocationServiceAuthorization') + .then(parseLocationAuthorizationStatus); + } +} diff --git a/packages/network_info_plus_platform_interface/lib/src/utils.dart b/packages/network_info_plus_platform_interface/lib/src/utils.dart new file mode 100644 index 0000000000..2dfac1860a --- /dev/null +++ b/packages/network_info_plus_platform_interface/lib/src/utils.dart @@ -0,0 +1,19 @@ +import 'package:network_info_plus_platform_interface/network_info_plus_platform_interface.dart'; + +/// Convert a String to a LocationAuthorizationStatus value. +LocationAuthorizationStatus parseLocationAuthorizationStatus(String result) { + switch (result) { + case 'notDetermined': + return LocationAuthorizationStatus.notDetermined; + case 'restricted': + return LocationAuthorizationStatus.restricted; + case 'denied': + return LocationAuthorizationStatus.denied; + case 'authorizedAlways': + return LocationAuthorizationStatus.authorizedAlways; + case 'authorizedWhenInUse': + return LocationAuthorizationStatus.authorizedWhenInUse; + default: + return LocationAuthorizationStatus.unknown; + } +} diff --git a/packages/network_info_plus_platform_interface/pubspec.yaml b/packages/network_info_plus_platform_interface/pubspec.yaml new file mode 100644 index 0000000000..fae64b2bd3 --- /dev/null +++ b/packages/network_info_plus_platform_interface/pubspec.yaml @@ -0,0 +1,20 @@ +name: network_info_plus_platform_interface +description: A common platform interface for the network_info_plus plugin. +version: 0.1.0 +homepage: https://plus.fluttercommunity.dev/ +repository: https://github.com/fluttercommunity/plus_plugins/tree/main/packages/ + +dependencies: + flutter: + sdk: flutter + meta: ^1.0.5 + plugin_platform_interface: ^1.0.1 + +dev_dependencies: + flutter_test: + sdk: flutter + pedantic: ^1.9.2 + +environment: + sdk: ">=2.1.0 <3.0.0" + flutter: ">=1.12.13+hotfix.5 <2.0.0" diff --git a/packages/network_info_plus_platform_interface/test/method_channel_network_info_test.dart b/packages/network_info_plus_platform_interface/test/method_channel_network_info_test.dart new file mode 100644 index 0000000000..cc75723813 --- /dev/null +++ b/packages/network_info_plus_platform_interface/test/method_channel_network_info_test.dart @@ -0,0 +1,113 @@ +// 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 'package:network_info_plus_platform_interface/network_info_plus_platform_interface.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:network_info_plus_platform_interface/src/method_channel_network_info.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('$MethodChannelNetworkInfo', () { + final log = []; + MethodChannelNetworkInfo methodChannelNetworkInfo; + + setUp(() async { + methodChannelNetworkInfo = MethodChannelNetworkInfo(); + + methodChannelNetworkInfo.methodChannel + .setMockMethodCallHandler((MethodCall methodCall) async { + log.add(methodCall); + switch (methodCall.method) { + case 'wifiName': + return '1337wifi'; + case 'wifiBSSID': + return 'c0:ff:33:c0:d3:55'; + case 'wifiIPAddress': + return '127.0.0.1'; + case 'requestLocationServiceAuthorization': + return 'authorizedAlways'; + case 'getLocationServiceAuthorization': + return 'authorizedAlways'; + default: + return null; + } + }); + log.clear(); + }); + + test('getWifiName', () async { + final result = await methodChannelNetworkInfo.getWifiName(); + expect(result, '1337wifi'); + expect( + log, + [ + isMethodCall( + 'wifiName', + arguments: null, + ), + ], + ); + }); + + test('getWifiBSSID', () async { + final result = await methodChannelNetworkInfo.getWifiBSSID(); + expect(result, 'c0:ff:33:c0:d3:55'); + expect( + log, + [ + isMethodCall( + 'wifiBSSID', + arguments: null, + ), + ], + ); + }); + + test('getWifiIP', () async { + final result = await methodChannelNetworkInfo.getWifiIP(); + expect(result, '127.0.0.1'); + expect( + log, + [ + isMethodCall( + 'wifiIPAddress', + arguments: null, + ), + ], + ); + }); + + test('requestLocationServiceAuthorization', () async { + final result = + await methodChannelNetworkInfo.requestLocationServiceAuthorization(); + expect(result, LocationAuthorizationStatus.authorizedAlways); + expect( + log, + [ + isMethodCall( + 'requestLocationServiceAuthorization', + arguments: [false], + ), + ], + ); + }); + + test('getLocationServiceAuthorization', () async { + final result = + await methodChannelNetworkInfo.getLocationServiceAuthorization(); + expect(result, LocationAuthorizationStatus.authorizedAlways); + expect( + log, + [ + isMethodCall( + 'getLocationServiceAuthorization', + arguments: null, + ), + ], + ); + }); + }); +}