diff --git a/.gitignore b/.gitignore
index 0f3e480..c8bc461 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,5 +6,12 @@
build/
+coverage/
+
+# IntelliJ related
.idea/
-.vscode/
\ No newline at end of file
+!.idea/codeStyleConfig.xml
+
+# Visual Studio Code related
+.vscode/
+!/.vscode/settings.json
diff --git a/.idea/codeStyleConfig.xml b/.idea/codeStyleConfig.xml
new file mode 100644
index 0000000..673acd8
--- /dev/null
+++ b/.idea/codeStyleConfig.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..391e560
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,9 @@
+{
+ "[dart]": {
+ "editor.rulers": [
+ 100
+ ],
+ "editor.formatOnSave": true
+ },
+ "dart.lineLength": 100
+}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9809846..7dbb2ff 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,23 +1,30 @@
+## 0.2.0
+
+* update SDK constraints.
+* updates documentation.
+* adds tests.
+* adds .vscode and .idea IDE configuration settings.
+
## 0.1.14
-* fix MissingPluginException on Android。
+* fix MissingPluginException on Android.
## 0.1.13
-* dartfrmt fix。
+* dartfrmt fix.
## 0.1.12
-* bug fix。
+* bug fix.
## 0.1.11
-* added example and enhanced null-safety on proxy set。
+* added example and enhanced null-safety on proxy set.
## 0.1.10
-* enhance readme。
+* enhance readme.
## 0.1.9
-* add example。
+* add example.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..08449f8
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,25 @@
+# Contribution Guide
+
+Feel free to contribute to this project. If you want to contribute, please follow the steps below:
+
+1. Fork the project
+2. Commit your changes
+3. Create a pull request
+
+Please make sure that your code is well tested.
+
+## Running Tests 🧪
+
+Install lcov:
+
+```sh
+brew install lcov
+```
+
+Run and open the report using the following command:
+
+```sh
+flutter test --coverage --test-randomize-ordering-seed random && genhtml coverage/lcov.info -o coverage/ && open coverage/index.html
+```
+
+Everything should be green! 🎉
diff --git a/analysis_options.yaml b/analysis_options.yaml
new file mode 100644
index 0000000..f17506e
--- /dev/null
+++ b/analysis_options.yaml
@@ -0,0 +1,8 @@
+include: package:very_good_analysis/analysis_options.yaml
+
+formatter:
+ page_width: 100
+
+linter:
+ rules:
+ lines_longer_than_80_chars: false
\ No newline at end of file
diff --git a/android/build.gradle b/android/build.gradle
index ba1187e..47564ac 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -1,31 +1,27 @@
-group 'com.victorblaess.native_flutter_proxy'
-version '1.0-SNAPSHOT'
-
-buildscript {
- ext.kotlin_version = '1.6.10'
- repositories {
- google()
- jcenter()
- }
-
- dependencies {
- classpath 'com.android.tools.build:gradle:3.5.0'
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- }
+plugins {
+ id 'com.android.library'
+ id 'org.jetbrains.kotlin.android'
}
-rootProject.allprojects {
+allprojects {
repositories {
+ gradlePluginPortal()
google()
- jcenter()
+ mavenCentral()
}
}
-apply plugin: 'com.android.library'
-apply plugin: 'kotlin-android'
+group 'com.victorblaess.native_flutter_proxy'
android {
- compileSdkVersion 28
+
+ namespace 'com.victorblaess.native_flutter_proxy'
+ compileSdk 33
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_17
+ targetCompatibility JavaVersion.VERSION_17
+ }
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
@@ -40,5 +36,6 @@ android {
}
dependencies {
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
-}
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$KotlinVersion"
+ implementation "org.jetbrains.kotlin:kotlin-reflect:$KotlinVersion"
+}
\ No newline at end of file
diff --git a/android/gradle.properties b/android/gradle.properties
index 38c8d45..236fe15 100644
--- a/android/gradle.properties
+++ b/android/gradle.properties
@@ -1,4 +1,5 @@
org.gradle.jvmargs=-Xmx1536M
-android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true
+AGPVersion=7.4.2
+KotlinVersion=1.8.22
\ No newline at end of file
diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..d64cd49
Binary files /dev/null and b/android/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
index 01a286e..1af9e09 100644
--- a/android/gradle/wrapper/gradle-wrapper.properties
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
diff --git a/android/gradlew b/android/gradlew
new file mode 100755
index 0000000..1aa94a4
--- /dev/null
+++ b/android/gradlew
@@ -0,0 +1,249 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# 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
+#
+# https://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.
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/android/gradlew.bat b/android/gradlew.bat
new file mode 100644
index 0000000..6689b85
--- /dev/null
+++ b/android/gradlew.bat
@@ -0,0 +1,92 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/android/settings.gradle b/android/settings.gradle
index 2922dd1..f5ac3e8 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -1 +1,13 @@
-rootProject.name = 'native_flutter_proxy'
+pluginManagement {
+ repositories {
+ gradlePluginPortal()
+ google()
+ mavenCentral()
+ }
+ plugins {
+ id 'com.android.library' version "${AGPVersion}"
+ id 'org.jetbrains.kotlin.android' version "${KotlinVersion}"
+ }
+}
+
+rootProject.name = 'native_flutter_proxy'
\ No newline at end of file
diff --git a/android/src/main/kotlin/com/victorblaess/native_flutter_proxy/FlutterProxyPlugin.kt b/android/src/main/kotlin/com/victorblaess/native_flutter_proxy/FlutterProxyPlugin.kt
index e7d8e26..ca412ea 100644
--- a/android/src/main/kotlin/com/victorblaess/native_flutter_proxy/FlutterProxyPlugin.kt
+++ b/android/src/main/kotlin/com/victorblaess/native_flutter_proxy/FlutterProxyPlugin.kt
@@ -9,12 +9,23 @@ import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry.Registrar
import java.util.*
-/** FlutterProxyPlugin */
+/**
+ * FlutterProxyPlugin
+ *
+ * Este plugin de Flutter se utiliza para obtener la configuración del proxy del sistema.
+ * Implementa las interfaces FlutterPlugin y MethodCallHandler.
+ */
public class FlutterProxyPlugin : FlutterPlugin, MethodCallHandler {
+ // Canal de método para la comunicación entre Flutter y el código nativo.
private var mMethodChannel: MethodChannel? = null;
companion object {
+ /**
+ * Método estático para registrar el plugin con un registrar.
+ *
+ * @param registrar El registrar que se utiliza para registrar el plugin.
+ */
@JvmStatic
fun registerWith(registrar: Registrar) {
val instance = FlutterProxyPlugin()
@@ -22,21 +33,42 @@ public class FlutterProxyPlugin : FlutterPlugin, MethodCallHandler {
}
}
+ /**
+ * Método privado para adjuntar el plugin al motor de Flutter.
+ *
+ * @param messenger El mensajero binario utilizado para la comunicación.
+ */
private fun onAttachedToEngine(messenger: BinaryMessenger) {
mMethodChannel = MethodChannel(messenger, "native_flutter_proxy")
mMethodChannel!!.setMethodCallHandler(this)
}
+ /**
+ * Método llamado cuando el plugin se adjunta al motor de Flutter.
+ *
+ * @param binding El enlace del plugin de Flutter.
+ */
override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
mMethodChannel = MethodChannel(binding.binaryMessenger, "native_flutter_proxy")
mMethodChannel!!.setMethodCallHandler(this)
}
+ /**
+ * Método llamado cuando el plugin se desadjunta del motor de Flutter.
+ *
+ * @param binding El enlace del plugin de Flutter.
+ */
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
mMethodChannel!!.setMethodCallHandler(null)
mMethodChannel = null
}
+ /**
+ * Método llamado cuando se realiza una llamada de método desde Flutter.
+ *
+ * @param call La llamada de método.
+ * @param result El resultado de la llamada de método.
+ */
override fun onMethodCall(call: MethodCall, result: Result) {
if (call.method == "getProxySetting") {
result.success(getProxySetting())
@@ -45,6 +77,11 @@ public class FlutterProxyPlugin : FlutterPlugin, MethodCallHandler {
}
}
+ /**
+ * Método privado para obtener la configuración del proxy del sistema.
+ *
+ * @return Un mapa con la configuración del proxy.
+ */
private fun getProxySetting(): Any? {
val map = LinkedHashMap()
map["host"] = System.getProperty("http.proxyHost")
@@ -52,4 +89,4 @@ public class FlutterProxyPlugin : FlutterPlugin, MethodCallHandler {
return map
}
-}
+}
\ No newline at end of file
diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml
new file mode 100644
index 0000000..fac60e2
--- /dev/null
+++ b/example/analysis_options.yaml
@@ -0,0 +1 @@
+include: ../../analysis_options.yaml
\ No newline at end of file
diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle
index 937a7a6..69135ec 100644
--- a/example/android/app/build.gradle
+++ b/example/android/app/build.gradle
@@ -1,3 +1,9 @@
+plugins {
+ id "com.android.application"
+ id "kotlin-android"
+ id "dev.flutter.flutter-gradle-plugin"
+}
+
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
@@ -21,12 +27,13 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
-
android {
- compileSdkVersion 30
+ compileSdkVersion 34
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_17
+ targetCompatibility JavaVersion.VERSION_17
+ }
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
@@ -35,7 +42,7 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.veebee.proxy.example.example"
- minSdkVersion 16
+ minSdkVersion flutter.minSdkVersion
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
@@ -55,5 +62,5 @@ flutter {
}
dependencies {
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
-}
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$KotlinVersion"
+}
\ No newline at end of file
diff --git a/example/android/build.gradle b/example/android/build.gradle
index 9b6ed06..d15fe59 100644
--- a/example/android/build.gradle
+++ b/example/android/build.gradle
@@ -1,29 +1,19 @@
-buildscript {
- ext.kotlin_version = '1.3.50'
- repositories {
- google()
- jcenter()
- }
-
- dependencies {
- classpath 'com.android.tools.build:gradle:4.1.0'
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- }
-}
-
allprojects {
repositories {
+ gradlePluginPortal()
google()
- jcenter()
+ mavenCentral()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
+}
+subprojects {
project.evaluationDependsOn(':app')
}
-task clean(type: Delete) {
+tasks.register("clean", Delete) {
delete rootProject.buildDir
-}
+}
\ No newline at end of file
diff --git a/example/android/gradle.properties b/example/android/gradle.properties
index 94adc3a..236fe15 100644
--- a/example/android/gradle.properties
+++ b/example/android/gradle.properties
@@ -1,3 +1,5 @@
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
+AGPVersion=7.4.2
+KotlinVersion=1.8.22
\ No newline at end of file
diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties
index bc6a58a..25406ab 100644
--- a/example/android/gradle/wrapper/gradle-wrapper.properties
+++ b/example/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
+zipStoreBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
\ No newline at end of file
diff --git a/example/android/settings.gradle b/example/android/settings.gradle
index 44e62bc..7ef8a88 100644
--- a/example/android/settings.gradle
+++ b/example/android/settings.gradle
@@ -1,11 +1,25 @@
-include ':app'
+pluginManagement {
+ def flutterSdkPath = {
+ def properties = new Properties()
+ file("local.properties").withInputStream { properties.load(it) }
+ def flutterSdkPath = properties.getProperty("flutter.sdk")
+ assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+ return flutterSdkPath
+ }()
-def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
-def properties = new Properties()
+ includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
-assert localPropertiesFile.exists()
-localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
-def flutterSdkPath = properties.getProperty("flutter.sdk")
-assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
-apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
+plugins {
+ id "dev.flutter.flutter-plugin-loader" version "1.0.0"
+ id "com.android.application" version "${AGPVersion}" apply false
+ id "org.jetbrains.kotlin.android" version "${KotlinVersion}" apply false
+}
+
+include ":app"
\ No newline at end of file
diff --git a/example/lib/main.dart b/example/lib/main.dart
index 8bd8364..3b200a7 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -1,125 +1,71 @@
+// ignore_for_file: unused_local_variable
+
import 'package:flutter/material.dart';
-import 'package:native_flutter_proxy/native_proxy_reader.dart';
-import 'package:native_flutter_proxy/custom_proxy.dart';
+import 'package:native_flutter_proxy/native_flutter_proxy.dart';
void main() async {
+ // Ensure that the WidgetsBinding is initialized before calling the
+ // [NativeProxyReader.proxySetting] method.
WidgetsFlutterBinding.ensureInitialized();
- bool enabled = false;
+ // Get the proxy settings from the native platform.
+ var enabled = false;
String? host;
int? port;
try {
- ProxySetting settings = await NativeProxyReader.proxySetting;
+ final settings = await NativeProxyReader.proxySetting;
enabled = settings.enabled;
host = settings.host;
port = settings.port;
} catch (e) {
print(e);
}
+
+ // Enable the proxy if it is enabled and the host is not null.
if (enabled && host != null) {
- final proxy = CustomProxy(ipAddress: host, port: port);
- proxy.enable();
- print("proxy enabled");
+ final proxy = CustomProxy(ipAddress: host, port: port).enable();
+ debugPrint('proxy enabled');
}
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(
- // This is the theme of your application.
- //
- // Try running your application with "flutter run". You'll see the
- // application has a blue toolbar. Then, without quitting the app, try
- // changing the primarySwatch below to Colors.green and then invoke
- // "hot reload" (press "r" in the console where you ran "flutter run",
- // or simply save your changes to "hot reload" in a Flutter IDE).
- // Notice that the counter didn't reset back to zero; the application
- // is not restarted.
- primarySwatch: Colors.blue,
- ),
+ theme: ThemeData(primarySwatch: Colors.blue),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
- MyHomePage({Key? key, required this.title}) : super(key: key);
-
- // This widget is the home page of your application. It is stateful, meaning
- // that it has a State object (defined below) that contains fields that affect
- // how it looks.
-
- // This class is the configuration for the state. It holds the values (in this
- // case the title) provided by the parent (in this case the App widget) and
- // used by the build method of the State. Fields in a Widget subclass are
- // always marked "final".
-
+ MyHomePage({super.key, required this.title});
final String title;
@override
- _MyHomePageState createState() => _MyHomePageState();
+ State createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
- int _counter = 0;
+ int counter = 0;
- void _incrementCounter() {
- setState(() {
- // This call to setState tells the Flutter framework that something has
- // changed in this State, which causes it to rerun the build method below
- // so that the display can reflect the updated values. If we changed
- // _counter without calling setState(), then the build method would not be
- // called again, and so nothing would appear to happen.
- _counter++;
- });
- }
+ void _incrementCounter() => setState(() => counter++);
@override
Widget build(BuildContext context) {
- // This method is rerun every time setState is called, for instance as done
- // by the _incrementCounter method above.
- //
- // The Flutter framework has been optimized to make rerunning build methods
- // fast, so that you can just rebuild anything that needs updating rather
- // than having to individually change instances of widgets.
return Scaffold(
- appBar: AppBar(
- // Here we take the value from the MyHomePage object that was created by
- // the App.build method, and use it to set our appbar title.
- title: Text(widget.title),
- ),
+ appBar: AppBar(title: Text(widget.title)),
body: Center(
- // Center is a layout widget. It takes a single child and positions it
- // in the middle of the parent.
child: Column(
- // Column is also a layout widget. It takes a list of children and
- // arranges them vertically. By default, it sizes itself to fit its
- // children horizontally, and tries to be as tall as its parent.
- //
- // Invoke "debug painting" (press "p" in the console, choose the
- // "Toggle Debug Paint" action from the Flutter Inspector in Android
- // Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
- // to see the wireframe for each widget.
- //
- // Column has various properties to control how it sizes itself and
- // how it positions its children. Here we use mainAxisAlignment to
- // center the children vertically; the main axis here is the vertical
- // axis because Columns are vertical (the cross axis would be
- // horizontal).
mainAxisAlignment: MainAxisAlignment.center,
- children: [
+ children: [
+ Text('You have pushed the button this many times:'),
Text(
- 'You have pushed the button this many times:',
- ),
- Text(
- '$_counter',
- style: Theme.of(context).textTheme.headline4,
+ '$counter',
+ style: Theme.of(context).textTheme.headlineMedium,
),
],
),
@@ -128,7 +74,7 @@ class _MyHomePageState extends State {
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
- ), // This trailing comma makes auto-formatting nicer for build methods.
+ ),
);
}
}
diff --git a/example/pubspec.lock b/example/pubspec.lock
index aab9531..3d9ddb2 100644
--- a/example/pubspec.lock
+++ b/example/pubspec.lock
@@ -1,161 +1,62 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
- async:
- dependency: transitive
- description:
- name: async
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.8.1"
- boolean_selector:
- dependency: transitive
- description:
- name: boolean_selector
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.1.0"
characters:
dependency: transitive
description:
name: characters
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.1.0"
- charcode:
- dependency: transitive
- description:
- name: charcode
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.3.1"
- clock:
- dependency: transitive
- description:
- name: clock
- url: "https://pub.dartlang.org"
+ sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
+ url: "https://pub.dev"
source: hosted
- version: "1.1.0"
+ version: "1.4.0"
collection:
dependency: transitive
description:
name: collection
- url: "https://pub.dartlang.org"
+ sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
+ url: "https://pub.dev"
source: hosted
- version: "1.15.0"
- cupertino_icons:
- dependency: "direct main"
- description:
- name: cupertino_icons
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.3"
- fake_async:
- dependency: transitive
- description:
- name: fake_async
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.2.0"
+ version: "1.19.1"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
- flutter_test:
- dependency: "direct dev"
- description: flutter
- source: sdk
- version: "0.0.0"
- matcher:
+ material_color_utilities:
dependency: transitive
description:
- name: matcher
- url: "https://pub.dartlang.org"
+ name: material_color_utilities
+ sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
+ url: "https://pub.dev"
source: hosted
- version: "0.12.10"
+ version: "0.11.1"
meta:
dependency: transitive
description:
name: meta
- url: "https://pub.dartlang.org"
+ sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
+ url: "https://pub.dev"
source: hosted
- version: "1.7.0"
+ version: "1.16.0"
native_flutter_proxy:
- dependency: "direct dev"
+ dependency: "direct main"
description:
path: ".."
relative: true
source: path
- version: "0.1.13"
- path:
- dependency: transitive
- description:
- name: path
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.8.0"
+ version: "0.2.0"
sky_engine:
dependency: transitive
description: flutter
source: sdk
- version: "0.0.99"
- source_span:
- dependency: transitive
- description:
- name: source_span
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.8.1"
- stack_trace:
- dependency: transitive
- description:
- name: stack_trace
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.10.0"
- stream_channel:
- dependency: transitive
- description:
- name: stream_channel
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.1.0"
- string_scanner:
- dependency: transitive
- description:
- name: string_scanner
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.1.0"
- term_glyph:
- dependency: transitive
- description:
- name: term_glyph
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.2.0"
- test_api:
- dependency: transitive
- description:
- name: test_api
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.4.2"
- typed_data:
- dependency: transitive
- description:
- name: typed_data
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.3.0"
+ version: "0.0.0"
vector_math:
dependency: transitive
description:
name: vector_math
- url: "https://pub.dartlang.org"
+ sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.0"
+ version: "2.1.4"
sdks:
- dart: ">=2.12.0 <3.0.0"
- flutter: ">=1.12.0"
\ No newline at end of file
+ dart: ">=3.7.0-0 <4.0.0"
diff --git a/example/pubspec.yaml b/example/pubspec.yaml
index 3427922..680bb4d 100644
--- a/example/pubspec.yaml
+++ b/example/pubspec.yaml
@@ -1,78 +1,15 @@
name: example
description: A new Flutter project.
-
-# The following line prevents the package from being accidentally published to
-# pub.dev using `pub publish`. This is preferred for private packages.
-publish_to: 'none' # Remove this line if you wish to publish to pub.dev
-
-# The following defines the version and build number for your application.
-# A version number is three numbers separated by dots, like 1.2.43
-# followed by an optional build number separated by a +.
-# Both the version and the builder number may be overridden in flutter
-# build by specifying --build-name and --build-number, respectively.
-# In Android, build-name is used as versionName while build-number used as versionCode.
-# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
-# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
-# Read more about iOS versioning at
-# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
+publish_to: "none"
version: 1.0.0+1
environment:
- sdk: ">=2.12.0 <3.0.0"
+ sdk: ">=3.0.0 <4.0.0"
dependencies:
flutter:
sdk: flutter
+ native_flutter_proxy: ^0.2.0
-
- # The following adds the Cupertino Icons font to your application.
- # Use with the CupertinoIcons class for iOS style icons.
- cupertino_icons: ^1.0.2
-
-dev_dependencies:
- flutter_test:
- sdk: flutter
- native_flutter_proxy:
- path: ../
-
-# For information on the generic Dart part of this file, see the
-# following page: https://dart.dev/tools/pub/pubspec
-
-# The following section is specific to Flutter.
flutter:
-
- # The following line ensures that the Material Icons font is
- # included with your application, so that you can use the icons in
- # the material Icons class.
uses-material-design: true
-
- # To add assets to your application, add an assets section, like this:
- # assets:
- # - images/a_dot_burr.jpeg
- # - images/a_dot_ham.jpeg
-
- # An image asset can refer to one or more resolution-specific "variants", see
- # https://flutter.dev/assets-and-images/#resolution-aware.
-
- # For details regarding adding assets from package dependencies, see
- # https://flutter.dev/assets-and-images/#from-packages
-
- # To add custom fonts to your application, add a fonts section here,
- # in this "flutter" section. Each entry in this list should have a
- # "family" key with the font family name, and a "fonts" key with a
- # list giving the asset and other descriptors for the font. For
- # example:
- # fonts:
- # - family: Schyler
- # fonts:
- # - asset: fonts/Schyler-Regular.ttf
- # - asset: fonts/Schyler-Italic.ttf
- # style: italic
- # - family: Trajan Pro
- # fonts:
- # - asset: fonts/TrajanPro.ttf
- # - asset: fonts/TrajanPro_Bold.ttf
- # weight: 700
- #
- # For details regarding fonts from package dependencies,
- # see https://flutter.dev/custom-fonts/#from-packages
\ No newline at end of file
diff --git a/example/pubspec_overrides.yaml b/example/pubspec_overrides.yaml
new file mode 100644
index 0000000..e817a71
--- /dev/null
+++ b/example/pubspec_overrides.yaml
@@ -0,0 +1,3 @@
+dependency_overrides:
+ native_flutter_proxy:
+ path: ../
\ No newline at end of file
diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart
deleted file mode 100644
index 747db1d..0000000
--- a/example/test/widget_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// This is a basic Flutter widget test.
-//
-// To perform an interaction with a widget in your test, use the WidgetTester
-// utility that Flutter provides. For example, you can send tap and scroll
-// gestures. You can also use WidgetTester to find child widgets in the widget
-// tree, read text, and verify that the values of widget properties are correct.
-
-import 'package:flutter/material.dart';
-import 'package:flutter_test/flutter_test.dart';
-
-import 'package:example/main.dart';
-
-void main() {
- testWidgets('Counter increments smoke test', (WidgetTester tester) async {
- // Build our app and trigger a frame.
- await tester.pumpWidget(MyApp());
-
- // Verify that our counter starts at 0.
- expect(find.text('0'), findsOneWidget);
- expect(find.text('1'), findsNothing);
-
- // Tap the '+' icon and trigger a frame.
- await tester.tap(find.byIcon(Icons.add));
- await tester.pump();
-
- // Verify that our counter has incremented.
- expect(find.text('0'), findsNothing);
- expect(find.text('1'), findsOneWidget);
- });
-}
diff --git a/ios/Classes/FlutterProxyPlugin.h b/ios/Classes/FlutterProxyPlugin.h
index 909e6bc..f4a3e69 100644
--- a/ios/Classes/FlutterProxyPlugin.h
+++ b/ios/Classes/FlutterProxyPlugin.h
@@ -1,4 +1,11 @@
#import
-@interface FlutterProxyPlugin : NSObject
-@end
+/**
+ * @class FlutterProxyPlugin
+ * @brief A plugin class for handling proxy settings in Flutter.
+ *
+ * This class serves as an interface for the Flutter plugin, allowing
+ * the registration of the plugin with the Flutter engine.
+ */
+@interface FlutterProxyPlugin : NSObject
+@end
\ No newline at end of file
diff --git a/ios/Classes/FlutterProxyPlugin.m b/ios/Classes/FlutterProxyPlugin.m
index 2d67deb..f725fd1 100644
--- a/ios/Classes/FlutterProxyPlugin.m
+++ b/ios/Classes/FlutterProxyPlugin.m
@@ -8,8 +8,21 @@
#import "native_flutter_proxy-Swift.h"
#endif
+/**
+ * @class FlutterProxyPlugin
+ * @brief An Objective-C wrapper for the Swift Flutter plugin.
+ *
+ * This class registers the Swift implementation of the plugin with the Flutter engine.
+ */
@implementation FlutterProxyPlugin
+
+/**
+ * Registers the plugin with the Flutter plugin registrar.
+ *
+ * @param registrar The Flutter plugin registrar.
+ */
+ (void)registerWithRegistrar:(NSObject*)registrar {
[SwiftFlutterProxyPlugin registerWithRegistrar:registrar];
}
-@end
+
+@end
\ No newline at end of file
diff --git a/ios/Classes/SwiftFlutterProxyPlugin.swift b/ios/Classes/SwiftFlutterProxyPlugin.swift
index 3349ece..360c8a2 100644
--- a/ios/Classes/SwiftFlutterProxyPlugin.swift
+++ b/ios/Classes/SwiftFlutterProxyPlugin.swift
@@ -1,13 +1,32 @@
import Flutter
import UIKit
+/**
+ * @class SwiftFlutterProxyPlugin
+ * @brief A Swift implementation of the Flutter plugin for handling proxy settings.
+ *
+ * This class registers the plugin with the Flutter engine and handles method calls
+ * from Dart code. It provides functionality to retrieve the system proxy settings.
+ */
public class SwiftFlutterProxyPlugin: NSObject, FlutterPlugin {
+
+ /**
+ * Registers the plugin with the Flutter plugin registrar.
+ *
+ * @param registrar The Flutter plugin registrar.
+ */
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "native_flutter_proxy", binaryMessenger: registrar.messenger())
let instance = SwiftFlutterProxyPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}
+ /**
+ * Handles method calls from Dart code.
+ *
+ * @param call The method call from Dart.
+ * @param result The result callback to send the response back to Dart.
+ */
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "getProxySetting":
@@ -19,20 +38,25 @@ public class SwiftFlutterProxyPlugin: NSObject, FlutterPlugin {
}
}
- func getProxySetting() -> NSDictionary? {
- guard let proxySettings = CFNetworkCopySystemProxySettings()?.takeUnretainedValue(),
- let url = URL(string: "https://www.bing.com/") else {
- return nil
- }
- let proxies = CFNetworkCopyProxiesForURL((url as CFURL), proxySettings).takeUnretainedValue() as NSArray
- guard let settings = proxies.firstObject as? NSDictionary,
- let _ = settings.object(forKey: (kCFProxyTypeKey as String)) as? String else {
- return nil
- }
+ /**
+ * Retrieves the system proxy settings.
+ *
+ * @return A dictionary containing the proxy host and port, or nil if not available.
+ */
+ func getProxySetting() -> NSDictionary? {
+ guard let proxySettings = CFNetworkCopySystemProxySettings()?.takeUnretainedValue(),
+ let url = URL(string: "https://www.bing.com/") else {
+ return nil
+ }
+ let proxies = CFNetworkCopyProxiesForURL((url as CFURL), proxySettings).takeUnretainedValue() as NSArray
+ guard let settings = proxies.firstObject as? NSDictionary,
+ let _ = settings.object(forKey: (kCFProxyTypeKey as String)) as? String else {
+ return nil
+ }
- if let hostName = settings.object(forKey: (kCFProxyHostNameKey as String)), let port = settings.object(forKey: (kCFProxyPortNumberKey as String)) {
- return ["host":hostName, "port":port]
- }
- return nil;
+ if let hostName = settings.object(forKey: (kCFProxyHostNameKey as String)), let port = settings.object(forKey: (kCFProxyPortNumberKey as String)) {
+ return ["host": hostName, "port": port]
}
+ return nil
+ }
}
\ No newline at end of file
diff --git a/lib/custom_proxy.dart b/lib/custom_proxy.dart
deleted file mode 100644
index 33d63e9..0000000
--- a/lib/custom_proxy.dart
+++ /dev/null
@@ -1,53 +0,0 @@
-import 'dart:io';
-import 'custom_proxy_override.dart';
-
-/// Allows you to set and enable a proxy for your app
-class CustomProxy {
- /// A string representing an IP address for the proxy server
- final String ipAddress;
-
- /// The port number for the proxy server
- /// Can be null if port is default.
- final int? port;
-
- /// Set this to true
- /// - Warning: Setting this to true in production apps can be dangerous. Use with care!
- bool allowBadCertificates;
-
- /// Initializer
- CustomProxy(
- {required this.ipAddress, this.port, this.allowBadCertificates = false});
-
- /// Initializer from string
- static CustomProxy? fromString({required String proxy}) {
- // Check if valid
- if (proxy.isEmpty) {
- assert(
- false, "Proxy string passed to CustomProxy.fromString() is invalid.");
- return null;
- }
-
- // Build and return
- final proxyParts = proxy.split(":");
- final _ipAddress = proxyParts[0];
- final _port = proxyParts.length > 0 ? int.tryParse(proxyParts[1]) : null;
- return CustomProxy(
- ipAddress: _ipAddress,
- port: _port,
- );
- }
-
- /// Enable the proxy
- void enable() => HttpOverrides.global =
- new CustomProxyHttpOverride.withProxy(this.toString());
-
- /// Disable the proxy
- void disable() => HttpOverrides.global = null;
-
- @override
- String toString() {
- String _proxy = this.ipAddress;
- if (this.port != null) _proxy += ":" + this.port.toString();
- return _proxy;
- }
-}
diff --git a/lib/custom_proxy_override.dart b/lib/custom_proxy_override.dart
deleted file mode 100644
index 2c71e04..0000000
--- a/lib/custom_proxy_override.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-import 'dart:io';
-
-/// This class overrides the global proxy settings.
-class CustomProxyHttpOverride extends HttpOverrides {
- /// The entire proxy server
- /// Format: "localhost:8888"
- final String proxyString;
-
- /// Set this to true
- /// - Warning: Setting this to true in production apps can be dangerous. Use with care!
- final bool allowBadCertificates;
-
- /// Initializer
- CustomProxyHttpOverride.withProxy(
- this.proxyString, {
- this.allowBadCertificates = false,
- });
-
- /// Override HTTP client creation
- @override
- HttpClient createHttpClient(SecurityContext? context) {
- return super.createHttpClient(context)
- ..findProxy = (uri) {
- assert(this.proxyString.isNotEmpty,
- 'You must set a valid proxy if you enable it!');
- return "PROXY " + this.proxyString + ";";
- };
-/* ..badCertificateCallback = this.allowBadCertificates
- ? (X509Certificate cert, String host, int port) => true
- : null;*/
- }
-}
diff --git a/lib/native_flutter_proxy.dart b/lib/native_flutter_proxy.dart
new file mode 100644
index 0000000..ab35c9a
--- /dev/null
+++ b/lib/native_flutter_proxy.dart
@@ -0,0 +1,9 @@
+/// This library is used to create a custom proxy for HTTP requests in Flutter.
+///
+/// To use, import `package:native_flutter_proxy/native_flutter_proxy.dart`.
+/// Find the [native_flutter_proxy package](https://pub.dev/packages/native_flutter_proxy) 🚀
+library;
+
+export './src/custom_proxy.dart';
+export './src/custom_proxy_override.dart';
+export './src/native_proxy_reader.dart';
diff --git a/lib/native_proxy_reader.dart b/lib/native_proxy_reader.dart
deleted file mode 100644
index 7e60ba1..0000000
--- a/lib/native_proxy_reader.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-import 'dart:async';
-import 'package:flutter/services.dart';
-
-/// A flutter plugin to read network proxy info from native. It can be used to set up the network proxy for flutter.
-class NativeProxyReader {
- /// channel
- static const MethodChannel _channel =
- const MethodChannel('native_flutter_proxy');
-
- /// ProxySetting
- static Future get proxySetting async {
- return _channel //
- .invokeMapMethod('getProxySetting')
- .then((e) => ProxySetting._fromMap(e));
- }
-}
-
-/// ProxySetting
-class ProxySetting {
- /// host
- String? host;
-
- /// port
- int? port;
-
- /// private
- ProxySetting._({
- this.host,
- this.port,
- });
-
- /// private
- factory ProxySetting._fromMap(Map? map) {
- map ??= {};
- return ProxySetting._(
- host: map['host'],
- port: map['port'] != null //
- ? int.parse(map['port'].toString())
- : null,
- );
- }
-
- /// enabled
- bool get enabled =>
- (host?.isNotEmpty ?? false) && //
- (port != null && port! > 0);
-}
diff --git a/lib/src/custom_proxy.dart b/lib/src/custom_proxy.dart
new file mode 100644
index 0000000..de5391a
--- /dev/null
+++ b/lib/src/custom_proxy.dart
@@ -0,0 +1,98 @@
+import 'dart:io';
+
+import 'package:native_flutter_proxy/native_flutter_proxy.dart';
+
+/// {@template custom_proxy}
+/// A class that manages custom proxy settings for Flutter applications.
+///
+/// This class provides functionality to set up and manage a proxy server configuration,
+/// including the ability to enable/disable the proxy and handle custom certificates.
+///
+/// Example usage:
+/// ```dart
+/// final proxy = CustomProxy(ipAddress: '192.168.1.1', port: 8080);
+/// proxy.enable(); // Enables the proxy
+/// proxy.disable(); // Disables the proxy
+/// ```
+///
+/// You can also create a proxy instance from a string:
+/// ```dart
+/// final proxy = CustomProxy.fromString(proxy: '192.168.1.1:8080');
+/// ```
+///
+/// The class supports:
+/// * Setting custom IP address and port
+/// * Enabling/disabling proxy settings
+/// * Optional bad certificate handling
+/// * String representation of proxy settings
+///
+/// Note: When [allowBadCertificates] is set to true, it may pose security risks
+/// and should be used with caution, especially in production environments.
+/// {@endtemplate}
+class CustomProxy {
+ /// {@macro custom_proxy}
+ const CustomProxy({
+ required this.ipAddress,
+ this.port,
+ this.allowBadCertificates = false,
+ });
+
+ /// A string representing an IP address for the proxy server
+ final String ipAddress;
+
+ /// The port number for the proxy server
+ /// Can be null if port is default.
+ final int? port;
+
+ /// Set this to true
+ /// - Warning: Setting this to true in production apps can be dangerous. Use with care!
+ final bool allowBadCertificates;
+
+ /// Creates a [CustomProxy] instance from a string representation.
+ ///
+ /// The [proxy] string should be in the format "ipAddress:port".
+ /// For example: "192.168.1.1:8080"
+ ///
+ /// Returns null if:
+ /// * The proxy string is empty
+ /// * The port number cannot be parsed to an integer
+ ///
+ /// Throws an [AssertionError] in debug mode if the proxy string is empty.
+ static CustomProxy? fromString({required String proxy}) {
+ // Check if the proxy string is empty
+ if (proxy.isEmpty) {
+ assert(false, 'Proxy string passed to CustomProxy.fromString() is invalid.');
+
+ return null;
+ }
+
+ // Split the proxy string into parts and extract the IP address and port number if available
+ // Format: "ipAddress:port"
+ final proxyParts = proxy.split(':');
+ final ipAddress = proxyParts[0];
+ final port = proxyParts.isNotEmpty ? int.tryParse(proxyParts[1]) : null;
+
+ return CustomProxy(ipAddress: ipAddress, port: port);
+ }
+
+ /// Enables the custom proxy by setting a global HTTP override.
+ ///
+ /// Sets [HttpOverrides.global] to a new instance of [CustomProxyHttpOverride]
+ /// configured with the proxy settings from this object's string representation.
+ void enable() => HttpOverrides.global = CustomProxyHttpOverride.withProxy(toString());
+
+ /// Disables the global HTTP proxy settings by setting HttpOverrides.global to null.
+ ///
+ /// This method removes any previously configured proxy settings and restores
+ /// the default HTTP client behavior for network requests.
+ void disable() => HttpOverrides.global = null;
+
+ @override
+ String toString() {
+ var proxy = ipAddress;
+
+ if (port != null) proxy += ':$port';
+
+ return proxy;
+ }
+}
diff --git a/lib/src/custom_proxy_override.dart b/lib/src/custom_proxy_override.dart
new file mode 100644
index 0000000..2ba572a
--- /dev/null
+++ b/lib/src/custom_proxy_override.dart
@@ -0,0 +1,57 @@
+import 'dart:io';
+
+/// {@template custom_proxy_http_override}
+/// A custom HTTP override class that allows setting a global proxy for all HTTP requests.
+///
+/// This class extends [HttpOverrides] to provide proxy configuration capabilities.
+/// It can be used to route all HTTP traffic through a specified proxy server and
+/// optionally allow bad certificates for testing purposes.
+///
+/// Example usage:
+/// ```dart
+/// HttpOverrides.global = CustomProxyHttpOverride.withProxy(
+/// 'localhost:8888',
+/// allowBadCertificates: true,
+/// );
+/// ```
+///
+/// Important:
+/// - The proxy string must be in the format "host:port"
+/// - Allowing bad certificates should only be used for development/testing
+/// - This affects all HTTP requests made by the application
+///
+/// Note: Use with caution in production environments as it can compromise
+/// security if not configured properly.
+/// {@endtemplate}
+final class CustomProxyHttpOverride extends HttpOverrides {
+ /// Create a new instance of [CustomProxyHttpOverride] with the specified proxy settings.
+ ///
+ /// {@macro custom_proxy_http_override}
+ CustomProxyHttpOverride.withProxy(
+ this.proxyString, {
+ this.allowBadCertificates = false,
+ });
+
+ /// The entire proxy server
+ /// Format: "localhost:8888"
+ final String proxyString;
+
+ /// Set this to true
+ /// - Warning: Setting this to true in production apps can be dangerous. Use with care!
+ final bool allowBadCertificates;
+
+ /// Override HTTP client creation to set the proxy and bad certificate callback.
+ @override
+ HttpClient createHttpClient(SecurityContext? context) {
+ final client = super.createHttpClient(context)
+ ..findProxy = (uri) {
+ assert(proxyString.isNotEmpty, 'You must set a valid proxy if you enable it!');
+
+ return 'PROXY $proxyString;';
+ };
+
+ if (allowBadCertificates) client.badCertificateCallback = (cert, host, port) => true;
+
+ return client;
+ }
+}
diff --git a/lib/src/native_proxy_reader.dart b/lib/src/native_proxy_reader.dart
new file mode 100644
index 0000000..042cc00
--- /dev/null
+++ b/lib/src/native_proxy_reader.dart
@@ -0,0 +1,65 @@
+import 'dart:async';
+
+import 'package:flutter/services.dart';
+
+/// {@template custom_proxy}
+/// A class to read network proxy settings from native platform code.
+///
+/// This class provides functionality to retrieve proxy settings like host and
+/// port from the native platform (iOS/Android) through a method channel.
+///
+/// Example usage:
+/// ```dart
+/// ProxySetting settings = await NativeProxyReader.proxySetting;
+/// if (settings.enabled) {
+/// print('Proxy host: ${settings.host}');
+/// print('Proxy port: ${settings.port}');
+/// }
+/// ```
+/// {@endtemplate}
+abstract final class NativeProxyReader {
+ /// Method channel for native platform communication.ƒ
+ static const _channel = MethodChannel('native_flutter_proxy');
+
+ /// Get the proxy settings from the native platform.
+ static Future get proxySetting async {
+ return _channel.invokeMapMethod('getProxySetting').then(ProxySetting._fromMap);
+ }
+}
+
+/// {@template proxy_setting}
+/// A class to hold proxy settings like host and port.
+/// {@endtemplate}
+class ProxySetting {
+ /// {@macro proxy_setting}
+ const ProxySetting._({this.host, this.port});
+
+ /// Create a new instance of [ProxySetting] from a map.
+ ///
+ /// {@macro proxy_setting}
+ factory ProxySetting._fromMap(Map? map) {
+ map ??= {};
+
+ final host = map['host'];
+ final port = map['port'];
+
+ return ProxySetting._(
+ host: host is String ? host : null,
+ port: port != null ? int.tryParse(port.toString()) : null,
+ );
+ }
+
+ /// The proxy server hostname or IP address.
+ final String? host;
+
+ /// The proxy server port number.
+ final int? port;
+
+ /// A boolean indicating if proxy settings are valid and can be used.
+ bool get enabled {
+ final validHost = host?.isNotEmpty ?? false;
+ final validPort = port != null && port! > 0;
+
+ return validHost && validPort;
+ }
+}
diff --git a/pubspec.lock b/pubspec.lock
index 20a4615..939a55c 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -5,51 +5,50 @@ packages:
dependency: transitive
description:
name: async
- url: "https://pub.dartlang.org"
+ sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
+ url: "https://pub.dev"
source: hosted
- version: "2.8.1"
+ version: "2.12.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
- url: "https://pub.dartlang.org"
+ sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.0"
+ version: "2.1.2"
characters:
dependency: transitive
description:
name: characters
- url: "https://pub.dartlang.org"
+ sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
+ url: "https://pub.dev"
source: hosted
- version: "1.1.0"
- charcode:
- dependency: transitive
- description:
- name: charcode
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.3.1"
+ version: "1.4.0"
clock:
dependency: transitive
description:
name: clock
- url: "https://pub.dartlang.org"
+ sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
+ url: "https://pub.dev"
source: hosted
- version: "1.1.0"
+ version: "1.1.2"
collection:
dependency: transitive
description:
name: collection
- url: "https://pub.dartlang.org"
+ sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
+ url: "https://pub.dev"
source: hosted
- version: "1.15.0"
+ version: "1.19.1"
fake_async:
dependency: transitive
description:
name: fake_async
- url: "https://pub.dartlang.org"
+ sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
+ url: "https://pub.dev"
source: hosted
- version: "1.2.0"
+ version: "1.3.2"
flutter:
dependency: "direct main"
description: flutter
@@ -60,88 +59,139 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
+ leak_tracker:
+ dependency: transitive
+ description:
+ name: leak_tracker
+ sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
+ url: "https://pub.dev"
+ source: hosted
+ version: "10.0.8"
+ leak_tracker_flutter_testing:
+ dependency: transitive
+ description:
+ name: leak_tracker_flutter_testing
+ sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.9"
+ leak_tracker_testing:
+ dependency: transitive
+ description:
+ name: leak_tracker_testing
+ sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.1"
matcher:
dependency: transitive
description:
name: matcher
- url: "https://pub.dartlang.org"
+ sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
+ url: "https://pub.dev"
source: hosted
- version: "0.12.10"
+ version: "0.12.17"
+ material_color_utilities:
+ dependency: transitive
+ description:
+ name: material_color_utilities
+ sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.11.1"
meta:
dependency: transitive
description:
name: meta
- url: "https://pub.dartlang.org"
+ sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
+ url: "https://pub.dev"
source: hosted
- version: "1.7.0"
+ version: "1.16.0"
path:
dependency: transitive
description:
name: path
- url: "https://pub.dartlang.org"
+ sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
+ url: "https://pub.dev"
source: hosted
- version: "1.8.0"
+ version: "1.9.1"
sky_engine:
dependency: transitive
description: flutter
source: sdk
- version: "0.0.99"
+ version: "0.0.0"
source_span:
dependency: transitive
description:
name: source_span
- url: "https://pub.dartlang.org"
+ sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
+ url: "https://pub.dev"
source: hosted
- version: "1.8.1"
+ version: "1.10.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
- url: "https://pub.dartlang.org"
+ sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
+ url: "https://pub.dev"
source: hosted
- version: "1.10.0"
+ version: "1.12.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
- url: "https://pub.dartlang.org"
+ sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.0"
+ version: "2.1.4"
string_scanner:
dependency: transitive
description:
name: string_scanner
- url: "https://pub.dartlang.org"
+ sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
+ url: "https://pub.dev"
source: hosted
- version: "1.1.0"
+ version: "1.4.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
- url: "https://pub.dartlang.org"
+ sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
+ url: "https://pub.dev"
source: hosted
- version: "1.2.0"
+ version: "1.2.2"
test_api:
dependency: transitive
description:
name: test_api
- url: "https://pub.dartlang.org"
+ sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
+ url: "https://pub.dev"
source: hosted
- version: "0.4.2"
- typed_data:
+ version: "0.7.4"
+ vector_math:
dependency: transitive
description:
- name: typed_data
- url: "https://pub.dartlang.org"
+ name: vector_math
+ sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
+ url: "https://pub.dev"
source: hosted
- version: "1.3.0"
- vector_math:
+ version: "2.1.4"
+ very_good_analysis:
+ dependency: "direct dev"
+ description:
+ name: very_good_analysis
+ sha256: "62d2b86d183fb81b2edc22913d9f155d26eb5cf3855173adb1f59fac85035c63"
+ url: "https://pub.dev"
+ source: hosted
+ version: "7.0.0"
+ vm_service:
dependency: transitive
description:
- name: vector_math
- url: "https://pub.dartlang.org"
+ name: vm_service
+ sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.0"
+ version: "14.3.1"
sdks:
- dart: ">=2.12.0 <3.0.0"
- flutter: ">=1.12.0"
\ No newline at end of file
+ dart: ">=3.7.0-0 <4.0.0"
+ flutter: ">=3.18.0-18.0.pre.54"
diff --git a/pubspec.yaml b/pubspec.yaml
index c1e5bc2..cc0b4c1 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,11 +1,11 @@
name: native_flutter_proxy
description: A flutter plugin to read and set network proxy info from native.
-version: 0.1.14
+version: 0.2.0
homepage: https://github.com/victorblaess/native_flutter_proxy
environment:
- sdk: ">=2.12.0 <3.0.0"
- flutter: ">=1.12.0"
+ sdk: ">=3.0.0 <4.0.0"
+ flutter: ">=3.0.0"
dependencies:
flutter:
@@ -14,16 +14,9 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
+ very_good_analysis: ^7.0.0
-# For information on the generic Dart part of this file, see the
-# following page: https://dart.dev/tools/pub/pubspec
-
-# The following section is specific to Flutter.
flutter:
- # This section identifies this Flutter project as a plugin project.
- # The androidPackage and pluginClass identifiers should not ordinarily
- # be modified. They are used by the tooling to maintain consistency when
- # adding or updating assets for this project.
plugin:
platforms:
android:
@@ -31,34 +24,3 @@ flutter:
pluginClass: FlutterProxyPlugin
ios:
pluginClass: FlutterProxyPlugin
-
- # To add assets to your plugin package, add an assets section, like this:
- # assets:
- # - images/a_dot_burr.jpeg
- # - images/a_dot_ham.jpeg
- #
- # For details regarding assets in packages, see
- # https://flutter.dev/assets-and-images/#from-packages
- #
- # An image asset can refer to one or more resolution-specific "variants", see
- # https://flutter.dev/assets-and-images/#resolution-aware.
-
- # To add custom fonts to your plugin package, add a fonts section here,
- # in this "flutter" section. Each entry in this list should have a
- # "family" key with the font family name, and a "fonts" key with a
- # list giving the asset and other descriptors for the font. For
- # example:
- # fonts:
- # - family: Schyler
- # fonts:
- # - asset: fonts/Schyler-Regular.ttf
- # - asset: fonts/Schyler-Italic.ttf
- # style: italic
- # - family: Trajan Pro
- # fonts:
- # - asset: fonts/TrajanPro.ttf
- # - asset: fonts/TrajanPro_Bold.ttf
- # weight: 700
- #
- # For details regarding fonts in packages, see
- # https://flutter.dev/custom-fonts/#from-packages
diff --git a/test/custom_proxy_override_test.dart b/test/custom_proxy_override_test.dart
new file mode 100644
index 0000000..7ceea13
--- /dev/null
+++ b/test/custom_proxy_override_test.dart
@@ -0,0 +1,16 @@
+import 'package:flutter_test/flutter_test.dart';
+import 'package:native_flutter_proxy/native_flutter_proxy.dart';
+
+void main() {
+ group('CustomProxyHttpOverride', () {
+ test('creates instance with proxy settings', () {
+ final override = CustomProxyHttpOverride.withProxy(
+ 'localhost:8888',
+ allowBadCertificates: true,
+ );
+
+ expect(override.proxyString, equals('localhost:8888'));
+ expect(override.allowBadCertificates, isTrue);
+ });
+ });
+}
diff --git a/test/custom_proxy_test.dart b/test/custom_proxy_test.dart
new file mode 100644
index 0000000..a34b652
--- /dev/null
+++ b/test/custom_proxy_test.dart
@@ -0,0 +1,47 @@
+import 'package:flutter_test/flutter_test.dart';
+import 'package:native_flutter_proxy/native_flutter_proxy.dart';
+
+void main() {
+ group('CustomProxy', () {
+ test('creates instance with required parameters', () {
+ const proxy = CustomProxy(ipAddress: '192.168.1.1');
+ expect(proxy.ipAddress, equals('192.168.1.1'));
+ expect(proxy.port, isNull);
+ expect(proxy.allowBadCertificates, isFalse);
+ });
+
+ test('creates instance with all parameters', () {
+ const proxy = CustomProxy(
+ ipAddress: '192.168.1.1',
+ port: 8080,
+ allowBadCertificates: true,
+ );
+
+ expect(proxy.ipAddress, equals('192.168.1.1'));
+ expect(proxy.port, equals(8080));
+ expect(proxy.allowBadCertificates, isTrue);
+ });
+
+ group('fromString', () {
+ test('creates instance from valid proxy string with port', () {
+ final proxy = CustomProxy.fromString(proxy: '192.168.1.1:8080');
+
+ expect(proxy, isNotNull);
+ expect(proxy?.ipAddress, equals('192.168.1.1'));
+ expect(proxy?.port, equals(8080));
+ });
+ });
+
+ group('toString', () {
+ test('returns correct string with port', () {
+ const proxy = CustomProxy(ipAddress: '192.168.1.1', port: 8080);
+ expect(proxy.toString(), equals('192.168.1.1:8080'));
+ });
+
+ test('returns correct string without port', () {
+ const proxy = CustomProxy(ipAddress: '192.168.1.1');
+ expect(proxy.toString(), equals('192.168.1.1'));
+ });
+ });
+ });
+}
diff --git a/test/flutter_proxy_test.dart b/test/flutter_proxy_test.dart
deleted file mode 100644
index 8417a3c..0000000
--- a/test/flutter_proxy_test.dart
+++ /dev/null
@@ -1,26 +0,0 @@
-import 'package:flutter/services.dart';
-import 'package:flutter_test/flutter_test.dart';
-
-void main() {
-/* const MethodChannel channel = MethodChannel('native_flutter_proxy');
-
- TestWidgetsFlutterBinding.ensureInitialized();
-
- setUp(() {
- channel.setMockMethodCallHandler((MethodCall methodCall) async {
- return {
- 'host': '192.168.1.9',
- 'port': 9909,
- };
- });
- });
-
- tearDown(() {
- channel.setMockMethodCallHandler(null);
- });
-
- test('getProxySetting', () async {
- final setting = await NativeProxyReader.proxySetting;
- expect(setting.enabled, true);
- });*/
-}
diff --git a/test/native_proxy_reader_test.dart b/test/native_proxy_reader_test.dart
new file mode 100644
index 0000000..e6757e6
--- /dev/null
+++ b/test/native_proxy_reader_test.dart
@@ -0,0 +1,37 @@
+import 'package:flutter/services.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:native_flutter_proxy/src/native_proxy_reader.dart';
+
+void main() {
+ const channel = MethodChannel('native_flutter_proxy');
+
+ TestWidgetsFlutterBinding.ensureInitialized();
+
+ setUp(() {
+ TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
+ .setMockMethodCallHandler(channel, (call) async {
+ if (call.method == 'getProxySetting') {
+ return {
+ 'host': '192.168.1.9',
+ 'port': 9909,
+ };
+ }
+ return null;
+ });
+ });
+
+ tearDown(() {
+ TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
+ .setMockMethodCallHandler(channel, null);
+ });
+
+ group('NativeProxyReader', () {
+ test('returns valid proxy settings when data is available', () async {
+ final setting = await NativeProxyReader.proxySetting;
+
+ expect(setting.host, equals('192.168.1.9'));
+ expect(setting.port, equals(9909));
+ expect(setting.enabled, isTrue);
+ });
+ });
+}