#1032 screen saver: black background
This commit is contained in:
parent
171258ba2b
commit
ece28db3f8
10 changed files with 75 additions and 31 deletions
|
@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
### Changed
|
||||
|
||||
- Screen saver: black background, consistent with slideshow
|
||||
- upgraded Flutter to stable v3.22.1
|
||||
|
||||
### Removed
|
||||
|
|
|
@ -9,6 +9,7 @@ import deckers.thibault.aves.channel.calls.*
|
|||
import deckers.thibault.aves.channel.calls.window.ServiceWindowHandler
|
||||
import deckers.thibault.aves.channel.calls.window.WindowHandler
|
||||
import deckers.thibault.aves.channel.streams.ImageByteStreamHandler
|
||||
import deckers.thibault.aves.channel.streams.MediaCommandStreamHandler
|
||||
import deckers.thibault.aves.channel.streams.MediaStoreStreamHandler
|
||||
import deckers.thibault.aves.utils.LogUtils
|
||||
import io.flutter.FlutterInjector
|
||||
|
@ -18,12 +19,14 @@ import io.flutter.embedding.android.FlutterView
|
|||
import io.flutter.embedding.engine.FlutterEngine
|
||||
import io.flutter.embedding.engine.dart.DartExecutor.DartEntrypoint
|
||||
import io.flutter.embedding.engine.plugins.util.GeneratedPluginRegister
|
||||
import io.flutter.plugin.common.EventChannel
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
|
||||
// for FlutterView-level integration, cf https://docs.flutter.dev/development/add-to-app/android/add-flutter-view
|
||||
class ScreenSaverService : DreamService() {
|
||||
private var flutterEngine: FlutterEngine? = null
|
||||
private var flutterView: FlutterView? = null
|
||||
private lateinit var mediaSessionHandler: MediaSessionHandler
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
Log.i(LOG_TAG, "onAttachedToWindow")
|
||||
|
@ -77,6 +80,7 @@ class ScreenSaverService : DreamService() {
|
|||
|
||||
private fun release() {
|
||||
destroyView()
|
||||
mediaSessionHandler.dispose()
|
||||
flutterEngine = null
|
||||
flutterView = null
|
||||
}
|
||||
|
@ -96,12 +100,19 @@ class ScreenSaverService : DreamService() {
|
|||
private fun initChannels() {
|
||||
val messenger = flutterEngine!!.dartExecutor
|
||||
|
||||
// notification: platform -> dart
|
||||
val mediaCommandStreamHandler = MediaCommandStreamHandler().apply {
|
||||
EventChannel(messenger, MediaCommandStreamHandler.CHANNEL).setStreamHandler(this)
|
||||
}
|
||||
|
||||
// dart -> platform -> dart
|
||||
// - need Context
|
||||
mediaSessionHandler = MediaSessionHandler(this, mediaCommandStreamHandler)
|
||||
MethodChannel(messenger, DeviceHandler.CHANNEL).setMethodCallHandler(DeviceHandler(this))
|
||||
MethodChannel(messenger, EmbeddedDataHandler.CHANNEL).setMethodCallHandler(EmbeddedDataHandler(this))
|
||||
MethodChannel(messenger, MediaFetchBytesHandler.CHANNEL, AvesByteSendingMethodCodec.INSTANCE).setMethodCallHandler(MediaFetchBytesHandler(this))
|
||||
MethodChannel(messenger, MediaFetchObjectHandler.CHANNEL).setMethodCallHandler(MediaFetchObjectHandler(this))
|
||||
MethodChannel(messenger, MediaSessionHandler.CHANNEL).setMethodCallHandler(mediaSessionHandler)
|
||||
MethodChannel(messenger, MediaStoreHandler.CHANNEL).setMethodCallHandler(MediaStoreHandler(this))
|
||||
MethodChannel(messenger, MetadataFetchHandler.CHANNEL).setMethodCallHandler(MetadataFetchHandler(this))
|
||||
MethodChannel(messenger, StorageHandler.CHANNEL).setMethodCallHandler(StorageHandler(this))
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
enum AppMode {
|
||||
initialization,
|
||||
main,
|
||||
pickCollectionFiltersExternal,
|
||||
pickSingleMediaExternal,
|
||||
|
|
|
@ -86,6 +86,8 @@ class AvesApp extends StatefulWidget {
|
|||
// so that we can react to fullscreen `PageRoute`s only
|
||||
static final RouteObserver<PageRoute> pageRouteObserver = RouteObserver<PageRoute>();
|
||||
|
||||
static ScreenBrightness? get screenBrightness => _AvesAppState._screenBrightness;
|
||||
|
||||
const AvesApp({
|
||||
super.key,
|
||||
required this.flavor,
|
||||
|
@ -159,7 +161,7 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
|||
|
||||
final ValueNotifier<PageTransitionsBuilder> _pageTransitionsBuilderNotifier = ValueNotifier(defaultPageTransitionsBuilder);
|
||||
final ValueNotifier<TvMediaQueryModifier?> _tvMediaQueryModifierNotifier = ValueNotifier(null);
|
||||
final ValueNotifier<AppMode> _appModeNotifier = ValueNotifier(AppMode.main);
|
||||
final ValueNotifier<AppMode> _appModeNotifier = ValueNotifier(AppMode.initialization);
|
||||
|
||||
// observers are not registered when using the same list object with different items
|
||||
// the list itself needs to be reassigned
|
||||
|
@ -175,6 +177,7 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
|||
// - `ZoomPageTransitionsBuilder` on Android 10 / API 29 and above (default in Flutter v3.0.0)
|
||||
static const defaultPageTransitionsBuilder = FadeUpwardsPageTransitionsBuilder();
|
||||
static final GlobalKey<NavigatorState> _navigatorKey = GlobalKey(debugLabel: 'app-navigator');
|
||||
static ScreenBrightness? _screenBrightness;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -187,6 +190,7 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
|||
_subscriptions.add(_analysisCompletionChannel.receiveBroadcastStream().listen((event) => _onAnalysisCompletion()));
|
||||
_subscriptions.add(_errorChannel.receiveBroadcastStream().listen((event) => _onError(event as String?)));
|
||||
_updateCutoutInsets();
|
||||
_appModeNotifier.addListener(_onAppModeChanged);
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
}
|
||||
|
||||
|
@ -539,9 +543,9 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
|||
switch (settings.maxBrightness) {
|
||||
case MaxBrightness.never:
|
||||
case MaxBrightness.viewerOnly:
|
||||
ScreenBrightness().resetScreenBrightness();
|
||||
AvesApp.screenBrightness?.resetScreenBrightness();
|
||||
case MaxBrightness.always:
|
||||
ScreenBrightness().setScreenBrightness(1);
|
||||
AvesApp.screenBrightness?.setScreenBrightness(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -627,6 +631,20 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
|||
}
|
||||
|
||||
void _onError(String? error) => reportService.recordError(error, null);
|
||||
|
||||
void _onAppModeChanged() {
|
||||
final appMode = _appModeNotifier.value;
|
||||
debugPrint('App mode set to $appMode');
|
||||
switch (appMode) {
|
||||
case AppMode.screenSaver:
|
||||
// we cannot modify brightness without access to the activity
|
||||
_screenBrightness = null;
|
||||
break;
|
||||
default:
|
||||
_screenBrightness = ScreenBrightness();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AvesScrollBehavior extends MaterialScrollBehavior {
|
||||
|
|
|
@ -49,13 +49,7 @@ class InteractiveTile extends StatelessWidget {
|
|||
case AppMode.pickFilteredMediaInternal:
|
||||
case AppMode.pickUnfilteredMediaInternal:
|
||||
Navigator.maybeOf(context)?.pop(entry);
|
||||
case AppMode.pickCollectionFiltersExternal:
|
||||
case AppMode.pickFilterInternal:
|
||||
case AppMode.screenSaver:
|
||||
case AppMode.setWallpaper:
|
||||
case AppMode.slideshow:
|
||||
case AppMode.view:
|
||||
case AppMode.edit:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
|
|
@ -10,6 +10,7 @@ import 'package:aves/model/entry/extensions/props.dart';
|
|||
import 'package:aves/model/settings/settings.dart';
|
||||
import 'package:aves/model/source/collection_lens.dart';
|
||||
import 'package:aves/theme/durations.dart';
|
||||
import 'package:aves/widgets/aves_app.dart';
|
||||
import 'package:aves/widgets/common/behaviour/springy_scroll_physics.dart';
|
||||
import 'package:aves/widgets/common/extensions/theme.dart';
|
||||
import 'package:aves/widgets/viewer/action/entry_action_delegate.dart';
|
||||
|
@ -26,7 +27,6 @@ import 'package:aves_model/aves_model.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:screen_brightness/screen_brightness.dart';
|
||||
|
||||
class ViewerVerticalPageView extends StatefulWidget {
|
||||
final CollectionLens? collection;
|
||||
|
@ -86,7 +86,7 @@ class _ViewerVerticalPageViewState extends State<ViewerVerticalPageView> {
|
|||
_registerWidget(widget);
|
||||
|
||||
if (settings.maxBrightness == MaxBrightness.viewerOnly) {
|
||||
_systemBrightness = ScreenBrightness().system;
|
||||
_systemBrightness = AvesApp.screenBrightness?.system;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,7 +328,7 @@ class _ViewerVerticalPageViewState extends State<ViewerVerticalPageView> {
|
|||
if (settings.maxBrightness == MaxBrightness.viewerOnly) {
|
||||
_systemBrightness?.then((system) {
|
||||
final value = lerpDouble(maximumBrightness, system, ((1 - page).abs() * 2).clamp(0, 1))!;
|
||||
ScreenBrightness().setScreenBrightness(value);
|
||||
AvesApp.screenBrightness?.setScreenBrightness(value);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,6 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:screen_brightness/screen_brightness.dart';
|
||||
|
||||
class EntryViewerStack extends StatefulWidget {
|
||||
final CollectionLens? collection;
|
||||
|
@ -106,7 +105,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
|
|||
void initState() {
|
||||
super.initState();
|
||||
if (settings.maxBrightness == MaxBrightness.viewerOnly) {
|
||||
ScreenBrightness().setScreenBrightness(1);
|
||||
AvesApp.screenBrightness?.setScreenBrightness(1);
|
||||
}
|
||||
if (settings.keepScreenOn == KeepScreenOn.viewerOnly) {
|
||||
windowService.keepScreenOn(true);
|
||||
|
@ -901,15 +900,15 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
|
|||
switch (settings.maxBrightness) {
|
||||
case MaxBrightness.never:
|
||||
case MaxBrightness.viewerOnly:
|
||||
await ScreenBrightness().resetScreenBrightness();
|
||||
await AvesApp.screenBrightness?.resetScreenBrightness();
|
||||
case MaxBrightness.always:
|
||||
await ScreenBrightness().setScreenBrightness(1);
|
||||
await AvesApp.screenBrightness?.setScreenBrightness(1);
|
||||
}
|
||||
if (settings.keepScreenOn == KeepScreenOn.viewerOnly) {
|
||||
await windowService.keepScreenOn(false);
|
||||
}
|
||||
await mediaSessionService.release();
|
||||
await AvesApp.showSystemUI();
|
||||
await _showSystemUI(context, true);
|
||||
AvesApp.setSystemUIStyle(theme);
|
||||
if (!settings.useTvLayout) {
|
||||
await windowService.requestOrientation();
|
||||
|
@ -950,10 +949,16 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
|
|||
// overlay
|
||||
|
||||
Future<void> _initOverlay() async {
|
||||
// wait for MaterialPageRoute.transitionDuration
|
||||
// to show overlay after hero animation is complete
|
||||
await Future.delayed(ModalRoute.of(context)!.transitionDuration * timeDilation);
|
||||
await _onOverlayVisibleChanged();
|
||||
final appMode = context.read<ValueNotifier<AppMode>>().value;
|
||||
if (appMode == AppMode.screenSaver) {
|
||||
_overlayVisible.value = false;
|
||||
await _onOverlayVisibleChanged(animate: false);
|
||||
} else {
|
||||
// wait for MaterialPageRoute.transitionDuration
|
||||
// to show overlay after hero animation is complete
|
||||
await Future.delayed(ModalRoute.of(context)!.transitionDuration * timeDilation);
|
||||
await _onOverlayVisibleChanged();
|
||||
}
|
||||
_overlayInitialized = true;
|
||||
}
|
||||
|
||||
|
@ -963,7 +968,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
|
|||
if (_viewLocked.value) {
|
||||
await _startOverlayHidingTimer();
|
||||
} else {
|
||||
await AvesApp.showSystemUI();
|
||||
await _showSystemUI(context, true);
|
||||
AvesApp.setSystemUIStyle(Theme.of(context));
|
||||
}
|
||||
if (animate) {
|
||||
|
@ -978,7 +983,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
|
|||
_frozenViewInsets = mediaQuery.viewInsets;
|
||||
_frozenViewPadding = mediaQuery.viewPadding;
|
||||
});
|
||||
await AvesApp.hideSystemUI();
|
||||
await _showSystemUI(context, false);
|
||||
if (animate) {
|
||||
await _overlayAnimationController.reverse();
|
||||
} else {
|
||||
|
@ -993,10 +998,10 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
|
|||
|
||||
Future<void> _onViewLockedChanged() async {
|
||||
if (_viewLocked.value) {
|
||||
await AvesApp.hideSystemUI();
|
||||
await _showSystemUI(context, false);
|
||||
await _startOverlayHidingTimer();
|
||||
} else {
|
||||
await AvesApp.showSystemUI();
|
||||
await _showSystemUI(context, true);
|
||||
AvesApp.setSystemUIStyle(Theme.of(context));
|
||||
_stopOverlayHidingTimer();
|
||||
_overlayVisible.value = true;
|
||||
|
@ -1010,4 +1015,18 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
|
|||
}
|
||||
|
||||
void _stopOverlayHidingTimer() => _overlayHidingTimer?.cancel();
|
||||
|
||||
Future<void> _showSystemUI(BuildContext context, bool show) async {
|
||||
final appMode = context.read<ValueNotifier<AppMode>>().value;
|
||||
if (appMode == AppMode.screenSaver) {
|
||||
// as of Flutter v3.22.1, calls to `SystemChrome.setEnabledSystemUIMode` hang when app is used as a screen saver
|
||||
return;
|
||||
}
|
||||
|
||||
if (show) {
|
||||
await AvesApp.showSystemUI();
|
||||
} else {
|
||||
await AvesApp.hideSystemUI();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -488,6 +488,7 @@ class _EntryPageViewState extends State<EntryPageView> with TickerProviderStateM
|
|||
}
|
||||
|
||||
void _onViewStateChanged(MagnifierState v) {
|
||||
if (!mounted) return;
|
||||
_viewStateNotifier.value = _viewStateNotifier.value.copyWith(
|
||||
position: v.position,
|
||||
scale: v.scale,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:aves/theme/icons.dart';
|
||||
import 'package:aves/widgets/aves_app.dart';
|
||||
import 'package:decorated_icon/decorated_icon.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:screen_brightness/screen_brightness.dart';
|
||||
import 'package:volume_controller/volume_controller.dart';
|
||||
|
||||
enum SwipeAction { brightness, volume }
|
||||
|
@ -12,7 +12,7 @@ extension ExtraSwipeAction on SwipeAction {
|
|||
Future<double> get() {
|
||||
switch (this) {
|
||||
case SwipeAction.brightness:
|
||||
return ScreenBrightness().current;
|
||||
return AvesApp.screenBrightness?.current ?? Future.value(1);
|
||||
case SwipeAction.volume:
|
||||
return VolumeController().getVolume();
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ extension ExtraSwipeAction on SwipeAction {
|
|||
Future<void> set(double value) async {
|
||||
switch (this) {
|
||||
case SwipeAction.brightness:
|
||||
await ScreenBrightness().setScreenBrightness(value);
|
||||
await AvesApp.screenBrightness?.setScreenBrightness(value);
|
||||
case SwipeAction.volume:
|
||||
VolumeController().setVolume(value, showSystemUI: false);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import 'package:aves_model/aves_model.dart';
|
|||
import 'package:aves_video/aves_video.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:screen_brightness/screen_brightness.dart';
|
||||
|
||||
class WallpaperPage extends StatelessWidget {
|
||||
static const routeName = '/set_wallpaper';
|
||||
|
@ -89,7 +88,7 @@ class _EntryEditorState extends State<EntryEditor> with EntryViewControllerMixin
|
|||
void initState() {
|
||||
super.initState();
|
||||
if (settings.maxBrightness == MaxBrightness.viewerOnly) {
|
||||
ScreenBrightness().setScreenBrightness(1);
|
||||
AvesApp.screenBrightness?.setScreenBrightness(1);
|
||||
}
|
||||
if (settings.keepScreenOn == KeepScreenOn.viewerOnly) {
|
||||
windowService.keepScreenOn(true);
|
||||
|
|
Loading…
Reference in a new issue