tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 0bf980d7abf0f0fa3cb9c8904556fe7de61ffb10
parent d0a896ca628bff9eb5710a19bf34849e4ddc0fcf
Author: alwu <alwu@mozilla.com>
Date:   Wed, 22 Oct 2025 18:53:29 +0000

Bug 1990812 - handle the case where switching the decoder state machine fails due to shutdown. r=media-playback-reviewers,chunmin

We will not create a new state machine if the decoder has already been shut
down. In this case, the old state machine will still report as unsupported,
which currently triggers a MOZ_DIAGNOSTIC_CRASH.

Instead of crashing, we should simply reject the promise.

Differential Revision: https://phabricator.services.mozilla.com/D268464

Diffstat:
Mdom/media/MediaDecoder.cpp | 14++++++++------
Mdom/media/MediaDecoder.h | 3++-
2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/dom/media/MediaDecoder.cpp b/dom/media/MediaDecoder.cpp @@ -381,7 +381,7 @@ void MediaDecoder::OnPlaybackErrorEvent(const MediaResult& aError) { #ifdef MOZ_WMF_MEDIA_ENGINE if (aError == NS_ERROR_DOM_MEDIA_EXTERNAL_ENGINE_NOT_SUPPORTED_ERR || aError == NS_ERROR_DOM_MEDIA_CDM_PROXY_NOT_SUPPORTED_ERR) { - SwitchStateMachine(aError); + Unused << SwitchStateMachine(aError); return; } #endif @@ -389,12 +389,12 @@ void MediaDecoder::OnPlaybackErrorEvent(const MediaResult& aError) { } #ifdef MOZ_WMF_MEDIA_ENGINE -void MediaDecoder::SwitchStateMachine(const MediaResult& aError) { +bool MediaDecoder::SwitchStateMachine(const MediaResult& aError) { MOZ_ASSERT(aError == NS_ERROR_DOM_MEDIA_EXTERNAL_ENGINE_NOT_SUPPORTED_ERR || aError == NS_ERROR_DOM_MEDIA_CDM_PROXY_NOT_SUPPORTED_ERR); // Already in shutting down decoder, no need to create another state machine. if (mPlayState == PLAY_STATE_SHUTDOWN) { - return; + return false; } // External engine can't play the resource or we intentionally disable it, try @@ -473,6 +473,7 @@ void MediaDecoder::SwitchStateMachine(const MediaResult& aError) { discardStateMachine->BeginShutdown()->Then( AbstractThread::MainThread(), __func__, [discardStateMachine] {}); + return true; } #endif @@ -1513,12 +1514,13 @@ RefPtr<SetCDMPromise> MediaDecoder::SetCDMProxy(CDMProxy* aProxy) { // given CDM proxy. LOG("CDM proxy %s not supported! Switch to another state machine.", NS_ConvertUTF16toUTF8(aProxy->KeySystem()).get()); - SwitchStateMachine( + bool switched = SwitchStateMachine( MediaResult{NS_ERROR_DOM_MEDIA_CDM_PROXY_NOT_SUPPORTED_ERR, aProxy}); rv = GetStateMachine()->IsCDMProxySupported(aProxy); if (NS_FAILED(rv)) { - MOZ_DIAGNOSTIC_CRASH("CDM proxy not supported after switch!"); - LOG("CDM proxy not supported after switch!"); + MOZ_DIAGNOSTIC_ASSERT( + !switched, "We should only reach here if we failed to switch"); + LOG("CDM proxy is still not supported!"); return SetCDMPromise::CreateAndReject(rv, __func__); } } diff --git a/dom/media/MediaDecoder.h b/dom/media/MediaDecoder.h @@ -565,7 +565,8 @@ class MediaDecoder : public DecoderDoctorLifeLogger<MediaDecoder> { void ConnectMirrors(MediaDecoderStateMachineBase* aObject); void DisconnectMirrors(); # ifdef MOZ_WMF_MEDIA_ENGINE - void SwitchStateMachine(const MediaResult& aError); + // Return true if we switched to a new state machine. + bool SwitchStateMachine(const MediaResult& aError); # endif virtual bool CanPlayThroughImpl() = 0;