wallpaper: fixed video playback, session, controls

This commit is contained in:
Thibault Deckers 2023-03-09 19:56:30 +01:00
parent edab909fb0
commit d671030cb3
5 changed files with 38 additions and 11 deletions

View file

@ -13,17 +13,20 @@ import deckers.thibault.aves.channel.calls.*
import deckers.thibault.aves.channel.calls.window.ActivityWindowHandler import deckers.thibault.aves.channel.calls.window.ActivityWindowHandler
import deckers.thibault.aves.channel.calls.window.WindowHandler import deckers.thibault.aves.channel.calls.window.WindowHandler
import deckers.thibault.aves.channel.streams.ImageByteStreamHandler import deckers.thibault.aves.channel.streams.ImageByteStreamHandler
import deckers.thibault.aves.channel.streams.MediaCommandStreamHandler
import deckers.thibault.aves.utils.FlutterUtils import deckers.thibault.aves.utils.FlutterUtils
import deckers.thibault.aves.utils.FlutterUtils.enableSoftwareRendering import deckers.thibault.aves.utils.FlutterUtils.enableSoftwareRendering
import deckers.thibault.aves.utils.LogUtils import deckers.thibault.aves.utils.LogUtils
import deckers.thibault.aves.utils.getParcelableExtraCompat import deckers.thibault.aves.utils.getParcelableExtraCompat
import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
class WallpaperActivity : FlutterFragmentActivity() { class WallpaperActivity : FlutterFragmentActivity() {
private lateinit var intentDataMap: MutableMap<String, Any?> private lateinit var intentDataMap: MutableMap<String, Any?>
private lateinit var mediaSessionHandler: MediaSessionHandler
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
if (FlutterUtils.isSoftwareRenderingRequired()) { if (FlutterUtils.isSoftwareRenderingRequired()) {
@ -42,12 +45,19 @@ class WallpaperActivity : FlutterFragmentActivity() {
super.configureFlutterEngine(flutterEngine) super.configureFlutterEngine(flutterEngine)
val messenger = flutterEngine.dartExecutor val messenger = flutterEngine.dartExecutor
// notification: platform -> dart
val mediaCommandStreamHandler = MediaCommandStreamHandler().apply {
EventChannel(messenger, MediaCommandStreamHandler.CHANNEL).setStreamHandler(this)
}
// dart -> platform -> dart // dart -> platform -> dart
// - need Context // - need Context
mediaSessionHandler = MediaSessionHandler(this, mediaCommandStreamHandler)
MethodChannel(messenger, DeviceHandler.CHANNEL).setMethodCallHandler(DeviceHandler(this)) MethodChannel(messenger, DeviceHandler.CHANNEL).setMethodCallHandler(DeviceHandler(this))
MethodChannel(messenger, EmbeddedDataHandler.CHANNEL).setMethodCallHandler(EmbeddedDataHandler(this)) MethodChannel(messenger, EmbeddedDataHandler.CHANNEL).setMethodCallHandler(EmbeddedDataHandler(this))
MethodChannel(messenger, MediaFetchBytesHandler.CHANNEL, AvesByteSendingMethodCodec.INSTANCE).setMethodCallHandler(MediaFetchBytesHandler(this)) MethodChannel(messenger, MediaFetchBytesHandler.CHANNEL, AvesByteSendingMethodCodec.INSTANCE).setMethodCallHandler(MediaFetchBytesHandler(this))
MethodChannel(messenger, MediaFetchObjectHandler.CHANNEL).setMethodCallHandler(MediaFetchObjectHandler(this)) MethodChannel(messenger, MediaFetchObjectHandler.CHANNEL).setMethodCallHandler(MediaFetchObjectHandler(this))
MethodChannel(messenger, MediaSessionHandler.CHANNEL).setMethodCallHandler(mediaSessionHandler)
MethodChannel(messenger, MetadataFetchHandler.CHANNEL).setMethodCallHandler(MetadataFetchHandler(this)) MethodChannel(messenger, MetadataFetchHandler.CHANNEL).setMethodCallHandler(MetadataFetchHandler(this))
MethodChannel(messenger, StorageHandler.CHANNEL).setMethodCallHandler(StorageHandler(this)) MethodChannel(messenger, StorageHandler.CHANNEL).setMethodCallHandler(StorageHandler(this))
// - need ContextWrapper // - need ContextWrapper
@ -79,6 +89,11 @@ class WallpaperActivity : FlutterFragmentActivity() {
} }
} }
override fun onDestroy() {
mediaSessionHandler.dispose()
super.onDestroy()
}
private fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { private fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) { when (call.method) {
"getIntentData" -> { "getIntentData" -> {

View file

@ -229,9 +229,12 @@ class _HomePageState extends State<HomePage> {
} }
} }
break; break;
case AppMode.setWallpaper:
// for video playback storage
await metadataDb.init();
break;
case AppMode.pickMediaInternal: case AppMode.pickMediaInternal:
case AppMode.pickFilterInternal: case AppMode.pickFilterInternal:
case AppMode.setWallpaper:
case AppMode.slideshow: case AppMode.slideshow:
break; break;
} }

View file

@ -483,6 +483,10 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
} }
} else if (notification is ToggleOverlayNotification) { } else if (notification is ToggleOverlayNotification) {
_overlayVisible.value = notification.visible ?? !_overlayVisible.value; _overlayVisible.value = notification.visible ?? !_overlayVisible.value;
} else if (notification is VideoActionNotification) {
final controller = notification.controller;
final action = notification.action;
_onVideoAction(context, controller, action);
} else if (notification is TvShowLessInfoNotification) { } else if (notification is TvShowLessInfoNotification) {
if (_overlayVisible.value) { if (_overlayVisible.value) {
_overlayVisible.value = false; _overlayVisible.value = false;
@ -503,10 +507,6 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
_goToHorizontalPageByDelta(delta: 1, animate: notification.animate); _goToHorizontalPageByDelta(delta: 1, animate: notification.animate);
} else if (notification is ShowEntryNotification) { } else if (notification is ShowEntryNotification) {
_goToHorizontalPageByIndex(page: notification.index, animate: notification.animate); _goToHorizontalPageByIndex(page: notification.index, animate: notification.animate);
} else if (notification is VideoActionNotification) {
final controller = notification.controller;
final action = notification.action;
_onVideoAction(context, controller, action);
} else { } else {
return false; return false;
} }

View file

@ -1,3 +1,5 @@
import 'dart:math';
import 'package:aves/app_mode.dart'; import 'package:aves/app_mode.dart';
import 'package:aves/model/actions/entry_actions.dart'; import 'package:aves/model/actions/entry_actions.dart';
import 'package:aves/model/entry.dart'; import 'package:aves/model/entry.dart';
@ -79,7 +81,7 @@ class ViewerButtons extends StatelessWidget {
return Selector<Settings, bool>( return Selector<Settings, bool>(
selector: (context, s) => s.isRotationLocked, selector: (context, s) => s.isRotationLocked,
builder: (context, s, child) { builder: (context, s, child) {
final quickActions = (trashed ? EntryActions.trashed : settings.viewerQuickActions).where(isVisible).where(actionDelegate.canApply).take(availableCount - 1).toList(); final quickActions = (trashed ? EntryActions.trashed : settings.viewerQuickActions).where(isVisible).where(actionDelegate.canApply).take(max(0, availableCount - 1)).toList();
List<EntryAction> getMenuActions(List<EntryAction> categoryActions) { List<EntryAction> getMenuActions(List<EntryAction> categoryActions) {
return categoryActions.where((action) => !quickActions.contains(action)).where(isVisible).toList(); return categoryActions.where((action) => !quickActions.contains(action)).where(isVisible).toList();
} }

View file

@ -1,3 +1,4 @@
import 'package:aves/model/actions/entry_actions.dart';
import 'package:aves/model/entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/settings/enums/enums.dart'; import 'package:aves/model/settings/enums/enums.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
@ -130,6 +131,10 @@ class _EntryEditorState extends State<EntryEditor> with EntryViewControllerMixin
onNotification: (dynamic notification) { onNotification: (dynamic notification) {
if (notification is ToggleOverlayNotification) { if (notification is ToggleOverlayNotification) {
_overlayVisible.value = notification.visible ?? !_overlayVisible.value; _overlayVisible.value = notification.visible ?? !_overlayVisible.value;
} else if (notification is VideoActionNotification) {
final controller = notification.controller;
final action = notification.action;
_onVideoAction(context, controller, action);
} }
return true; return true;
}, },
@ -171,11 +176,7 @@ class _EntryEditorState extends State<EntryEditor> with EntryViewControllerMixin
entry: targetEntry, entry: targetEntry,
controller: videoController, controller: videoController,
scale: _overlayVideoControlScale, scale: _overlayVideoControlScale,
onActionSelected: (action) { onActionSelected: (action) => _onVideoAction(context, videoController, action),
if (videoController != null) {
_videoActionDelegate.onActionSelected(context, videoController, action);
}
},
onActionMenuOpened: () { onActionMenuOpened: () {
// if the menu is opened while overlay is hiding, // if the menu is opened while overlay is hiding,
// the popup menu button is disposed and menu items are ineffective, // the popup menu button is disposed and menu items are ineffective,
@ -235,6 +236,12 @@ class _EntryEditorState extends State<EntryEditor> with EntryViewControllerMixin
); );
} }
void _onVideoAction(BuildContext context, AvesVideoController? videoController, EntryAction action) {
if (videoController != null) {
_videoActionDelegate.onActionSelected(context, videoController, action);
}
}
// overlay // overlay
Future<void> _onOverlayVisibleChanged({bool animate = true}) async { Future<void> _onOverlayVisibleChanged({bool animate = true}) async {