initial
This commit is contained in:
@@ -21,6 +21,7 @@ import 'dart:async';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter_background_service/flutter_background_service.dart';
|
||||
import 'package:pluggable_transports_proxy/pluggable_transports_proxy.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
import 'package:weblibre/core/logger.dart';
|
||||
@@ -36,8 +37,12 @@ class _TorService {
|
||||
|
||||
ValueStream<int?> get portStream => _portSubject.stream;
|
||||
|
||||
Future<void> start() async {
|
||||
Future<void> start({ProxyType? proxyType, String? bridgeLines}) async {
|
||||
await service.startService();
|
||||
service.invoke('start', {
|
||||
if (proxyType != null) 'proxyType': proxyType.name,
|
||||
if (bridgeLines != null) 'bridgeLines': bridgeLines,
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> requestSync() async {
|
||||
|
||||
@@ -19,12 +19,15 @@
|
||||
*/
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter_background_service/flutter_background_service.dart';
|
||||
import 'package:pluggable_transports_proxy/pluggable_transports_proxy.dart';
|
||||
import 'package:tor/tor.dart';
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
Future<void> onStart(ServiceInstance service) async {
|
||||
Timer? timeout;
|
||||
final startedProxyType = <ProxyType>{};
|
||||
|
||||
await Tor.init();
|
||||
|
||||
@@ -37,6 +40,12 @@ Future<void> onStart(ServiceInstance service) async {
|
||||
timeout = null;
|
||||
|
||||
Tor.instance.stop();
|
||||
|
||||
for (final proxyType in startedProxyType) {
|
||||
await IPtProxyController().stop(proxyType);
|
||||
}
|
||||
startedProxyType.clear();
|
||||
|
||||
service.invoke('portUpdate', {'port': -1});
|
||||
|
||||
await portSub.cancel();
|
||||
@@ -52,7 +61,36 @@ Future<void> onStart(ServiceInstance service) async {
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> startService(ProxyType? proxyType, String? bridgeLines) async {
|
||||
if (proxyType != null) {
|
||||
final port = await IPtProxyController().start(proxyType, "");
|
||||
startedProxyType.add(proxyType);
|
||||
|
||||
switch (proxyType) {
|
||||
case ProxyType.obfs4:
|
||||
await Tor.instance.start(obfs4Port: port, bridgeLines: bridgeLines);
|
||||
case ProxyType.meekLite:
|
||||
throw UnimplementedError();
|
||||
case ProxyType.webtunnel:
|
||||
throw UnimplementedError();
|
||||
case ProxyType.snowflake:
|
||||
await Tor.instance.start(
|
||||
snowflakePort: port,
|
||||
bridgeLines: bridgeLines,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
await Tor.instance.start();
|
||||
}
|
||||
}
|
||||
|
||||
service.on("start").listen((event) async {
|
||||
final proxyType = ProxyType.values.firstWhereOrNull(
|
||||
(x) => x.name == event?['proxyType'],
|
||||
);
|
||||
|
||||
await startService(proxyType, event?['bridgeLines'] as String?);
|
||||
});
|
||||
|
||||
service.on("heartbeat").listen((event) {
|
||||
// logger.d('Received tor heartbeat');
|
||||
|
||||
+3
-3
@@ -51,6 +51,8 @@ dependencies:
|
||||
path: ^1.9.1
|
||||
path_provider: ^2.1.5
|
||||
permission_handler: ^12.0.1
|
||||
pluggable_transports_proxy:
|
||||
path: ../packages/pluggable_transports_proxy
|
||||
pretty_qr_code: ^3.5.0
|
||||
riverpod: ^2.6.1
|
||||
riverpod_annotation: ^2.6.1
|
||||
@@ -75,9 +77,7 @@ dependencies:
|
||||
text_scroll: ^0.2.0
|
||||
timeago: ^3.7.1
|
||||
tor:
|
||||
git:
|
||||
url: https://github.com/FaFre/tor.git
|
||||
ref: update
|
||||
path: /home/fafre/development/repos/tor
|
||||
universal_io: ^2.2.2
|
||||
uri_to_file:
|
||||
git:
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# Miscellaneous
|
||||
*.class
|
||||
*.log
|
||||
*.pyc
|
||||
*.swp
|
||||
.DS_Store
|
||||
.atom/
|
||||
.build/
|
||||
.buildlog/
|
||||
.history
|
||||
.svn/
|
||||
.swiftpm/
|
||||
migrate_working_dir/
|
||||
|
||||
# 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
|
||||
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
|
||||
/pubspec.lock
|
||||
**/doc/api/
|
||||
.dart_tool/
|
||||
.flutter-plugins-dependencies
|
||||
/build/
|
||||
/coverage/
|
||||
.gradle/
|
||||
@@ -0,0 +1,30 @@
|
||||
# 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: "20f82749394e68bcfbbeee96bad384abaae09c13"
|
||||
channel: "stable"
|
||||
|
||||
project_type: plugin
|
||||
|
||||
# Tracks metadata for the flutter migrate command
|
||||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: 20f82749394e68bcfbbeee96bad384abaae09c13
|
||||
base_revision: 20f82749394e68bcfbbeee96bad384abaae09c13
|
||||
- platform: android
|
||||
create_revision: 20f82749394e68bcfbbeee96bad384abaae09c13
|
||||
base_revision: 20f82749394e68bcfbbeee96bad384abaae09c13
|
||||
|
||||
# User provided section
|
||||
|
||||
# List of Local paths (relative to this file) that should be
|
||||
# ignored by the migrate tool.
|
||||
#
|
||||
# Files that are not part of the templates will be ignored by default.
|
||||
unmanaged_files:
|
||||
- 'lib/main.dart'
|
||||
- 'ios/Runner.xcodeproj/project.pbxproj'
|
||||
@@ -0,0 +1,3 @@
|
||||
## 0.0.1
|
||||
|
||||
* TODO: Describe initial release.
|
||||
@@ -0,0 +1 @@
|
||||
TODO: Add your license here.
|
||||
@@ -0,0 +1,15 @@
|
||||
# pluggable_transports_proxy
|
||||
|
||||
A new Flutter plugin project.
|
||||
|
||||
## Getting Started
|
||||
|
||||
This project is a starting point for a Flutter
|
||||
[plug-in package](https://flutter.dev/to/develop-plugins),
|
||||
a specialized package that includes platform-specific implementation code for
|
||||
Android and/or iOS.
|
||||
|
||||
For help getting started with Flutter development, view the
|
||||
[online documentation](https://docs.flutter.dev), which offers tutorials,
|
||||
samples, guidance on mobile development, and a full API reference.
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# This file configures the static analysis results for your project (errors,
|
||||
# warnings, and lints).
|
||||
#
|
||||
# This enables the 'recommended' set of lints from `package:lints`.
|
||||
# This set helps identify many issues that may lead to problems when running
|
||||
# or consuming Dart code, and enforces writing Dart using a single, idiomatic
|
||||
# style and format.
|
||||
#
|
||||
# If you want a smaller set of lints you can change this to specify
|
||||
# 'package:lints/core.yaml'. These are just the most critical lints
|
||||
# (the recommended set includes the core lints).
|
||||
# The core lints are also what is used by pub.dev for scoring packages.
|
||||
|
||||
include: package:lint/package.yaml
|
||||
# Uncomment the following section to specify additional rules.
|
||||
|
||||
linter:
|
||||
rules:
|
||||
unawaited_futures: true
|
||||
discarded_futures: true
|
||||
collection_methods_unrelated_type: true
|
||||
|
||||
analyzer:
|
||||
plugins:
|
||||
- custom_lint
|
||||
exclude:
|
||||
- "**.g.dart"
|
||||
- "**.swagger.dart"
|
||||
- "**.freezed.dart"
|
||||
- "**.chopper.dart"
|
||||
# For more information about the core and recommended set of lints, see
|
||||
# https://dart.dev/go/core-lints
|
||||
|
||||
# For additional information about configuring this file, see
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
@@ -0,0 +1,9 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.cxx
|
||||
@@ -0,0 +1,70 @@
|
||||
group = "eu.weblibre.pluggable_transports_proxy"
|
||||
version = "1.0-SNAPSHOT"
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = "2.1.0"
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle:8.9.1")
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: "com.android.library"
|
||||
apply plugin: "kotlin-android"
|
||||
|
||||
android {
|
||||
namespace = "eu.weblibre.pluggable_transports_proxy"
|
||||
|
||||
compileSdk = 36
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += "src/main/kotlin"
|
||||
test.java.srcDirs += "src/test/kotlin"
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdk = 24
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-test")
|
||||
testImplementation("org.mockito:mockito-core:5.0.0")
|
||||
}
|
||||
|
||||
testOptions {
|
||||
unitTests.all {
|
||||
useJUnitPlatform()
|
||||
|
||||
testLogging {
|
||||
events "passed", "skipped", "failed", "standardOut", "standardError"
|
||||
outputs.upToDateWhen {false}
|
||||
showStandardStreams = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.netzarchitekten:IPtProxy:4.2.2'
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
rootProject.name = 'pluggable_transports_proxy'
|
||||
@@ -0,0 +1,3 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="eu.weblibre.pluggable_transports_proxy">
|
||||
</manifest>
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package eu.weblibre.pluggable_transports_proxy
|
||||
|
||||
import IPtProxy.Controller
|
||||
import eu.weblibre.pluggable_transports_proxy.pigeons.IPtProxyController
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import java.io.File
|
||||
|
||||
/** PluggableTransportsProxyPlugin */
|
||||
class PluggableTransportsProxyPlugin : FlutterPlugin {
|
||||
private lateinit var channel: MethodChannel
|
||||
|
||||
companion object {
|
||||
@Volatile
|
||||
private var INSTANCE: Controller? = null
|
||||
|
||||
fun getController(ptDirPath: String): Controller {
|
||||
return INSTANCE ?: synchronized(this) {
|
||||
INSTANCE ?: Controller(ptDirPath, true, false, "INFO", null).also { INSTANCE = it }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
val ptDir = File(flutterPluginBinding.applicationContext.cacheDir, "pt_state")
|
||||
val ptc = getController(ptDir.path)
|
||||
|
||||
IPtProxyController.setUp(flutterPluginBinding.binaryMessenger, ProxyImpl(controller = ptc))
|
||||
}
|
||||
|
||||
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
// Controller instance remains alive for reuse
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package eu.weblibre.pluggable_transports_proxy
|
||||
|
||||
import eu.weblibre.pluggable_transports_proxy.pigeons.IPtProxyController
|
||||
import eu.weblibre.pluggable_transports_proxy.pigeons.ProxyType
|
||||
|
||||
class ProxyImpl(val controller: IPtProxy.Controller) : IPtProxyController {
|
||||
override fun start(
|
||||
proxyType: ProxyType,
|
||||
proxy: String
|
||||
): Long {
|
||||
val type = when (proxyType) {
|
||||
ProxyType.OBFS4 -> IPtProxy.IPtProxy.Obfs4
|
||||
ProxyType.MEEK_LITE -> IPtProxy.IPtProxy.MeekLite
|
||||
ProxyType.WEBTUNNEL -> IPtProxy.IPtProxy.Webtunnel
|
||||
ProxyType.SNOWFLAKE -> IPtProxy.IPtProxy.Snowflake
|
||||
};
|
||||
|
||||
controller.start(type, proxy)
|
||||
|
||||
return controller.port(type)
|
||||
}
|
||||
|
||||
override fun stop(proxyType: ProxyType) {
|
||||
val type = when (proxyType) {
|
||||
ProxyType.OBFS4 -> IPtProxy.IPtProxy.Obfs4
|
||||
ProxyType.MEEK_LITE -> IPtProxy.IPtProxy.MeekLite
|
||||
ProxyType.WEBTUNNEL -> IPtProxy.IPtProxy.Webtunnel
|
||||
ProxyType.SNOWFLAKE -> IPtProxy.IPtProxy.Snowflake
|
||||
};
|
||||
|
||||
controller.stop(type)
|
||||
}
|
||||
}
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
// Autogenerated from Pigeon (v26.0.1), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
|
||||
|
||||
package eu.weblibre.pluggable_transports_proxy.pigeons
|
||||
|
||||
import android.util.Log
|
||||
import io.flutter.plugin.common.BasicMessageChannel
|
||||
import io.flutter.plugin.common.BinaryMessenger
|
||||
import io.flutter.plugin.common.EventChannel
|
||||
import io.flutter.plugin.common.MessageCodec
|
||||
import io.flutter.plugin.common.StandardMethodCodec
|
||||
import io.flutter.plugin.common.StandardMessageCodec
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.nio.ByteBuffer
|
||||
private object ProxyPigeonUtils {
|
||||
|
||||
fun wrapResult(result: Any?): List<Any?> {
|
||||
return listOf(result)
|
||||
}
|
||||
|
||||
fun wrapError(exception: Throwable): List<Any?> {
|
||||
return if (exception is FlutterError) {
|
||||
listOf(
|
||||
exception.code,
|
||||
exception.message,
|
||||
exception.details
|
||||
)
|
||||
} else {
|
||||
listOf(
|
||||
exception.javaClass.simpleName,
|
||||
exception.toString(),
|
||||
"Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error class for passing custom error details to Flutter via a thrown PlatformException.
|
||||
* @property code The error code.
|
||||
* @property message The error message.
|
||||
* @property details The error details. Must be a datatype supported by the api codec.
|
||||
*/
|
||||
class FlutterError (
|
||||
val code: String,
|
||||
override val message: String? = null,
|
||||
val details: Any? = null
|
||||
) : Throwable()
|
||||
|
||||
enum class ProxyType(val raw: Int) {
|
||||
OBFS4(0),
|
||||
MEEK_LITE(1),
|
||||
WEBTUNNEL(2),
|
||||
SNOWFLAKE(3);
|
||||
|
||||
companion object {
|
||||
fun ofRaw(raw: Int): ProxyType? {
|
||||
return values().firstOrNull { it.raw == raw }
|
||||
}
|
||||
}
|
||||
}
|
||||
private open class ProxyPigeonCodec : StandardMessageCodec() {
|
||||
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
|
||||
return when (type) {
|
||||
129.toByte() -> {
|
||||
return (readValue(buffer) as Long?)?.let {
|
||||
ProxyType.ofRaw(it.toInt())
|
||||
}
|
||||
}
|
||||
else -> super.readValueOfType(type, buffer)
|
||||
}
|
||||
}
|
||||
override fun writeValue(stream: ByteArrayOutputStream, value: Any?) {
|
||||
when (value) {
|
||||
is ProxyType -> {
|
||||
stream.write(129)
|
||||
writeValue(stream, value.raw)
|
||||
}
|
||||
else -> super.writeValue(stream, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
||||
interface IPtProxyController {
|
||||
fun start(proxyType: ProxyType, proxy: String): Long
|
||||
fun stop(proxyType: ProxyType)
|
||||
|
||||
companion object {
|
||||
/** The codec used by IPtProxyController. */
|
||||
val codec: MessageCodec<Any?> by lazy {
|
||||
ProxyPigeonCodec()
|
||||
}
|
||||
/** Sets up an instance of `IPtProxyController` to handle messages through the `binaryMessenger`. */
|
||||
@JvmOverloads
|
||||
fun setUp(binaryMessenger: BinaryMessenger, api: IPtProxyController?, messageChannelSuffix: String = "") {
|
||||
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.pluggable_transports_proxy.IPtProxyController.start$separatedMessageChannelSuffix", codec)
|
||||
if (api != null) {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val proxyTypeArg = args[0] as ProxyType
|
||||
val proxyArg = args[1] as String
|
||||
val wrapped: List<Any?> = try {
|
||||
listOf(api.start(proxyTypeArg, proxyArg))
|
||||
} catch (exception: Throwable) {
|
||||
ProxyPigeonUtils.wrapError(exception)
|
||||
}
|
||||
reply.reply(wrapped)
|
||||
}
|
||||
} else {
|
||||
channel.setMessageHandler(null)
|
||||
}
|
||||
}
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.pluggable_transports_proxy.IPtProxyController.stop$separatedMessageChannelSuffix", codec)
|
||||
if (api != null) {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val proxyTypeArg = args[0] as ProxyType
|
||||
val wrapped: List<Any?> = try {
|
||||
api.stop(proxyTypeArg)
|
||||
listOf(null)
|
||||
} catch (exception: Throwable) {
|
||||
ProxyPigeonUtils.wrapError(exception)
|
||||
}
|
||||
reply.reply(wrapped)
|
||||
}
|
||||
} else {
|
||||
channel.setMessageHandler(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export 'src/pigeons/proxy.g.dart' show IPtProxyController, ProxyType;
|
||||
@@ -0,0 +1,116 @@
|
||||
// Autogenerated from Pigeon (v26.0.1), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
|
||||
|
||||
import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
PlatformException _createConnectionError(String channelName) {
|
||||
return PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel: "$channelName".',
|
||||
);
|
||||
}
|
||||
|
||||
enum ProxyType {
|
||||
obfs4,
|
||||
meekLite,
|
||||
webtunnel,
|
||||
snowflake,
|
||||
}
|
||||
|
||||
|
||||
class _PigeonCodec extends StandardMessageCodec {
|
||||
const _PigeonCodec();
|
||||
@override
|
||||
void writeValue(WriteBuffer buffer, Object? value) {
|
||||
if (value is int) {
|
||||
buffer.putUint8(4);
|
||||
buffer.putInt64(value);
|
||||
} else if (value is ProxyType) {
|
||||
buffer.putUint8(129);
|
||||
writeValue(buffer, value.index);
|
||||
} else {
|
||||
super.writeValue(buffer, value);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Object? readValueOfType(int type, ReadBuffer buffer) {
|
||||
switch (type) {
|
||||
case 129:
|
||||
final int? value = readValue(buffer) as int?;
|
||||
return value == null ? null : ProxyType.values[value];
|
||||
default:
|
||||
return super.readValueOfType(type, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class IPtProxyController {
|
||||
/// Constructor for [IPtProxyController]. The [binaryMessenger] named argument is
|
||||
/// available for dependency injection. If it is left null, the default
|
||||
/// BinaryMessenger will be used which routes to the host platform.
|
||||
IPtProxyController({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''})
|
||||
: pigeonVar_binaryMessenger = binaryMessenger,
|
||||
pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
|
||||
final BinaryMessenger? pigeonVar_binaryMessenger;
|
||||
|
||||
static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();
|
||||
|
||||
final String pigeonVar_messageChannelSuffix;
|
||||
|
||||
Future<int> start(ProxyType proxyType, String proxy) async {
|
||||
final String pigeonVar_channelName = 'dev.flutter.pigeon.pluggable_transports_proxy.IPtProxyController.start$pigeonVar_messageChannelSuffix';
|
||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||
pigeonVar_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: pigeonVar_binaryMessenger,
|
||||
);
|
||||
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[proxyType, proxy]);
|
||||
final List<Object?>? pigeonVar_replyList =
|
||||
await pigeonVar_sendFuture as List<Object?>?;
|
||||
if (pigeonVar_replyList == null) {
|
||||
throw _createConnectionError(pigeonVar_channelName);
|
||||
} else if (pigeonVar_replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: pigeonVar_replyList[0]! as String,
|
||||
message: pigeonVar_replyList[1] as String?,
|
||||
details: pigeonVar_replyList[2],
|
||||
);
|
||||
} else if (pigeonVar_replyList[0] == null) {
|
||||
throw PlatformException(
|
||||
code: 'null-error',
|
||||
message: 'Host platform returned null value for non-null return value.',
|
||||
);
|
||||
} else {
|
||||
return (pigeonVar_replyList[0] as int?)!;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> stop(ProxyType proxyType) async {
|
||||
final String pigeonVar_channelName = 'dev.flutter.pigeon.pluggable_transports_proxy.IPtProxyController.stop$pigeonVar_messageChannelSuffix';
|
||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||
pigeonVar_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: pigeonVar_binaryMessenger,
|
||||
);
|
||||
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[proxyType]);
|
||||
final List<Object?>? pigeonVar_replyList =
|
||||
await pigeonVar_sendFuture as List<Object?>?;
|
||||
if (pigeonVar_replyList == null) {
|
||||
throw _createConnectionError(pigeonVar_channelName);
|
||||
} else if (pigeonVar_replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: pigeonVar_replyList[0]! as String,
|
||||
message: pigeonVar_replyList[1] as String?,
|
||||
details: pigeonVar_replyList[2],
|
||||
);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import 'package:pigeon/pigeon.dart';
|
||||
|
||||
enum ProxyType { obfs4, meekLite, webtunnel, snowflake }
|
||||
|
||||
@ConfigurePigeon(
|
||||
PigeonOptions(
|
||||
dartOut: 'lib/src/pigeons/proxy.g.dart',
|
||||
dartOptions: DartOptions(),
|
||||
kotlinOut:
|
||||
'android/src/main/kotlin/eu/weblibre/pluggable_transports_proxy/pigeons/Proxy.g.kt',
|
||||
kotlinOptions: KotlinOptions(
|
||||
package: 'eu.weblibre.pluggable_transports_proxy.pigeons',
|
||||
),
|
||||
dartPackageName: 'pluggable_transports_proxy',
|
||||
),
|
||||
)
|
||||
@HostApi()
|
||||
abstract class IPtProxyController {
|
||||
int start(ProxyType proxyType, String proxy);
|
||||
void stop(ProxyType proxyType);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
name: pluggable_transports_proxy
|
||||
description: "A new Flutter plugin project."
|
||||
version: 0.0.1
|
||||
publish_to: 'none'
|
||||
resolution: workspace
|
||||
|
||||
environment:
|
||||
sdk: ^3.9.0
|
||||
flutter: '>=3.3.0'
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
lint: ^2.8.0
|
||||
pigeon: ^26.0.1
|
||||
|
||||
# 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 packages.
|
||||
flutter:
|
||||
# This section identifies this Flutter project as a plugin project.
|
||||
# The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.)
|
||||
# which should be registered in the plugin registry. This is required for
|
||||
# using method channels.
|
||||
# The Android 'package' specifies package in which the registered class is.
|
||||
# This is required for using method channels on Android.
|
||||
# The 'ffiPlugin' specifies that native code should be built and bundled.
|
||||
# This is required for using `dart:ffi`.
|
||||
# All these are used by the tooling to maintain consistency when
|
||||
# adding or updating assets for this project.
|
||||
plugin:
|
||||
platforms:
|
||||
android:
|
||||
package: eu.weblibre.pluggable_transports_proxy
|
||||
pluginClass: PluggableTransportsProxyPlugin
|
||||
|
||||
# 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/to/asset-from-package
|
||||
#
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.dev/to/resolution-aware-images
|
||||
|
||||
# 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/to/font-from-package
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Autogenerated from Pigeon (v26.0.0), do not edit directly.
|
||||
// Autogenerated from Pigeon (v26.0.1), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Autogenerated from Pigeon (v26.0.0), do not edit directly.
|
||||
// Autogenerated from Pigeon (v26.0.1), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ workspace:
|
||||
- app/
|
||||
- packages/flutter_mozilla_components
|
||||
- packages/flutter_mozilla_components/example
|
||||
- packages/pluggable_transports_proxy
|
||||
- packages/simple_intent_receiver
|
||||
- packages/simple_intent_receiver/example
|
||||
dev_dependencies:
|
||||
|
||||
Reference in New Issue
Block a user