560 lines
17 KiB
Dart
560 lines
17 KiB
Dart
// Autogenerated from Pigeon (v26.3.4), do not edit directly.
|
|
// See also: https://pub.dev/packages/pigeon
|
|
// ignore_for_file: unused_import, unused_shown_name
|
|
// ignore_for_file: type=lint
|
|
|
|
import 'dart:async';
|
|
import 'dart:typed_data' show Float64List, Int32List, Int64List;
|
|
|
|
import 'package:flutter/services.dart';
|
|
import 'package:meta/meta.dart' show immutable, protected, visibleForTesting;
|
|
|
|
Object? _extractReplyValueOrThrow(
|
|
List<Object?>? replyList,
|
|
String channelName, {
|
|
required bool isNullValid,
|
|
}) {
|
|
if (replyList == null) {
|
|
throw PlatformException(
|
|
code: 'channel-error',
|
|
message: 'Unable to establish connection on channel: "$channelName".',
|
|
);
|
|
} else if (replyList.length > 1) {
|
|
throw PlatformException(
|
|
code: replyList[0]! as String,
|
|
message: replyList[1] as String?,
|
|
details: replyList[2],
|
|
);
|
|
} else if (!isNullValid && (replyList.isNotEmpty && replyList[0] == null)) {
|
|
throw PlatformException(
|
|
code: 'null-error',
|
|
message: 'Host platform returned null value for non-null return value.',
|
|
);
|
|
}
|
|
return replyList.firstOrNull;
|
|
}
|
|
|
|
|
|
List<Object?> wrapResponse({Object? result, PlatformException? error, bool empty = false}) {
|
|
if (empty) {
|
|
return <Object?>[];
|
|
}
|
|
if (error == null) {
|
|
return <Object?>[result];
|
|
}
|
|
return <Object?>[error.code, error.message, error.details];
|
|
}
|
|
bool _deepEquals(Object? a, Object? b) {
|
|
if (identical(a, b)) {
|
|
return true;
|
|
}
|
|
if (a is double && b is double) {
|
|
if (a.isNaN && b.isNaN) {
|
|
return true;
|
|
}
|
|
return a == b;
|
|
}
|
|
if (a is List && b is List) {
|
|
return a.length == b.length &&
|
|
a.indexed
|
|
.every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]));
|
|
}
|
|
if (a is Map && b is Map) {
|
|
if (a.length != b.length) {
|
|
return false;
|
|
}
|
|
for (final MapEntry<Object?, Object?> entryA in a.entries) {
|
|
bool found = false;
|
|
for (final MapEntry<Object?, Object?> entryB in b.entries) {
|
|
if (_deepEquals(entryA.key, entryB.key)) {
|
|
if (_deepEquals(entryA.value, entryB.value)) {
|
|
found = true;
|
|
break;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
if (!found) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
return a == b;
|
|
}
|
|
|
|
int _deepHash(Object? value) {
|
|
if (value is List) {
|
|
return Object.hashAll(value.map(_deepHash));
|
|
}
|
|
if (value is Map) {
|
|
int result = 0;
|
|
for (final MapEntry<Object?, Object?> entry in value.entries) {
|
|
result += (_deepHash(entry.key) * 31) ^ _deepHash(entry.value);
|
|
}
|
|
return result;
|
|
}
|
|
if (value is double && value.isNaN) {
|
|
// Normalize NaN to a consistent hash.
|
|
return 0x7FF8000000000000.hashCode;
|
|
}
|
|
if (value is double && value == 0.0) {
|
|
// Normalize -0.0 to 0.0 so they have the same hash code.
|
|
return 0.0.hashCode;
|
|
}
|
|
return value.hashCode;
|
|
}
|
|
|
|
|
|
/// Transport types for Tor connections
|
|
enum TransportType {
|
|
/// Direct Tor connection (no bridges)
|
|
none,
|
|
/// obfs4 pluggable transport
|
|
obfs4,
|
|
/// Snowflake pluggable transport (default broker)
|
|
snowflake,
|
|
/// Snowflake via AMP cache
|
|
snowflakeAmp,
|
|
/// Meek pluggable transport
|
|
meek,
|
|
/// Meek via Azure CDN
|
|
meekAzure,
|
|
/// WebTunnel pluggable transport
|
|
webtunnel,
|
|
/// Custom bridge lines (passthrough)
|
|
custom,
|
|
}
|
|
|
|
/// Configuration for starting Tor
|
|
class TorConfiguration {
|
|
TorConfiguration({
|
|
required this.transport,
|
|
required this.bridgeLines,
|
|
this.entryNodeCountries,
|
|
this.exitNodeCountries,
|
|
this.strictNodes,
|
|
});
|
|
|
|
/// Transport type to use
|
|
TransportType transport;
|
|
|
|
/// Bridge lines for the transport (empty for direct connection)
|
|
List<String> bridgeLines;
|
|
|
|
/// Entry node countries (ISO 3166-1 alpha-2, comma-separated, e.g., "de,fr,nl")
|
|
String? entryNodeCountries;
|
|
|
|
/// Exit node countries (ISO 3166-1 alpha-2, comma-separated, e.g., "ch,is,se")
|
|
String? exitNodeCountries;
|
|
|
|
/// If true, never use nodes outside specified countries
|
|
bool? strictNodes;
|
|
|
|
List<Object?> _toList() {
|
|
return <Object?>[
|
|
transport,
|
|
bridgeLines,
|
|
entryNodeCountries,
|
|
exitNodeCountries,
|
|
strictNodes,
|
|
];
|
|
}
|
|
|
|
Object encode() {
|
|
return _toList(); }
|
|
|
|
static TorConfiguration decode(Object result) {
|
|
result as List<Object?>;
|
|
return TorConfiguration(
|
|
transport: result[0]! as TransportType,
|
|
bridgeLines: (result[1]! as List<Object?>).cast<String>(),
|
|
entryNodeCountries: result[2] as String?,
|
|
exitNodeCountries: result[3] as String?,
|
|
strictNodes: result[4] as bool?,
|
|
);
|
|
}
|
|
|
|
@override
|
|
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
|
bool operator ==(Object other) {
|
|
if (other is! TorConfiguration || other.runtimeType != runtimeType) {
|
|
return false;
|
|
}
|
|
if (identical(this, other)) {
|
|
return true;
|
|
}
|
|
return _deepEquals(transport, other.transport) && _deepEquals(bridgeLines, other.bridgeLines) && _deepEquals(entryNodeCountries, other.entryNodeCountries) && _deepEquals(exitNodeCountries, other.exitNodeCountries) && _deepEquals(strictNodes, other.strictNodes);
|
|
}
|
|
|
|
@override
|
|
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
|
int get hashCode => _deepHash(<Object?>[runtimeType, ..._toList()]);
|
|
}
|
|
|
|
/// Current Tor status
|
|
class TorStatus {
|
|
TorStatus({
|
|
required this.isRunning,
|
|
this.socksPort,
|
|
required this.bootstrapProgress,
|
|
this.currentCircuit,
|
|
this.exitNodeCountry,
|
|
});
|
|
|
|
/// Whether Tor is running
|
|
bool isRunning;
|
|
|
|
/// SOCKS proxy port (if running)
|
|
int? socksPort;
|
|
|
|
/// Bootstrap progress (0-100)
|
|
int bootstrapProgress;
|
|
|
|
/// Current circuit ID
|
|
String? currentCircuit;
|
|
|
|
/// Exit node country code
|
|
String? exitNodeCountry;
|
|
|
|
List<Object?> _toList() {
|
|
return <Object?>[
|
|
isRunning,
|
|
socksPort,
|
|
bootstrapProgress,
|
|
currentCircuit,
|
|
exitNodeCountry,
|
|
];
|
|
}
|
|
|
|
Object encode() {
|
|
return _toList(); }
|
|
|
|
static TorStatus decode(Object result) {
|
|
result as List<Object?>;
|
|
return TorStatus(
|
|
isRunning: result[0]! as bool,
|
|
socksPort: result[1] as int?,
|
|
bootstrapProgress: result[2]! as int,
|
|
currentCircuit: result[3] as String?,
|
|
exitNodeCountry: result[4] as String?,
|
|
);
|
|
}
|
|
|
|
@override
|
|
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
|
bool operator ==(Object other) {
|
|
if (other is! TorStatus || other.runtimeType != runtimeType) {
|
|
return false;
|
|
}
|
|
if (identical(this, other)) {
|
|
return true;
|
|
}
|
|
return _deepEquals(isRunning, other.isRunning) && _deepEquals(socksPort, other.socksPort) && _deepEquals(bootstrapProgress, other.bootstrapProgress) && _deepEquals(currentCircuit, other.currentCircuit) && _deepEquals(exitNodeCountry, other.exitNodeCountry);
|
|
}
|
|
|
|
@override
|
|
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
|
int get hashCode => _deepHash(<Object?>[runtimeType, ..._toList()]);
|
|
}
|
|
|
|
/// Log message from Tor
|
|
class TorLogMessage {
|
|
TorLogMessage({
|
|
required this.severity,
|
|
required this.message,
|
|
required this.timestamp,
|
|
});
|
|
|
|
/// Log severity (NOTICE, WARN, ERR, DEBUG)
|
|
String severity;
|
|
|
|
/// Log message
|
|
String message;
|
|
|
|
/// Timestamp (milliseconds since epoch)
|
|
int timestamp;
|
|
|
|
List<Object?> _toList() {
|
|
return <Object?>[
|
|
severity,
|
|
message,
|
|
timestamp,
|
|
];
|
|
}
|
|
|
|
Object encode() {
|
|
return _toList(); }
|
|
|
|
static TorLogMessage decode(Object result) {
|
|
result as List<Object?>;
|
|
return TorLogMessage(
|
|
severity: result[0]! as String,
|
|
message: result[1]! as String,
|
|
timestamp: result[2]! as int,
|
|
);
|
|
}
|
|
|
|
@override
|
|
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
|
bool operator ==(Object other) {
|
|
if (other is! TorLogMessage || other.runtimeType != runtimeType) {
|
|
return false;
|
|
}
|
|
if (identical(this, other)) {
|
|
return true;
|
|
}
|
|
return _deepEquals(severity, other.severity) && _deepEquals(message, other.message) && _deepEquals(timestamp, other.timestamp);
|
|
}
|
|
|
|
@override
|
|
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
|
int get hashCode => _deepHash(<Object?>[runtimeType, ..._toList()]);
|
|
}
|
|
|
|
|
|
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 TransportType) {
|
|
buffer.putUint8(129);
|
|
writeValue(buffer, value.index);
|
|
} else if (value is TorConfiguration) {
|
|
buffer.putUint8(130);
|
|
writeValue(buffer, value.encode());
|
|
} else if (value is TorStatus) {
|
|
buffer.putUint8(131);
|
|
writeValue(buffer, value.encode());
|
|
} else if (value is TorLogMessage) {
|
|
buffer.putUint8(132);
|
|
writeValue(buffer, value.encode());
|
|
} else {
|
|
super.writeValue(buffer, value);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Object? readValueOfType(int type, ReadBuffer buffer) {
|
|
switch (type) {
|
|
case 129:
|
|
final value = readValue(buffer) as int?;
|
|
return value == null ? null : TransportType.values[value];
|
|
case 130:
|
|
return TorConfiguration.decode(readValue(buffer)!);
|
|
case 131:
|
|
return TorStatus.decode(readValue(buffer)!);
|
|
case 132:
|
|
return TorLogMessage.decode(readValue(buffer)!);
|
|
default:
|
|
return super.readValueOfType(type, buffer);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Host API (Flutter -> Native)
|
|
class TorApi {
|
|
/// Constructor for [TorApi]. 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.
|
|
TorApi({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;
|
|
|
|
/// Start Tor with the given configuration
|
|
/// Returns a Future to avoid blocking the main thread
|
|
Future<int> startTor(TorConfiguration config) async {
|
|
final pigeonVar_channelName = 'dev.flutter.pigeon.flutter_tor.TorApi.startTor$pigeonVar_messageChannelSuffix';
|
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
|
pigeonVar_channelName,
|
|
pigeonChannelCodec,
|
|
binaryMessenger: pigeonVar_binaryMessenger,
|
|
);
|
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[config]);
|
|
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
|
|
|
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
|
|
pigeonVar_replyList,
|
|
pigeonVar_channelName,
|
|
isNullValid: false,
|
|
)
|
|
;
|
|
return pigeonVar_replyValue! as int;
|
|
}
|
|
|
|
/// Stop Tor
|
|
Future<void> stopTor() async {
|
|
final pigeonVar_channelName = 'dev.flutter.pigeon.flutter_tor.TorApi.stopTor$pigeonVar_messageChannelSuffix';
|
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
|
pigeonVar_channelName,
|
|
pigeonChannelCodec,
|
|
binaryMessenger: pigeonVar_binaryMessenger,
|
|
);
|
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
|
|
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
|
|
|
_extractReplyValueOrThrow(
|
|
pigeonVar_replyList,
|
|
pigeonVar_channelName,
|
|
isNullValid: true,
|
|
)
|
|
;
|
|
}
|
|
|
|
/// Get current status
|
|
Future<TorStatus> getStatus() async {
|
|
final pigeonVar_channelName = 'dev.flutter.pigeon.flutter_tor.TorApi.getStatus$pigeonVar_messageChannelSuffix';
|
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
|
pigeonVar_channelName,
|
|
pigeonChannelCodec,
|
|
binaryMessenger: pigeonVar_binaryMessenger,
|
|
);
|
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
|
|
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
|
|
|
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
|
|
pigeonVar_replyList,
|
|
pigeonVar_channelName,
|
|
isNullValid: false,
|
|
)
|
|
;
|
|
return pigeonVar_replyValue! as TorStatus;
|
|
}
|
|
|
|
/// Request a new Tor identity (new circuit)
|
|
Future<void> requestNewIdentity() async {
|
|
final pigeonVar_channelName = 'dev.flutter.pigeon.flutter_tor.TorApi.requestNewIdentity$pigeonVar_messageChannelSuffix';
|
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
|
pigeonVar_channelName,
|
|
pigeonChannelCodec,
|
|
binaryMessenger: pigeonVar_binaryMessenger,
|
|
);
|
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
|
|
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
|
|
|
_extractReplyValueOrThrow(
|
|
pigeonVar_replyList,
|
|
pigeonVar_channelName,
|
|
isNullValid: true,
|
|
)
|
|
;
|
|
}
|
|
}
|
|
|
|
/// Flutter API (Native -> Flutter)
|
|
abstract class TorLogApi {
|
|
static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();
|
|
|
|
/// Called when a log message is received
|
|
void onLogMessage(TorLogMessage log);
|
|
|
|
/// Called when status changes
|
|
void onStatusChanged(TorStatus status);
|
|
|
|
static void setUp(TorLogApi? api, {BinaryMessenger? binaryMessenger, String messageChannelSuffix = '',}) {
|
|
messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
|
|
{
|
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
|
'dev.flutter.pigeon.flutter_tor.TorLogApi.onLogMessage$messageChannelSuffix', pigeonChannelCodec,
|
|
binaryMessenger: binaryMessenger);
|
|
if (api == null) {
|
|
pigeonVar_channel.setMessageHandler(null);
|
|
} else {
|
|
pigeonVar_channel.setMessageHandler((Object? message) async {
|
|
final List<Object?> args = message! as List<Object?>;
|
|
final TorLogMessage arg_log = args[0]! as TorLogMessage;
|
|
try {
|
|
api.onLogMessage(arg_log);
|
|
return wrapResponse(empty: true);
|
|
} on PlatformException catch (e) {
|
|
return wrapResponse(error: e);
|
|
} catch (e) {
|
|
return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
{
|
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
|
'dev.flutter.pigeon.flutter_tor.TorLogApi.onStatusChanged$messageChannelSuffix', pigeonChannelCodec,
|
|
binaryMessenger: binaryMessenger);
|
|
if (api == null) {
|
|
pigeonVar_channel.setMessageHandler(null);
|
|
} else {
|
|
pigeonVar_channel.setMessageHandler((Object? message) async {
|
|
final List<Object?> args = message! as List<Object?>;
|
|
final TorStatus arg_status = args[0]! as TorStatus;
|
|
try {
|
|
api.onStatusChanged(arg_status);
|
|
return wrapResponse(empty: true);
|
|
} on PlatformException catch (e) {
|
|
return wrapResponse(error: e);
|
|
} catch (e) {
|
|
return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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(TransportType proxyType, String proxy) async {
|
|
final pigeonVar_channelName = 'dev.flutter.pigeon.flutter_tor.IPtProxyController.start$pigeonVar_messageChannelSuffix';
|
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
|
pigeonVar_channelName,
|
|
pigeonChannelCodec,
|
|
binaryMessenger: pigeonVar_binaryMessenger,
|
|
);
|
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[proxyType, proxy]);
|
|
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
|
|
|
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
|
|
pigeonVar_replyList,
|
|
pigeonVar_channelName,
|
|
isNullValid: false,
|
|
)
|
|
;
|
|
return pigeonVar_replyValue! as int;
|
|
}
|
|
|
|
Future<void> stop(TransportType proxyType) async {
|
|
final pigeonVar_channelName = 'dev.flutter.pigeon.flutter_tor.IPtProxyController.stop$pigeonVar_messageChannelSuffix';
|
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
|
pigeonVar_channelName,
|
|
pigeonChannelCodec,
|
|
binaryMessenger: pigeonVar_binaryMessenger,
|
|
);
|
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[proxyType]);
|
|
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
|
|
|
_extractReplyValueOrThrow(
|
|
pigeonVar_replyList,
|
|
pigeonVar_channelName,
|
|
isNullValid: true,
|
|
)
|
|
;
|
|
}
|
|
}
|