369e42d06a
CI / Analyze & Test (push) Failing after 31s
- The original chmod call used Process.run('chmod', ...) which fails on Android
because chmod is not available in the app sandbox PATH
- /system/bin/sh is always present on Android and can execute chmod on the
extracted binary, setting executable permissions before the first run
59 lines
1.7 KiB
Dart
59 lines
1.7 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:flutter/services.dart';
|
|
import 'package:path_provider/path_provider.dart';
|
|
|
|
/// Provides the path to the iperf3 binary on the device.
|
|
///
|
|
/// Call [initialize] in [main] (before [runApp]) to extract the
|
|
/// bundled asset and populate the cache. After initialization,
|
|
/// [path] returns a synchronous [String].
|
|
class Iperf3BinaryPathProvider {
|
|
static String? _cachedPath;
|
|
|
|
/// Extract the bundled iperf3 binary to the app's cache directory.
|
|
///
|
|
/// Call this once in [main] before [runApp].
|
|
static Future<void> initialize() async {
|
|
if (_cachedPath != null) return;
|
|
|
|
final cacheDir = await getApplicationCacheDirectory();
|
|
final binaryDir = Directory('${cacheDir.path}/iperf3');
|
|
if (!await binaryDir.exists()) {
|
|
await binaryDir.create(recursive: true);
|
|
}
|
|
|
|
final abi = await _detectAbi();
|
|
final assetPath = 'assets/iperf3/$abi/iperf3';
|
|
|
|
final bytes = await rootBundle.load(assetPath);
|
|
final file = File('${binaryDir.path}/iperf3');
|
|
await file.writeAsBytes(bytes.buffer.asUint8List());
|
|
|
|
// chmod +x the binary — /system/bin/sh is always present on Android
|
|
await Process.run(
|
|
'/system/bin/sh',
|
|
['-c', 'chmod +x "\$1"', '_', file.path],
|
|
);
|
|
|
|
_cachedPath = file.path;
|
|
}
|
|
|
|
/// The resolved path to the iperf3 binary.
|
|
///
|
|
/// Must call [initialize] first, or this will return a placeholder.
|
|
static String get path {
|
|
return _cachedPath ?? '/data/local/tmp/iperf3';
|
|
}
|
|
|
|
static Future<String> _detectAbi() async {
|
|
final result = await Process.run(
|
|
'getprop',
|
|
['ro.product.cpu.abi'],
|
|
);
|
|
final abi = result.stdout.toString().trim();
|
|
if (abi.contains('arm64')) return 'arm64-v8a';
|
|
return 'armeabi-v7a';
|
|
}
|
|
}
|