Merge pull request #969 from Heap-Hop/ignore_battery_optimizations
Update Android
This commit is contained in:
commit
dde3e4f994
@ -3,6 +3,7 @@
|
||||
package="com.carriez.flutter_hbb">
|
||||
|
||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
@ -8,14 +8,14 @@ package com.carriez.flutter_hbb
|
||||
|
||||
import android.accessibilityservice.AccessibilityService
|
||||
import android.accessibilityservice.GestureDescription
|
||||
import android.content.Context
|
||||
import android.graphics.Path
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import android.view.accessibility.AccessibilityEvent
|
||||
import androidx.annotation.Keep
|
||||
import androidx.annotation.RequiresApi
|
||||
import java.util.*
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
|
||||
const val LIFT_DOWN = 9
|
||||
const val LIFT_MOVE = 8
|
||||
@ -49,28 +49,40 @@ class InputService : AccessibilityService() {
|
||||
|
||||
private val wheelActionsQueue = LinkedList<GestureDescription>()
|
||||
private var isWheelActionsPolling = false
|
||||
private var isWaitingLongPress = false
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
fun onMouseInput(mask: Int, _x: Int, _y: Int) {
|
||||
val x = if (_x < 0) {
|
||||
0
|
||||
} else {
|
||||
_x
|
||||
}
|
||||
|
||||
val y = if (_y < 0) {
|
||||
0
|
||||
} else {
|
||||
_y
|
||||
}
|
||||
val x = max(0, _x)
|
||||
val y = max(0, _y)
|
||||
|
||||
if (mask == 0 || mask == LIFT_MOVE) {
|
||||
val oldX = mouseX
|
||||
val oldY = mouseY
|
||||
mouseX = x * SCREEN_INFO.scale
|
||||
mouseY = y * SCREEN_INFO.scale
|
||||
if (isWaitingLongPress) {
|
||||
val delta = abs(oldX - mouseX) + abs(oldY - mouseY)
|
||||
Log.d(logTag,"delta:$delta")
|
||||
if (delta > 8) {
|
||||
isWaitingLongPress = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// left button down ,was up
|
||||
if (mask == LIFT_DOWN) {
|
||||
isWaitingLongPress = true
|
||||
timer.schedule(object : TimerTask() {
|
||||
override fun run() {
|
||||
if (isWaitingLongPress) {
|
||||
isWaitingLongPress = false
|
||||
leftIsDown = false
|
||||
endGesture(mouseX, mouseY)
|
||||
}
|
||||
}
|
||||
}, LONG_TAP_DELAY * 4)
|
||||
|
||||
leftIsDown = true
|
||||
startGesture(mouseX, mouseY)
|
||||
return
|
||||
@ -83,9 +95,12 @@ class InputService : AccessibilityService() {
|
||||
|
||||
// left up ,was down
|
||||
if (mask == LIFT_UP) {
|
||||
leftIsDown = false
|
||||
endGesture(mouseX, mouseY)
|
||||
return
|
||||
if (leftIsDown) {
|
||||
leftIsDown = false
|
||||
isWaitingLongPress = false
|
||||
endGesture(mouseX, mouseY)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (mask == RIGHT_UP) {
|
||||
|
||||
@ -2,20 +2,26 @@ package com.carriez.flutter_hbb
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.media.AudioRecord
|
||||
import android.media.AudioRecord.READ_BLOCKING
|
||||
import android.media.MediaCodecList
|
||||
import android.media.MediaFormat
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import android.os.PowerManager
|
||||
import android.provider.Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS
|
||||
import android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.content.ContextCompat.getSystemService
|
||||
import com.hjq.permissions.Permission
|
||||
import com.hjq.permissions.XXPermissions
|
||||
import java.nio.ByteBuffer
|
||||
import java.util.*
|
||||
|
||||
|
||||
@SuppressLint("ConstantLocale")
|
||||
val LOCAL_NAME = Locale.getDefault().toString()
|
||||
val SCREEN_INFO = Info(0, 0, 1, 200)
|
||||
@ -38,8 +44,19 @@ fun testVP9Support(): Boolean {
|
||||
return res != null
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.M)
|
||||
fun requestPermission(context: Context, type: String) {
|
||||
val permission = when (type) {
|
||||
"ignore_battery_optimizations" -> {
|
||||
try {
|
||||
context.startActivity(Intent(ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
|
||||
data = Uri.parse("package:" + context.packageName)
|
||||
})
|
||||
} catch (e:Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return
|
||||
}
|
||||
"audio" -> {
|
||||
Permission.RECORD_AUDIO
|
||||
}
|
||||
@ -52,7 +69,7 @@ fun requestPermission(context: Context, type: String) {
|
||||
}
|
||||
XXPermissions.with(context)
|
||||
.permission(permission)
|
||||
.request { permissions, all ->
|
||||
.request { _, all ->
|
||||
if (all) {
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
MainActivity.flutterMethodChannel.invokeMethod(
|
||||
@ -64,8 +81,13 @@ fun requestPermission(context: Context, type: String) {
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.M)
|
||||
fun checkPermission(context: Context, type: String): Boolean {
|
||||
val permission = when (type) {
|
||||
"ignore_battery_optimizations" -> {
|
||||
val pw = context.getSystemService(Context.POWER_SERVICE) as PowerManager
|
||||
return pw.isIgnoringBatteryOptimizations(context.packageName)
|
||||
}
|
||||
"audio" -> {
|
||||
Permission.RECORD_AUDIO
|
||||
}
|
||||
|
||||
@ -260,7 +260,7 @@ class PermissionManager {
|
||||
static Timer? _timer;
|
||||
static var _current = "";
|
||||
|
||||
static final permissions = ["audio", "file"];
|
||||
static final permissions = ["audio", "file", "ignore_battery_optimizations"];
|
||||
|
||||
static bool isWaitingFile() {
|
||||
if (_completer != null) {
|
||||
@ -279,9 +279,12 @@ class PermissionManager {
|
||||
if (!permissions.contains(type))
|
||||
return Future.error("Wrong permission!$type");
|
||||
|
||||
FFI.invokeMethod("request_permission", type);
|
||||
if (type == "ignore_battery_optimizations") {
|
||||
return Future.value(false);
|
||||
}
|
||||
_current = type;
|
||||
_completer = Completer<bool>();
|
||||
FFI.invokeMethod("request_permission", type);
|
||||
|
||||
// timeout
|
||||
_timer?.cancel();
|
||||
|
||||
@ -262,7 +262,6 @@ class _RemotePageState extends State<RemotePage> {
|
||||
: SafeArea(child:
|
||||
OrientationBuilder(builder: (ctx, orientation) {
|
||||
if (_currentOrientation != orientation) {
|
||||
debugPrint("on orientation changed");
|
||||
Timer(Duration(milliseconds: 200), () {
|
||||
resetMobileActionsOverlay();
|
||||
_currentOrientation = orientation;
|
||||
@ -1061,6 +1060,8 @@ void showOptions() {
|
||||
getRadio('Optimize reaction time', 'low', quality, setQuality),
|
||||
Divider(color: MyTheme.border),
|
||||
getToggle(setState, 'show-remote-cursor', 'Show remote cursor'),
|
||||
getToggle(
|
||||
setState, 'show-quality-monitor', 'Show quality monitor'),
|
||||
] +
|
||||
more),
|
||||
actions: [],
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:settings_ui/settings_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
@ -26,11 +28,75 @@ class SettingsPage extends StatefulWidget implements PageShape {
|
||||
|
||||
class _SettingsState extends State<SettingsPage> {
|
||||
static const url = 'https://rustdesk.com/';
|
||||
var _showIgnoreBattery = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (androidVersion >= 26) {
|
||||
() async {
|
||||
final res =
|
||||
await PermissionManager.check("ignore_battery_optimizations");
|
||||
if (_showIgnoreBattery != !res) {
|
||||
setState(() {
|
||||
_showIgnoreBattery = !res;
|
||||
});
|
||||
}
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Provider.of<FfiModel>(context);
|
||||
final username = getUsername();
|
||||
final enableAbr = FFI.getByName("option", "enable-abr") != 'N';
|
||||
final enhancementsTiles = [
|
||||
SettingsTile.switchTile(
|
||||
leading: Icon(Icons.more_horiz),
|
||||
title: Text(translate('Adaptive Bitrate') + '(beta)'),
|
||||
initialValue: enableAbr,
|
||||
onToggle: (v) {
|
||||
final msg = Map()
|
||||
..["name"] = "enable-abr"
|
||||
..["value"] = "";
|
||||
if (!v) {
|
||||
msg["value"] = "N";
|
||||
}
|
||||
FFI.setByName("option", json.encode(msg));
|
||||
setState(() {});
|
||||
},
|
||||
)
|
||||
];
|
||||
if (_showIgnoreBattery) {
|
||||
enhancementsTiles.insert(
|
||||
0,
|
||||
SettingsTile.navigation(
|
||||
title: Text(translate('Keep RustDesk background service')),
|
||||
description:
|
||||
Text('* ${translate('Ignore Battery Optimizations')}'),
|
||||
leading: Icon(Icons.battery_saver),
|
||||
onPressed: (context) {
|
||||
PermissionManager.request("ignore_battery_optimizations");
|
||||
var count = 0;
|
||||
Timer.periodic(Duration(seconds: 1), (timer) async {
|
||||
if (count > 5) {
|
||||
count = 0;
|
||||
timer.cancel();
|
||||
}
|
||||
if (await PermissionManager.check(
|
||||
"ignore_battery_optimizations")) {
|
||||
count = 0;
|
||||
timer.cancel();
|
||||
setState(() {
|
||||
_showIgnoreBattery = false;
|
||||
});
|
||||
}
|
||||
count++;
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
return SettingsList(
|
||||
sections: [
|
||||
SettingsSection(
|
||||
@ -51,17 +117,17 @@ class _SettingsState extends State<SettingsPage> {
|
||||
),
|
||||
],
|
||||
),
|
||||
SettingsSection(
|
||||
title: Text(translate("Settings")),
|
||||
tiles: [
|
||||
SettingsTile.navigation(
|
||||
SettingsSection(title: Text(translate("Settings")), tiles: [
|
||||
SettingsTile.navigation(
|
||||
title: Text(translate('ID/Relay Server')),
|
||||
leading: Icon(Icons.cloud),
|
||||
onPressed: (context) {
|
||||
showServerSettings();
|
||||
},
|
||||
),
|
||||
],
|
||||
})
|
||||
]),
|
||||
SettingsSection(
|
||||
title: Text(translate("Enhancements")),
|
||||
tiles: enhancementsTiles,
|
||||
),
|
||||
SettingsSection(
|
||||
title: Text(translate("About")),
|
||||
|
||||
@ -316,6 +316,9 @@ async fn test_nat_type_() -> ResultType<bool> {
|
||||
}
|
||||
|
||||
pub async fn get_rendezvous_server(ms_timeout: u64) -> (String, Vec<String>, bool) {
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||
let (mut a, mut b) = get_rendezvous_server_(ms_timeout);
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
let (mut a, mut b) = get_rendezvous_server_(ms_timeout).await;
|
||||
let mut b: Vec<String> = b
|
||||
.drain(..)
|
||||
|
||||
@ -284,5 +284,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("In privacy mode", "进入隐私模式"),
|
||||
("Out privacy mode", "退出隐私模式"),
|
||||
("Language", "语言"),
|
||||
("Keep RustDesk background service", "保持RustDesk后台服务"),
|
||||
("Ignore Battery Optimizations", "忽略电池优化"),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@ -284,5 +284,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("In privacy mode", "v režimu soukromí"),
|
||||
("Out privacy mode", "mimo režim soukromí"),
|
||||
("Language", ""),
|
||||
("Keep RustDesk background service", ""),
|
||||
("Ignore Battery Optimizations", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@ -284,5 +284,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("In privacy mode", "I databeskyttelsestilstand"),
|
||||
("Out privacy mode", "Databeskyttelsestilstand fra"),
|
||||
("Language", ""),
|
||||
("Keep RustDesk background service", ""),
|
||||
("Ignore Battery Optimizations", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@ -284,5 +284,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("In privacy mode", "im Datenschutzmodus"),
|
||||
("Out privacy mode", "Datenschutzmodus aus"),
|
||||
("Language", "Sprache"),
|
||||
("Keep RustDesk background service", ""),
|
||||
("Ignore Battery Optimizations", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@ -284,5 +284,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("In privacy mode", ""),
|
||||
("Out privacy mode", ""),
|
||||
("Language", ""),
|
||||
("Keep RustDesk background service", ""),
|
||||
("Ignore Battery Optimizations", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@ -284,5 +284,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("In privacy mode", "En modo de privacidad"),
|
||||
("Out privacy mode", "Fuera del modo de privacidad"),
|
||||
("Language", ""),
|
||||
("Keep RustDesk background service", ""),
|
||||
("Ignore Battery Optimizations", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@ -284,5 +284,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("In privacy mode", "en mode privé"),
|
||||
("Out privacy mode", "hors mode de confidentialité"),
|
||||
("Language", "Langue"),
|
||||
("Keep RustDesk background service", ""),
|
||||
("Ignore Battery Optimizations", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@ -270,7 +270,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Overwrite", "Felülírás"),
|
||||
("This file exists, skip or overwrite this file?", "Ez a fájl már létezik, skippeljünk, vagy felülírjuk ezt a fájlt?"),
|
||||
("Quit", "Kilépés"),
|
||||
("doc_mac_permission", "https://rustdesk.com/docs/hu/manual/mac/#enable-permissions"),
|
||||
("doc_mac_permission", "https://rustdesk.com/docs/hu/manual/mac/#enable-permissions"),
|
||||
("Help", "Segítség"),
|
||||
("Failed", "Sikertelen"),
|
||||
("Succeeded", "Sikeres"),
|
||||
@ -284,5 +284,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("In privacy mode", "Belépés a privát módba"),
|
||||
("Out privacy mode", "Kilépés a privát módból"),
|
||||
("Language", "Nyelv"),
|
||||
("Keep RustDesk background service", ""),
|
||||
("Ignore Battery Optimizations", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@ -284,5 +284,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("In privacy mode", "Dalam mode privasi"),
|
||||
("Out privacy mode", "Keluar dari mode privasi"),
|
||||
("Language", ""),
|
||||
("Keep RustDesk background service", ""),
|
||||
("Ignore Battery Optimizations", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@ -284,5 +284,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("In privacy mode", "In modalità privacy"),
|
||||
("Out privacy mode", "Fuori modalità privacy"),
|
||||
("Language", "Linguaggio"),
|
||||
("Keep RustDesk background service", ""),
|
||||
("Ignore Battery Optimizations", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@ -284,5 +284,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("In privacy mode", "No modo de privacidade"),
|
||||
("Out privacy mode", "Fora do modo de privacidade"),
|
||||
("Language", ""),
|
||||
("Keep RustDesk background service", ""),
|
||||
("Ignore Battery Optimizations", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@ -284,5 +284,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("In privacy mode", "В режиме конфиденциальности"),
|
||||
("Out privacy mode", "Выход из режима конфиденциальности"),
|
||||
("Language", "Язык"),
|
||||
("Keep RustDesk background service", ""),
|
||||
("Ignore Battery Optimizations", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@ -284,5 +284,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("In privacy mode", "V režime súkromia"),
|
||||
("Out privacy mode", "Mimo režimu súkromia"),
|
||||
("Language", ""),
|
||||
("Keep RustDesk background service", ""),
|
||||
("Ignore Battery Optimizations", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@ -284,5 +284,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("In privacy mode", ""),
|
||||
("Out privacy mode", ""),
|
||||
("Language", ""),
|
||||
("Keep RustDesk background service", ""),
|
||||
("Ignore Battery Optimizations", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@ -284,5 +284,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("In privacy mode", "Gizlilik modunda"),
|
||||
("Out privacy mode", "Gizlilik modu dışında"),
|
||||
("Language", ""),
|
||||
("Keep RustDesk background service", ""),
|
||||
("Ignore Battery Optimizations", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@ -284,5 +284,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("In privacy mode", "開啟隱私模式"),
|
||||
("Out privacy mode", "退出隱私模式"),
|
||||
("Language", "語言"),
|
||||
("Keep RustDesk background service", "保持RustDesk後台服務"),
|
||||
("Ignore Battery Optimizations", "忽略電池優化"),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@ -147,7 +147,6 @@ impl VideoQoS {
|
||||
// handle image_quality change from peer
|
||||
pub fn update_image_quality(&mut self, image_quality: i32) {
|
||||
let image_quality = Self::convert_quality(image_quality) as _;
|
||||
log::debug!("VideoQoS update_image_quality: {}", image_quality);
|
||||
if self.current_image_quality != image_quality {
|
||||
self.current_image_quality = image_quality;
|
||||
let _ = self.generate_bitrate().ok();
|
||||
@ -171,7 +170,7 @@ impl VideoQoS {
|
||||
#[cfg(target_os = "android")]
|
||||
{
|
||||
// fix when andorid screen shrinks
|
||||
let fix = Display::fix_quality() as u32;
|
||||
let fix = scrap::Display::fix_quality() as u32;
|
||||
log::debug!("Android screen, fix quality:{}", fix);
|
||||
let base_bitrate = base_bitrate * fix;
|
||||
self.target_bitrate = base_bitrate * self.current_image_quality / 100;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user