1. add _systemAlertWindow and _enableStartOnBoot options.

2. opt settings_page.dart state variables
This commit is contained in:
csf 2023-02-28 11:31:30 +09:00
parent 8cd9f8745d
commit 48100c9e91
5 changed files with 116 additions and 21 deletions

View File

@ -12,6 +12,7 @@
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<application
android:icon="@mipmap/ic_launcher"

View File

@ -13,6 +13,7 @@ import android.content.Intent
import android.content.ServiceConnection
import android.os.Build
import android.os.IBinder
import android.preference.PreferenceManager
import android.provider.Settings
import android.util.Log
import android.view.WindowManager
@ -149,6 +150,25 @@ class MainActivity : FlutterActivity() {
result.success(true)
}
}
GET_START_ON_BOOT_OPT -> {
val prefs = getSharedPreferences(KEY_SHARED_PREFERENCES, MODE_PRIVATE)
result.success(prefs.getBoolean(KEY_START_ON_BOOT_OPT, false))
}
SET_START_ON_BOOT_OPT -> {
try {
if (call.arguments is Boolean) {
val prefs = getSharedPreferences(KEY_SHARED_PREFERENCES, MODE_PRIVATE)
val edit = prefs.edit()
edit.putBoolean(KEY_START_ON_BOOT_OPT, call.arguments as Boolean)
edit.apply()
result.success(true)
} else {
result.success(false)
}
} finally {
result.success(false)
}
}
else -> {
result.error("-1", "No such method", null)
}

View File

@ -37,9 +37,14 @@ const val REQ_REQUEST_MEDIA_PROJECTION = 201
const val RES_FAILED = -100
// Flutter channel
const val START_ACTION = "start_action";
const val IGNORE_BATTERY_OPTIMIZATIONS = "ignore_battery_optimizations";
const val START_ACTION = "start_action"
const val GET_START_ON_BOOT_OPT = "get_start_on_boot_opt"
const val SET_START_ON_BOOT_OPT = "set_start_on_boot_opt"
const val IGNORE_BATTERY_OPTIMIZATIONS = "ignore_battery_optimizations"
const val KEY_SHARED_PREFERENCES = "KEY_SHARED_PREFERENCES"
const val KEY_START_ON_BOOT_OPT = "KEY_START_ON_BOOT_OPT"
@SuppressLint("ConstantLocale")
val LOCAL_NAME = Locale.getDefault().toString()

View File

@ -150,7 +150,11 @@ const kSystemAlertWindow = "android.permission.SYSTEM_ALERT_WINDOW";
const kIgnoreBatteryOptimizations = "ignore_battery_optimizations";
/// Android channel invoke type key
const kStartAction = "start_action";
class AndroidChannel {
static final kStartAction = "start_action";
static final kGetStartOnBootOpt = "get_start_on_boot_opt";
static final kSetStartOnBootOpt = "set_start_on_boot_opt";
}
/// flutter/packages/flutter/lib/src/services/keyboard_key.dart -> _keyLabels
/// see [LogicalKeyboardKey.keyLabel]

View File

