Add linux deb dependencies Add backup recovery strategy select Support custom text scaling Optimize the display of different text scale Optimize windows setup experience Optimize startTun performance Optimize android tv experience Optimize default option Optimize computed text size Optimize hyperOS freeform window Add developer mode Update core Optimize more details
121 lines
3.5 KiB
Dart
121 lines
3.5 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:device_info_plus/device_info_plus.dart';
|
|
import 'package:fl_clash/common/common.dart';
|
|
import 'package:fl_clash/enum/enum.dart';
|
|
import 'package:fl_clash/plugins/app.dart';
|
|
import 'package:fl_clash/state.dart';
|
|
import 'package:fl_clash/widgets/input.dart';
|
|
import 'package:flutter/services.dart';
|
|
|
|
class System {
|
|
static System? _instance;
|
|
|
|
System._internal();
|
|
|
|
factory System() {
|
|
_instance ??= System._internal();
|
|
return _instance!;
|
|
}
|
|
|
|
bool get isDesktop =>
|
|
Platform.isWindows || Platform.isMacOS || Platform.isLinux;
|
|
|
|
Future<int> get version async {
|
|
final deviceInfo = await DeviceInfoPlugin().deviceInfo;
|
|
return switch (Platform.operatingSystem) {
|
|
"macos" => (deviceInfo as MacOsDeviceInfo).majorVersion,
|
|
"android" => (deviceInfo as AndroidDeviceInfo).version.sdkInt,
|
|
"windows" => (deviceInfo as WindowsDeviceInfo).majorVersion,
|
|
String() => 0
|
|
};
|
|
}
|
|
|
|
Future<bool> checkIsAdmin() async {
|
|
final corePath = appPath.corePath.replaceAll(' ', '\\\\ ');
|
|
if (Platform.isWindows) {
|
|
final result = await windows?.checkService();
|
|
return result == WindowsHelperServiceStatus.running;
|
|
} else if (Platform.isMacOS) {
|
|
final result = await Process.run('stat', ['-f', '%Su:%Sg %Sp', corePath]);
|
|
final output = result.stdout.trim();
|
|
if (output.startsWith('root:admin') && output.contains('rws')) {
|
|
return true;
|
|
}
|
|
return false;
|
|
} else if (Platform.isLinux) {
|
|
final result = await Process.run('stat', ['-c', '%U:%G %A', corePath]);
|
|
final output = result.stdout.trim();
|
|
if (output.startsWith('root:') && output.contains('rws')) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
Future<AuthorizeCode> authorizeCore() async {
|
|
if (Platform.isAndroid) {
|
|
return AuthorizeCode.none;
|
|
}
|
|
final corePath = appPath.corePath.replaceAll(' ', '\\\\ ');
|
|
final isAdmin = await checkIsAdmin();
|
|
if (isAdmin) {
|
|
return AuthorizeCode.none;
|
|
}
|
|
|
|
if (Platform.isWindows) {
|
|
final result = await windows?.registerService();
|
|
if (result == true) {
|
|
return AuthorizeCode.success;
|
|
}
|
|
return AuthorizeCode.error;
|
|
}
|
|
|
|
if (Platform.isMacOS) {
|
|
final shell = 'chown root:admin $corePath; chmod +sx $corePath';
|
|
final arguments = [
|
|
"-e",
|
|
'do shell script "$shell" with administrator privileges',
|
|
];
|
|
final result = await Process.run("osascript", arguments);
|
|
if (result.exitCode != 0) {
|
|
return AuthorizeCode.error;
|
|
}
|
|
return AuthorizeCode.success;
|
|
} else if (Platform.isLinux) {
|
|
final shell = Platform.environment['SHELL'] ?? 'bash';
|
|
final password = await globalState.showCommonDialog<String>(
|
|
child: InputDialog(
|
|
title: appLocalizations.pleaseInputAdminPassword,
|
|
value: '',
|
|
),
|
|
);
|
|
final arguments = [
|
|
"-c",
|
|
'echo "$password" | sudo -S chown root:root "$corePath" && echo "$password" | sudo -S chmod +sx "$corePath"'
|
|
];
|
|
final result = await Process.run(shell, arguments);
|
|
if (result.exitCode != 0) {
|
|
return AuthorizeCode.error;
|
|
}
|
|
return AuthorizeCode.success;
|
|
}
|
|
return AuthorizeCode.error;
|
|
}
|
|
|
|
back() async {
|
|
await app?.moveTaskToBack();
|
|
await window?.hide();
|
|
}
|
|
|
|
exit() async {
|
|
if (Platform.isAndroid) {
|
|
await SystemNavigator.pop();
|
|
}
|
|
await window?.close();
|
|
}
|
|
}
|
|
|
|
final system = System();
|