fix: suppress position sync when app backgrounded
This commit is contained in:
@@ -472,6 +472,10 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen> with WidgetsBindin
|
||||
return;
|
||||
}
|
||||
|
||||
// Suppress Watch Together heartbeats while backgrounded so App Nap
|
||||
// doesn't cause stale position broadcasts that make guests loop.
|
||||
_watchTogetherProvider?.setBackgrounded(true);
|
||||
|
||||
final currentPlayer = player;
|
||||
if (currentPlayer == null || !_isPlayerInitialized) {
|
||||
_recordLifecycleState('hidden', action: 'skipped_no_player');
|
||||
@@ -511,6 +515,7 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen> with WidgetsBindin
|
||||
|
||||
Future<void> _handleAppResumed() async {
|
||||
_recordLifecycleState('resumed', action: 'begin');
|
||||
_watchTogetherProvider?.setBackgrounded(false);
|
||||
|
||||
if (Platform.isAndroid && _androidAutoPipTransitionInFlight && !PipService().isPipActive.value) {
|
||||
_setAndroidAutoPipTransitionInFlight(false, reason: 'resume_without_pip');
|
||||
|
||||
@@ -402,6 +402,11 @@ class WatchTogetherProvider with ChangeNotifier {
|
||||
appLogger.d('WatchTogether: Player detached from sync manager');
|
||||
}
|
||||
|
||||
/// Suppress position sync while the app is backgrounded.
|
||||
void setBackgrounded(bool value) {
|
||||
_syncManager?.setBackgrounded(value);
|
||||
}
|
||||
|
||||
/// Set up listeners for peer service events
|
||||
void _setupPeerServiceListeners() {
|
||||
_peerConnectedSubscription = _peerService!.onPeerConnected.listen((peerId) {
|
||||
|
||||
@@ -79,6 +79,9 @@ class WatchTogetherSyncManager {
|
||||
// Whether we've announced our player as ready (first buffering: false)
|
||||
bool _hasAnnouncedReady = false;
|
||||
|
||||
// Whether the app is backgrounded (suppress heartbeats to avoid stale positions)
|
||||
bool _backgrounded = false;
|
||||
|
||||
// Callbacks
|
||||
SessionConfigCallback? onSessionConfigReceived;
|
||||
SyncStateCallback? onSyncStateChanged;
|
||||
@@ -204,6 +207,7 @@ class WatchTogetherSyncManager {
|
||||
}
|
||||
_positionSyncTimer?.cancel();
|
||||
_positionSyncTimer = null;
|
||||
_backgrounded = false;
|
||||
|
||||
appLogger.d('WatchTogether: Player detached');
|
||||
}
|
||||
@@ -313,7 +317,7 @@ class WatchTogetherSyncManager {
|
||||
void _startPositionSync() {
|
||||
_positionSyncTimer?.cancel();
|
||||
_positionSyncTimer = Timer.periodic(positionSyncInterval, (_) {
|
||||
if (_player != null && _session.isHost) {
|
||||
if (_player != null && _session.isHost && !_backgrounded) {
|
||||
_peerService.broadcast(
|
||||
SyncMessage.positionSync(
|
||||
_player!.state.position,
|
||||
@@ -956,6 +960,16 @@ class WatchTogetherSyncManager {
|
||||
}
|
||||
}
|
||||
|
||||
/// Suppress heartbeats while the app is backgrounded.
|
||||
///
|
||||
/// macOS App Nap can throttle the event loop, causing stale position reads.
|
||||
/// Guests would drift-correct to the stale position every heartbeat, making
|
||||
/// playback loop. Pausing heartbeats avoids this; drift correction catches
|
||||
/// up when the app returns to the foreground.
|
||||
void setBackgrounded(bool value) {
|
||||
_backgrounded = value;
|
||||
}
|
||||
|
||||
/// Re-announce player readiness after reconnect.
|
||||
///
|
||||
/// During reconnect the host resets our _peerReady entry to false via
|
||||
|
||||
Reference in New Issue
Block a user