@ -32,18 +32,21 @@ class SettingsPage extends StatefulWidget implements PageShape {
}
const url = 'https://rustdesk.com/';
final _hasIgnoreBattery = androidVersion >= 26;
var _ignoreBatteryOpt = false;
var _enableAbr = false;
var _denyLANDiscovery = false;
var _onlyWhiteList = false;
var _enableDirectIPAccess = false;
var _enableRecordSession = false;
var _autoRecordIncomingSession = false;
var _localIP = "";
var _directAccessPort = "";
class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
final _hasIgnoreBattery = androidVersion >= 26;
var _ignoreBatteryOpt = false;
var _systemAlertWindow = false;
var _enableStartOnBoot = false;
var _enableAbr = false;
var _denyLANDiscovery = false;
var _onlyWhiteList = false;
var _enableDirectIPAccess = false;
var _enableRecordSession = false;
var _autoRecordIncomingSession = false;
var _localIP = "";
var _directAccessPort = "";
@override
void initState() {
super.initState();
@ -51,11 +54,35 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
() async {
var update = false;
if (_hasIgnoreBattery) {
update = await updateIgnoreBatteryStatus();
if (await checkAndUpdateIgnoreBatteryStatus()) {
update = true;
}
}
final enableAbrRes = await bind.mainGetOption(key: "enable-abr") != "N";
if (await checkAndUpdateSystemAlertWindow()) {
update = true;
}
// TODO need input
// start on boot depends on ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS and SYSTEM_ALERT_WINDOW
var enableStartOnBoot =
await gFFI.invokeMethod(AndroidChannel.kGetStartOnBootOpt);
if (enableStartOnBoot) {
if (!canStartOnBoot()) {
enableStartOnBoot = false;
gFFI.invokeMethod(AndroidChannel.kSetStartOnBootOpt, false);
}
}
if (enableStartOnBoot != _enableStartOnBoot) {
update = true;
_enableStartOnBoot = enableStartOnBoot;
}
final enableAbrRes = option2bool(
"enable-abr", await bind.mainGetOption(key: "enable-abr"));
if (enableAbrRes != _enableAbr) {
update = true;
_enableAbr = enableAbrRes;
@ -126,14 +153,15 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
() async {
if (await updateIgnoreBatteryStatus()) {
if (await checkAndUpdateIgnoreBatteryStatus() ||
await checkAndUpdateSystemAlertWindow()) {
setState(() {});
}
}();
}
}
Future<bool> updateIgnoreBatteryStatus() async {
Future<bool> checkAndUpdateIgnoreBatteryStatus() async {
final res =
await AndroidPermissionManager.check(kIgnoreBatteryOptimizations);
if (_ignoreBatteryOpt != res) {
@ -144,6 +172,16 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
}
}
Future<bool> checkAndUpdateSystemAlertWindow() async {
final res = await AndroidPermissionManager.check(kSystemAlertWindow);
if (_systemAlertWindow != res) {
_systemAlertWindow = res;
return true;
} else {
return false;
}
}
@override
Widget build(BuildContext context) {
Provider.of<FfiModel>(context);
@ -267,8 +305,8 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
]),
onToggle: (v) async {
if (v) {
gFFI.invokeMethod(
kStartAction, kActionRequestIgnoreBatteryOptimizations);
gFFI.invokeMethod(AndroidChannel.kStartAction,
kActionRequestIgnoreBatteryOptimizations);
} else {
final res = await gFFI.dialogManager
.show<bool>((setState, close) => CustomAlertDialog(
@ -285,12 +323,27 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
],
));
if (res == true) {
gFFI.invokeMethod(
kStartAction, kActionApplicationDetailsSettings);
gFFI.invokeMethod(AndroidChannel.kStartAction,
kActionApplicationDetailsSettings);
}
}
}));
}
enhancementsTiles.add(SettingsTile.switchTile(
initialValue: _enableStartOnBoot,
title: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text("$translate('Start on Boot') (beta)"),
Text(
'* ${translate('Start the screen recording service on boot, which requires special permissions')}',
style: Theme.of(context).textTheme.bodySmall),
]),
onToggle: (v) async {
if (v) {
// TODO
} else {
gFFI.invokeMethod(AndroidChannel.kSetStartOnBootOpt, false);
}
}));
return SettingsList(
sections: [
@ -391,6 +444,18 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
],
);
}
bool canStartOnBoot() {
// TODO need input
// start on boot depends on ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS and SYSTEM_ALERT_WINDOW
if (_hasIgnoreBattery && !_ignoreBatteryOpt) {
return false;
}
if (!_systemAlertWindow) {
return false;
}
return true;
}
}
void showServerSettings(OverlayDialogManager dialogManager) async {