From 0b67164ecf073c9b8b5e760cfe8a243cdeb096bc Mon Sep 17 00:00:00 2001 From: csf Date: Thu, 26 May 2022 18:25:16 +0800 Subject: [PATCH 1/3] adapt to flutter 3 --- flutter/lib/common.dart | 12 ++++++------ flutter/lib/pages/remote_page.dart | 2 +- flutter/lib/widgets/gestures.dart | 19 +++++++++---------- flutter/pubspec.lock | 22 +++++++++++----------- flutter/pubspec.yaml | 11 ++++++----- 5 files changed, 33 insertions(+), 33 deletions(-) diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 3070833e4..c6a70460d 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -223,10 +223,10 @@ class AccessibilityListener extends StatelessWidget { Widget build(BuildContext context) { return Listener( onPointerDown: (evt) { - if (evt.size == 1 && GestureBinding.instance != null) { - GestureBinding.instance!.handlePointerEvent(PointerAddedEvent( + if (evt.size == 1) { + GestureBinding.instance.handlePointerEvent(PointerAddedEvent( pointer: evt.pointer + offset, position: evt.position)); - GestureBinding.instance!.handlePointerEvent(PointerDownEvent( + GestureBinding.instance.handlePointerEvent(PointerDownEvent( pointer: evt.pointer + offset, size: 0.1, position: evt.position)); @@ -234,17 +234,17 @@ class AccessibilityListener extends StatelessWidget { }, onPointerUp: (evt) { if (evt.size == 1 && GestureBinding.instance != null) { - GestureBinding.instance!.handlePointerEvent(PointerUpEvent( + GestureBinding.instance.handlePointerEvent(PointerUpEvent( pointer: evt.pointer + offset, size: 0.1, position: evt.position)); - GestureBinding.instance!.handlePointerEvent(PointerRemovedEvent( + GestureBinding.instance.handlePointerEvent(PointerRemovedEvent( pointer: evt.pointer + offset, position: evt.position)); } }, onPointerMove: (evt) { if (evt.size == 1 && GestureBinding.instance != null) { - GestureBinding.instance!.handlePointerEvent(PointerMoveEvent( + GestureBinding.instance.handlePointerEvent(PointerMoveEvent( pointer: evt.pointer + offset, size: 0.1, delta: evt.delta, diff --git a/flutter/lib/pages/remote_page.dart b/flutter/lib/pages/remote_page.dart index 50e645540..e86c94cfd 100644 --- a/flutter/lib/pages/remote_page.dart +++ b/flutter/lib/pages/remote_page.dart @@ -45,7 +45,7 @@ class _RemotePageState extends State { void initState() { super.initState(); FFI.connect(widget.id); - WidgetsBinding.instance!.addPostFrameCallback((_) { + WidgetsBinding.instance.addPostFrameCallback((_) { SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []); showLoading(translate('Connecting...')); _interval = diff --git a/flutter/lib/widgets/gestures.dart b/flutter/lib/widgets/gestures.dart index 8d690c734..d70fe05e6 100644 --- a/flutter/lib/widgets/gestures.dart +++ b/flutter/lib/widgets/gestures.dart @@ -213,7 +213,7 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer { _stopSecondTapDownTimer(); final _TapTracker tracker = _TapTracker( event: event, - entry: GestureBinding.instance!.gestureArena.add(event.pointer, this), + entry: GestureBinding.instance.gestureArena.add(event.pointer, this), doubleTapMinTime: kDoubleTapMinTime, gestureSettings: gestureSettings, ); @@ -318,13 +318,13 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer { final _TapTracker tracker = _firstTap!; _firstTap = null; _reject(tracker); - GestureBinding.instance!.gestureArena.release(tracker.pointer); + GestureBinding.instance.gestureArena.release(tracker.pointer); if (_secondTap != null) { final _TapTracker tracker = _secondTap!; _secondTap = null; _reject(tracker); - GestureBinding.instance!.gestureArena.release(tracker.pointer); + GestureBinding.instance.gestureArena.release(tracker.pointer); } } _firstTap = null; @@ -334,7 +334,7 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer { void _registerFirstTap(_TapTracker tracker) { _startFirstTapUpTimer(); - GestureBinding.instance!.gestureArena.hold(tracker.pointer); + GestureBinding.instance.gestureArena.hold(tracker.pointer); // Note, order is important below in order for the clear -> reject logic to // work properly. _freezeTracker(tracker); @@ -350,7 +350,7 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer { } _startSecondTapDownTimer(); - GestureBinding.instance!.gestureArena.hold(tracker.pointer); + GestureBinding.instance.gestureArena.hold(tracker.pointer); _secondTap = tracker; @@ -463,7 +463,7 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer { void _trackTap(PointerDownEvent event) { final _TapTracker tracker = _TapTracker( event: event, - entry: GestureBinding.instance!.gestureArena.add(event.pointer, this), + entry: GestureBinding.instance.gestureArena.add(event.pointer, this), doubleTapMinTime: kDoubleTapMinTime, gestureSettings: gestureSettings, ); @@ -532,7 +532,7 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer { } void _registerTap(_TapTracker tracker) { - GestureBinding.instance!.gestureArena.hold(tracker.pointer); + GestureBinding.instance.gestureArena.hold(tracker.pointer); // Note, order is important below in order for the clear -> reject logic to // work properly. } @@ -615,15 +615,14 @@ class _TapTracker { void startTrackingPointer(PointerRoute route, Matrix4? transform) { if (!_isTrackingPointer) { _isTrackingPointer = true; - GestureBinding.instance!.pointerRouter - .addRoute(pointer, route, transform); + GestureBinding.instance.pointerRouter.addRoute(pointer, route, transform); } } void stopTrackingPointer(PointerRoute route) { if (_isTrackingPointer) { _isTrackingPointer = false; - GestureBinding.instance!.pointerRouter.removeRoute(pointer, route); + GestureBinding.instance.pointerRouter.removeRoute(pointer, route); } } diff --git a/flutter/pubspec.lock b/flutter/pubspec.lock index 27c7c2e74..2876170af 100644 --- a/flutter/pubspec.lock +++ b/flutter/pubspec.lock @@ -233,12 +233,10 @@ packages: flutter_smart_dialog: dependency: "direct main" description: - path: "." - ref: HEAD - resolved-ref: c89ce60664cbc206cb98c1f407e86b8a766f4c0e - url: "https://github.com/Heap-Hop/flutter_smart_dialog.git" - source: git - version: "4.0.0" + name: flutter_smart_dialog + url: "https://pub.dartlang.org" + source: hosted + version: "4.3.1" flutter_test: dependency: "direct dev" description: flutter @@ -455,9 +453,11 @@ packages: qr_code_scanner: dependency: "direct main" description: - name: qr_code_scanner - url: "https://pub.dartlang.org" - source: hosted + path: "." + ref: fix_break_changes_platform + resolved-ref: "0feca6f15042c279ff575c559a3430df917b623d" + url: "https://github.com/Heap-Hop/qr_code_scanner.git" + source: git version: "0.7.0" quiver: dependency: transitive @@ -745,5 +745,5 @@ packages: source: hosted version: "0.1.0" sdks: - dart: ">=2.16.1 <3.0.0" - flutter: ">=2.10.0" + dart: ">=2.17.0-0 <3.0.0" + flutter: ">=3.0.0" diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index eba7dfd12..bc21fa6d8 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -19,7 +19,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.1.10+27 environment: - sdk: ">=2.16.1 <3.0.0" + sdk: ">=2.16.1" dependencies: flutter: @@ -46,13 +46,14 @@ dependencies: settings_ui: ^2.0.2 flutter_breadcrumb: ^1.0.1 http: ^0.13.4 - qr_code_scanner: ^0.7.0 + qr_code_scanner: + git: + url: https://github.com/Heap-Hop/qr_code_scanner.git + ref: fix_break_changes_platform zxing2: ^0.1.0 image_picker: ^0.8.5 image: ^3.1.3 - flutter_smart_dialog: - git: - url: https://github.com/Heap-Hop/flutter_smart_dialog.git + flutter_smart_dialog: ^4.3.1 flutter_rust_bridge: ^1.30.0 dev_dependencies: From 20f6bdb8e7b997a46efa5d22a210f404d9f0e2d9 Mon Sep 17 00:00:00 2001 From: csf Date: Wed, 1 Jun 2022 15:42:12 +0800 Subject: [PATCH 2/3] .gitignore Flutter Generated Files --- flutter/.gitignore | 13 ++++++++++++- flutter/pubspec.lock | 16 ++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/flutter/.gitignore b/flutter/.gitignore index ab9a85d6c..e1efea109 100644 --- a/flutter/.gitignore +++ b/flutter/.gitignore @@ -44,4 +44,15 @@ jniLibs .vscode # flutter rust bridge -lib/generated_bridge.dart \ No newline at end of file +lib/generated_bridge.dart + +# Flutter Generated Files +linux/flutter/generated_plugin_registrant.cc +linux/flutter/generated_plugin_registrant.h +linux/flutter/generated_plugins.cmake +macos/Flutter/GeneratedPluginRegistrant.swift +windows/flutter/generated_plugin_registrant.cc +windows/flutter/generated_plugin_registrant.h +windows/flutter/generated_plugins.cmake +flutter_export_environment.sh +Flutter-Generated.xcconfig \ No newline at end of file diff --git a/flutter/pubspec.lock b/flutter/pubspec.lock index 2876170af..a1db4ba6c 100644 --- a/flutter/pubspec.lock +++ b/flutter/pubspec.lock @@ -56,7 +56,7 @@ packages: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0" + version: "1.16.0" cross_file: dependency: transitive description: @@ -126,7 +126,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.3.0" ffi: dependency: "direct main" description: @@ -316,7 +316,7 @@ packages: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.3" + version: "0.6.4" matcher: dependency: transitive description: @@ -330,7 +330,7 @@ packages: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" + version: "0.1.4" meta: dependency: transitive description: @@ -358,7 +358,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" + version: "1.8.1" path_provider: dependency: "direct main" description: @@ -540,7 +540,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.2" stack_trace: dependency: transitive description: @@ -575,7 +575,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.8" + version: "0.4.9" toggle_switch: dependency: "direct main" description: @@ -673,7 +673,7 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "2.1.2" wakelock: dependency: "direct main" description: From 16fd96aa96ddf3f40672c4e0c1c94e34b65bf9f1 Mon Sep 17 00:00:00 2001 From: csf Date: Wed, 1 Jun 2022 17:52:21 +0800 Subject: [PATCH 3/3] fix android bit rate --- Cargo.lock | 1 + .../com/carriez/flutter_hbb/MainService.kt | 8 +++- libs/scrap/Cargo.toml | 1 + libs/scrap/src/common/android.rs | 40 +++++++++++++------ libs/scrap/src/common/mod.rs | 8 ++-- libs/scrap/src/lib.rs | 4 +- src/server/video_service.rs | 10 +++++ 7 files changed, 51 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e6942ef72..a91100885 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4265,6 +4265,7 @@ dependencies = [ "quest", "repng", "serde 1.0.136", + "serde_json 1.0.79", "target_build_utils", "tracing", "webm", diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt index 4a1b8c06f..62376ae5f 100644 --- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt +++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt @@ -72,7 +72,13 @@ class MainService : Service() { @Keep fun rustGetByName(name: String): String { return when (name) { - "screen_size" -> "${SCREEN_INFO.width}:${SCREEN_INFO.height}" + "screen_size" -> { + JSONObject().apply { + put("width",SCREEN_INFO.width) + put("height",SCREEN_INFO.height) + put("scale",SCREEN_INFO.scale) + }.toString() + } else -> "" } } diff --git a/libs/scrap/Cargo.toml b/libs/scrap/Cargo.toml index 00c4509ab..de39534ac 100644 --- a/libs/scrap/Cargo.toml +++ b/libs/scrap/Cargo.toml @@ -28,6 +28,7 @@ android_logger = "0.10" jni = "0.19" lazy_static = "1.4" log = "0.4" +serde_json = "1.0" [target.'cfg(not(target_os = "android"))'.dev-dependencies] repng = "0.2" diff --git a/libs/scrap/src/common/android.rs b/libs/scrap/src/common/android.rs index 555e6cd7b..1975a6505 100644 --- a/libs/scrap/src/common/android.rs +++ b/libs/scrap/src/common/android.rs @@ -1,11 +1,13 @@ use crate::android::ffi::*; use crate::rgba_to_i420; use lazy_static::lazy_static; +use serde_json::Value; +use std::collections::HashMap; use std::io; use std::sync::Mutex; lazy_static! { - static ref SCREEN_SIZE: Mutex<(u16, u16)> = Mutex::new((0, 0)); + static ref SCREEN_SIZE: Mutex<(u16, u16, u16)> = Mutex::new((0, 0, 0)); // (width, height, scale) } pub struct Capturer { @@ -65,9 +67,7 @@ impl Display { pub fn primary() -> io::Result { let mut size = SCREEN_SIZE.lock().unwrap(); if size.0 == 0 || size.1 == 0 { - let (w, h) = get_size().unwrap_or((0, 0)); - size.0 = w; - size.1 = h; + *size = get_size().unwrap_or_default(); } Ok(Display { default: true, @@ -111,19 +111,33 @@ impl Display { pub fn refresh_size() { let mut size = SCREEN_SIZE.lock().unwrap(); - let (w, h) = get_size().unwrap_or((0, 0)); - size.0 = w; - size.1 = h; + *size = get_size().unwrap_or_default(); + } + + // Big android screen size will be shrinked, to improve performance when screen-capturing and encoding + // e.g 2280x1080 size will be set to 1140x540, and `scale` is 2 + // need to multiply by `4` (2*2) when compute the bitrate + pub fn fix_quality() -> u16 { + let scale = SCREEN_SIZE.lock().unwrap().2; + if scale <= 0 { + 1 + } else { + scale * scale + } } } -fn get_size() -> Option<(u16, u16)> { +fn get_size() -> Option<(u16, u16, u16)> { let res = call_main_service_get_by_name("screen_size").ok()?; - if res.len() > 0 { - let mut sp = res.split(":"); - let w = sp.next()?.parse::().ok()?; - let h = sp.next()?.parse::().ok()?; - return Some((w, h)); + if let Ok(json) = serde_json::from_str::>(&res) { + if let (Some(Value::Number(w)), Some(Value::Number(h)), Some(Value::Number(scale))) = + (json.get("width"), json.get("height"), json.get("scale")) + { + let w = w.as_i64()? as _; + let h = h.as_i64()? as _; + let scale = scale.as_i64()? as _; + return Some((w, h, scale)); + } } None } diff --git a/libs/scrap/src/common/mod.rs b/libs/scrap/src/common/mod.rs index dd2b4295a..108a4ae31 100644 --- a/libs/scrap/src/common/mod.rs +++ b/libs/scrap/src/common/mod.rs @@ -19,7 +19,7 @@ cfg_if! { } else if #[cfg(dxgi)] { mod dxgi; pub use self::dxgi::*; - } else if #[cfg(android)] { + } else if #[cfg(target_os = "android")] { mod android; pub use self::android::*; }else { @@ -36,13 +36,11 @@ mod vpx; #[inline] pub fn would_block_if_equal(old: &mut Vec, b: &[u8]) -> std::io::Result<()> { - let b = unsafe { - std::slice::from_raw_parts::(b.as_ptr() as _, b.len() / 16) - }; + let b = unsafe { std::slice::from_raw_parts::(b.as_ptr() as _, b.len() / 16) }; if b == &old[..] { return Err(std::io::ErrorKind::WouldBlock.into()); } old.resize(b.len(), 0); old.copy_from_slice(b); Ok(()) -} \ No newline at end of file +} diff --git a/libs/scrap/src/lib.rs b/libs/scrap/src/lib.rs index 4d481ed26..504f0a4b3 100644 --- a/libs/scrap/src/lib.rs +++ b/libs/scrap/src/lib.rs @@ -14,13 +14,13 @@ pub mod quartz; #[cfg(x11)] pub mod x11; -#[cfg(all(x11, feature="wayland"))] +#[cfg(all(x11, feature = "wayland"))] pub mod wayland; #[cfg(dxgi)] pub mod dxgi; -#[cfg(android)] +#[cfg(target_os = "android")] pub mod android; mod common; diff --git a/src/server/video_service.rs b/src/server/video_service.rs index 17b545426..8c0edba43 100644 --- a/src/server/video_service.rs +++ b/src/server/video_service.rs @@ -567,5 +567,15 @@ fn get_quality(w: usize, h: usize, q: i32) -> (u32, u32, u32, i32) { let bitrate = q >> 8 & 0xFF; let quantizer = q & 0xFF; let b = ((w * h) / 1000) as u32; + + #[cfg(target_os = "android")] + { + // fix when andorid screen shrinks + let fix = Display::fix_quality() as u32; + log::debug!("Android screen, fix quality:{}", fix); + let b = b * fix; + return (bitrate as u32 * b / 100, quantizer as _, 56, 7); + } + (bitrate as u32 * b / 100, quantizer as _, 56, 7) }