refactor: pin the look-alike code paths that must not be merged
Several pairs of near-identical code paths differ in one load-bearing line. Each site now carries a comment naming the invariant that forces it apart, backed by a characterization test so a future deduplication fails loudly instead of silently changing behaviour. Pinned: focusable wrapper vs. chip D-pad activation policy, profile connection cleanup's raw-id vs. ServerId-typed server projections, live TV tab loaders, video player display matching and playback service wiring, track selection container ordering, tracker HTTP client status ladder, and the MediaServerHttpClient shutdown/cancellation contract versus ManagedHttpClient's closing guard. New tests: test/focus/dpad_activation_policy_test.dart test/services/track_selection_container_ordinal_test.dart test/services/trackers/tracker_status_ladder_test.dart test/utils/media_server_http_client_shutdown_test.dart
This commit is contained in:
@@ -1509,6 +1509,11 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen> with WidgetsBindin
|
||||
_chromeController.dispose();
|
||||
_toastController.dispose();
|
||||
|
||||
// The release sequence below mirrors _tearDownFailedPlayerAttempt but is
|
||||
// deliberately separate: dispose() cannot await, and it destroys the
|
||||
// notifiers, focus nodes and player that the rollback path keeps alive
|
||||
// for a retry on a still-mounted screen.
|
||||
//
|
||||
// Stop progress tracking and send final state. Normal back navigation
|
||||
// awaits this before popping; dispose keeps a fallback for externally
|
||||
// removed routes where dispose() cannot await.
|
||||
@@ -1531,6 +1536,9 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen> with WidgetsBindin
|
||||
SleepTimerService().markNeedsRestart();
|
||||
}
|
||||
|
||||
// Teardown scope: every subscription the screen ever owns, including the
|
||||
// initState-owned sleep-timer and Apple TV ones that the rollback path
|
||||
// must leave alive.
|
||||
_playingSubscription?.cancel();
|
||||
_completedSubscription?.cancel();
|
||||
_errorSubscription?.cancel();
|
||||
@@ -1577,6 +1585,9 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen> with WidgetsBindin
|
||||
FullscreenStateManager().removeListener(_onFullscreenChanged);
|
||||
_fullscreenListenerAttached = false;
|
||||
}
|
||||
// Not _restoreWindowsDisplayMode(): that helper waits 200ms after clearing
|
||||
// the HDR hint before restoring, which dispose() cannot do. Fire the hint
|
||||
// clear at the still-live player and restore immediately.
|
||||
if (!isReplacingWithVideo &&
|
||||
Platform.isWindows &&
|
||||
_displayModeService != null &&
|
||||
|
||||
Reference in New Issue
Block a user