Skip to content

Commit

Permalink
More accurate WSA status report
Browse files Browse the repository at this point in the history
  • Loading branch information
alesimula committed Dec 21, 2021
1 parent c66fb22 commit e51a996
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 16 deletions.
43 changes: 27 additions & 16 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class WSAStatusAlert {
}

enum ConnectionStatus {
UNSUPPORTED, MISSING, UNKNOWN, ARRESTED, OFFLINE, DISCONNECTED, CONNECTED
UNSUPPORTED, MISSING, UNKNOWN, ARRESTED, STARTING, OFFLINE, DISCONNECTED, CONNECTED
}
extension on ConnectionStatus {
static final Map<ConnectionStatus, WSAStatusAlert> _statusAlers = {
Expand All @@ -70,10 +70,12 @@ extension on ConnectionStatus {
"WSA not found; this application depends on WSA, please install Windows Subsystem for Android (or the Amazon Appstore) from the Microsoft Store"),
ConnectionStatus.UNKNOWN: WSAStatusAlert(InfoBarSeverity.info, "Connecting",
"Waiting for a WSA connection to be enstablished..."),
ConnectionStatus.STARTING: WSAStatusAlert(InfoBarSeverity.info, "Starting",
"WSA is turning on, patience you must have..."),
ConnectionStatus.ARRESTED: WSAStatusAlert(InfoBarSeverity.warning, "Arrested",
"Could not enstablish a connection with WSA: either developer mode and USB debugging are disabled, WSA is powered-off or a wrong port is specified"),
ConnectionStatus.OFFLINE: WSAStatusAlert(InfoBarSeverity.warning, "Arrested",
"Could not enstablish a connection with WSA: either developer mode and USB debugging are disabled, WSA is powered-off or a wrong port is specified"),
"WSA is turned off"),
ConnectionStatus.OFFLINE: WSAStatusAlert(InfoBarSeverity.warning, "Offline",
"Could not enstablish a connection with WSA: either developer mode and USB debugging are disabled or a wrong port is specified"),
ConnectionStatus.DISCONNECTED: WSAStatusAlert(InfoBarSeverity.error, "Disconnected",
"A WSA connection could not be enstablished for unknown reasons"),
ConnectionStatus.CONNECTED: WSAStatusAlert(InfoBarSeverity.success, "Connected",
Expand Down Expand Up @@ -106,7 +108,11 @@ class Env {
}

class WSAPeriodicConnector {
static const PERIODIC_CHECK_TIMER = Duration(seconds:5);
static const PERIODIC_CHECK_BOOT_DURATION = Duration(milliseconds: 500);
static const PERIODIC_CHECK_CONNECT_DURATION = Duration(seconds: 5);
static int lastStart = 0;
static bool get shouldWaitStart => DateTime.now().millisecondsSinceEpoch - lastStart < 15000;
static final DynamicTimer timer = DynamicTimer((Timer t) => WSAPeriodicConnector._checkConnectionStatus());
static ConnectionStatus status = ConnectionStatus.UNKNOWN;
static WSAStatusAlert alertStatus = ConnectionStatus.UNKNOWN.statusAlert;
static bool _statusInitialized = false;
Expand All @@ -121,20 +127,25 @@ class WSAPeriodicConnector {
});
}

final bool isBooted = WSAStatus.isBooted;
if (!isBooted) {
//if (PERIODIC_CHECK_TIMER.inMilliseconds != 500) PERIODIC_CHECK_TIMER.setDuration(milliseconds: 500);
if (status != ConnectionStatus.ARRESTED) GState.connectionStatus.$ = ConnectionStatus.ARRESTED.statusAlert;
if (!WSAStatus.isBooted) {
timer.setDuration(PERIODIC_CHECK_BOOT_DURATION);
ConnectionStatus newStatus = Env.WSA_INSTALLED ? ConnectionStatus.ARRESTED : WinVer.isWindows11OrGreater ? ConnectionStatus.MISSING : ConnectionStatus.UNSUPPORTED;
if (status != newStatus) GState.connectionStatus.$ = (status = newStatus).statusAlert;
return;
}
//else if (PERIODIC_CHECK_TIMER.inSeconds != 5) PERIODIC_CHECK_TIMER.setDuration(seconds: 5);
else {
timer.setDuration(PERIODIC_CHECK_CONNECT_DURATION);
if (status == ConnectionStatus.ARRESTED || status == ConnectionStatus.MISSING || status == ConnectionStatus.UNSUPPORTED)
lastStart = DateTime.now().millisecondsSinceEpoch;
}

var prevStatus = status;
var process = await Process.run('${Env.TOOLS_DIR}\\adb.exe', ['devices']);
var output = process.stdout.toString();
final prevStatus = status;
final process = await Process.run('${Env.TOOLS_DIR}\\adb.exe', ['devices']);
final output = process.stdout.toString();
if (output.contains(RegExp('(^|\\n)(localhost|127.0.0.1):${GState.androidPort.$}\\s+'))) {
if (output.contains(RegExp('(^|\\n)(localhost|127.0.0.1):${GState.androidPort.$}\\s+offline(\$|\\n|\\s)')))
status = ConnectionStatus.OFFLINE;
status = (status == ConnectionStatus.ARRESTED || status == ConnectionStatus.STARTING) && shouldWaitStart ?
ConnectionStatus.STARTING : ConnectionStatus.OFFLINE;
else if (output.contains(RegExp('(^|\\n)(localhost|127.0.0.1):${GState.androidPort.$}\\s+host(\$|\\n|\\s)'))) {
await Process.run('${Env.TOOLS_DIR}\\adb.exe', ['disconnect', '127.0.0.1:${GState.androidPort.$}']);
_tryConnect();
Expand All @@ -161,7 +172,8 @@ class WSAPeriodicConnector {
ProcessResult? process = await Process.run('${Env.TOOLS_DIR}\\adb.exe', ['connect', '127.0.0.1:${GState.androidPort.$}'])
.timeout(const Duration(milliseconds:200), onTimeout: () => Future.value(ProcessResult(-1, -1, null, null)));
if (process.stdout?.toString().contains(RegExp(r'(^|\n)(cannot|failed to) connect\s.*')) ?? true)
status = Env.WSA_INSTALLED ? ConnectionStatus.ARRESTED : WinVer.isWindows11OrGreater ? ConnectionStatus.MISSING : ConnectionStatus.UNSUPPORTED;
status = Env.WSA_INSTALLED ? (status == ConnectionStatus.ARRESTED || status == ConnectionStatus.STARTING) && shouldWaitStart ?
ConnectionStatus.STARTING : ConnectionStatus.OFFLINE : ConnectionStatus.DISCONNECTED;
else status = ConnectionStatus.CONNECTED;
}
}
Expand Down Expand Up @@ -214,7 +226,6 @@ void main(List<String> arguments) async {
}

WSAPeriodicConnector._checkConnectionStatus();
Timer.periodic(WSAPeriodicConnector.PERIODIC_CHECK_TIMER, (Timer t) => WSAPeriodicConnector._checkConnectionStatus());
runApp(wrappedApp);

flutter_acrylic.Window.hideWindowControls();
Expand Down
24 changes: 24 additions & 0 deletions lib/utils/misc_utils.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
import 'dart:async';
import 'package:archive/archive.dart';
import 'package:fluent_ui/fluent_ui.dart';

class DynamicTimer {
int _durationUs;
int _tick = 0;
final void Function(Timer timer) _callback;
Timer? _timer;

DynamicTimer(this._callback) : _durationUs = -1;
DynamicTimer.periodic(Duration _duration, this._callback) : _durationUs = _duration.inMicroseconds, _timer = Timer.periodic(_duration, _callback);

void cancel() => _timer?.cancel();
int get tick => _tick + (_timer?.tick ?? 0);
bool get isActive => _timer?.isActive ?? false;

/// Starts or restarts the timer with a new duration
void setDuration(Duration duration) {
if (duration.inMicroseconds == _durationUs) return;
_timer?.cancel();
_tick += _timer?.tick ?? 0;
_durationUs = duration.inMicroseconds;
_timer = Timer.periodic(duration, _callback);
}
}

class ColorConst extends Color {
const ColorConst.withOpacity(int value, double opacity) : super(
( (((opacity * 0xff ~/ 1) & 0xff) << 24) | ((0x00ffffff & value)) ) & 0xFFFFFFFF);
Expand Down

0 comments on commit e51a996

Please sign in to comment.